openssl-1.0.0 upgrade

external/openssl

    Updated version to 1.0.0
	openssl.version

    Updated small records patch for 1.0.0. This is probably the most significant change.
	patches/small_records.patch

    Removed bad_version.patch since fix is included in 0.9.8n and beyond
	patches/README
	patches/bad_version.patch
	openssl.config

    Changed import_openssl.sh to generate armv4 asm with the 1.0.0
    scripts, not our backported 0.9.9-dev backported version in
    patches/arm-asm.patch.
	import_openssl.sh
	openssl.config
	patches/README
	patches/arm-asm.patch

    Added -DOPENSSL_NO_STORE to match ./Configure output
    Added -DOPENSSL_NO_WHIRLPOOL (no-whrlpool) to skip new optional cipher
	android-config.mk
	openssl.config

    Fixed import to remove include directory during import like other
    imported directories (apps, ssl, crypto)
	import_openssl.sh

    Updated UNNEEDED_SOURCES. Pruned Makefiles which we don't use.
	openssl.config

    Updated to build newly required files
	patches/apps_Android.mk
	patches/crypto_Android.mk

    Disable some new openssl tools
	patches/progs.patch

    Updated upgrade testing notes to include running BigInteger tests
	README.android

    Automatically imported
	android.testssl/
	apps/
	crypto/
	e_os.h
	e_os2.h
	include/
	ssl/

dalvik

   Change makeCipherList to skip SSLv2 ciphers that 1.0.0 now returns
   so there are not duplicate ciphersuite names in getEnabledCipherSuites.
	libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp

   Updated OpenSSLSocketImpl_cipherauthenticationmethod for new
   SSL_CIPHER algorithms -> algorithm_auth (and const-ness)
	libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp

   Update to const SSL_CIPHER in OpenSSLSessionImpl_getCipherSuite (and cipherauthenticationmethod)
	libcore/x-net/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp

   test_EnabledCipherSuites on both SSLSocketTest and
   SSLServerSocketTest caught the makeCipherList problem. However the
   asserts where a bit out of sync and didn't give good messages
   because they didn't actually show what was going on. As part of
   debugging the issue they found, I tried to make align the asserts
   and improve their output for the future.

	libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java
	libcore/x-net/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java

vendor/google

    Add const to X509V3_EXT_METHOD* for 1.0.0 compatibility
	libraries/libjingle/talk/base/openssladapter.cc

Change-Id: I90fb1566dede6034eebc96d2b0dcf4533d9643bf
diff --git a/ssl/Makefile b/ssl/Makefile
index 5ac3507..2b275fa 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -53,7 +53,7 @@
 top:
 	(cd ..; $(MAKE) DIRS=$(DIR) all)
 
-all:	lib
+all:	shared
 
 lib:	$(LIBOBJ)
 	$(AR) $(LIB) $(LIBOBJ)
@@ -106,45 +106,43 @@
 # 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/bn.h ../include/openssl/buffer.h
-bio_ssl.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-bio_ssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-bio_ssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-bio_ssl.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-bio_ssl.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h
-bio_ssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-bio_ssl.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-bio_ssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-bio_ssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-bio_ssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-bio_ssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h bio_ssl.c
+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/bn.h ../include/openssl/buffer.h
-d1_both.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_both.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-d1_both.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-d1_both.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-d1_both.o: ../include/openssl/err.h ../include/openssl/evp.h
-d1_both.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-d1_both.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-d1_both.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_both.o: ../include/openssl/x509_vfy.h d1_both.c ssl_locl.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
@@ -152,14 +150,13 @@
 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/fips.h
-d1_clnt.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
-d1_clnt.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-d1_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-d1_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-d1_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-d1_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_clnt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.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
@@ -168,90 +165,83 @@
 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/bn.h ../include/openssl/buffer.h
-d1_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-d1_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-d1_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-d1_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-d1_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h
-d1_enc.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
-d1_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_enc.c
-d1_enc.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-d1_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-d1_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-d1_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-d1_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
-d1_lib.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-d1_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_lib.c
-d1_lib.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-d1_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-d1_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-d1_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-d1_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
-d1_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-d1_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-d1_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-d1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-d1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-d1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-d1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_meth.c
-d1_meth.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-d1_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-d1_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-d1_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-d1_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-d1_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
-d1_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-d1_pkt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-d1_pkt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_pkt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_pkt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_pkt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_pkt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_pkt.o: ../include/openssl/x509_vfy.h d1_pkt.c ssl_locl.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
@@ -259,14 +249,13 @@
 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/fips.h
-d1_srvr.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
-d1_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-d1_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-d1_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-d1_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-d1_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.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
@@ -275,276 +264,257 @@
 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/bn.h ../include/openssl/buffer.h
-kssl.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-kssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-kssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-kssl.o: ../include/openssl/ecdsa.h ../include/openssl/evp.h
-kssl.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h
-kssl.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-kssl.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-kssl.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-kssl.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-kssl.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-kssl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl.c
+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/bn.h ../include/openssl/buffer.h
-s23_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_clnt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s23_clnt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s23_clnt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s23_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
-s23_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s23_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s23_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_clnt.o: ../include/openssl/x509_vfy.h s23_clnt.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-s23_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s23_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s23_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s23_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
-s23_lib.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s23_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_lib.c
-s23_lib.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s23_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s23_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s23_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s23_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
-s23_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s23_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_meth.c
-s23_meth.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s23_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s23_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s23_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s23_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
-s23_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s23_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s23_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s23_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s23_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s23_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s23_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s23_pkt.c
-s23_pkt.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s23_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s23_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s23_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s23_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s23_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
-s23_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s23_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s23_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s23_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s23_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s23_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s23_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s23_srvr.o: ../include/openssl/x509_vfy.h s23_srvr.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-s2_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_clnt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s2_clnt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s2_clnt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s2_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
-s2_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s2_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s2_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_clnt.o: ../include/openssl/x509_vfy.h s2_clnt.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-s2_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s2_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s2_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s2_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-s2_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s2_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_enc.c
-s2_enc.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s2_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s2_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s2_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s2_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
-s2_lib.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h
-s2_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-s2_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_lib.o: ../include/openssl/x509_vfy.h s2_lib.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-s2_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s2_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s2_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s2_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
-s2_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s2_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_meth.c
-s2_meth.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s2_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s2_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s2_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s2_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
-s2_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s2_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s2_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s2_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s2_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s2_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s2_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s2_pkt.c
-s2_pkt.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s2_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s2_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s2_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s2_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s2_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
-s2_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s2_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s2_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s2_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s2_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s2_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s2_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s2_srvr.o: ../include/openssl/x509_vfy.h s2_srvr.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-s3_both.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_both.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s3_both.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s3_both.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s3_both.o: ../include/openssl/err.h ../include/openssl/evp.h
-s3_both.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s3_both.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s3_both.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_both.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_both.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.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
@@ -553,13 +523,12 @@
 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/fips.h ../include/openssl/hmac.h
-s3_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s3_clnt.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-s3_clnt.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-s3_clnt.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s3_clnt.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s3_clnt.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.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
@@ -569,90 +538,84 @@
 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/bn.h ../include/openssl/buffer.h
-s3_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s3_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s3_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s3_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-s3_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h
-s3_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-s3_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_enc.o: ../include/openssl/x509_vfy.h s3_enc.c ssl_locl.h
-s3_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_lib.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-s3_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-s3_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-s3_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_lib.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h ../include/openssl/pqueue.h
-s3_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
-s3_lib.o: s3_lib.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-s3_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s3_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s3_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s3_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
-s3_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s3_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_meth.c
-s3_meth.o: ssl_locl.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/bn.h ../include/openssl/buffer.h
-s3_pkt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_pkt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s3_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s3_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s3_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
-s3_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-s3_pkt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_pkt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_pkt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_pkt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_pkt.c
-s3_pkt.o: ssl_locl.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
@@ -660,14 +623,13 @@
 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/fips.h
-s3_srvr.o: ../include/openssl/hmac.h ../include/openssl/krb5_asn.h
-s3_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s3_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-s3_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-s3_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s3_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s3_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.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
@@ -677,47 +639,44 @@
 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/bn.h ../include/openssl/buffer.h
-ssl_algs.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_algs.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_algs.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_algs.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_algs.o: ../include/openssl/err.h ../include/openssl/evp.h
-ssl_algs.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-ssl_algs.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_algs.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_algs.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_algs.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_algs.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_algs.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_algs.c
-ssl_algs.o: ssl_locl.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/bn.h
-ssl_asn1.o: ../include/openssl/buffer.h ../include/openssl/comp.h
-ssl_asn1.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-ssl_asn1.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-ssl_asn1.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-ssl_asn1.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_asn1.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h
-ssl_asn1.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-ssl_asn1.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_asn1.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_asn1.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_asn1.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_asn1.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_asn1.o: ../include/openssl/x509_vfy.h ssl_asn1.c ssl_locl.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
@@ -726,13 +685,12 @@
 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/fips.h
-ssl_cert.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
-ssl_cert.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-ssl_cert.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-ssl_cert.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-ssl_cert.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssl_cert.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.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
@@ -742,19 +700,18 @@
 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/bn.h ../include/openssl/buffer.h
-ssl_ciph.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_ciph.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_ciph.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_ciph.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.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/fips.h ../include/openssl/hmac.h
-ssl_ciph.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-ssl_ciph.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-ssl_ciph.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-ssl_ciph.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-ssl_ciph.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_ciph.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.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
@@ -763,276 +720,256 @@
 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/bn.h ../include/openssl/buffer.h
-ssl_err.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_err.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-ssl_err.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-ssl_err.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_err.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h
-ssl_err.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-ssl_err.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_err.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_err.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_err.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_err.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err.c
+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/bn.h ../include/openssl/buffer.h
-ssl_err2.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_err2.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-ssl_err2.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-ssl_err2.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_err2.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h
-ssl_err2.o: ../include/openssl/pqueue.h ../include/openssl/safestack.h
-ssl_err2.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_err2.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_err2.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_err2.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_err2.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_err2.c
+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/bn.h ../include/openssl/buffer.h
-ssl_lib.o: ../include/openssl/comp.h ../include/openssl/conf.h
-ssl_lib.o: ../include/openssl/crypto.h ../include/openssl/dh.h
-ssl_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_lib.o: ../include/openssl/engine.h ../include/openssl/err.h
-ssl_lib.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h ../include/openssl/pqueue.h
-ssl_lib.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-ssl_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h kssl_lcl.h
-ssl_lib.o: ssl_lib.c ssl_locl.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/bn.h ../include/openssl/buffer.h
-ssl_rsa.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_rsa.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_rsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_rsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_rsa.o: ../include/openssl/err.h ../include/openssl/evp.h
-ssl_rsa.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-ssl_rsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_rsa.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_rsa.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_rsa.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_rsa.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_rsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_rsa.o: ssl_rsa.c
+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/bn.h ../include/openssl/buffer.h
-ssl_sess.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_sess.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_sess.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_sess.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_sess.o: ../include/openssl/engine.h ../include/openssl/err.h
-ssl_sess.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h
-ssl_sess.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
-ssl_sess.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_sess.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_sess.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_sess.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_sess.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_sess.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_sess.o: ssl_sess.c
+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/bn.h ../include/openssl/buffer.h
-ssl_stat.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_stat.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_stat.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_stat.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_stat.o: ../include/openssl/err.h ../include/openssl/evp.h
-ssl_stat.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-ssl_stat.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_stat.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_stat.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_stat.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_stat.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_stat.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_stat.o: ssl_stat.c
+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/bn.h ../include/openssl/buffer.h
-ssl_txt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-ssl_txt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-ssl_txt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-ssl_txt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_txt.o: ../include/openssl/err.h ../include/openssl/evp.h
-ssl_txt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-ssl_txt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_txt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_txt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_txt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_txt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_txt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-ssl_txt.o: ssl_txt.c
+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/bn.h ../include/openssl/buffer.h
-t1_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_clnt.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-t1_clnt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-t1_clnt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-t1_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-t1_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-t1_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_clnt.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_clnt.c
+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/bn.h ../include/openssl/buffer.h
-t1_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_enc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-t1_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-t1_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-t1_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h
-t1_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-t1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_enc.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_enc.c
+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/bn.h ../include/openssl/buffer.h
-t1_lib.o: ../include/openssl/comp.h ../include/openssl/conf.h
-t1_lib.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-t1_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-t1_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-t1_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-t1_lib.o: ../include/openssl/evp.h ../include/openssl/fips.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/pq_compat.h ../include/openssl/pqueue.h
-t1_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-t1_lib.o: ../include/openssl/x509v3.h ssl_locl.h t1_lib.c
+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/bn.h ../include/openssl/buffer.h
-t1_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_meth.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-t1_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-t1_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-t1_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-t1_meth.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_meth.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_meth.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_meth.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_meth.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_meth.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_meth.o: t1_meth.c
+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/bn.h ../include/openssl/buffer.h
-t1_reneg.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_reneg.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-t1_reneg.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-t1_reneg.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-t1_reneg.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_reneg.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-t1_reneg.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_reneg.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_reneg.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_reneg.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_reneg.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_reneg.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_reneg.o: t1_reneg.c
+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/bn.h ../include/openssl/buffer.h
-t1_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-t1_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-t1_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-t1_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-t1_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.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/pq_compat.h ../include/openssl/pqueue.h
-t1_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-t1_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_srvr.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_srvr.c
+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/ssl/bio_ssl.c b/ssl/bio_ssl.c
index 420deb7..af319af 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -398,17 +398,19 @@
 			}
 		break;
 	case BIO_CTRL_POP:
-		/* ugly bit of a hack */
-		if (ssl->rbio != ssl->wbio) /* we are in trouble :-( */
+		/* Only detach if we are the BIO explicitly being popped */
+		if (b == ptr)
 			{
-			BIO_free_all(ssl->wbio);
+			/* 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;
 			}
-		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);
@@ -543,7 +545,6 @@
 	return(ret);
 err:
 	if (con != NULL) BIO_free(con);
-	if (ret != NULL) BIO_free(ret);
 	return(NULL);
 	}
 
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index 0a5c08d..0242f1e 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -226,7 +226,7 @@
 			(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
 
 	if (s->write_hash)
-		mac_size = EVP_MD_size(s->write_hash);
+		mac_size = EVP_MD_CTX_size(s->write_hash);
 	else
 		mac_size = 0;
 
@@ -312,7 +312,7 @@
 				const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
 				int xlen;
 
-				if (frag_off == 0 && s->client_version != DTLS1_BAD_VER)
+				if (frag_off == 0 && s->version != DTLS1_BAD_VER)
 					{
 					/* reconstruct message header is if it
 					 * is being sent in single fragment */
@@ -419,9 +419,10 @@
 			s2n (msg_hdr->seq,p);
 			l2n3(0,p);
 			l2n3(msg_len,p);
-			if (s->client_version != DTLS1_BAD_VER)
-				p       -= DTLS1_HM_HEADER_LENGTH,
+			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)
@@ -485,7 +486,7 @@
 		{
 		/* msg_len is limited to 2^24, but is effectively checked
 		 * against max above */
-		if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH))
+		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;
@@ -567,17 +568,17 @@
 	int i=-1;
 	hm_fragment *frag = NULL;
 	pitem *item = NULL;
-	PQ_64BIT seq64;
+	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 */
-	pq_64bit_init(&seq64);
-	pq_64bit_assign_word(&seq64, msg_hdr->seq);
-	item = pqueue_find(s->d1->buffered_messages, seq64);
-	pq_64bit_free(&seq64);
+	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);
 	
 	/* Discard the message if sequence number was already there, is
 	 * too far in the future, already in the queue or if we received
@@ -601,29 +602,29 @@
 		}
 
 	if (frag_len)
-	{
+		{
 		frag = dtls1_hm_fragment_new(frag_len);
 		if ( frag == NULL)
 			goto err;
 
 		memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
 
-		/* read the body of the fragment (header has already been read) */
+		/* 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;
 
-		pq_64bit_init(&seq64);
-		pq_64bit_assign_word(&seq64, msg_hdr->seq);
+		memset(seq64be,0,sizeof(seq64be));
+		seq64be[6] = (unsigned char)(msg_hdr->seq>>8);
+		seq64be[7] = (unsigned char)(msg_hdr->seq);
 
-		item = pitem_new(seq64, frag);
-		pq_64bit_free(&seq64);
+		item = pitem_new(seq64be, frag);
 		if ( item == NULL)
 			goto err;
 
 		pqueue_insert(s->d1->buffered_messages, item);
-	}
+		}
 
 	return DTLS1_HM_FRAGMENT_RETRY;
 
@@ -757,8 +758,6 @@
 		p= &(d[DTLS1_HM_HEADER_LENGTH]);
 
 		i=s->method->ssl3_enc->final_finish_mac(s,
-			&(s->s3->finish_dgst1),
-			&(s->s3->finish_dgst2),
 			sender,slen,s->s3->tmp.finish_md);
 		s->s3->tmp.finish_md_len = i;
 		memcpy(p, s->s3->tmp.finish_md, i);
@@ -823,12 +822,11 @@
 		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
 		s->init_num=DTLS1_CCS_HEADER_LENGTH;
 
-		if (s->client_version == DTLS1_BAD_VER)
-			{
+		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;
 
@@ -847,21 +845,21 @@
 
 static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
 	{
-		int n;
-		unsigned char *p;
+	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;
+	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;
+	return 1;
 	}
 unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
 	{
@@ -880,7 +878,7 @@
 	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);
@@ -888,6 +886,8 @@
   			}
   
 		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);
@@ -900,7 +900,7 @@
   			}
   		X509_STORE_CTX_cleanup(&xs_ctx);
   		}
-	/* Thawte special :-) */
+  	/* Thawte special :-) */
 	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
 		{
 		x=sk_X509_value(s->ctx->extra_certs,i);
@@ -1004,7 +1004,7 @@
 	{
 	pitem *item;
 	hm_fragment *frag;
-	PQ_64BIT seq64;
+	unsigned char seq64be[8];
 
 	/* this function is called immediately after a message has 
 	 * been serialized */
@@ -1017,7 +1017,7 @@
 	if ( is_ccs)
 		{
 		OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
-			DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
+			       ((s->version==DTLS1_VERSION)?DTLS1_CCS_HEADER_LENGTH:3) == (unsigned int)s->init_num);
 		}
 	else
 		{
@@ -1038,15 +1038,14 @@
 	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));
 
-	pq_64bit_init(&seq64);
-
-	pq_64bit_assign_word(&seq64,
-						 dtls1_get_queue_priority(frag->msg_header.seq,
-												  frag->msg_header.is_ccs));
-		
-	item = pitem_new(seq64, frag);
-	pq_64bit_free(&seq64);
+	item = pitem_new(seq64be, frag);
 	if ( item == NULL)
 		{
 		dtls1_hm_fragment_free(frag);
@@ -1072,7 +1071,7 @@
 	pitem *item;
 	hm_fragment *frag ;
 	unsigned long header_length;
-	PQ_64BIT seq64;
+	unsigned char seq64be[8];
 	struct dtls1_retransmit_state saved_state;
 	unsigned char save_write_sequence[8];
 
@@ -1082,11 +1081,11 @@
 	 */
 
 	/* XDTLS:  the requested message ought to be found, otherwise error */
-	pq_64bit_init(&seq64);
-	pq_64bit_assign_word(&seq64, seq);
+	memset(seq64be,0,sizeof(seq64be));
+	seq64be[6] = (unsigned char)(seq>>8);
+	seq64be[7] = (unsigned char)seq;
 
-	item = pqueue_find(s->d1->sent_messages, seq64);
-	pq_64bit_free(&seq64);
+	item = pqueue_find(s->d1->sent_messages, seq64be);
 	if ( item == NULL)
 		{
 		fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
@@ -1237,7 +1236,7 @@
 static unsigned int 
 dtls1_guess_mtu(unsigned int curr_mtu)
 	{
-	size_t i;
+	unsigned int i;
 
 	if ( curr_mtu == 0 )
 		return g_probable_mtu[0] ;
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 223d116..5bc9eb6 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -4,7 +4,7 @@
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
  */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -115,20 +115,23 @@
 
 #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 SSL_METHOD *dtls1_get_client_method(int ver);
+static const SSL_METHOD *dtls1_get_client_method(int ver);
 static int dtls1_get_hello_verify(SSL *s);
 
-static SSL_METHOD *dtls1_get_client_method(int ver)
+static const SSL_METHOD *dtls1_get_client_method(int ver)
 	{
 	if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
 		return(DTLSv1_client_method());
@@ -144,7 +147,7 @@
 int dtls1_connect(SSL *s)
 	{
 	BUF_MEM *buf=NULL;
-	unsigned long Time=(unsigned long)time(NULL),l;
+	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;;
@@ -296,8 +299,9 @@
 				break;
 				}
 #endif
-			/* Check if it is anon DH */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+			/* 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;
@@ -374,7 +378,6 @@
 			dtls1_start_timer(s);
 			ret=dtls1_send_client_key_exchange(s);
 			if (ret <= 0) goto end;
-			l=s->s3->tmp.new_cipher->algorithms;
 			/* EAY EAY EAY need to check for DH fix cert
 			 * sent back */
 			/* For TLS, cert_req is set to 2, so a cert chain
@@ -471,7 +474,6 @@
 				s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
 				}
 			s->init_num=0;
-
 			break;
 
 #ifndef OPENSSL_NO_TLSEXT
@@ -617,6 +619,7 @@
 		/* 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++) ;
@@ -624,7 +627,7 @@
 			{
 			Time=(unsigned long)time(NULL);	/* Time */
 			l2n(Time,p);
-			RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
+			RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
 			}
 
 		/* Do the message type and length last */
@@ -771,7 +774,7 @@
 	{
 	unsigned char *p,*d;
 	int n;
-	unsigned long l;
+	unsigned long alg_k;
 #ifndef OPENSSL_NO_RSA
 	unsigned char *q;
 	EVP_PKEY *pkey=NULL;
@@ -779,18 +782,26 @@
 #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]);
-
-		l=s->s3->tmp.new_cipher->algorithms;
+		
+		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
                 /* Fool emacs indentation */
                 if (0) {}
 #ifndef OPENSSL_NO_RSA
-		else if (l & SSL_kRSA)
+		else if (alg_k & SSL_kRSA)
 			{
 			RSA *rsa;
 			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
@@ -849,7 +860,7 @@
 			}
 #endif
 #ifndef OPENSSL_NO_KRB5
-		else if (l & SSL_kKRB5)
+		else if (alg_k & SSL_kKRB5)
                         {
                         krb5_error_code	krb5rc;
                         KSSL_CTX	*kssl_ctx = s->kssl_ctx;
@@ -857,7 +868,7 @@
                         krb5_data	*enc_ticket;
                         krb5_data	authenticator, *authp = NULL;
 			EVP_CIPHER_CTX	ciph_ctx;
-			EVP_CIPHER	*enc = NULL;
+			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 
@@ -868,7 +879,7 @@
 
 #ifdef KSSL_DEBUG
                         printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
-                                l, SSL_kKRB5);
+                                alg_k, SSL_kKRB5);
 #endif	/* KSSL_DEBUG */
 
 			authp = NULL;
@@ -958,7 +969,7 @@
 				sizeof tmp_buf);
 			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
 			outl += padl;
-			if (outl > sizeof epms)
+			if (outl > (int)sizeof epms)
 				{
 				SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
 				goto err;
@@ -981,7 +992,7 @@
                         }
 #endif
 #ifndef OPENSSL_NO_DH
-		else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 			{
 			DH *dh_srvr,*dh_clnt;
 
@@ -1036,6 +1047,274 @@
 			/* 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);
@@ -1064,6 +1343,13 @@
 	/* 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);
 	}
 
@@ -1076,7 +1362,7 @@
 	unsigned u=0;
 #endif
 	unsigned long n;
-#ifndef OPENSSL_NO_DSA
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
 	int j;
 #endif
 
@@ -1086,14 +1372,16 @@
 		p= &(d[DTLS1_HM_HEADER_LENGTH]);
 		pkey=s->cert->key->privatekey;
 
-		s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),
+		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,
-				&(s->s3->finish_dgst1),&(data[0]));
+				NID_md5,
+				&(data[0]));
 			if (RSA_sign(NID_md5_sha1, data,
 					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
 					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
@@ -1122,6 +1410,23 @@
 			}
 		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;
diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c
index 3dfa5ad..8fa5734 100644
--- a/ssl/d1_enc.c
+++ b/ssl/d1_enc.c
@@ -136,8 +136,12 @@
 
 	if (send)
 		{
-		if (s->write_hash != NULL)
-			n=EVP_MD_size(s->write_hash);
+		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)
@@ -158,8 +162,12 @@
 		}
 	else
 		{
-		if (s->read_hash != NULL)
-			n=EVP_MD_size(s->read_hash);
+		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)
@@ -206,11 +214,10 @@
 		{
                 unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
-                        (void *)ds,rec->data,rec->input,l);
-		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\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,
-                        (unsigned long)DES_KEY_SZ,
-			(unsigned long)DES_SCHEDULE_SZ,
+                        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]);
@@ -235,10 +242,10 @@
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long ki;
+                unsigned long i;
                 printf("\trec->data=");
-		for (ki=0; ki<l; ki++)
-                        printf(" %02x", rec->data[ki]);  printf("\n");
+		for (i=0; i<l; i++)
+                        printf(" %02x", rec->data[i]);  printf("\n");
                 }
 #endif	/* KSSL_DEBUG */
 
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index 63bfbac..eeffce3 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -91,11 +91,6 @@
 	return(60*60*2);
 	}
 
-IMPLEMENT_dtls1_meth_func(dtlsv1_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int dtls1_new(SSL *s)
 	{
 	DTLS1_STATE *d1;
@@ -105,17 +100,6 @@
 	memset(d1,0, sizeof *d1);
 
 	/* d1->handshake_epoch=0; */
-#if defined(OPENSSL_SYS_VMS) || defined(VMS_TEST)
-	d1->bitmap.length=64;
-#else
-	d1->bitmap.length=sizeof(d1->bitmap.map) * 8;
-#endif
-	pq_64bit_init(&(d1->bitmap.map));
-	pq_64bit_init(&(d1->bitmap.max_seq_num));
-	
-	d1->next_bitmap.length = d1->bitmap.length;
-	pq_64bit_init(&(d1->next_bitmap.map));
-	pq_64bit_init(&(d1->next_bitmap.max_seq_num));
 
 	d1->unprocessed_rcds.q=pqueue_new();
 	d1->processed_rcds.q=pqueue_new();
@@ -185,19 +169,13 @@
 	pqueue_free(s->d1->sent_messages);
 
 	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);
-	}
+		}
 	pqueue_free(s->d1->buffered_app_data.q);
-	
-	pq_64bit_free(&(s->d1->bitmap.map));
-	pq_64bit_free(&(s->d1->bitmap.max_seq_num));
-
-	pq_64bit_free(&(s->d1->next_bitmap.map));
-	pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
 
 	OPENSSL_free(s->d1);
 	}
@@ -244,13 +222,13 @@
  * to explicitly list their SSL_* codes. Currently RC4 is the only one
  * available, but if new ones emerge, they will have to be added...
  */
-SSL_CIPHER *dtls1_get_cipher(unsigned int u)
+const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
 	{
-	SSL_CIPHER *ciph = ssl3_get_cipher(u);
+	const SSL_CIPHER *ciph = ssl3_get_cipher(u);
 
 	if (ciph != NULL)
 		{
-		if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4)
+		if (ciph->algorithm_enc == SSL_RC4)
 			return NULL;
 		}
 
diff --git a/ssl/d1_meth.c b/ssl/d1_meth.c
index 8a6cf31..5c4004b 100644
--- a/ssl/d1_meth.c
+++ b/ssl/d1_meth.c
@@ -61,8 +61,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *dtls1_get_method(int ver);
-static SSL_METHOD *dtls1_get_method(int ver)
+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());
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 2af5272..13ffc75 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -122,10 +122,53 @@
 #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,
-	PQ_64BIT *seq_num);
+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);
@@ -134,11 +177,8 @@
 	unsigned short *priority, unsigned long *offset);
 #endif
 static int dtls1_buffer_record(SSL *s, record_pqueue *q,
-	PQ_64BIT *priority);
+	unsigned char *priority);
 static int dtls1_process_record(SSL *s);
-#if PQ_64BIT_IS_INTEGER
-static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num);
-#endif
 static void dtls1_clear_timeouts(SSL *s);
 
 /* copy buffered record into SSL structure */
@@ -162,9 +202,9 @@
 
 
 static int
-dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority)
-{
-    DTLS1_RECORD_DATA *rdata;
+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 */
@@ -172,7 +212,7 @@
 		return 0;
 		
 	rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA));
-	item = pitem_new(*priority, rdata);
+	item = pitem_new(priority, rdata);
 	if (rdata == NULL || item == NULL)
 		{
 		if (rdata != NULL) OPENSSL_free(rdata);
@@ -211,7 +251,7 @@
 		}
 	
 	return(1);
-    }
+	}
 
 
 static int
@@ -267,7 +307,7 @@
             if ( ! dtls1_process_record(s))
                 return(0);
             dtls1_buffer_record(s, &(s->d1->processed_rcds), 
-                &s->s3->rrec.seq_num);
+                s->s3->rrec.seq_num);
             }
         }
 
@@ -328,17 +368,17 @@
 static int
 dtls1_process_record(SSL *s)
 {
-    int i,al;
+	int i,al;
 	int clear=0;
-    int enc_err;
+	int enc_err;
 	SSL_SESSION *sess;
-    SSL3_RECORD *rr;
+	SSL3_RECORD *rr;
 	unsigned int mac_size;
 	unsigned char md[EVP_MAX_MD_SIZE];
 
 
 	rr= &(s->s3->rrec);
-    sess = s->session;
+	sess = s->session;
 
 	/* At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
 	 * and we have that many bytes in s->packet
@@ -384,14 +424,18 @@
 #endif
 
 	/* r->length is now the compressed data plus mac */
-if (	(sess == NULL) ||
+	if (	(sess == NULL) ||
 		(s->enc_read_ctx == NULL) ||
 		(s->read_hash == NULL))
-    clear=1;
+		clear=1;
 
 	if (!clear)
 		{
-		mac_size=EVP_MD_size(s->read_hash);
+		/* !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)
 			{
@@ -416,7 +460,7 @@
 			}
 		rr->length-=mac_size;
 		i=s->method->ssl3_enc->mac(s,md,0);
-		if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
+		if (i < 0 || memcmp(md,&(rr->data[rr->length]),mac_size) != 0)
 			{
 			goto decryption_failed_or_bad_record_mac;
 			}
@@ -457,8 +501,8 @@
 
 	/* 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);
+	dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */
+	return(1);
 
 decryption_failed_or_bad_record_mac:
 	/* Separate 'decryption_failed' alert was introduced with TLS 1.0,
@@ -498,10 +542,10 @@
 	rr= &(s->s3->rrec);
 	sess=s->session;
 
-    /* The epoch may have changed.  If so, process all the
-     * pending records.  This is a non-blocking operation. */
-    if ( ! dtls1_process_buffered_records(s))
-        return 0;
+	/* The epoch may have changed.  If so, process all the
+	 * pending records.  This is a non-blocking operation. */
+	if ( ! dtls1_process_buffered_records(s))
+            return 0;
 
 	/* if we're renegotiating, then there may be buffered records */
 	if (dtls1_get_processed_record(s))
@@ -545,7 +589,7 @@
 		/* Lets check version */
 		if (!s->first_packet)
 			{
-			if (version != s->version && version != DTLS1_BAD_VER)
+			if (version != s->version)
 				{
 				/* unexpected version, silently discard */
 				rr->length = 0;
@@ -554,8 +598,7 @@
 				}
 			}
 
-		if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
-		    (version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
+		if ((version & 0xff00) != (s->version & 0xff00))
 			{
 			/* wrong version, silently discard record */
 			rr->length = 0;
@@ -589,7 +632,6 @@
 			s->packet= &(s->s3->rbuf.buf[0]);
 			}
 
-		s->client_version = version;
 		/* now s->rstate == SSL_ST_READ_BODY */
 		}
 
@@ -618,13 +660,13 @@
 	/* 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 */
+		{
+		rr->length = 0;
+		s->packet_length = 0;  /* dump this record */
+		goto again;   /* get another record */
 		}
 
- 	/* Check whether this is a repeat, or aged 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
@@ -632,7 +674,7 @@
 	 */
 	if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE &&
 		*p == SSL3_MT_CLIENT_HELLO) &&
-		! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
+		!dtls1_record_replay_check(s, bitmap))
 		{
 		rr->length = 0;
 		s->packet_length=0; /* dump this record */
@@ -642,21 +684,22 @@
 	/* just read a 0 length packet */
 	if (rr->length == 0) goto again;
 
-    /* If this record is from the next epoch (either HM or ALERT), buffer it
-     * since it cannot be processed at this time.
-     * Records from the next epoch are marked as received even though they are 
-     * not processed, so as to prevent any potential resource DoS attack */
-    if (is_next_epoch)
-        {
-        dtls1_record_bitmap_update(s, bitmap);
-        dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num);
-	rr->length = 0;
-        s->packet_length = 0;
-        goto again;
-        }
+	/* If this record is from the next epoch (either HM or ALERT),
+	 * buffer it since it cannot be processed at this time. Records
+	 * from the next epoch are marked as received even though they
+	 * are not processed, so as to prevent any potential resource
+	 * DoS attack */
+	if (is_next_epoch)
+		{
+		dtls1_record_bitmap_update(s, bitmap);
+		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))
-        return(0);
+	if ( ! dtls1_process_record(s))
+		return(0);
 
 	dtls1_clear_timeouts(s);  /* done waiting */
 	return(1);
@@ -1066,13 +1109,14 @@
 
 		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 (s->client_version == DTLS1_BAD_VER || s->version == DTLS1_BAD_VER)
-			ccs_hdr_len = 3;
-
-		if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
+		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);
@@ -1102,7 +1146,7 @@
 		/* do this whenever CCS is processed */
 		dtls1_reset_seq_numbers(s, SSL3_CC_READ);
 
-		if (s->client_version == DTLS1_BAD_VER)
+		if (s->version == DTLS1_BAD_VER)
 			s->d1->handshake_read_seq++;
 
 		goto start;
@@ -1356,13 +1400,17 @@
 
 	if (	(sess == NULL) ||
 		(s->enc_write_ctx == NULL) ||
-		(s->write_hash == NULL))
+		(EVP_MD_CTX_md(s->write_hash) == NULL))
 		clear=1;
 
 	if (clear)
 		mac_size=0;
 	else
-		mac_size=EVP_MD_size(s->write_hash);
+		{
+		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
@@ -1395,7 +1443,6 @@
 		s->s3->empty_fragment_done = 1;
 		}
 #endif
-
 	p = wb->buf + prefix_len;
 
 	/* write the header */
@@ -1403,12 +1450,8 @@
 	*(p++)=type&0xff;
 	wr->type=type;
 
-	if (s->client_version == DTLS1_BAD_VER)
-		*(p++) = DTLS1_BAD_VER>>8,
-		*(p++) = DTLS1_BAD_VER&0xff;
-	else
-		*(p++)=(s->version>>8),
-		*(p++)=s->version&0xff;
+	*(p++)=(s->version>>8);
+	*(p++)=s->version&0xff;
 
 	/* field where we are to write out packet epoch, seq num and len */
 	pseq=p; 
@@ -1453,7 +1496,8 @@
 
 	if (mac_size != 0)
 		{
-		s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1);
+		if(s->method->ssl3_enc->mac(s,&(p[wr->length + bs]),1) < 0)
+			goto err;
 		wr->length+=mac_size;
 		}
 
@@ -1530,111 +1574,50 @@
 
 
 
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap,
-	PQ_64BIT *seq_num)
+static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
 	{
-#if PQ_64BIT_IS_INTEGER
-	PQ_64BIT mask = 0x0000000000000001L;
-#endif
-	PQ_64BIT rcd_num, tmp;
+	int cmp;
+	unsigned int shift;
+	const unsigned char *seq = s->s3->read_sequence;
 
-	pq_64bit_init(&rcd_num);
-	pq_64bit_init(&tmp);
-
-	/* this is the sequence number for the record just read */
-	pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
-
-	
-	if (pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
-		pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
+	cmp = satsub64be(seq,bitmap->max_seq_num);
+	if (cmp > 0)
 		{
-		pq_64bit_assign(seq_num, &rcd_num);
-		pq_64bit_free(&rcd_num);
-		pq_64bit_free(&tmp);
-		return 1;  /* this record is new */
+		memcpy (s->s3->rrec.seq_num,seq,8);
+		return 1; /* this record in new */
 		}
-
-	pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
-
-	if ( pq_64bit_get_word(&tmp) > bitmap->length)
-		{
-		pq_64bit_free(&rcd_num);
-		pq_64bit_free(&tmp);
-		return 0;  /* stale, outside the window */
-		}
-
-#if PQ_64BIT_IS_BIGNUM
-	{
-	int offset;
-	pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
-	pq_64bit_sub_word(&tmp, 1);
-	offset = pq_64bit_get_word(&tmp);
-	if ( pq_64bit_is_bit_set(&(bitmap->map), offset))
-		{
-		pq_64bit_free(&rcd_num);
-		pq_64bit_free(&tmp);
-		return 0;
-		}
-	}
-#else
-	mask <<= (bitmap->max_seq_num - rcd_num - 1);
-	if (bitmap->map & mask)
+	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 */
-#endif
-	
-	pq_64bit_assign(seq_num, &rcd_num);
-	pq_64bit_free(&rcd_num);
-	pq_64bit_free(&tmp);
+
+	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;
-	PQ_64BIT rcd_num;
-	PQ_64BIT tmp;
-	PQ_64BIT_CTX *ctx;
+	const unsigned char *seq = s->s3->read_sequence;
 
-	pq_64bit_init(&rcd_num);
-	pq_64bit_init(&tmp);
-
-	pq_64bit_bin2num(&rcd_num, s->s3->read_sequence, 8);
-
-	/* unfortunate code complexity due to 64-bit manipulation support
-	 * on 32-bit machines */
-	if ( pq_64bit_gt(&rcd_num, &(bitmap->max_seq_num)) ||
-		pq_64bit_eq(&rcd_num, &(bitmap->max_seq_num)))
+	cmp = satsub64be(seq,bitmap->max_seq_num);
+	if (cmp > 0)
 		{
-		pq_64bit_sub(&tmp, &rcd_num, &(bitmap->max_seq_num));
-		pq_64bit_add_word(&tmp, 1);
-
-		shift = (unsigned int)pq_64bit_get_word(&tmp);
-
-		pq_64bit_lshift(&(tmp), &(bitmap->map), shift);
-		pq_64bit_assign(&(bitmap->map), &tmp);
-
-		pq_64bit_set_bit(&(bitmap->map), 0);
-		pq_64bit_add_word(&rcd_num, 1);
-		pq_64bit_assign(&(bitmap->max_seq_num), &rcd_num);
-
-		pq_64bit_assign_word(&tmp, 1);
-		pq_64bit_lshift(&tmp, &tmp, bitmap->length);
-		ctx = pq_64bit_ctx_new(&ctx);
-		pq_64bit_mod(&(bitmap->map), &(bitmap->map), &tmp, ctx);
-		pq_64bit_ctx_free(ctx);
+		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
-		{
-		pq_64bit_sub(&tmp, &(bitmap->max_seq_num), &rcd_num);
-		pq_64bit_sub_word(&tmp, 1);
-		shift = (unsigned int)pq_64bit_get_word(&tmp);
-
-		pq_64bit_set_bit(&(bitmap->map), shift);
+	else	{
+		shift = -cmp;
+		if (shift < sizeof(bitmap->map)*8)
+			bitmap->map |= 1UL<<shift;
 		}
-
-	pq_64bit_free(&rcd_num);
-	pq_64bit_free(&tmp);
 	}
 
 
@@ -1681,7 +1664,7 @@
 #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)
@@ -1800,17 +1783,8 @@
 		{
 		seq = s->s3->read_sequence;
 		s->d1->r_epoch++;
-
-		pq_64bit_assign(&(s->d1->bitmap.map), &(s->d1->next_bitmap.map));
-		s->d1->bitmap.length = s->d1->next_bitmap.length;
-		pq_64bit_assign(&(s->d1->bitmap.max_seq_num), 
-			&(s->d1->next_bitmap.max_seq_num));
-
-		pq_64bit_free(&(s->d1->next_bitmap.map));
-		pq_64bit_free(&(s->d1->next_bitmap.max_seq_num));
+		memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
 		memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
-		pq_64bit_init(&(s->d1->next_bitmap.map));
-		pq_64bit_init(&(s->d1->next_bitmap.max_seq_num));
 		}
 	else
 		{
@@ -1822,26 +1796,6 @@
 	memset(seq, 0x00, seq_bytes);
 	}
 
-#if PQ_64BIT_IS_INTEGER
-static PQ_64BIT
-bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num)
-       {
-       PQ_64BIT _num;
-
-       _num = (((PQ_64BIT)bytes[0]) << 56) |
-               (((PQ_64BIT)bytes[1]) << 48) |
-               (((PQ_64BIT)bytes[2]) << 40) |
-               (((PQ_64BIT)bytes[3]) << 32) |
-               (((PQ_64BIT)bytes[4]) << 24) |
-               (((PQ_64BIT)bytes[5]) << 16) |
-               (((PQ_64BIT)bytes[6]) <<  8) |
-               (((PQ_64BIT)bytes[7])      );
-
-	   *num = _num ;
-       return _num;
-       }
-#endif
-
 
 static void
 dtls1_clear_timeouts(SSL *s)
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 5b31366..301ceda 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -4,7 +4,7 @@
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
  */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -121,14 +121,15 @@
 #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 SSL_METHOD *dtls1_get_server_method(int ver);
+static const SSL_METHOD *dtls1_get_server_method(int ver);
 static int dtls1_send_hello_verify_request(SSL *s);
 
-static SSL_METHOD *dtls1_get_server_method(int ver)
+static const SSL_METHOD *dtls1_get_server_method(int ver)
 	{
 	if (ver == DTLS1_VERSION)
 		return(DTLSv1_server_method());
@@ -144,8 +145,9 @@
 int dtls1_accept(SSL *s)
 	{
 	BUF_MEM *buf;
-	unsigned long l,Time=(unsigned long)time(NULL);
+	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;
 
@@ -290,8 +292,8 @@
 			s->state=SSL3_ST_SW_FLUSH;
 			s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
 
-			/* HelloVerifyRequests resets Finished MAC */
-			if (s->client_version != DTLS1_BAD_VER)
+			/* HelloVerifyRequest resets Finished MAC */
+			if (s->version != DTLS1_BAD_VER)
 				ssl3_init_finished_mac(s);
 			break;
 			
@@ -321,8 +323,9 @@
 
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
-			/* Check if it is anon DH */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+			/* 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);
@@ -350,13 +353,13 @@
 
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
-			l=s->s3->tmp.new_cipher->algorithms;
+			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
-				&& !(l & SSL_KRB5)
+				&& !(alg_k & SSL_kKRB5)
 #endif /* OPENSSL_NO_KRB5 */
 				)
 				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
@@ -367,11 +370,17 @@
 			else
 				s->s3->tmp.use_rsa_tmp=0;
 
-			/* only send if a DH key exchange, fortezza or
+			/* only send if a DH key exchange or
 			 * RSA but we have a sign only certificate */
 			if (s->s3->tmp.use_rsa_tmp
-			    || (l & (SSL_DH|SSL_kFZA))
-			    || ((l & SSL_kRSA)
+			/* 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)
@@ -402,12 +411,15 @@
 				/* never request cert in anonymous ciphersuites
 				 * (see section "Certificate request" in SSL 3 drafts
 				 * and in RFC 2246): */
-				((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
+				((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->algorithms & SSL_aKRB5))
+				 /* 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;
@@ -479,15 +491,30 @@
 			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,
-				&(s->s3->finish_dgst1),
-				&(s->s3->tmp.cert_verify_md[0]));
-			s->method->ssl3_enc->cert_verify_mac(s,
-				&(s->s3->finish_dgst2),
-				&(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
+			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:
@@ -686,12 +713,8 @@
 		buf = (unsigned char *)s->init_buf->data;
 
 		msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
-		if (s->client_version == DTLS1_BAD_VER)
-			*(p++) = DTLS1_BAD_VER>>8,
-			*(p++) = DTLS1_BAD_VER&0xff;
-		else
-			*(p++) = s->version >> 8,
-			*(p++) = s->version & 0xFF;
+		*(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,
@@ -740,12 +763,8 @@
 		/* Do the message type and length last */
 		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
 
-		if (s->client_version == DTLS1_BAD_VER)
-			*(p++)=DTLS1_BAD_VER>>8,
-			*(p++)=DTLS1_BAD_VER&0xff;
-		else
-			*(p++)=s->version>>8,
-			*(p++)=s->version&0xff;
+		*(p++)=s->version>>8;
+		*(p++)=s->version&0xff;
 
 		/* Random stuff */
 		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
@@ -851,6 +870,13 @@
 #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;
@@ -865,7 +891,7 @@
 	EVP_MD_CTX_init(&md_ctx);
 	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
 		{
-		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
+		type=s->s3->tmp.new_cipher->algorithm_mkey;
 		cert=s->cert;
 
 		buf=s->init_buf;
@@ -959,6 +985,142 @@
 			}
 		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 (!EC_KEY_up_ref(ecdhp))
+				{
+				SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB);
+				goto err;
+				}
+			ecdh = ecdhp;
+
+			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);
@@ -970,7 +1132,8 @@
 			n+=2+nr[i];
 			}
 
-		if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+		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)
@@ -1001,6 +1164,41 @@
 			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)
 			{
@@ -1054,6 +1252,25 @@
 				}
 			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_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;
@@ -1080,6 +1297,10 @@
 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);
 	}
@@ -1193,14 +1414,15 @@
 	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 */
-                        (s->s3->tmp.new_cipher->algorithms
-                                & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-                        != (SSL_aKRB5|SSL_kKRB5))
+		if (x == NULL)
 			{
-			SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
-			return(0);
+			/* 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);
diff --git a/ssl/dtls1.h b/ssl/dtls1.h
index a8ce51a..af363a9 100644
--- a/ssl/dtls1.h
+++ b/ssl/dtls1.h
@@ -108,15 +108,17 @@
 
 typedef struct dtls1_bitmap_st
 	{
-	PQ_64BIT map;
-	unsigned long length;     /* sizeof the bitmap in bits */
-	PQ_64BIT max_seq_num;  /* max record number seen so far */
+	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 */
-	const EVP_MD *write_hash;		/* used for mac generation */
+	EVP_MD_CTX *write_hash;			/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *compress;				/* compression */
 #else
diff --git a/ssl/kssl.c b/ssl/kssl.c
index 73401c9..b820e37 100644
--- a/ssl/kssl.c
+++ b/ssl/kssl.c
@@ -76,6 +76,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/krb5_asn.h>
+#include "kssl_lcl.h"
 
 #ifndef OPENSSL_NO_KRB5
 
@@ -131,7 +132,7 @@
 #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
+#define krb5_rc_default          kssl_krb5_rc_default
 
 #ifdef krb5_rc_initialize
 #undef krb5_rc_initialize
@@ -839,7 +840,7 @@
 **	"62 xx 30 yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and
 **	xx and yy are possibly multi-byte length fields.
 */
-int 	kssl_test_confound(unsigned char *p)
+static int 	kssl_test_confound(unsigned char *p)
 	{
 	int 	len = 2;
 	int 	xx = 0, yy = 0;
@@ -874,7 +875,7 @@
 **      what the highest assigned CKSUMTYPE_ constant is.  As of 1.2.2
 **      it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3).  So we will use 0x0010.
 */
-size_t  *populate_cksumlens(void)
+static size_t  *populate_cksumlens(void)
 	{
 	int 		i, j, n;
 	static size_t 	*cklens = NULL;
@@ -1025,7 +1026,7 @@
 /*	Display contents of krb5_principal_data struct, for debugging
 **	(krb5_principal is typedef'd == krb5_principal_data *)
 */
-void
+static void
 print_krb5_princ(char *label, krb5_principal_data *princ)
         {
 	int i, ui, uj;
@@ -1224,7 +1225,7 @@
 **				code here.  This tkt should alloc/free just
 **				like the real thing.
 */
-krb5_error_code
+static krb5_error_code
 kssl_TKT2tkt(	/* IN     */	krb5_context	krb5context,
 		/* IN     */	KRB5_TKTBODY	*asn1ticket,
 		/* OUT    */	krb5_ticket	**krb5ticket,
@@ -1802,6 +1803,9 @@
                                      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 */,
@@ -1899,7 +1903,7 @@
 **  Return pointer to the (partially) filled in struct tm on success,
 **  return NULL on failure.
 */
-struct tm	*k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
+static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm)
 	{
 	char 		c, *p;
 
@@ -1925,7 +1929,7 @@
 **  So we try to sneek the clockskew out through the replay cache.
 **	If that fails just return a likely default (300 seconds).
 */
-krb5_deltat	get_rc_clockskew(krb5_context context)
+static krb5_deltat get_rc_clockskew(krb5_context context)
 	{
 	krb5_rcache 	rc;
 	krb5_deltat 	clockskew;
@@ -2089,9 +2093,12 @@
         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)
@@ -2121,7 +2128,7 @@
  		tm_g = gmtime(&now);		tg = mktime(tm_g);
  		tz_offset = tg - tl;
 
-		*atimep = tr - tz_offset;
+		*atimep = (krb5_timestamp)(tr - tz_offset);
  		}
 
 #ifdef KSSL_DEBUG
diff --git a/ssl/kssl_lcl.h b/ssl/kssl_lcl.h
index 4cd8dd2..c039c91 100644
--- a/ssl/kssl_lcl.h
+++ b/ssl/kssl_lcl.h
@@ -75,7 +75,7 @@
 char *kstring(char *string);
 char *knumber(int len, krb5_octet *contents);
 
-EVP_CIPHER *kssl_map_enc(krb5_enctype enctype);
+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);
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index de02389..c4d8bf2 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -55,6 +55,59 @@
  * 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"
@@ -63,10 +116,10 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl23_get_client_method(int ver);
+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 SSL_METHOD *ssl23_get_client_method(int ver)
+static const SSL_METHOD *ssl23_get_client_method(int ver)
 	{
 #ifndef OPENSSL_NO_SSL2
 	if (ver == SSL2_VERSION)
@@ -197,6 +250,20 @@
 	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)
 	{
@@ -214,6 +281,9 @@
 
 	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;
@@ -226,7 +296,7 @@
 		{
 		version = SSL2_VERSION;
 		}
-#ifndef OPENSSL_NO_TLSEXT 
+#ifndef OPENSSL_NO_TLSEXT
 	if (version != SSL2_VERSION)
 		{
 		/* have to disable SSL 2.0 compatibility if we need TLS extensions */
@@ -235,6 +305,10 @@
 			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
 
@@ -260,14 +334,6 @@
 			version_major = TLS1_VERSION_MAJOR;
 			version_minor = TLS1_VERSION_MINOR;
 			}
-#ifdef OPENSSL_FIPS
-		else if(FIPS_mode())
-			{
-			SSLerr(SSL_F_SSL23_CLIENT_HELLO,
-					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
-			return -1;
-			}
-#endif
 		else if (version == SSL3_VERSION)
 			{
 			version_major = SSL3_VERSION_MAJOR;
@@ -321,6 +387,10 @@
 				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
@@ -371,7 +441,11 @@
 			p+=i;
 
 			/* COMPRESSION */
-			if (s->ctx->comp_methods == NULL)
+#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);
@@ -381,8 +455,16 @@
 				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);
@@ -391,7 +473,6 @@
 #endif
 			
 			l = p-d;
-			*p = 42;
 
 			/* fill in 4-byte handshake header */
 			d=&(buf[5]);
@@ -486,6 +567,10 @@
 			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;
@@ -506,7 +591,7 @@
 			/* use special padding (SSL 3.0 draft/RFC 2246, App. E.2) */
 			s->s2->ssl2_rollback=1;
 
-		/* setup the 5 bytes we have read so we get them from
+		/* 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;
@@ -522,39 +607,16 @@
 		s->handshake_func=s->method->ssl_connect;
 #endif
 		}
-	else if ((p[0] == SSL3_RT_HANDSHAKE) &&
-		 (p[1] == SSL3_VERSION_MAJOR) &&
-		 ((p[2] == SSL3_VERSION_MINOR) ||
-		  (p[2] == TLS1_VERSION_MINOR)) &&
-		 (p[5] == SSL3_MT_SERVER_HELLO))
+	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 */
-
-		if (!ssl_init_wbio_buffer(s,1)) goto err;
-
-		/* we are in this state */
-		s->state=SSL3_ST_CR_SRVR_HELLO_A;
-
-		/* put the 5 bytes we have read into the input buffer
-		 * for SSLv3 */
-		s->rstate=SSL_ST_READ_HEADER;
-		s->packet_length=n;
-		s->packet= &(s->s3->rbuf.buf[0]);
-		memcpy(s->packet,buf,n);
-		s->s3->rbuf.left=n;
-		s->s3->rbuf.offset=0;
+		/* we have sslv3 or tls1 (server hello or alert) */
 
 		if ((p[2] == SSL3_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_SSLv3))
 			{
-#ifdef OPENSSL_FIPS
-			if(FIPS_mode())
-				{
-				SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
-					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
-				goto err;
-				}
-#endif
 			s->version=SSL3_VERSION;
 			s->method=SSLv3_client_method();
 			}
@@ -569,35 +631,52 @@
 			SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
 			goto err;
 			}
-			
-		s->handshake_func=s->method->ssl_connect;
-		}
-	else if ((p[0] == SSL3_RT_ALERT) &&
-		 (p[1] == SSL3_VERSION_MAJOR) &&
-		 ((p[2] == SSL3_VERSION_MINOR) ||
-		  (p[2] == TLS1_VERSION_MINOR)) &&
-		 (p[3] == 0) &&
-		 (p[4] == 2))
-		{
-		void (*cb)(const SSL *ssl,int type,int val)=NULL;
-		int j;
 
-		/* An alert */
-		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)
+		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
 			{
-			j=(i<<8)|p[6];
-			cb(s,SSL_CB_READ_ALERT,j);
+			/* 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;
 			}
 
-		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
 		{
@@ -615,4 +694,3 @@
 err:
 	return(-1);
 	}
-
diff --git a/ssl/s23_lib.c b/ssl/s23_lib.c
index fc29813..e3fce53 100644
--- a/ssl/s23_lib.c
+++ b/ssl/s23_lib.c
@@ -65,11 +65,6 @@
 	return(300);
 	}
 
-IMPLEMENT_ssl23_meth_func(sslv23_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int ssl23_num_ciphers(void)
 	{
 	return(ssl3_num_ciphers()
@@ -79,7 +74,7 @@
 	    );
 	}
 
-SSL_CIPHER *ssl23_get_cipher(unsigned int u)
+const SSL_CIPHER *ssl23_get_cipher(unsigned int u)
 	{
 	unsigned int uu=ssl3_num_ciphers();
 
@@ -95,9 +90,10 @@
 
 /* This function needs to check if the ciphers required are actually
  * available */
-SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
+const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p)
 	{
-	SSL_CIPHER c,*cp;
+	SSL_CIPHER c;
+	const SSL_CIPHER *cp;
 	unsigned long id;
 	int n;
 
diff --git a/ssl/s23_meth.c b/ssl/s23_meth.c
index 950d9aa..c6099ef 100644
--- a/ssl/s23_meth.c
+++ b/ssl/s23_meth.c
@@ -60,8 +60,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *ssl23_get_method(int ver);
-static SSL_METHOD *ssl23_get_method(int ver)
+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)
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 42f7de4..e22879c 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -116,9 +116,9 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl23_get_server_method(int ver);
+static const SSL_METHOD *ssl23_get_server_method(int ver);
 int ssl23_get_client_hello(SSL *s);
-static SSL_METHOD *ssl23_get_server_method(int ver)
+static const SSL_METHOD *ssl23_get_server_method(int ver)
 	{
 #ifndef OPENSSL_NO_SSL2
 	if (ver == SSL2_VERSION)
@@ -393,15 +393,6 @@
 			}
 		}
 
-#ifdef OPENSSL_FIPS
-	if (FIPS_mode() && (s->version < TLS1_VERSION))
-		{
-		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
-					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
-		goto err;
-		}
-#endif
-
 	if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
 		{
 		/* we have SSLv3/TLSv1 in an SSLv2 header
@@ -437,7 +428,9 @@
 		n2s(p,sil);
 		n2s(p,cl);
 		d=(unsigned char *)s->init_buf->data;
-		if ((csl+sil+cl+11) != s->packet_length)
+		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;
@@ -480,6 +473,15 @@
 		*(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);
 
@@ -555,6 +557,10 @@
 			 * 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;
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index 782129c..00ac158 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -117,7 +117,7 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl2_get_client_method(int ver);
+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);
@@ -129,7 +129,7 @@
 	unsigned char *to,int padding);
 #define BREAK	break
 
-static SSL_METHOD *ssl2_get_client_method(int ver)
+static const SSL_METHOD *ssl2_get_client_method(int ver)
 	{
 	if (ver == SSL2_VERSION)
 		return(SSLv2_client_method());
@@ -621,7 +621,7 @@
 	if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A)
 		{
 
-		if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+		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);
@@ -863,8 +863,10 @@
 		EVP_SignUpdate(&ctx,s->s2->key_material,
 			       s->s2->key_material_length);
 		EVP_SignUpdate(&ctx,cert_ch,(unsigned int)cert_ch_len);
-		n=i2d_X509(s->session->sess_cert->peer_key->x509,&p);
-		EVP_SignUpdate(&ctx,buf,(unsigned int)n);
+		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;
diff --git a/ssl/s2_enc.c b/ssl/s2_enc.c
index 1f62acd..ff3395f 100644
--- a/ssl/s2_enc.c
+++ b/ssl/s2_enc.c
@@ -68,15 +68,14 @@
 	const EVP_MD *md;
 	int num;
 
-	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+	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);
 		}
-
-	s->read_hash=md;
-	s->write_hash=md;
+	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 *)
@@ -176,7 +175,7 @@
 
 	/* There has to be a MAC algorithm. */
 	EVP_MD_CTX_init(&c);
-	EVP_DigestInit_ex(&c, s->read_hash, NULL);
+	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); 
diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c
index 10751b2..9914604 100644
--- a/ssl/s2_lib.c
+++ b/ssl/s2_lib.c
@@ -55,6 +55,59 @@
  * 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
@@ -68,143 +121,172 @@
 #define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER))
 
 /* list of available SSLv2 ciphers (sorted by id) */
-OPENSSL_GLOBAL SSL_CIPHER ssl2_ciphers[]={
-/* NULL_WITH_MD5 v3 */
+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_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_EXPORT|SSL_EXP40|SSL_STRONG_NONE,
 	0,
 	0,
 	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #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_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_MEDIUM,
 	0,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_EXPORT|SSL_EXP40,
 	SSL2_CF_5_BYTE_ENC,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_MEDIUM,
 	0,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_EXPORT|SSL_EXP40,
 	SSL2_CF_5_BYTE_ENC,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
-/* IDEA_128_CBC_WITH_MD5 */
+
 #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_kRSA,
+	SSL_aRSA,
+	SSL_IDEA,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_MEDIUM,
 	0,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #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_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_LOW,
 	0,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_HIGH,
 	0,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
-/* RC4_64_WITH_MD5 */
+
 #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_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV2,
 	SSL_NOT_EXP|SSL_LOW,
 	SSL2_CF_8_BYTE_ENC,
 	64,
 	64,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
-/* NULL SSLeay (testing) */
+
 #if 0
+/* NULL SSLeay (testing) */
 	{	
 	0,
 	SSL2_TXT_NULL,
 	SSL2_CK_NULL,
 	0,
+	0,
+	0,
+	0,
+	SSL_SSLV2,
 	SSL_STRONG_NONE,
 	0,
 	0,
 	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
 
@@ -216,17 +298,12 @@
 	return(300);
 	}
 
-IMPLEMENT_ssl2_meth_func(sslv2_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int ssl2_num_ciphers(void)
 	{
 	return(SSL2_NUM_CIPHERS);
 	}
 
-SSL_CIPHER *ssl2_get_cipher(unsigned int u)
+const SSL_CIPHER *ssl2_get_cipher(unsigned int u)
 	{
 	if (u < SSL2_NUM_CIPHERS)
 		return(&(ssl2_ciphers[SSL2_NUM_CIPHERS-1-u]));
@@ -337,18 +414,16 @@
 
 /* This function needs to check if the ciphers required are actually
  * available */
-SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
+const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p)
 	{
-	SSL_CIPHER c,*cp;
+	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 = (SSL_CIPHER *)OBJ_bsearch((char *)&c,
-		(char *)ssl2_ciphers,
-		SSL2_NUM_CIPHERS,sizeof(SSL_CIPHER),
-		FP_ICC ssl_cipher_id_cmp);
+	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS);
 	if ((cp == NULL) || (cp->valid == 0))
 		return NULL;
 	else
@@ -377,6 +452,7 @@
 	unsigned char *km;
 	unsigned char c='0';
 	const EVP_MD *md5;
+	int md_size;
 
 	md5 = EVP_md5();
 
@@ -393,10 +469,12 @@
  		SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR);
  		return 0;
  		}
-
-	for (i=0; i<s->s2->key_material_length; i += EVP_MD_size(md5))
+	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) + EVP_MD_size(md5)) >
+		if (((km - s->s2->key_material) + md_size) >
 				(int)sizeof(s->s2->key_material))
 			{
 			/* EVP_DigestFinal_ex() below would write beyond buffer */
@@ -415,7 +493,7 @@
 		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 += EVP_MD_size(md5);
+		km += md_size;
 		}
 
 	EVP_MD_CTX_cleanup(&ctx);
diff --git a/ssl/s2_meth.c b/ssl/s2_meth.c
index a35e435..f0e8ca5 100644
--- a/ssl/s2_meth.c
+++ b/ssl/s2_meth.c
@@ -61,8 +61,8 @@
 #include <stdio.h>
 #include <openssl/objects.h>
 
-static SSL_METHOD *ssl2_get_method(int ver);
-static SSL_METHOD *ssl2_get_method(int ver)
+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());
@@ -71,9 +71,9 @@
 	}
 
 IMPLEMENT_ssl2_meth_func(SSLv2_method,
-			ssl2_accept,
-			ssl2_connect,
-			ssl2_get_method)
+			 ssl2_accept,
+			 ssl2_connect,
+			 ssl2_get_method)
 
 #else /* !OPENSSL_NO_SSL2 */
 
diff --git a/ssl/s2_pkt.c b/ssl/s2_pkt.c
index a10929a..ac963b2 100644
--- a/ssl/s2_pkt.c
+++ b/ssl/s2_pkt.c
@@ -116,7 +116,7 @@
 #define USE_SOCKETS
 
 static int read_n(SSL *s,unsigned int n,unsigned int max,unsigned int extend);
-static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len);
+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);
 
@@ -130,7 +130,7 @@
 	unsigned char mac[MAX_MAC_SIZE];
 	unsigned char *p;
 	int i;
-	unsigned int mac_size;
+	int mac_size;
 
  ssl2_read_again:
 	if (SSL_in_init(s) && !s->in_handshake)
@@ -246,7 +246,9 @@
 			}
 		else
 			{
-			mac_size=EVP_MD_size(s->read_hash);
+			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];
@@ -261,7 +263,7 @@
 		/* 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 >= mac_size))
+			(s->s2->rlength >= (unsigned int)mac_size))
 			{
 			ssl2_enc(s,0);
 			s->s2->ract_data_length-=mac_size;
@@ -447,7 +449,7 @@
 	n=(len-tot);
 	for (;;)
 		{
-		i=do_ssl_write(s,&(buf[tot]),n);
+		i=n_do_ssl_write(s,&(buf[tot]),n);
 		if (i <= 0)
 			{
 			s->s2->wnum=tot;
@@ -511,9 +513,10 @@
 		}
 	}
 
-static int do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
+static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len)
 	{
-	unsigned int j,k,olen,p,mac_size,bs;
+	unsigned int j,k,olen,p,bs;
+	int mac_size;
 	register unsigned char *pp;
 
 	olen=len;
@@ -529,7 +532,11 @@
 	if (s->s2->clear_text)
 		mac_size=0;
 	else
-		mac_size=EVP_MD_size(s->write_hash);
+		{
+		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)
diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c
index 01d62fa..1434e73 100644
--- a/ssl/s2_srvr.c
+++ b/ssl/s2_srvr.c
@@ -117,7 +117,7 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *ssl2_get_server_method(int ver);
+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); 
@@ -129,7 +129,7 @@
 	unsigned char *to,int padding);
 #define BREAK	break
 
-static SSL_METHOD *ssl2_get_server_method(int ver)
+static const SSL_METHOD *ssl2_get_server_method(int ver)
 	{
 	if (ver == SSL2_VERSION)
 		return(SSLv2_server_method());
@@ -366,7 +366,7 @@
 	int is_export,i,n,keya,ek;
 	unsigned long len;
 	unsigned char *p;
-	SSL_CIPHER *cp;
+	const SSL_CIPHER *cp;
 	const EVP_CIPHER *c;
 	const EVP_MD *md;
 
@@ -451,7 +451,7 @@
 
 	is_export=SSL_C_IS_EXPORT(s->session->cipher);
 	
-	if (!ssl_cipher_get_evp(s->session,&c,&md,NULL))
+	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);
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 73f6002..cb391cd 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -160,8 +160,6 @@
 		p= &(d[4]);
 
 		i=s->method->ssl3_enc->final_finish_mac(s,
-			&(s->s3->finish_dgst1),
-			&(s->s3->finish_dgst2),
 			sender,slen,s->s3->tmp.finish_md);
 		s->s3->tmp.finish_md_len = i;
 		memcpy(p, s->s3->tmp.finish_md, i);
@@ -300,21 +298,21 @@
 
 static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
 	{
-		int n;
-		unsigned char *p;
+	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;
+	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);
+	return(0);
 	}
 
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
@@ -354,6 +352,8 @@
 				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);
@@ -550,9 +550,16 @@
 	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);
@@ -618,58 +625,202 @@
 	return(al);
 	}
 
-int ssl3_setup_buffers(SSL *s)
+#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;
-	unsigned int extra,headerlen;
-	size_t len;
-
+	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
+  		else
 			{
+			len = SSL3_RT_MAX_PLAIN_LENGTH
+				+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+				+ headerlen + align;
 			if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
-				extra=SSL3_RT_MAX_EXTRA;
-			else
-				extra=0;
-			len = SSL3_RT_MAX_PACKET_SIZE + extra;
+				{
+				s->s3->init_extra = 1;
+				len += SSL3_RT_MAX_EXTRA;
+				}
 			}
-		if ((p=OPENSSL_malloc(len)) == NULL)
+#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
+  		else
 			{
-			len = SSL3_RT_MAX_PACKET_SIZE;
+			len = s->max_send_fragment;
 			}
-		len += SSL3_RT_DEFAULT_WRITE_OVERHEAD; /* extra space for empty
-                                                          fragment, header, MAC
-                                                          and padding */
-		if ((p=OPENSSL_malloc(len)) == NULL)
+		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;
 		}
-	s->packet= &(s->s3->rbuf.buf[0]);
-	return(1);
+
+	return 1;
+
 err:
-	SSLerr(SSL_F_SSL3_SETUP_BUFFERS,ERR_R_MALLOC_FAILURE);
-	return(0);
+	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/ssl/s3_clnt.c b/ssl/s3_clnt.c
index e5138b6..41769fe 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -121,6 +121,32 @@
  * 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"
@@ -130,10 +156,6 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
-
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
@@ -142,15 +164,10 @@
 #include <openssl/engine.h>
 #endif
 
-static SSL_METHOD *ssl3_get_client_method(int ver);
+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);
 
-#ifndef OPENSSL_NO_ECDH
-static int curve_id2nid(int curve_id);
-int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs);
-#endif
-
-static SSL_METHOD *ssl3_get_client_method(int ver)
+static const SSL_METHOD *ssl3_get_client_method(int ver)
 	{
 	if (ver == SSL3_VERSION)
 		return(SSLv3_client_method());
@@ -166,7 +183,7 @@
 int ssl3_connect(SSL *s)
 	{
 	BUF_MEM *buf=NULL;
-	unsigned long Time=(unsigned long)time(NULL),l;
+	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;
@@ -261,6 +278,7 @@
 		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
@@ -285,7 +303,9 @@
 				}
 #endif
 			/* Check if it is anon DH/ECDH */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+			/* 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;
@@ -360,7 +380,6 @@
 		case SSL3_ST_CW_KEY_EXCH_B:
 			ret=ssl3_send_client_key_exchange(s);
 			if (ret <= 0) goto end;
-			l=s->s3->tmp.new_cipher->algorithms;
 			/* EAY EAY EAY need to check for DH fix cert
 			 * sent back */
 			/* For TLS, cert_req is set to 2, so a cert chain
@@ -381,6 +400,11 @@
 				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;
@@ -650,7 +674,9 @@
 #ifdef OPENSSL_NO_COMP
 		*(p++)=1;
 #else
-		if (s->ctx->comp_methods == NULL)
+
+		if ((s->options & SSL_OP_NO_COMPRESSION)
+					|| !s->ctx->comp_methods)
 			j=0;
 		else
 			j=sk_SSL_COMP_num(s->ctx->comp_methods);
@@ -662,13 +688,21 @@
 			}
 #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		
+#endif
+		
 		l=(p-d);
 		d=buf;
 		*(d++)=SSL3_MT_CLIENT_HELLO;
@@ -689,7 +723,7 @@
 int ssl3_get_server_hello(SSL *s)
 	{
 	STACK_OF(SSL_CIPHER) *sk;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 	unsigned char *p,*d;
 	int i,al,ok;
 	unsigned int j;
@@ -758,6 +792,23 @@
 		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)
 	    {
@@ -824,6 +875,8 @@
 			}
 		}
 	s->s3->tmp.new_cipher=c;
+	if (!ssl3_digest_cached_records(s))
+		goto f_err;
 
 	/* lets get the compression algorithm */
 	/* COMPRESSION */
@@ -834,10 +887,31 @@
 		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);
 	
@@ -852,6 +926,7 @@
 		s->s3->tmp.new_compression=comp;
 		}
 #endif
+
 #ifndef OPENSSL_NO_TLSEXT
 	/* TLS extensions*/
 	if (s->version >= SSL3_VERSION)
@@ -870,7 +945,6 @@
 		}
 #endif
 
-
 	if (p != (d+n))
 		{
 		/* wrong packet length */
@@ -908,7 +982,7 @@
 	if (!ok) return((int)n);
 
 	if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) ||
-		((s->s3->tmp.new_cipher->algorithms & SSL_aKRB5) && 
+		((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && 
 		(s->s3->tmp.message_type == SSL3_MT_SERVER_DONE)))
 		{
 		s->s3->tmp.reuse_message=1;
@@ -973,10 +1047,10 @@
 	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->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-	        != (SSL_aKRB5|SSL_kKRB5)
+	    && !((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);
@@ -1000,15 +1074,15 @@
 	pkey=X509_get_pubkey(x);
 
 	/* VRS: allow null cert if auth == KRB5 */
-	need_cert =	((s->s3->tmp.new_cipher->algorithms
-	                 & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-	                 == (SSL_aKRB5|SSL_kKRB5))? 0: 1;
+	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", (void *)pkey,(void *)x);
+	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, %d\n", s->s3->tmp.new_cipher->name,
-	        s->s3->tmp.new_cipher->algorithms, need_cert);
+	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)))
@@ -1080,7 +1154,7 @@
 	EVP_MD_CTX md_ctx;
 	unsigned char *param,*p;
 	int al,i,j,param_len,ok;
-	long n,alg;
+	long n,alg_k,alg_a;
 	EVP_PKEY *pkey=NULL;
 #ifndef OPENSSL_NO_RSA
 	RSA *rsa=NULL;
@@ -1104,17 +1178,28 @@
 		-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
@@ -1145,11 +1230,57 @@
 		}
 
 	param_len=0;
-	alg=s->s3->tmp.new_cipher->algorithms;
+	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 & SSL_kRSA)
+	if (alg_k & SSL_kRSA)
 		{
 		if ((rsa=RSA_new()) == NULL)
 			{
@@ -1188,7 +1319,7 @@
 		n-=param_len;
 
 		/* this should be because we are using an export cipher */
-		if (alg & SSL_aRSA)
+		if (alg_a & SSL_aRSA)
 			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 		else
 			{
@@ -1203,7 +1334,7 @@
 		;
 #endif
 #ifndef OPENSSL_NO_DH
-	else if (alg & SSL_kEDH)
+	else if (alg_k & SSL_kEDH)
 		{
 		if ((dh=DH_new()) == NULL)
 			{
@@ -1257,14 +1388,14 @@
 		n-=param_len;
 
 #ifndef OPENSSL_NO_RSA
-		if (alg & SSL_aRSA)
+		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 & SSL_aDSS)
+		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. */
@@ -1272,7 +1403,7 @@
 		s->session->sess_cert->peer_dh_tmp=dh;
 		dh=NULL;
 		}
-	else if ((alg & SSL_kDHr) || (alg & SSL_kDHd))
+	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);
@@ -1281,7 +1412,7 @@
 #endif /* !OPENSSL_NO_DH */
 
 #ifndef OPENSSL_NO_ECDH
-	else if (alg & SSL_kECDHE)
+	else if (alg_k & SSL_kEECDH)
 		{
 		EC_GROUP *ngroup;
 		const EC_GROUP *group;
@@ -1304,7 +1435,7 @@
 		param_len=3;
 		if ((param_len > n) ||
 		    (*p != NAMED_CURVE_TYPE) || 
-		    ((curve_nid = curve_id2nid(*(p + 2))) == 0)) 
+		    ((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);
@@ -1365,11 +1496,11 @@
 		 */
 		if (0) ;
 #ifndef OPENSSL_NO_RSA
-		else if (alg & SSL_aRSA)
+		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 & SSL_aECDSA)
+		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. */
@@ -1380,19 +1511,13 @@
 		EC_POINT_free(srvr_ecpoint);
 		srvr_ecpoint = NULL;
 		}
-	else if (alg & SSL_kECDH)
+	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 */
-	if (alg & SSL_aFZA)
-		{
-		al=SSL_AD_HANDSHAKE_FAILURE;
-		SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
-		goto f_err;
-		}
 
 
 	/* p points to the next byte, there are 'n' bytes left */
@@ -1421,8 +1546,6 @@
 			q=md_buf;
 			for (num=2; num > 0; num--)
 				{
-				EVP_MD_CTX_set_flags(&md_ctx,
-					EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 				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);
@@ -1493,12 +1616,13 @@
 		}
 	else
 		{
-		/* still data left over */
-		if (!(alg & SSL_aNULL))
+		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;
@@ -1568,8 +1692,7 @@
 	/* TLS does not like anon-DH with client cert */
 	if (s->version > SSL3_VERSION)
 		{
-		l=s->s3->tmp.new_cipher->algorithms;
-		if (l & SSL_aNULL)
+		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);
@@ -1771,8 +1894,7 @@
 int ssl3_get_cert_status(SSL *s)
 	{
 	int ok, al;
-	unsigned long resplen;
-	long n;
+	unsigned long resplen,n;
 	const unsigned char *p;
 
 	n=s->method->ssl_get_message(s,
@@ -1798,7 +1920,7 @@
 		goto f_err;
 		}
 	n2l3(p, resplen);
-	if (resplen + 4 != (unsigned long)n)
+	if (resplen + 4 != n)
 		{
 		al = SSL_AD_DECODE_ERROR;
 		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
@@ -1867,7 +1989,7 @@
 	{
 	unsigned char *p,*d;
 	int n;
-	unsigned long l;
+	unsigned long alg_k;
 #ifndef OPENSSL_NO_RSA
 	unsigned char *q;
 	EVP_PKEY *pkey=NULL;
@@ -1889,12 +2011,12 @@
 		d=(unsigned char *)s->init_buf->data;
 		p= &(d[4]);
 
-		l=s->s3->tmp.new_cipher->algorithms;
+		alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
 		/* Fool emacs indentation */
 		if (0) {}
 #ifndef OPENSSL_NO_RSA
-		else if (l & SSL_kRSA)
+		else if (alg_k & SSL_kRSA)
 			{
 			RSA *rsa;
 			unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
@@ -1953,7 +2075,7 @@
 			}
 #endif
 #ifndef OPENSSL_NO_KRB5
-		else if (l & SSL_kKRB5)
+		else if (alg_k & SSL_kKRB5)
 			{
 			krb5_error_code	krb5rc;
 			KSSL_CTX	*kssl_ctx = s->kssl_ctx;
@@ -1961,7 +2083,7 @@
 			krb5_data	*enc_ticket;
 			krb5_data	authenticator, *authp = NULL;
 			EVP_CIPHER_CTX	ciph_ctx;
-			EVP_CIPHER	*enc = NULL;
+			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 
@@ -1972,7 +2094,7 @@
 
 #ifdef KSSL_DEBUG
 			printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
-			        l, SSL_kKRB5);
+				alg_k, SSL_kKRB5);
 #endif	/* KSSL_DEBUG */
 
 			authp = NULL;
@@ -2064,7 +2186,7 @@
 				sizeof tmp_buf);
 			EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl);
 			outl += padl;
-			if (outl > sizeof epms)
+			if (outl > (int)sizeof epms)
 				{
 				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
 				goto err;
@@ -2078,7 +2200,7 @@
 			n+=outl + 2;
 
 			s->session->master_key_length=
-			        s->method->ssl3_enc->generate_master_secret(s,
+				s->method->ssl3_enc->generate_master_secret(s,
 					s->session->master_key,
 					tmp_buf, sizeof tmp_buf);
 
@@ -2087,7 +2209,7 @@
 			}
 #endif
 #ifndef OPENSSL_NO_DH
-		else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		else if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 			{
 			DH *dh_srvr,*dh_clnt;
 
@@ -2096,7 +2218,7 @@
 				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;
@@ -2151,7 +2273,7 @@
 #endif
 
 #ifndef OPENSSL_NO_ECDH 
-		else if ((l & SSL_kECDH) || (l & SSL_kECDHE))
+		else if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
 			{
 			const EC_GROUP *srvr_group = NULL;
 			EC_KEY *tkey;
@@ -2163,7 +2285,7 @@
 			 * computation as part of client certificate?
 			 * If so, set ecdh_clnt_cert to 1.
 			 */
-			if ((l & SSL_kECDH) && (s->cert != NULL)) 
+			if ((alg_k & (SSL_kECDHr|SSL_kECDHe)) && (s->cert != NULL)) 
 				{
 				/* XXX: For now, we do not support client
 				 * authentication using ECDH certificates.
@@ -2335,6 +2457,178 @@
 			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,
@@ -2371,28 +2665,37 @@
 	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;
-#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[4]);
 		pkey=s->cert->key->privatekey;
-
-		s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2),
-			&(data[MD5_DIGEST_LENGTH]));
-
+/* 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,
-				&(s->s3->finish_dgst1),&(data[0]));
+				NID_md5,
+			 	&(data[0]));
 			if (RSA_sign(NID_md5_sha1, data,
 					 MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH,
 					&(p[2]), &u, pkey->pkey.rsa) <= 0 )
@@ -2438,10 +2741,30 @@
 			}
 		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);
 
@@ -2449,8 +2772,10 @@
 		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);
 	}
 
@@ -2535,7 +2860,7 @@
 int ssl3_check_cert_and_algorithm(SSL *s)
 	{
 	int i,idx;
-	long algs;
+	long alg_k,alg_a;
 	EVP_PKEY *pkey=NULL;
 	SESS_CERT *sc;
 #ifndef OPENSSL_NO_RSA
@@ -2545,14 +2870,14 @@
 	DH *dh;
 #endif
 
-	sc=s->session->sess_cert;
-
-	algs=s->s3->tmp.new_cipher->algorithms;
+	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 (algs & (SSL_aDH|SSL_aNULL|SSL_aKRB5))
+	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);
@@ -2572,11 +2897,11 @@
 #ifndef OPENSSL_NO_ECDH
 	if (idx == SSL_PKEY_ECC)
 		{
-		if (check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509,
+		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;			
+			goto f_err;
 			}
 		else 
 			{
@@ -2590,20 +2915,20 @@
 
 	
 	/* Check that we have a certificate if we require one */
-	if ((algs & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN))
+	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 ((algs & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN))
+	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 ((algs & SSL_kRSA) &&
+	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);
@@ -2611,19 +2936,19 @@
 		}
 #endif
 #ifndef OPENSSL_NO_DH
-	if ((algs & SSL_kEDH) &&
+	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 ((algs & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA))
+	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 ((algs & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_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;
@@ -2634,7 +2959,7 @@
 	if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP))
 		{
 #ifndef OPENSSL_NO_RSA
-		if (algs & SSL_kRSA)
+		if (alg_k & SSL_kRSA)
 			{
 			if (rsa == NULL
 			    || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher))
@@ -2646,7 +2971,7 @@
 		else
 #endif
 #ifndef OPENSSL_NO_DH
-			if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+			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))
@@ -2669,49 +2994,6 @@
 	return(0);
 	}
 
-
-#ifndef OPENSSL_NO_ECDH
-/* This is the complement of nid2curve_id in s3_srvr.c. */
-static int curve_id2nid(int curve_id)
-{
-	/* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001)
-	 * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */
-	static int nid_list[26] =
-	{
-		0,
-		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) */	
-	};
-	
-	if ((curve_id < 1) || (curve_id > 25)) return 0;
-
-	return nid_list[curve_id];
-}
-#endif
-
 /* 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.
@@ -2722,11 +3004,8 @@
 	{
 	int ok;
 	long n;
-	/* If we have no ticket or session ID is non-zero length (a match of
-	 * a non-zero session length would never reach here) it cannot be a
-	 * resumed session.
-	 */
-	if (!s->session->tlsext_tick || s->session->session_id_length)
+	/* 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 */
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 06e5466..3d7aec9 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -108,6 +108,32 @@
  * 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"
@@ -129,10 +155,8 @@
 	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, EVP_MD_CTX *in_ctx,
+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;
@@ -146,7 +170,6 @@
 #endif
 	k=0;
 	EVP_MD_CTX_init(&m5);
-	EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 	EVP_MD_CTX_init(&s1);
 	for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
 		{
@@ -208,6 +231,8 @@
 	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;
@@ -226,7 +251,8 @@
 			/* 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;
-		s->read_hash=m;
+
+		ssl_replace_hash(&s->read_hash,m);
 #ifndef OPENSSL_NO_COMP
 		/* COMPRESS */
 		if (s->expand != NULL)
@@ -262,7 +288,7 @@
 			/* 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;
-		s->write_hash=m;
+		ssl_replace_hash(&s->write_hash,m);
 #ifndef OPENSSL_NO_COMP
 		/* COMPRESS */
 		if (s->compress != NULL)
@@ -289,6 +315,8 @@
 
 	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;
@@ -369,7 +397,7 @@
 	if (s->s3->tmp.key_block_length != 0)
 		return(1);
 
-	if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
+	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);
@@ -383,7 +411,11 @@
 	s->s3->tmp.new_compression=comp;
 #endif
 
-	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
+	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);
@@ -405,11 +437,11 @@
 
 		if (s->session->cipher != NULL)
 			{
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL)
+			if (s->session->cipher->algorithm_enc == SSL_eNULL)
 				s->s3->need_empty_fragments = 0;
 			
 #ifndef OPENSSL_NO_RC4
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
+			if (s->session->cipher->algorithm_enc == SSL_RC4)
 				s->s3->need_empty_fragments = 0;
 #endif
 			}
@@ -519,50 +551,131 @@
 
 void ssl3_init_finished_mac(SSL *s)
 	{
-	EVP_MD_CTX_set_flags(&(s->s3->finish_dgst1),
-		EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	EVP_DigestInit_ex(&(s->s3->finish_dgst1),s->ctx->md5, NULL);
-	EVP_DigestInit_ex(&(s->s3->finish_dgst2),s->ctx->sha1, NULL);
+	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)
 	{
-	EVP_DigestUpdate(&(s->s3->finish_dgst1),buf,len);
-	EVP_DigestUpdate(&(s->s3->finish_dgst2),buf,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_cert_verify_mac(SSL *s, EVP_MD_CTX *ctx, unsigned char *p)
+int ssl3_digest_cached_records(SSL *s)
 	{
-	return(ssl3_handshake_mac(s,ctx,NULL,0,p));
+	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_final_finish_mac(SSL *s, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
+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,ctx1,sender,len,p);
+	ret=ssl3_handshake_mac(s,NID_md5,sender,len,p);
 	p+=ret;
-	ret+=ssl3_handshake_mac(s,ctx2,sender,len,p);
+	ret+=ssl3_handshake_mac(s,NID_sha1,sender,len,p);
 	return(ret);
 	}
-
-static int ssl3_handshake_mac(SSL *s, EVP_MD_CTX *in_ctx,
+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;
+	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_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	EVP_MD_CTX_copy_ex(&ctx,in_ctx);
-
+	EVP_MD_CTX_copy_ex(&ctx,d);
 	n=EVP_MD_CTX_size(&ctx);
-	npad=(48/n)*n;
+	if (n < 0)
+		return 0;
 
+	npad=(48/n)*n;
 	if (sender != NULL)
 		EVP_DigestUpdate(&ctx,sender,len);
 	EVP_DigestUpdate(&ctx,s->session->master_key,
@@ -582,15 +695,16 @@
 	return((int)ret);
 	}
 
-int ssl3_mac(SSL *ssl, unsigned char *md, int send)
+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 *hash;
+	const EVP_MD_CTX *hash;
 	unsigned char *p,rec_char;
 	unsigned int md_size;
 	int npad;
+	int t;
 
 	if (send)
 		{
@@ -607,13 +721,16 @@
 		hash=ssl->read_hash;
 		}
 
-	md_size=EVP_MD_size(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_DigestInit_ex(  &md_ctx,hash, NULL);
+	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);
@@ -625,7 +742,7 @@
 	EVP_DigestUpdate(&md_ctx,rec->input,rec->length);
 	EVP_DigestFinal_ex( &md_ctx,md,NULL);
 
-	EVP_DigestInit_ex(  &md_ctx,hash, 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);
@@ -718,6 +835,12 @@
 	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/ssl/s3_lib.c b/ssl/s3_lib.c
index 8fa4ab0..d6b047c 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -121,16 +121,46 @@
  * 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
-#include <openssl/pq_compat.h>
 
 const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT;
 
@@ -138,217 +168,265 @@
 
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_eNULL,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 02 */
 	{
 	1,
 	SSL3_TXT_RSA_NULL_SHA,
 	SSL3_CK_RSA_NULL_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_SHA1|SSL_SSLV3,
+	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,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_IDEA,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #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_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kRSA,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kDHd,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0C */
 	{
-	0,
+	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_kDHd,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0D */
 	{
-	0,
+	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_kDHd,
+	SSL_aDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0E */
 	{
-	0,
+	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_kDHr,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 0F */
 	{
-	0,
+	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_kDHr,
+	SSL_aDH,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 10 */
 	{
-	0,
+	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_kDHr,
+	SSL_aDH,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* The Ephemeral DH ciphers */
@@ -357,158 +435,193 @@
 	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_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aDSS,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aDSS,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aRSA,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aNULL,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aNULL,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aNULL,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* 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_kEDH,
+	SSL_aNULL,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
-/* Fortezza */
+/* 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_kFZA,
+	SSL_aFZA,
+	SSL_eNULL,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 1D */
@@ -516,45 +629,50 @@
 	0,
 	SSL3_TXT_FZA_DMS_FZA_SHA,
 	SSL3_CK_FZA_DMS_FZA_SHA,
-	SSL_kFZA|SSL_aFZA |SSL_eFZA |SSL_SHA1|SSL_SSLV3,
+	SSL_kFZA,
+	SSL_aFZA,
+	SSL_eFZA,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
 	0,
-	0,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
-#if 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_kFZA,
+	SSL_aFZA,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif
 
 #ifndef OPENSSL_NO_KRB5
-/* The Kerberos ciphers */
+/* 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_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 1F */
@@ -562,13 +680,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 20 */
@@ -576,13 +696,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_128_SHA,
 	SSL3_CK_KRB5_RC4_128_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_SHA1  |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 21 */
@@ -590,13 +712,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_IDEA,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 22 */
@@ -604,13 +728,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_LOW,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	56,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 23 */
@@ -618,13 +744,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_3DES,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 24 */
@@ -632,13 +760,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_128_MD5,
 	SSL3_CK_KRB5_RC4_128_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_MD5  |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 25 */
@@ -646,13 +776,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_IDEA,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 26 */
@@ -660,13 +792,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 27 */
@@ -674,13 +808,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_RC2,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 28 */
@@ -688,13 +824,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_40_SHA,
 	SSL3_CK_KRB5_RC4_40_SHA,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_SHA1   |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_SHA1,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 29 */
@@ -702,13 +840,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_DES,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	56,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 2A */
@@ -716,13 +856,15 @@
 	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_kKRB5,
+	SSL_aKRB5,
+	SSL_RC2,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 2B */
@@ -730,13 +872,15 @@
 	1,
 	SSL3_TXT_KRB5_RC4_40_MD5,
 	SSL3_CK_KRB5_RC4_40_MD5,
-	SSL_kKRB5|SSL_aKRB5|  SSL_RC4|SSL_MD5    |SSL_SSLV3,
+	SSL_kKRB5,
+	SSL_aKRB5,
+	SSL_RC4,
+	SSL_MD5,
+	SSL_SSLV3,
 	SSL_EXPORT|SSL_EXP40,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	40,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 #endif	/* OPENSSL_NO_KRB5 */
 
@@ -746,78 +890,90 @@
 	1,
 	TLS1_TXT_RSA_WITH_AES_128_SHA,
 	TLS1_CK_RSA_WITH_AES_128_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 30 */
 	{
 	0,
 	TLS1_TXT_DH_DSS_WITH_AES_128_SHA,
 	TLS1_CK_DH_DSS_WITH_AES_128_SHA,
-	SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 31 */
 	{
 	0,
 	TLS1_TXT_DH_RSA_WITH_AES_128_SHA,
 	TLS1_CK_DH_RSA_WITH_AES_128_SHA,
-	SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 32 */
 	{
 	1,
 	TLS1_TXT_DHE_DSS_WITH_AES_128_SHA,
 	TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 33 */
 	{
 	1,
 	TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
 	TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 34 */
 	{
 	1,
 	TLS1_TXT_ADH_WITH_AES_128_SHA,
 	TLS1_CK_ADH_WITH_AES_128_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 /* Cipher 35 */
@@ -825,78 +981,94 @@
 	1,
 	TLS1_TXT_RSA_WITH_AES_256_SHA,
 	TLS1_CK_RSA_WITH_AES_256_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 /* Cipher 36 */
 	{
 	0,
 	TLS1_TXT_DH_DSS_WITH_AES_256_SHA,
 	TLS1_CK_DH_DSS_WITH_AES_256_SHA,
-	SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 37 */
 	{
-	0,
+	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_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 38 */
 	{
 	1,
 	TLS1_TXT_DHE_DSS_WITH_AES_256_SHA,
 	TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
-	SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 /* Cipher 39 */
 	{
 	1,
 	TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
 	TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
-	SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
+
 	/* Cipher 3A */
 	{
 	1,
 	TLS1_TXT_ADH_WITH_AES_256_SHA,
 	TLS1_CK_ADH_WITH_AES_256_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 #ifndef OPENSSL_NO_CAMELLIA
@@ -907,78 +1079,95 @@
 	1,
 	TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 46 */
 	{
 	1,
 	TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA,
 	TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_CAMELLIA128,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
 #endif /* OPENSSL_NO_CAMELLIA */
 
@@ -986,98 +1175,174 @@
 	/* 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,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	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,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    56,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    56,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_SHA|SSL_TLSV1,
-	    SSL_EXPORT|SSL_EXP56,
-	    0,
-	    56,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_SHA|SSL_TLSV1,
-	    SSL_NOT_EXP|SSL_MEDIUM,
-	    0,
-	    128,
-	    128,
-	    SSL_ALL_CIPHERS,
-	    SSL_ALL_STRENGTHS
-	    },
+	{
+	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) */
@@ -1087,81 +1352,163 @@
 	1,
 	TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHd,
+	SSL_aDH,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kDHr,
+	SSL_aDH,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aDSS,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* 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_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
+
 	/* Cipher 89 */
 	{
 	1,
 	TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA,
 	TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_CAMELLIA|SSL_SHA|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_CAMELLIA256,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_HIGH,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS
 	},
 #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 */
 
@@ -1170,13 +1517,15 @@
 	1,
 	TLS1_TXT_RSA_WITH_SEED_SHA,
 	TLS1_CK_RSA_WITH_SEED_SHA,
-	SSL_kRSA|SSL_aRSA|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kRSA,
+	SSL_aRSA,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 97 */
@@ -1184,13 +1533,15 @@
 	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_kDHd,
+	SSL_aDH,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 98 */
@@ -1198,13 +1549,15 @@
 	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_kDHr,
+	SSL_aDH,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 99 */
@@ -1212,13 +1565,15 @@
 	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_kEDH,
+	SSL_aDSS,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 9A */
@@ -1226,13 +1581,15 @@
 	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_kEDH,
+	SSL_aRSA,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 	/* Cipher 9B */
@@ -1240,376 +1597,487 @@
 	1,
 	TLS1_TXT_ADH_WITH_SEED_SHA,
 	TLS1_CK_ADH_WITH_SEED_SHA,
-	SSL_kEDH|SSL_aNULL|SSL_SEED|SSL_SHA1|SSL_TLSV1,
+	SSL_kEDH,
+	SSL_aNULL,
+	SSL_SEED,
+	SSL_SHA1,
+	SSL_TLSV1,
 	SSL_NOT_EXP|SSL_MEDIUM,
-	0,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
-	SSL_ALL_CIPHERS,
-	SSL_ALL_STRENGTHS,
 	},
 
 #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_kECDH|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aNULL|SSL_eNULL|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            0,
-            0,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_kECDHE|SSL_aNULL|SSL_RC4|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-	    },
+	{
+	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_kECDHE|SSL_aNULL|SSL_3DES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            168,
-            168,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            128,
-            128,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
-            SSL_NOT_EXP|SSL_HIGH,
-            0,
-            256,
-            256,
-            SSL_ALL_CIPHERS,
-            SSL_ALL_STRENGTHS,
-            },
+	{
+	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,
-	ssl3_mac,
+	n_ssl3_mac,
 	ssl3_setup_key_block,
 	ssl3_generate_master_secret,
 	ssl3_change_cipher_state,
@@ -1628,17 +2096,12 @@
 	return(60*60*2);
 	}
 
-IMPLEMENT_ssl3_meth_func(sslv3_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int ssl3_num_ciphers(void)
 	{
 	return(SSL3_NUM_CIPHERS);
 	}
 
-SSL_CIPHER *ssl3_get_cipher(unsigned int u)
+const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
 	{
 	if (u < SSL3_NUM_CIPHERS)
 		return(&(ssl3_ciphers[SSL3_NUM_CIPHERS-1-u]));
@@ -1660,10 +2123,8 @@
 
 	if ((s3=OPENSSL_malloc(sizeof *s3)) == NULL) goto err;
 	memset(s3,0,sizeof *s3);
-	EVP_MD_CTX_init(&s3->finish_dgst1);
-	EVP_MD_CTX_init(&s3->finish_dgst2);
-	pq_64bit_init(&(s3->rrec.seq_num));
-	pq_64bit_init(&(s3->wrec.seq_num));
+	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;
 
@@ -1678,11 +2139,18 @@
 	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)
-		OPENSSL_free(s->s3->rbuf.buf);
+		ssl3_release_read_buffer(s);
 	if (s->s3->wbuf.buf != NULL)
-		OPENSSL_free(s->s3->wbuf.buf);
+		ssl3_release_write_buffer(s);
 	if (s->s3->rrec.comp != NULL)
 		OPENSSL_free(s->s3->rrec.comp);
 #ifndef OPENSSL_NO_DH
@@ -1696,11 +2164,10 @@
 
 	if (s->s3->tmp.ca_names != NULL)
 		sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free);
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst1);
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst2);
-	pq_64bit_free(&(s->s3->rrec.seq_num));
-	pq_64bit_free(&(s->s3->wrec.seq_num));
-
+	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;
@@ -1711,6 +2178,15 @@
 	unsigned char *rp,*wp;
 	size_t rlen, wlen;
 
+#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);
@@ -1733,10 +2209,13 @@
 	wp = s->s3->wbuf.buf;
 	rlen = s->s3->rbuf.len;
  	wlen = s->s3->wbuf.len;
-
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst1);
-	EVP_MD_CTX_cleanup(&s->s3->finish_dgst2);
-
+	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;
@@ -1936,7 +2415,31 @@
 		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;
@@ -2194,13 +2697,20 @@
 			}
 		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)
@@ -2250,7 +2760,13 @@
 	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;
@@ -2271,17 +2787,15 @@
 
 /* This function needs to check if the ciphers required are actually
  * available */
-SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
+const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
 	{
-	SSL_CIPHER c,*cp;
+	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 = (SSL_CIPHER *)OBJ_bsearch((char *)&c,
-		(char *)ssl3_ciphers,
-		SSL3_NUM_CIPHERS,sizeof(SSL_CIPHER),
-		FP_ICC ssl_cipher_id_cmp);
+	cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
 	if (cp == NULL || cp->valid == 0)
 		return NULL;
 	else
@@ -2307,10 +2821,14 @@
 	{
 	SSL_CIPHER *c,*ret=NULL;
 	STACK_OF(SSL_CIPHER) *prio, *allow;
-	int i,j,ok;
-
+	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,mask,emask;
+	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;
@@ -2326,73 +2844,237 @@
 #endif
 
 #ifdef CIPHER_DEBUG
-        printf("Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), srvr);
-        for(i=0 ; i < sk_SSL_CIPHER_num(srvr) ; ++i)
-	    {
-	    c=sk_SSL_CIPHER_value(srvr,i);
-	    printf("%p:%s\n",c,c->name);
-	    }
-        printf("Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), clnt);
-        for(i=0 ; i < sk_SSL_CIPHER_num(clnt) ; ++i)
+	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",c,c->name);
+	    printf("%p:%s\n",(void *)c,c->name);
 	    }
 #endif
 
 	if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE)
-	    {
-	    prio = srvr;
-	    allow = clnt;
-	    }
+		{
+		prio = srvr;
+		allow = clnt;
+		}
 	else
-	    {
-	    prio = clnt;
-	    allow = srvr;
-	    }
+		{
+		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=cert->mask;
-		emask=cert->export_mask;
+		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);
+/*		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
 #endif    /* KSSL_DEBUG */
 
-		alg=c->algorithms&(SSL_MKEY_MASK|SSL_AUTH_MASK);
+		alg_k=c->algorithm_mkey;
+		alg_a=c->algorithm_auth;
+
 #ifndef OPENSSL_NO_KRB5
-                if (alg & SSL_KRB5) 
-                        {
-                        if ( !kssl_keytab_is_available(s->kssl_ctx) )
-                            continue;
-                        }
+		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 & emask) == alg)?1:0;
+			ok = (alg_k & emask_k) && (alg_a & emask_a);
 #ifdef CIPHER_DEBUG
-			printf("%d:[%08lX:%08lX]%p:%s (export)\n",ok,alg,emask,
-			       c,c->name);
+			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 & mask) == alg)?1:0;
+			ok = (alg_k & mask_k) && (alg_a & mask_a);
 #ifdef CIPHER_DEBUG
-			printf("%d:[%08lX:%08lX]%p:%s\n",ok,alg,mask,c,
+			printf("%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n",ok,alg_k,alg_a,mask_k,mask_a,(void *)c,
 			       c->name);
 #endif
 			}
 
-		if (!ok) continue;
-		j=sk_SSL_CIPHER_find(allow,c);
-		if (j >= 0)
+#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)
+					)
+				)
+		)
 			{
-			ret=sk_SSL_CIPHER_value(allow,j);
+			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;
 			}
 		}
@@ -2402,12 +3084,24 @@
 int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
 	{
 	int ret=0;
-	unsigned long alg;
+	unsigned long alg_k;
 
-	alg=s->s3->tmp.new_cipher->algorithms;
+	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 & (SSL_kDHr|SSL_kEDH))
+	if (alg_k & (SSL_kDHr|SSL_kEDH))
 		{
 #  ifndef OPENSSL_NO_RSA
 		p[ret++]=SSL3_CT_RSA_FIXED_DH;
@@ -2417,7 +3111,7 @@
 #  endif
 		}
 	if ((s->version == SSL3_VERSION) &&
-		(alg & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
+		(alg_k & (SSL_kEDH|SSL_kDHd|SSL_kDHr)))
 		{
 #  ifndef OPENSSL_NO_RSA
 		p[ret++]=SSL3_CT_RSA_EPHEMERAL_DH;
@@ -2434,10 +3128,7 @@
 	p[ret++]=SSL3_CT_DSS_SIGN;
 #endif
 #ifndef OPENSSL_NO_ECDH
-	/* We should ask for fixed ECDH certificates only
-	 * for SSL_kECDH (and not SSL_kECDHE)
-	 */
-	if ((alg & SSL_kECDH) && (s->version >= TLS1_VERSION))
+	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;
@@ -2446,7 +3137,7 @@
 
 #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_kECDHE
+	 * so we don't need to check for SSL_kECDH or SSL_kEECDH
 	 */
 	if (s->version >= TLS1_VERSION)
 		{
diff --git a/ssl/s3_meth.c b/ssl/s3_meth.c
index 6a6eb1c..cdddb17 100644
--- a/ssl/s3_meth.c
+++ b/ssl/s3_meth.c
@@ -60,8 +60,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *ssl3_get_method(int ver);
-static SSL_METHOD *ssl3_get_method(int ver)
+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());
@@ -70,8 +70,8 @@
 	}
 
 IMPLEMENT_ssl3_meth_func(SSLv3_method,
-			ssl3_accept,
-			ssl3_connect,
-			ssl3_get_method)
+			 ssl3_accept,
+			 ssl3_connect,
+			 ssl3_get_method)
 
 
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 4634b29..9eaaad8 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -129,14 +129,49 @@
 	 * (If s->read_ahead is set, 'max' bytes may be stored in rbuf
 	 * [plus s->packet_length bytes if extend == 1].)
 	 */
-	int i,off,newb;
+	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 (s->s3->rbuf.left == 0)
-			s->s3->rbuf.offset = 0;
-		s->packet = s->s3->rbuf.buf + s->s3->rbuf.offset;
+		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 */
 		}
@@ -144,59 +179,63 @@
 	/* 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)
+	if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
 		{
-		if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
-			n = s->s3->rbuf.left;
+		if (left > 0 && n > left)
+			n = left;
 		}
 
 	/* if there is enough in the buffer from a previous read, take some */
-	if (s->s3->rbuf.left >= (int)n)
+	if (left >= n)
 		{
 		s->packet_length+=n;
-		s->s3->rbuf.left-=n;
-		s->s3->rbuf.offset+=n;
+		rb->left=left-n;
+		rb->offset+=n;
 		return(n);
 		}
 
 	/* else we need to read more data */
-	if (!s->read_ahead)
-		max=n;
 
-	{
-		/* avoid buffer overflow */
-		int max_max = s->s3->rbuf.len - s->packet_length;
-		if (max > max_max)
-			max = max_max;
-	}
-	if (n > max) /* does not happen */
+	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;
 		}
 
-	off = s->packet_length;
-	newb = s->s3->rbuf.left;
-	/* Move any available bytes to front of buffer:
-	 * 'off' bytes already pointed to by 'packet',
-	 * 'newb' extra ones at the end */
-	if (s->packet != s->s3->rbuf.buf)
+	if (!s->read_ahead)
+		/* ignore max parameter */
+		max = n;
+	else
 		{
-		/*  off > 0 */
-		memmove(s->s3->rbuf.buf, s->packet, off+newb);
-		s->packet = s->s3->rbuf.buf;
+		if (max < n)
+			max = n;
+		if (max > (int)(rb->len - rb->offset))
+			max = rb->len - rb->offset;
 		}
 
-	while (newb < n)
+	while (left < n)
 		{
-		/* Now we have off+newb bytes at the front of s->s3->rbuf.buf and need
-		 * to read in more until we have off+n (up to off+max if possible) */
+		/* 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,	&(s->s3->rbuf.buf[off+newb]), max-newb);
+			i=BIO_read(s->rbio,pkt+len+left, max-left);
 			}
 		else
 			{
@@ -206,23 +245,26 @@
 
 		if (i <= 0)
 			{
-			s->s3->rbuf.left = newb;
+			rb->left = left;
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+				if (len+left == 0)
+					ssl3_release_read_buffer(s);
 			return(i);
 			}
-		newb+=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)
+		if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
 			{
-			if (n > newb)
-				n = newb; /* makes the while condition false */
+			if (n > left)
+				n = left; /* makes the while condition false */
 			}
 		}
 
 	/* done reading, now the book-keeping */
-	s->s3->rbuf.offset = off + n;
-	s->s3->rbuf.left = newb - n;
+	rb->offset += n;
+	rb->left = left - n;
 	s->packet_length += n;
 	s->rwstate=SSL_NOTHING;
 	return(n);
@@ -246,7 +288,7 @@
 	unsigned char *p;
 	unsigned char md[EVP_MAX_MD_SIZE];
 	short version;
-	unsigned int mac_size;
+	int mac_size;
 	int clear=0;
 	size_t extra;
 	int decryption_failed_or_bad_record_mac = 0;
@@ -260,9 +302,9 @@
 	else
 		extra=0;
 	if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
-		extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
+		extra && !s->s3->init_extra)
 		{
-		/* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
+		/* 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;
@@ -285,6 +327,9 @@
 		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)
@@ -292,10 +337,9 @@
 			if (version != s->version)
 				{
 				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
-				/* If the major versions match then we'll send
-				 * the error back using the peer's version. */
-				if ((s->version & 0xFF00) == (version & 0xFF00))
-					s->version = version;
+                                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;
 				}
@@ -307,7 +351,7 @@
 			goto err;
 			}
 
-		if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
+		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);
@@ -395,12 +439,14 @@
 	/* r->length is now the compressed data plus mac */
 	if (	(sess == NULL) ||
 		(s->enc_read_ctx == NULL) ||
-		(s->read_hash == NULL))
+		(EVP_MD_CTX_md(s->read_hash) == NULL))
 		clear=1;
 
 	if (!clear)
 		{
-		mac_size=EVP_MD_size(s->read_hash);
+		/* !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)
 			{
@@ -413,7 +459,7 @@
 #endif			
 			}
 		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-		if (rr->length >= mac_size)
+		if (rr->length >= (unsigned int)mac_size)
 			{
 			rr->length -= mac_size;
 			mac = &rr->data[rr->length];
@@ -431,7 +477,7 @@
 #endif
 			}
 		i=s->method->ssl3_enc->mac(s,md,0);
-		if (mac == NULL || memcmp(md, mac, mac_size) != 0)
+		if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
 			{
 			decryption_failed_or_bad_record_mac = 1;
 			}
@@ -488,6 +534,10 @@
 	/* 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:
@@ -542,7 +592,7 @@
 	const unsigned char *buf=buf_;
 	unsigned int tot,n,nw;
 	int i;
-    unsigned int max_plain_length;
+	unsigned int max_plain_length;
 
 	s->rwstate=SSL_NOTHING;
 	tot=s->s3->wnum;
@@ -563,7 +613,7 @@
 	for (;;)
 		{
 		if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
-			max_plain_length = SSL3_RT_MAX_PLAIN_LENGTH;
+			max_plain_length = s->max_send_fragment;
 		else
 			max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
 
@@ -600,14 +650,19 @@
 	{
 	unsigned char *p,*plen;
 	int i,mac_size,clear=0;
-	int prefix_len = 0;
+	int prefix_len=0;
+	long align=0;
 	SSL3_RECORD *wr;
-	SSL3_BUFFER *wb;
+	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 (s->s3->wbuf.left != 0)
+	if (wb->left != 0)
 		return(ssl3_write_pending(s,type,buf,len));
 
 	/* If we have an alert to send, lets send it */
@@ -623,18 +678,21 @@
 		return 0;
 
 	wr= &(s->s3->wrec);
-	wb= &(s->s3->wbuf);
 	sess=s->session;
 
 	if (	(sess == NULL) ||
 		(s->enc_write_ctx == NULL) ||
-		(s->write_hash == NULL))
+		(EVP_MD_CTX_md(s->write_hash) == NULL))
 		clear=1;
 
 	if (clear)
 		mac_size=0;
 	else
-		mac_size=EVP_MD_size(s->write_hash);
+		{
+		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)
@@ -652,9 +710,8 @@
 			if (prefix_len <= 0)
 				goto err;
 
-			if (s->s3->wbuf.len < (size_t)prefix_len +
-				((SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) ? SSL3_RT_DEFAULT_PACKET_SIZE :
-					SSL3_RT_MAX_PACKET_SIZE))
+			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);
@@ -665,7 +722,32 @@
 		s->s3->empty_fragment_done = 1;
 		}
 
-	p = wb->buf + prefix_len;
+	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 */
 
@@ -708,7 +790,8 @@
 
 	if (mac_size != 0)
 		{
-		s->method->ssl3_enc->mac(s,&(p[wr->length]),1);
+		if (s->method->ssl3_enc->mac(s,&(p[wr->length]),1) < 0)
+			goto err;
 		wr->length+=mac_size;
 		wr->input=p;
 		wr->data=p;
@@ -736,7 +819,6 @@
 
 	/* 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;
@@ -755,6 +837,7 @@
 	unsigned int len)
 	{
 	int i;
+	SSL3_BUFFER *wb=&(s->s3->wbuf);
 
 /* XXXX */
 	if ((s->s3->wpend_tot > (int)len)
@@ -773,17 +856,20 @@
 			{
 			s->rwstate=SSL_WRITING;
 			i=BIO_write(s->wbio,
-				(char *)&(s->s3->wbuf.buf[s->s3->wbuf.offset]),
-				(unsigned int)s->s3->wbuf.left);
+				(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 == s->s3->wbuf.left)
+		if (i == wb->left)
 			{
-			s->s3->wbuf.left=0;
+			wb->left=0;
+			wb->offset+=i;
+			if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+				ssl3_release_write_buffer(s);
 			s->rwstate=SSL_NOTHING;
 			return(s->s3->wpend_ret);
 			}
@@ -792,12 +878,12 @@
 			    s->version == DTLS1_BAD_VER) {
 				/* For DTLS, just drop it. That's kind of the whole
 				   point in using a datagram service */
-				s->s3->wbuf.left = 0;
+				wb->left = 0;
 			}
 			return(i);
 		}
-		s->s3->wbuf.offset+=i;
-		s->s3->wbuf.left-=i;
+		wb->offset+=i;
+		wb->left-=i;
 		}
 	}
 
@@ -836,7 +922,7 @@
 	void (*cb)(const SSL *ssl,int type2,int val)=NULL;
 
 	if (s->s3->rbuf.buf == NULL) /* Not initialized yet */
-		if (!ssl3_setup_buffers(s))
+		if (!ssl3_setup_read_buffer(s))
 			return(-1);
 
 	if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE) && type) ||
@@ -945,6 +1031,8 @@
 				{
 				s->rstate=SSL_ST_READ_HEADER;
 				rr->off=0;
+				if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+					ssl3_release_read_buffer(s);
 				}
 			}
 		return(n);
@@ -1328,8 +1416,6 @@
 		}
 
 	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
-		&(s->s3->finish_dgst1),
-		&(s->s3->finish_dgst2),
 		sender,slen,s->s3->tmp.peer_finish_md);
 
 	return(1);
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index e696450..92f73b6 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1,4 +1,4 @@
-/* ssl/s3_srvr.c */
+/* ssl/s3_srvr.c -*- mode:C; c-file-style: "eay" -*- */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -121,6 +121,32 @@
  * 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
@@ -143,12 +169,9 @@
 #endif
 #include <openssl/md5.h>
 
-static SSL_METHOD *ssl3_get_server_method(int ver);
-#ifndef OPENSSL_NO_ECDH
-static int nid2curve_id(int nid);
-#endif
+static const SSL_METHOD *ssl3_get_server_method(int ver);
 
-static 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());
@@ -164,7 +187,7 @@
 int ssl3_accept(SSL *s)
 	{
 	BUF_MEM *buf;
-	unsigned long l,Time=(unsigned long)time(NULL);
+	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;
@@ -292,6 +315,7 @@
 			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;
@@ -320,9 +344,11 @@
 
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
-			/* Check if it is anon DH or anon ECDH or KRB5 */
-			if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL)
-				&& !(s->s3->tmp.new_cipher->algorithms & SSL_aKRB5))
+			/* 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;
@@ -349,13 +375,13 @@
 
 		case SSL3_ST_SW_KEY_EXCH_A:
 		case SSL3_ST_SW_KEY_EXCH_B:
-			l=s->s3->tmp.new_cipher->algorithms;
+			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
-				&& !(l & SSL_KRB5)
+				&& !(alg_k & SSL_kKRB5)
 #endif /* OPENSSL_NO_KRB5 */
 				)
 				/* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
@@ -370,16 +396,23 @@
 			/* 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 
+			 * server certificate contains the server's
 			 * public key for key exchange.
 			 */
 			if (s->s3->tmp.use_rsa_tmp
-			    || (l & SSL_kECDHE)
-			    || (l & (SSL_DH|SSL_kFZA))
-			    || ((l & SSL_kRSA)
+			/* 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)
@@ -409,12 +442,15 @@
 				/* never request cert in anonymous ciphersuites
 				 * (see section "Certificate request" in SSL 3 drafts
 				 * and in RFC 2246): */
-				((s->s3->tmp.new_cipher->algorithms & SSL_aNULL) &&
+				((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->algorithms & SSL_aKRB5))
+				 /* 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;
@@ -490,7 +526,7 @@
 		case SSL3_ST_SR_KEY_EXCH_A:
 		case SSL3_ST_SR_KEY_EXCH_B:
 			ret=ssl3_get_client_key_exchange(s);
-			if (ret <= 0) 
+			if (ret <= 0)
 				goto end;
 			if (ret == 2)
 				{
@@ -498,24 +534,43 @@
 				 * 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.
 				 */
 				s->state=SSL3_ST_SR_FINISHED_A;
 				s->init_num = 0;
 				}
-			else   
+			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
-				 */ 
-				s->method->ssl3_enc->cert_verify_mac(s,
-				    &(s->s3->finish_dgst1),
-				    &(s->s3->tmp.cert_verify_md[0]));
-				s->method->ssl3_enc->cert_verify_mac(s,
-				    &(s->s3->finish_dgst2),
-				    &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]));
+				 * 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;
 
@@ -535,11 +590,14 @@
 			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;
-#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;
@@ -769,7 +827,7 @@
 	    (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) 
+		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
 			{
 			/* similar to ssl3_get_record, send alert using remote version number */
 			s->version = s->client_version;
@@ -990,13 +1048,110 @@
 			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
-	if (s->ctx->comp_methods != NULL)
+	/* 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;
 
@@ -1020,22 +1175,15 @@
 		else
 			comp=NULL;
 		}
-#endif
-
-	/* TLS does not mind if there is extra stuff */
-#if 0   /* SSL 3.0 does not mind either, so we should disable this test
-         * (was enabled in 0.9.6d through 0.9.6j and 0.9.7 through 0.9.7b,
-         * in earlier SSLeay/OpenSSL releases this test existed but was buggy) */
-	if (s->version == SSL3_VERSION)
+#else
+	/* If compression is disabled we'd better not try to resume a session
+	 * using compression.
+	 */
+	if (s->session->compress_meth != 0)
 		{
-		if (p < (d+n))
-			{
-			/* wrong number of bytes,
-			 * there could be more to follow */
-			al=SSL_AD_DECODE_ERROR;
-			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH);
-			goto f_err;
-			}
+		al=SSL_AD_INTERNAL_ERROR;
+		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION);
+		goto f_err;
 		}
 #endif
 
@@ -1084,7 +1232,7 @@
 			for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
 				{
 				c=sk_SSL_CIPHER_value(sk,i);
-				if (c->algorithms & SSL_eNULL)
+				if (c->algorithm_enc & SSL_eNULL)
 					nc=c;
 				if (SSL_C_IS_EXPORT(c))
 					ec=c;
@@ -1100,6 +1248,9 @@
 #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
@@ -1128,16 +1279,22 @@
 	unsigned char *buf;
 	unsigned char *p,*d;
 	int i,sl;
-	unsigned long l,Time;
+	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]);
 
@@ -1191,6 +1348,11 @@
 			*(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);
@@ -1270,7 +1432,7 @@
 	EVP_MD_CTX_init(&md_ctx);
 	if (s->state == SSL3_ST_SW_KEY_EXCH_A)
 		{
-		type=s->s3->tmp.new_cipher->algorithms & SSL_MKEY_MASK;
+		type=s->s3->tmp.new_cipher->algorithm_mkey;
 		cert=s->cert;
 
 		buf=s->init_buf;
@@ -1365,7 +1527,7 @@
 		else 
 #endif
 #ifndef OPENSSL_NO_ECDH
-			if (type & SSL_kECDHE)
+			if (type & SSL_kEECDH)
 			{
 			const EC_GROUP *group;
 
@@ -1435,7 +1597,7 @@
 			 * supported named curves, curve_id is non-zero.
 			 */
 			if ((curve_id = 
-			    nid2curve_id(EC_GROUP_get_curve_name(group)))
+			    tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
 			    == 0)
 				{
 				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
@@ -1492,6 +1654,14 @@
 			}
 		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);
@@ -1503,7 +1673,8 @@
 			n+=2+nr[i];
 			}
 
-		if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
+		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)
@@ -1535,7 +1706,7 @@
 			}
 
 #ifndef OPENSSL_NO_ECDH
-		if (type & SSL_kECDHE) 
+		if (type & SSL_kEECDH) 
 			{
 			/* XXX: For now, we only support named (not generic) curves.
 			 * In this situation, the serverKeyExchange message has:
@@ -1559,6 +1730,16 @@
 			}
 #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)
 			{
@@ -1571,8 +1752,6 @@
 				j=0;
 				for (num=2; num > 0; num--)
 					{
-					EVP_MD_CTX_set_flags(&md_ctx,
-						EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 					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);
@@ -1756,7 +1935,7 @@
 	{
 	int i,al,ok;
 	long n;
-	unsigned long l;
+	unsigned long alg_k;
 	unsigned char *p;
 #ifndef OPENSSL_NO_RSA
 	RSA *rsa=NULL;
@@ -1767,7 +1946,7 @@
 	DH *dh_srvr;
 #endif
 #ifndef OPENSSL_NO_KRB5
-        KSSL_ERR kssl_err;
+	KSSL_ERR kssl_err;
 #endif /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
@@ -1787,10 +1966,10 @@
 	if (!ok) return((int)n);
 	p=(unsigned char *)s->init_msg;
 
-	l=s->s3->tmp.new_cipher->algorithms;
+	alg_k=s->s3->tmp.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_RSA
-	if (l & SSL_kRSA)
+	if (alg_k & SSL_kRSA)
 		{
 		/* FIX THIS UP EAY EAY EAY EAY */
 		if (s->s3->tmp.use_rsa_tmp)
@@ -1821,9 +2000,8 @@
 			rsa=pkey->pkey.rsa;
 			}
 
-		/* TLS and [incidentally] DTLS, including pre-0.9.8f */
-		if (s->version > SSL3_VERSION &&
-		    s->client_version != DTLS1_BAD_VER)
+		/* TLS and [incidentally] DTLS{0xFEFF} */
+		if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER)
 			{
 			n2s(p,i);
 			if (n != i+2)
@@ -1897,7 +2075,7 @@
 	else
 #endif
 #ifndef OPENSSL_NO_DH
-		if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
+		if (alg_k & (SSL_kEDH|SSL_kDHr|SSL_kDHd))
 		{
 		n2s(p,i);
 		if (n != i+2)
@@ -1960,30 +2138,30 @@
 	else
 #endif
 #ifndef OPENSSL_NO_KRB5
-        if (l & SSL_kKRB5)
-                {
-                krb5_error_code		krb5rc;
+	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;
+		KSSL_CTX		*kssl_ctx = s->kssl_ctx;
 		EVP_CIPHER_CTX		ciph_ctx;
-		EVP_CIPHER		*enc = NULL;
+		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;
+					       + 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();
+		if (!kssl_ctx)  kssl_ctx = kssl_ctx_new();
 
 		n2s(p,i);
 		enc_ticket.length = i;
 
-		if (n < (int)enc_ticket.length + 6)
+		if (n < (long)(enc_ticket.length + 6))
 			{
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				SSL_R_DATA_LENGTH_TOO_LONG);
@@ -1996,7 +2174,7 @@
 		n2s(p,i);
 		authenticator.length = i;
 
-		if (n < (int)(enc_ticket.length + authenticator.length) + 6)
+		if (n < (long)(enc_ticket.length + authenticator.length + 6))
 			{
 			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				SSL_R_DATA_LENGTH_TOO_LONG);
@@ -2029,19 +2207,19 @@
 			goto err;
 			}
 
-                if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
+		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);
+			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;
-                        }
+			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.
@@ -2050,29 +2228,29 @@
 					&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);
+			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;
+			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;
+			goto err;
 			}
 
 #ifdef KSSL_DEBUG
-                kssl_ctx_show(kssl_ctx);
+		kssl_ctx_show(kssl_ctx);
 #endif	/* KSSL_DEBUG */
 
 		enc = kssl_map_enc(kssl_ctx->enctype);
-                if (enc == NULL)
-                    goto err;
+		if (enc == NULL)
+		    goto err;
 
 		memset(iv, 0, sizeof iv);	/* per RFC 1510 */
 
@@ -2119,7 +2297,7 @@
 		     * (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;
@@ -2128,32 +2306,32 @@
 
 		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);
+		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);
-                                }
-                        }
+		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,
+		/*  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;
-                */
-                }
+		**  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 ((l & SSL_kECDH) || (l & SSL_kECDHE))
+		if (alg_k & (SSL_kEECDH|SSL_kECDHr|SSL_kECDHe))
 		{
 		int ret = 1;
 		int field_size = 0;
@@ -2161,18 +2339,18 @@
 		const EC_GROUP *group;
 		const BIGNUM *priv_key;
 
-                /* initialize structures for server's ECDH key pair */
+		/* initialize structures for server's ECDH key pair */
 		if ((srvr_ecdh = EC_KEY_new()) == NULL) 
 			{
-                	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 			    ERR_R_MALLOC_FAILURE);
-                	goto err;
+			goto err;
 			}
 
 		/* Let's get server private key and group information */
-		if (l & SSL_kECDH) 
+		if (alg_k & (SSL_kECDHr|SSL_kECDHe))
 			{ 
-                        /* use the certificate */
+			/* use the certificate */
 			tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
 			}
 		else
@@ -2202,20 +2380,20 @@
 			goto err;
 			}
 
-                if (n == 0L) 
-                        {
+		if (n == 0L) 
+			{
 			/* Client Publickey was in Client Certificate */
 
-			 if (l & SSL_kECDHE) 
+			 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))
+			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
@@ -2227,11 +2405,11 @@
 				 * the two ECDH shares are for the same
 				 * group.
 				 */
-                           	al=SSL_AD_HANDSHAKE_FAILURE;
-                           	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+			   	al=SSL_AD_HANDSHAKE_FAILURE;
+			   	SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 				    SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
-                           	goto f_err;
-                           	}
+			   	goto f_err;
+			   	}
 
 			if (EC_POINT_copy(clnt_ecpoint,
 			    EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)) == 0)
@@ -2240,10 +2418,10 @@
 					ERR_R_EC_LIB);
 				goto err;
 				}
-                        ret = 2; /* Skip certificate verify processing */
-                        }
-                else
-                        {
+			ret = 2; /* Skip certificate verify processing */
+			}
+		else
+			{
 			/* Get client's public key from encoded point
 			 * in the ClientKeyExchange message.
 			 */
@@ -2254,21 +2432,21 @@
 				goto err;
 				}
 
-                        /* Get encoded point length */
-                        i = *p; 
+			/* Get encoded point length */
+			i = *p; 
 			p += 1;
-                        if (EC_POINT_oct2point(group, 
+			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;
-                        }
+			/* 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);
@@ -2279,28 +2457,190 @@
 			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,
+		if (i <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
 			    ERR_R_ECDH_LIB);
-                        goto err;
-                        }
+			goto err;
+			}
 
 		EVP_PKEY_free(clnt_pub_pkey);
 		EC_POINT_free(clnt_ecpoint);
-		if (srvr_ecdh != NULL) 
-			EC_KEY_free(srvr_ecdh);
+		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-> \
+		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);
+		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;
+			unsigned char premaster_secret[32], *start;
+			size_t outlen=32, inlen;			
+
+			/* Get our certificate private key*/
+			pkey_ctx = EVP_PKEY_CTX_new(s->cert->key->privatekey,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,
@@ -2390,15 +2730,25 @@
 
 	/* we now have a signature that we need to verify */
 	p=(unsigned char *)s->init_msg;
-	n2s(p,i);
-	n-=2;
-	if (i > n)
+	/* 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) )
 		{
-		SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH);
-		al=SSL_AD_DECODE_ERROR;
-		goto f_err;
-		}
-
+		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))
 		{
@@ -2461,6 +2811,28 @@
 		}
 	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;
@@ -2643,14 +3015,15 @@
 	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 */
-                        (s->s3->tmp.new_cipher->algorithms
-                                & (SSL_MKEY_MASK|SSL_AUTH_MASK))
-                        != (SSL_aKRB5|SSL_kKRB5))
+		if (x == NULL)
 			{
-			SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR);
-			return(0);
+			/* 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);
@@ -2662,70 +3035,6 @@
 	/* SSL3_ST_SW_CERT_B */
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 	}
-
-
-#ifndef OPENSSL_NO_ECDH
-/* This is the complement of curve_id2nid in s3_clnt.c. */
-static int nid2curve_id(int nid)
-{
-	/* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001)
-	 * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */
-	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
 #ifndef OPENSSL_NO_TLSEXT
 int ssl3_send_newsession_ticket(SSL *s)
 	{
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 4e4964e..7858169 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -56,60 +56,7 @@
  * [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).
- *
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -166,6 +113,32 @@
  * 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 
@@ -248,56 +221,88 @@
 #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"
-#define	SSL_TXT_aFZA		"aFZA"
-#define SSL_TXT_eFZA		"eFZA"
-#define SSL_TXT_FZA		"FZA"
+
+#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_kKRB5     	"kKRB5"
-#define SSL_TXT_aKRB5     	"aKRB5"
-#define SSL_TXT_KRB5      	"KRB5"
-
 #define SSL_TXT_kRSA		"kRSA"
-#define SSL_TXT_kDHr		"kDHr"
-#define SSL_TXT_kDHd		"kDHd"
+#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"
+#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"
+#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"
-#define SSL_TXT_EXP		"EXP"
-#define SSL_TXT_EXPORT		"EXPORT"
-#define SSL_TXT_EXP40		"EXPORT40"
-#define SSL_TXT_EXP56		"EXPORT56"
+#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"
-#define SSL_TXT_ECC		"ECCdraft" /* ECC ciphersuites are not yet official */
 
 /*
  * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
@@ -319,7 +324,13 @@
 /* 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	"AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH" /* low priority for RC4 */
+#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
@@ -344,6 +355,7 @@
  * '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
@@ -351,17 +363,25 @@
 	int valid;
 	const char *name;		/* text name */
 	unsigned long id;		/* id, 4 bytes, first is version */
-	unsigned long algorithms;	/* what ciphers are used */
+
+	/* 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 */
-	unsigned long mask;		/* used for matching */
-	unsigned long mask_strength;	/* also used for matching */
 	} 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
 	{
@@ -385,12 +405,12 @@
 	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);
-	SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
+	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);
-	SSL_CIPHER *(*get_cipher)(unsigned ncipher);
-	struct ssl_method_st *(*get_ssl_method)(int version);
+	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);
@@ -402,17 +422,20 @@
  * 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
+ *	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'
- *	Compression [6] IMPLICIT ASN1_OBJECT	-- compression OID XXXXX
+ *	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 :-).
@@ -440,7 +463,10 @@
         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 */
@@ -459,9 +485,9 @@
 	long timeout;
 	long time;
 
-	int compress_meth;		/* Need to lookup the method */
+	unsigned int compress_meth;	/* Need to lookup the method */
 
-	SSL_CIPHER *cipher;
+	const SSL_CIPHER *cipher;
 	unsigned long cipher_id;	/* when ASN.1 loaded, this
 					 * needs to be used to load
 					 * the 'cipher' structure */
@@ -475,6 +501,12 @@
 	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 */	
@@ -504,7 +536,7 @@
 
 /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
  *             This used to be 0x000FFFFFL before 0.9.7. */
-#define SSL_OP_ALL					0x00000FFFL
+#define SSL_OP_ALL					0x80000FFFL
 
 /* DTLS options */
 #define SSL_OP_NO_QUERY_MTU                 0x00001000L
@@ -517,6 +549,8 @@
 
 /* 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 */
@@ -545,7 +579,11 @@
 #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): */
@@ -560,9 +598,13 @@
 #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 0x00000010L
+#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. */
@@ -641,17 +683,18 @@
 	} SSL_COMP;
 
 DECLARE_STACK_OF(SSL_COMP)
+DECLARE_LHASH_OF(SSL_SESSION);
 
 struct ssl_ctx_st
 	{
-	SSL_METHOD *method;
+	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;
-	struct lhash_st /* LHASH */ *sessions;	/* a set of SSL_SESSIONs */
+	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;
@@ -776,6 +819,12 @@
 
 	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
 	 */
@@ -794,14 +843,33 @@
 	int (*tlsext_ticket_key_cb)(SSL *ssl,
 					unsigned char *name, unsigned char *iv,
 					EVP_CIPHER_CTX *ectx,
-					HMAC_CTX *hctx, int enc);
+ 					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;
 #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
@@ -815,7 +883,7 @@
 #define SSL_SESS_CACHE_NO_INTERNAL \
 	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
 
-  struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
+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) \
@@ -857,6 +925,31 @@
 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_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
@@ -868,6 +961,9 @@
 #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
@@ -876,7 +972,7 @@
 	int version;
 	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
 
-	SSL_METHOD *method; /* SSLv3 */
+	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
@@ -959,9 +1055,9 @@
 
 	/* 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 */
-	const EVP_MD *read_hash;		/* used for mac generation */
+	EVP_MD_CTX *read_hash;		/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *expand;			/* uncompress */
 #else
@@ -969,7 +1065,7 @@
 #endif
 
 	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
-	const EVP_MD *write_hash;		/* used for mac generation */
+	EVP_MD_CTX *write_hash;		/* used for mac generation */
 #ifndef OPENSSL_NO_COMP
 	COMP_CTX *compress;			/* compression */
 #else
@@ -1007,6 +1103,14 @@
 	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 :-) */
@@ -1026,6 +1130,7 @@
 	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,
@@ -1052,11 +1157,33 @@
 
 	/* 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 */
 #define session_ctx initial_ctx
 #else
 #define session_ctx ctx
-#endif
+#endif /* OPENSSL_NO_TLSEXT */
 	};
 
 #ifdef __cplusplus
@@ -1163,20 +1290,13 @@
 #define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
 #define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
 
-#if 1 /*SSLEAY_MACROS*/
 #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)
-#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
-	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
-#define PEM_read_bio_SSL_SESSION(bp,x,cb,u) PEM_ASN1_read_bio_of(SSL_SESSION,d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,cb,u)
-#define PEM_write_SSL_SESSION(fp,x) \
-	PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
-		PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
-#define PEM_write_bio_SSL_SESSION(bp,x) \
-	PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
-#endif
 
-#define SSL_AD_REASON_OFFSET		1000
+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 */
@@ -1206,6 +1326,8 @@
 #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
@@ -1264,6 +1386,8 @@
 #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
@@ -1273,7 +1397,9 @@
 #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
@@ -1343,7 +1469,7 @@
 #endif
 
 int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
-SSL_CTX *SSL_CTX_new(SSL_METHOD *meth);
+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);
@@ -1354,7 +1480,7 @@
 
 void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
 
-SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+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);
@@ -1425,9 +1551,8 @@
 void	SSL_copy_session_id(SSL *to,const SSL *from);
 
 SSL_SESSION *SSL_SESSION_new(void);
-unsigned long SSL_SESSION_hash(const SSL_SESSION *a);
-int	SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b);
-const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+					unsigned int *len);
 #ifndef OPENSSL_NO_FP_API
 int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
 #endif
@@ -1487,6 +1612,9 @@
 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);
@@ -1502,27 +1630,29 @@
 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,SSL_METHOD *meth);
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
 
-SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
-SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
-SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+#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
 
-SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
-SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
-SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+const SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+const SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
 
-SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
-SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
-SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+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 */
 
-SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
-SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
-SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+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 */
 
-SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
-SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
-SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.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);
 
@@ -1531,8 +1661,8 @@
 int SSL_renegotiate_pending(SSL *s);
 int SSL_shutdown(SSL *s);
 
-SSL_METHOD *SSL_get_ssl_method(SSL *s);
-int SSL_set_ssl_method(SSL *s,SSL_METHOD *method);
+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);
@@ -1624,6 +1754,11 @@
 #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,
@@ -1665,6 +1800,15 @@
 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.
@@ -1682,7 +1826,7 @@
 #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			 280
+#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
@@ -1691,9 +1835,9 @@
 #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			 282
+#define SSL_F_DTLS1_HANDLE_TIMEOUT			 297
 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 255
-#define SSL_F_DTLS1_PREPROCESS_FRAGMENT			 277
+#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
@@ -1737,7 +1881,7 @@
 #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			 281
+#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
@@ -1745,11 +1889,12 @@
 #define SSL_F_SSL3_CONNECT				 132
 #define SSL_F_SSL3_CTRL					 213
 #define SSL_F_SSL3_CTX_CTRL				 133
-#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 279
+#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			 288
+#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
@@ -1762,7 +1907,8 @@
 #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_NEW_SESSION_TICKET			 284
+#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
@@ -1774,16 +1920,17 @@
 #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_BUFFERS			 156
 #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	 285
-#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT		 272
+#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	 286
-#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT		 273
+#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
@@ -1791,7 +1938,8 @@
 #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		 274
+#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
@@ -1801,7 +1949,7 @@
 #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		 278
+#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
@@ -1813,6 +1961,7 @@
 #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
@@ -1824,13 +1973,13 @@
 #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	 287
-#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT		 290
-#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT	 289
-#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT		 291
+#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_SSL_PREPARE_CLIENTHELLO_TLSEXT		 275
-#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT		 276
+#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
@@ -1845,6 +1994,7 @@
 #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
@@ -1857,13 +2007,19 @@
 #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
 
@@ -1884,12 +2040,15 @@
 #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
@@ -1913,8 +2072,9 @@
 #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			 157
+#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
@@ -1927,8 +2087,12 @@
 #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			 318
+#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
@@ -1939,11 +2103,13 @@
 #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			 316
-#define SSL_R_INVALID_TICKET_KEYS_LENGTH		 275
+#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
@@ -1987,23 +2153,27 @@
 #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			 317
+#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				 319
+#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				 223
+#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
@@ -2014,6 +2184,9 @@
 #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
@@ -2023,22 +2196,24 @@
 #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			 320
-#define SSL_R_RENEGOTIATION_ENCODING_ERR		 321
-#define SSL_R_RENEGOTIATION_MISMATCH			 322
+#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		 324
-#define SSL_R_SERVERHELLO_TLSEXT			 224
+#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_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_SERVERNAME		 225
-#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE		 226
+#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
@@ -2072,8 +2247,13 @@
 #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_INVALID_ECPOINTFORMAT_LIST		 227
+#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
@@ -2100,9 +2280,10 @@
 #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	 323
+#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
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index bf71ef9..fb41ca5 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -123,7 +123,6 @@
 #include <openssl/buffer.h>
 #include <openssl/evp.h>
 #include <openssl/ssl.h>
-#include <openssl/pq_compat.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -163,12 +162,14 @@
 #define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
 #define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
 
-#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
+#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
@@ -220,9 +221,11 @@
 #define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
 #define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
 
-#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"
+#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"
@@ -248,32 +251,75 @@
 #define SSL3_SESSION_ID_SIZE			32
 #define SSL3_RT_HEADER_LENGTH			5
 
-/* Due to MS stuffing up, this can change.... */
-#if defined(OPENSSL_SYS_WIN16) || \
-	(defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32))
-#define SSL3_RT_MAX_EXTRA			(14000)
+#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
-#define SSL3_RT_MAX_EXTRA			(16384)
+# 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
+#define SSL3_RT_MAX_COMPRESSED_LENGTH		SSL3_RT_MAX_PLAIN_LENGTH
 #else
-#define SSL3_RT_MAX_COMPRESSED_LENGTH	(1024+SSL3_RT_MAX_PLAIN_LENGTH)
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	\
+		(SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
 #endif
-#define SSL3_RT_MAX_ENCRYPTED_LENGTH	(1024+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#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_RT_MAX_PACKET_SIZE		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
-#define SSL3_RT_MAX_DATA_SIZE			(1024*1024)
 
 #define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
 #define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
@@ -312,7 +358,7 @@
 /*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 */  PQ_64BIT seq_num;       /* sequence number, needed by DTLS1 */
+/*r */  unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
 	} SSL3_RECORD;
 
 typedef struct ssl3_buffer_st
@@ -335,13 +381,14 @@
  * enough to contain all of the cert types defined either for
  * SSLv3 and TLSv1.
  */
-#define SSL3_CT_NUMBER			7
+#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
 
 typedef struct ssl3_state_st
 	{
@@ -349,8 +396,10 @@
 	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];
@@ -360,6 +409,9 @@
 	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 */
 
@@ -381,9 +433,11 @@
 	const unsigned char *wpend_buf;
 
 	/* used during startup, digest all incoming/outgoing packets */
-	EVP_MD_CTX finish_dgst1;
-	EVP_MD_CTX finish_dgst2;
-
+	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;
@@ -403,6 +457,14 @@
 
 	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;
+
 	struct	{
 		/* actually only needs to be 16+20 */
 		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
@@ -417,7 +479,7 @@
 		int message_type;
 
 		/* used to hold the new cipher we are going to use */
-		SSL_CIPHER *new_cipher;
+		const SSL_CIPHER *new_cipher;
 #ifndef OPENSSL_NO_DH
 		DH *dh;
 #endif
@@ -444,6 +506,8 @@
 
 		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
@@ -580,4 +644,3 @@
 }
 #endif
 #endif
-
diff --git a/ssl/ssl_algs.c b/ssl/ssl_algs.c
index 2d9077e..a26ae43 100644
--- a/ssl/ssl_algs.c
+++ b/ssl/ssl_algs.c
@@ -76,13 +76,16 @@
 #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());
@@ -91,7 +94,7 @@
 #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");
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index d82e47a..2870997 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -55,6 +55,32 @@
  * 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>
@@ -84,12 +110,16 @@
 	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;
+	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
@@ -97,8 +127,8 @@
 	unsigned char ibuf6[LSIZE2];
 #endif
 #ifndef OPENSSL_NO_COMP
-	int v11=0;
 	unsigned char cbuf;
+	int v11=0;
 #endif
 	long l;
 	SSL_SESSION_ASN1 a;
@@ -177,7 +207,7 @@
 		a.krb5_princ.data=in->krb5_client_princ;
 		}
 #endif /* OPENSSL_NO_KRB5 */
- 
+
 	if (in->time != 0L)
 		{
 		a.time.length=LSIZE2;
@@ -223,6 +253,21 @@
 		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);
@@ -256,6 +301,13 @@
         	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);
@@ -282,6 +334,14 @@
 #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)
@@ -295,7 +355,7 @@
 	}
 
 SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
-	     long length)
+			     long length)
 	{
 	int version,ssl_version=0,i;
 	long id;
@@ -475,6 +535,24 @@
 		}
 	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)
@@ -485,17 +563,17 @@
 	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_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;
- 		}
+		os.data = NULL;
+		os.length = 0;
+		}
 	else
 		ret->tlsext_tick=NULL;
 #endif /* OPENSSL_NO_TLSEXT */
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 16fda5d..27256ee 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -197,8 +197,10 @@
 	 * if you find that more readable */
 
 	ret->valid = cert->valid;
-	ret->mask = cert->mask;
-	ret->export_mask = cert->export_mask;
+	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)
@@ -753,6 +755,8 @@
 			sk_X509_NAME_push(stack,xn);
 		}
 
+	ERR_clear_error();
+
 	if (0)
 		{
 err:
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 5e2d436..bee3507 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -113,12 +113,41 @@
  * 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
@@ -126,18 +155,18 @@
 #define SSL_ENC_RC4_IDX		2
 #define SSL_ENC_RC2_IDX		3
 #define SSL_ENC_IDEA_IDX	4
-#define SSL_ENC_eFZA_IDX	5
-#define SSL_ENC_NULL_IDX	6
-#define SSL_ENC_AES128_IDX	7
-#define SSL_ENC_AES256_IDX	8
-#define SSL_ENC_CAMELLIA128_IDX	9
-#define SSL_ENC_CAMELLIA256_IDX	10
+#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,NULL,NULL,NULL,NULL,NULL,NULL,
 	};
 
 #define SSL_COMP_NULL_IDX	0
@@ -148,9 +177,30 @@
 
 #define SSL_MD_MD5_IDX	0
 #define SSL_MD_SHA1_IDX	1
-#define SSL_MD_NUM_IDX	2
+#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,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
@@ -161,72 +211,144 @@
 
 typedef struct cipher_order_st
 	{
-	SSL_CIPHER *cipher;
+	const SSL_CIPHER *cipher;
 	int active;
 	int dead;
 	struct cipher_order_st *next,*prev;
 	} CIPHER_ORDER;
 
 static const SSL_CIPHER cipher_aliases[]={
-	/* Don't include eNULL unless specifically enabled. */
-	/* Don't include ECC in ALL because these ciphers are not yet official. */
-	{0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL & ~SSL_kECDH & ~SSL_kECDHE, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL}, /* must be first */
-	/* TODO: COMPLEMENT OF ALL and COMPLEMENT OF DEFAULT do not have ECC cipher suites handled properly. */
-	{0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},  /* COMPLEMENT OF ALL */
-	{0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0},  /* VRS Kerberos5 */
-	{0,SSL_TXT_kRSA,0,SSL_kRSA,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kDHr,0,SSL_kDHr,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kDHd,0,SSL_kDHd,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kEDH,0,SSL_kEDH,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_kFZA,0,SSL_kFZA,  0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_DH,	0,SSL_DH,    0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_ECC,	0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0},
-	{0,SSL_TXT_EDH,	0,SSL_EDH,   0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0},  /* VRS Kerberos5 */
-	{0,SSL_TXT_aRSA,0,SSL_aRSA,  0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aDSS,0,SSL_aDSS,  0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aFZA,0,SSL_aFZA,  0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_aDH, 0,SSL_aDH,   0,0,0,0,SSL_AUTH_MASK,0},
-	{0,SSL_TXT_DSS,	0,SSL_DSS,   0,0,0,0,SSL_AUTH_MASK,0},
+	/* "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},
 
-	{0,SSL_TXT_DES,	0,SSL_DES,   0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_3DES,0,SSL_3DES,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_RC4,	0,SSL_RC4,   0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_RC2,	0,SSL_RC2,   0,0,0,0,SSL_ENC_MASK,0},
-#ifndef OPENSSL_NO_IDEA
-	{0,SSL_TXT_IDEA,0,SSL_IDEA,  0,0,0,0,SSL_ENC_MASK,0},
-#endif
-	{0,SSL_TXT_SEED,0,SSL_SEED,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_eFZA,0,SSL_eFZA,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_AES,	0,SSL_AES,   0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_CAMELLIA,0,SSL_CAMELLIA, 0,0,0,0,SSL_ENC_MASK,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},
 
-	{0,SSL_TXT_MD5,	0,SSL_MD5,   0,0,0,0,SSL_MAC_MASK,0},
-	{0,SSL_TXT_SHA1,0,SSL_SHA1,  0,0,0,0,SSL_MAC_MASK,0},
-	{0,SSL_TXT_SHA,	0,SSL_SHA,   0,0,0,0,SSL_MAC_MASK,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_NULL,0,SSL_NULL,  0,0,0,0,SSL_ENC_MASK,0},
-	{0,SSL_TXT_KRB5,0,SSL_KRB5,  0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
-	{0,SSL_TXT_RSA,	0,SSL_RSA,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
-	{0,SSL_TXT_ADH,	0,SSL_ADH,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0},
-	{0,SSL_TXT_FZA,	0,SSL_FZA,   0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,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_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0},
-	{0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0},
-	{0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0},
+	{0,SSL_TXT_kKRB5,0,   SSL_kKRB5, 0,0,0,0,0,0,0,0},
 
-	{0,SSL_TXT_EXP   ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
-	{0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK},
-	{0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK},
-	{0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK},
-	{0,SSL_TXT_LOW,   0, 0,   SSL_LOW, 0,0,0,0,SSL_STRONG_MASK},
-	{0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK},
-	{0,SSL_TXT_HIGH,  0, 0,  SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK},
-	{0,SSL_TXT_FIPS,  0, 0,  SSL_FIPS, 0,0,0,0,SSL_FIPS|SSL_STRONG_NONE},
+	{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)
 	{
@@ -252,16 +374,37 @@
 	  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,
@@ -316,10 +459,10 @@
 #endif
 
 int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
-	     const EVP_MD **md, SSL_COMP **comp)
+	     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size,SSL_COMP **comp)
 	{
 	int i;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 
 	c=s->cipher;
 	if (c == NULL) return(0);
@@ -344,7 +487,7 @@
 
 	if ((enc == NULL) || (md == NULL)) return(0);
 
-	switch (c->algorithms & SSL_ENC_MASK)
+	switch (c->algorithm_enc)
 		{
 	case SSL_DES:
 		i=SSL_ENC_DES_IDX;
@@ -364,26 +507,24 @@
 	case SSL_eNULL:
 		i=SSL_ENC_NULL_IDX;
 		break;
-	case SSL_AES:
-		switch(c->alg_bits)
-			{
-		case 128: i=SSL_ENC_AES128_IDX; break;
-		case 256: i=SSL_ENC_AES256_IDX; break;
-		default: i=-1; break;
-			}
+	case SSL_AES128:
+		i=SSL_ENC_AES128_IDX;
 		break;
-	case SSL_CAMELLIA:
-		switch(c->alg_bits)
-			{
-		case 128: i=SSL_ENC_CAMELLIA128_IDX; break;
-		case 256: i=SSL_ENC_CAMELLIA256_IDX; break;
-		default: i=-1; 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;
@@ -399,7 +540,7 @@
 			*enc=ssl_cipher_methods[i];
 		}
 
-	switch (c->algorithms & SSL_MAC_MASK)
+	switch (c->algorithm_mac)
 		{
 	case SSL_MD5:
 		i=SSL_MD_MD5_IDX;
@@ -407,21 +548,48 @@
 	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;
-	else
-		*md=ssl_digest_methods[i];
+	{
+		*md=NULL; 
+		if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
+		if (mac_secret_size!=NULL) *mac_secret_size = 0;
 
-	if ((*enc != NULL) && (*md != NULL))
+	}
+	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) == ','))
 
@@ -433,7 +601,7 @@
 		*head=curr->next;
 	if (curr->prev != NULL)
 		curr->prev->next=curr->next;
-	if (curr->next != NULL) /* should always be true */
+	if (curr->next != NULL)
 		curr->next->prev=curr->prev;
 	(*tail)->next=curr;
 	curr->prev= *tail;
@@ -441,69 +609,105 @@
 	*tail=curr;
 	}
 
-struct disabled_masks { /* This is a kludge no longer needed with OpenSSL 0.9.9,
-                         * where 128-bit and 256-bit algorithms simply will get
-                         * separate bits. */
-  unsigned long mask; /* everything except m256 */
-  unsigned long m256; /* applies to 256-bit algorithms only */
-};
-
-static struct disabled_masks ssl_cipher_get_disabled(void)
+static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
+	     CIPHER_ORDER **tail)
 	{
-	unsigned long mask;
-	unsigned long m256;
-	struct disabled_masks ret;
+	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;
+	}
 
-	mask = SSL_kFZA;
+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
-	mask |= SSL_aRSA|SSL_kRSA;
+	*mkey |= SSL_kRSA;
+	*auth |= SSL_aRSA;
 #endif
 #ifdef OPENSSL_NO_DSA
-	mask |= SSL_aDSS;
+	*auth |= SSL_aDSS;
 #endif
+	*mkey |= SSL_kDHr|SSL_kDHd; /* no such ciphersuites supported! */
+	*auth |= SSL_aDH;
 #ifdef OPENSSL_NO_DH
-	mask |= SSL_kDHr|SSL_kDHd|SSL_kEDH|SSL_aDH;
+	*mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH;
+	*auth |= SSL_aDH;
 #endif
 #ifdef OPENSSL_NO_KRB5
-	mask |= SSL_kKRB5|SSL_aKRB5;
+	*mkey |= SSL_kKRB5;
+	*auth |= SSL_aKRB5;
+#endif
+#ifdef OPENSSL_NO_ECDSA
+	*auth |= SSL_aECDSA;
 #endif
 #ifdef OPENSSL_NO_ECDH
-	mask |= SSL_kECDH|SSL_kECDHE;
+	*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
-	mask |= SSL_eNULL;
+	*enc |= SSL_eNULL;
 #endif
+		
 
-	mask |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
-	mask |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
-	mask |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
-	mask |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_eFZA_IDX] == NULL) ? SSL_eFZA:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0;
 
-	mask |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
-	mask |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
+	*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;
 
-	/* finally consider algorithms where mask and m256 differ */
-	m256 = mask;
-	mask |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES:0;
-	mask |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA:0;
-	m256 |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES:0;
-	m256 |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA: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;
 
-	ret.mask = mask;
-	ret.m256 = m256;
-	return ret;
 	}
 
 static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
-		int num_of_ciphers, unsigned long mask, unsigned long m256,
-		CIPHER_ORDER *co_list, CIPHER_ORDER **head_p,
-		CIPHER_ORDER **tail_p)
+                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;
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 
 	/*
 	 * We have num_of_ciphers descriptions compiled in, depending on the
@@ -517,14 +721,13 @@
 	for (i = 0; i < num_of_ciphers; i++)
 		{
 		c = ssl_method->get_cipher(i);
-#define IS_MASKED(c) ((c)->algorithms & (((c)->alg_bits == 256) ? m256 : mask))
 		/* drop those that use any of that is not available */
-#ifdef OPENSSL_FIPS
-		if ((c != NULL) && c->valid && !IS_MASKED(c)
-			&& (!FIPS_mode() || (c->algo_strength & SSL_FIPS)))
-#else
-		if ((c != NULL) && c->valid && !IS_MASKED(c))
-#endif
+		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;
@@ -532,7 +735,7 @@
 			co_list[co_list_num].active = 0;
 			co_list_num++;
 #ifdef KSSL_DEBUG
-			printf("\t%d: %s %lx %lx\n",i,c->name,c->id,c->algorithms);
+			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;
@@ -543,29 +746,45 @@
 	/*
 	 * Prepare linked list from list entries
 	 */	
-	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]);
-		}
 	if (co_list_num > 0)
 		{
-		(*head_p) = &(co_list[0]);
-		(*head_p)->prev = NULL;
-		(*head_p)->next = &(co_list[1]);
-		(*tail_p) = &(co_list[co_list_num - 1]);
-		(*tail_p)->prev = &(co_list[co_list_num - 2]);
-		(*tail_p)->next = NULL;
+		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(SSL_CIPHER **ca_list,
-			int num_of_group_aliases, unsigned long mask,
+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;
-	SSL_CIPHER **ca_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
@@ -581,84 +800,118 @@
 
 	/*
 	 * Now we add the available ones from the cipher_aliases[] table.
-	 * They represent either an algorithm, that must be fully
-	 * supported (not match any bit in mask) or represent a cipher
-	 * strength value (will be added in any case because algorithms=0).
+	 * 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++)
 		{
-		if ((i == 0) ||		/* always fetch "ALL" */
-		    !(cipher_aliases[i].algorithms & mask))
-			{
-			*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
-			ca_curr++;
-			}
+		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 ssl_version,
-		unsigned long algorithms, unsigned long mask,
-		unsigned long algo_strength, unsigned long mask_strength,
-		int rule, int strength_bits, CIPHER_ORDER *co_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, *tail2;
-	SSL_CIPHER *cp;
-	unsigned long ma, ma_s;
+	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 (%d)\n",
-		rule, algorithms, mask, algo_strength, mask_strength,
-		strength_bits);
+	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
 
-	curr = head = *head_p;
-	curr2 = head;
-	tail2 = tail = *tail_p;
+	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 == tail2)) break;
+		if ((curr == NULL) || (curr == last)) break;
 		curr = curr2;
-		curr2 = curr->next;
+		curr2 = reverse ? curr->prev : curr->next;
 
 		cp = curr->cipher;
 
-		/* If explicit cipher suite, match only that one for its own protocol version.
-		 * Usual selection criteria will be used for similar ciphersuites from other version! */
-
-		if (cipher_id && (cp->algorithms & SSL_SSL_MASK) == ssl_version)
+		/*
+		 * Selection criteria is either the value of strength_bits
+		 * or the algorithms used.
+		 */
+		if (strength_bits >= 0)
 			{
-			if (cp->id != cipher_id)
+			if (strength_bits != cp->strength_bits)
 				continue;
 			}
-
-		/*
-		 * Selection criteria is either the number of strength_bits
-		 * or the algorithm used.
-		 */
-		else if (strength_bits == -1)
+		else
 			{
-			ma = mask & cp->algorithms;
-			ma_s = mask_strength & cp->algo_strength;
-
 #ifdef CIPHER_DEBUG
-			printf("\nName: %s:\nAlgo = %08lx Algo_strength = %08lx\nMask = %08lx Mask_strength %08lx\n", cp->name, cp->algorithms, cp->algo_strength, mask, mask_strength);
-			printf("ma = %08lx ma_s %08lx, ma&algo=%08lx, ma_s&algos=%08lx\n", ma, ma_s, ma&algorithms, ma_s&algo_strength);
+			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
-			/*
-			 * Select: if none of the mask bit was met from the
-			 * cipher or not all of the bits were met, the
-			 * selection does not apply.
-			 */
-			if (((ma == 0) && (ma_s == 0)) ||
-			    ((ma & algorithms) != ma) ||
-			    ((ma_s & algo_strength) != ma_s))
-				continue; /* does not apply */
+
+			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;
 			}
-		else if (strength_bits != cp->strength_bits)
-			continue;	/* does not apply */
 
 #ifdef CIPHER_DEBUG
 		printf("Action = %d\n", rule);
@@ -667,38 +920,37 @@
 		/* add the cipher if it has not been added yet. */
 		if (rule == CIPHER_ADD)
 			{
+			/* reverse == 0 */
 			if (!curr->active)
 				{
-				int add_this_cipher = 1;
-
-				if (((cp->algorithms & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0))
-					{
-					/* Make sure "ECCdraft" ciphersuites are activated only if
-					 * *explicitly* requested, but not implicitly (such as
-					 * as part of the "AES" alias). */
-
-					add_this_cipher = (mask & (SSL_kECDHE|SSL_kECDH|SSL_aECDSA)) != 0 || cipher_id != 0;
-					}
-				
-				if (add_this_cipher)
-					{
-					ll_append_tail(&head, curr, &tail);
-					curr->active = 1;
-					}
+				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)
-			curr->active = 0;
+			{
+			/* 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
@@ -719,8 +971,7 @@
 	*tail_p = tail;
 	}
 
-static int ssl_cipher_strength_sort(CIPHER_ORDER *co_list,
-				    CIPHER_ORDER **head_p,
+static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
 				    CIPHER_ORDER **tail_p)
 	{
 	int max_strength_bits, i, *number_uses;
@@ -743,10 +994,10 @@
 
 	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));
 
 	/*
@@ -765,21 +1016,20 @@
 	 */
 	for (i = max_strength_bits; i >= 0; i--)
 		if (number_uses[i] > 0)
-			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i,
-					co_list, head_p, tail_p);
+			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 *co_list, CIPHER_ORDER **head_p,
-		CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)
+                CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p,
+                const SSL_CIPHER **ca_list)
 	{
-	unsigned long algorithms, mask, algo_strength, mask_strength;
+	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
 	const char *l, *start, *buf;
 	int j, multi, found, rule, retval, ok, buflen;
-	unsigned long cipher_id = 0, ssl_version = 0;
+	unsigned long cipher_id = 0;
 	char ch;
 
 	retval = 1;
@@ -807,7 +1057,12 @@
 			continue;
 			}
 
-		algorithms = mask = algo_strength = mask_strength = 0;
+		alg_mkey = 0;
+		alg_auth = 0;
+		alg_enc = 0;
+		alg_mac = 0;
+		alg_ssl = 0;
+		algo_strength = 0;
 
 		start=l;
 		for (;;)
@@ -868,10 +1123,9 @@
 			 * sufficient, we have to strncmp() anyway. (We cannot
 			 * use strcmp(), because buf is not '\0' terminated.)
 			 */
-			 j = found = 0;
-			 cipher_id = 0;
-			 ssl_version = 0;
-			 while (ca_list[j])
+			j = found = 0;
+			cipher_id = 0;
+			while (ca_list[j])
 				{
 				if (!strncmp(buf, ca_list[j]->name, buflen) &&
 				    (ca_list[j]->name[buflen] == '\0'))
@@ -882,31 +1136,100 @@
 				else
 					j++;
 				}
+
 			if (!found)
 				break;	/* ignore this entry */
 
-			/* New algorithms:
-			 *  1 - any old restrictions apply outside new mask
-			 *  2 - any new restrictions apply outside old mask
-			 *  3 - enforce old & new where masks intersect
-			 */
-			algorithms = (algorithms & ~ca_list[j]->mask) |		/* 1 */
-			             (ca_list[j]->algorithms & ~mask) |		/* 2 */
-			             (algorithms & ca_list[j]->algorithms);	/* 3 */
-			mask |= ca_list[j]->mask;
-			algo_strength = (algo_strength & ~ca_list[j]->mask_strength) |
-			                (ca_list[j]->algo_strength & ~mask_strength) |
-			                (algo_strength & ca_list[j]->algo_strength);
-			mask_strength |= ca_list[j]->mask_strength;
-
-			/* explicit ciphersuite found */
-			if (ca_list[j]->valid)
+			if (ca_list[j]->algorithm_mkey)
 				{
-				cipher_id = ca_list[j]->id;
-				ssl_version = ca_list[j]->algorithms & SSL_SSL_MASK;
-				break;
+				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;
 			}
 
@@ -918,8 +1241,7 @@
 			ok = 0;
 			if ((buflen == 8) &&
 				!strncmp(buf, "STRENGTH", 8))
-				ok = ssl_cipher_strength_sort(co_list,
-					head_p, tail_p);
+				ok = ssl_cipher_strength_sort(head_p, tail_p);
 			else
 				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
 					SSL_R_INVALID_COMMAND);
@@ -936,9 +1258,9 @@
 			}
 		else if (found)
 			{
-			ssl_cipher_apply_rule(cipher_id, ssl_version, algorithms, mask,
-				algo_strength, mask_strength, rule, -1,
-				co_list, head_p, tail_p);
+			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
 			{
@@ -957,12 +1279,11 @@
 		const char *rule_str)
 	{
 	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
-	unsigned long disabled_mask;
-	unsigned long disabled_m256;
+	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;
-	SSL_CIPHER **ca_list = NULL;
+	const SSL_CIPHER **ca_list = NULL;
 
 	/*
 	 * Return with error if nothing to do.
@@ -974,12 +1295,7 @@
 	 * To reduce the work to do we only want to process the compiled
 	 * in algorithms, so we first get the mask of disabled ciphers.
 	 */
-	{
-		struct disabled_masks d;
-		d = ssl_cipher_get_disabled();
-		disabled_mask = d.mask;
-		disabled_m256 = d.m256;
-	}
+	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
@@ -997,8 +1313,52 @@
 		return(NULL);	/* Failure */
 		}
 
-	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,
-				   disabled_m256, co_list, &head, &tail);
+	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.
@@ -1010,8 +1370,7 @@
 	 */
 	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
 	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
-	ca_list =
-		(SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
+	ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
 	if (ca_list == NULL)
 		{
 		OPENSSL_free(co_list);
@@ -1019,7 +1378,8 @@
 		return(NULL);	/* Failure */
 		}
 	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
-				   (disabled_mask & disabled_m256), head);
+	                           disabled_mkey, disabled_auth, disabled_enc,
+				   disabled_mac, disabled_ssl, head);
 
 	/*
 	 * If the rule_string begins with DEFAULT, apply the default rule
@@ -1030,23 +1390,23 @@
 	if (strncmp(rule_str,"DEFAULT",7) == 0)
 		{
 		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
-			co_list, &head, &tail, ca_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, co_list, &head, &tail,
-						ca_list);
+		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list);
 
-	OPENSSL_free(ca_list);	/* Not needed anymore */
+	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.
@@ -1063,11 +1423,7 @@
 	 */
 	for (curr = head; curr != NULL; curr = curr->next)
 		{
-#ifdef OPENSSL_FIPS
-		if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
-#else
 		if (curr->active)
-#endif
 			{
 			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
 #ifdef CIPHER_DEBUG
@@ -1100,14 +1456,19 @@
 	int is_export,pkl,kl;
 	const char *ver,*exp_str;
 	const char *kx,*au,*enc,*mac;
-	unsigned long alg,alg2,alg_s;
+	unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2,alg_s;
 #ifdef KSSL_DEBUG
-	static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx\n";
+	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=cipher->algorithms;
+	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;
+
 	alg_s=cipher->algo_strength;
 	alg2=cipher->algorithm2;
 
@@ -1116,14 +1477,14 @@
 	kl=SSL_C_EXPORT_KEYLENGTH(cipher);
 	exp_str=is_export?" export":"";
 	
-	if (alg & SSL_SSLV2)
+	if (alg_ssl & SSL_SSLV2)
 		ver="SSLv2";
-	else if (alg & SSL_SSLV3)
+	else if (alg_ssl & SSL_SSLV3)
 		ver="SSLv3";
 	else
 		ver="unknown";
 
-	switch (alg&SSL_MKEY_MASK)
+	switch (alg_mkey)
 		{
 	case SSL_kRSA:
 		kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";
@@ -1134,25 +1495,29 @@
 	case SSL_kDHd:
 		kx="DH/DSS";
 		break;
-        case SSL_kKRB5:         /* VRS */
-        case SSL_KRB5:          /* VRS */
-            kx="KRB5";
-            break;
-	case SSL_kFZA:
-		kx="Fortezza";
+        case SSL_kKRB5:
+		kx="KRB5";
 		break;
 	case SSL_kEDH:
 		kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";
 		break;
-	case SSL_kECDH:
-	case SSL_kECDHE:
-		kx=is_export?"ECDH(<=163)":"ECDH";
+	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&SSL_AUTH_MASK)
+	switch (alg_auth)
 		{
 	case SSL_aRSA:
 		au="RSA";
@@ -1163,23 +1528,27 @@
 	case SSL_aDH:
 		au="DH";
 		break;
-        case SSL_aKRB5:         /* VRS */
-        case SSL_KRB5:          /* VRS */
-            au="KRB5";
-            break;
-	case SSL_aFZA:
+        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&SSL_ENC_MASK)
+	switch (alg_enc)
 		{
 	case SSL_DES:
 		enc=(is_export && kl == 5)?"DES(40)":"DES(56)";
@@ -1197,39 +1566,30 @@
 	case SSL_IDEA:
 		enc="IDEA(128)";
 		break;
-	case SSL_eFZA:
-		enc="Fortezza";
-		break;
 	case SSL_eNULL:
 		enc="None";
 		break;
-	case SSL_AES:
-		switch(cipher->strength_bits)
-			{
-		case 128: enc="AES(128)"; break;
-		case 192: enc="AES(192)"; break;
-		case 256: enc="AES(256)"; break;
-		default: enc="AES(?""?""?)"; break;
-			}
+	case SSL_AES128:
+		enc="AES(128)";
 		break;
-	case SSL_CAMELLIA:
-		switch(cipher->strength_bits)
-			{
-		case 128: enc="Camellia(128)"; break;
-		case 256: enc="Camellia(256)"; break;
-		default: enc="Camellia(?""?""?)"; 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&SSL_MAC_MASK)
+	switch (alg_mac)
 		{
 	case SSL_MD5:
 		mac="MD5";
@@ -1252,7 +1612,7 @@
 		return("Buffer too small");
 
 #ifdef KSSL_DEBUG
-	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp_str,alg);
+	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 */
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 7eb5202..0eed464 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -1,6 +1,6 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2008 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -141,6 +141,7 @@
 {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"},
@@ -158,6 +159,7 @@
 {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"},
@@ -170,8 +172,9 @@
 {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_BUFFERS),	"SSL3_SETUP_BUFFERS"},
 {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"},
@@ -188,6 +191,7 @@
 {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"},
@@ -209,6 +213,7 @@
 {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"},
@@ -241,6 +246,7 @@
 {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"},
@@ -253,13 +259,19 @@
 {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}
@@ -283,12 +295,15 @@
 {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"},
@@ -314,6 +329,7 @@
 {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"},
@@ -328,6 +344,10 @@
 {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"},
@@ -338,8 +358,10 @@
 {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"},
@@ -389,18 +411,22 @@
 {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"},
@@ -413,6 +439,9 @@
 {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"},
@@ -426,6 +455,7 @@
 {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"},
@@ -436,6 +466,7 @@
 {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"},
@@ -471,6 +502,11 @@
 {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"},
@@ -502,6 +538,7 @@
 {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"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 15650da..3157f20 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -58,7 +58,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -115,6 +115,32 @@
  * 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>
@@ -143,9 +169,9 @@
 	ssl_undefined_function,
 	(int (*)(SSL *, unsigned char *, unsigned char *, int))ssl_undefined_function,
 	(int (*)(SSL*, int))ssl_undefined_function,
-	(int (*)(SSL *, EVP_MD_CTX *, EVP_MD_CTX *, const char*, int, unsigned char *))ssl_undefined_function,
+	(int (*)(SSL *,  const char*, int, unsigned char *))ssl_undefined_function,
 	0,	/* finish_mac_length */
-	(int (*)(SSL *, EVP_MD_CTX *, unsigned char *))ssl_undefined_function,
+	(int (*)(SSL *, int, unsigned char *))ssl_undefined_function,
 	NULL,	/* client_finished_label */
 	0,	/* client_finished_label_len */
 	NULL,	/* server_finished_label */
@@ -204,6 +230,8 @@
 		}
 
 	ssl_clear_cipher_ctx(s);
+	ssl_clear_hash_ctx(&s->read_hash);
+	ssl_clear_hash_ctx(&s->write_hash);
 
 	s->first_packet=0;
 
@@ -224,14 +252,15 @@
 	}
 
 /** Used to change an SSL_CTXs default SSL method type */
-int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth)
+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),SSL_DEFAULT_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);
@@ -308,6 +337,7 @@
 	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;
@@ -324,6 +354,7 @@
 	CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX);
 	s->initial_ctx=ctx;
 #endif
+
 	s->verify_result=X509_V_OK;
 
 	s->method=ctx->method;
@@ -338,6 +369,11 @@
 
 	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)
@@ -425,7 +461,7 @@
 		}
 
 	CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-	p = (SSL_SESSION *)lh_retrieve(ssl->ctx->sessions, &r);
+	p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
 	CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
 	return (p != NULL);
 	}
@@ -450,6 +486,16 @@
 	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;
@@ -504,6 +550,8 @@
 		}
 
 	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 */
@@ -512,6 +560,11 @@
 	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);
@@ -520,6 +573,7 @@
 	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);
 
@@ -844,7 +898,7 @@
 		}
 	if (ssl->cert == NULL)
 		{
-                SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
+		SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY,SSL_R_NO_CERTIFICATE_ASSIGNED);
 		return 0;
 		}
 	if (ssl->cert->key->x509 == NULL)
@@ -1007,6 +1061,11 @@
 			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;
@@ -1029,7 +1088,7 @@
 		}
 	}
 
-struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx)
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
 	{
 	return ctx->sessions;
 	}
@@ -1072,7 +1131,7 @@
 		return(ctx->session_cache_mode);
 
 	case SSL_CTRL_SESS_NUMBER:
-		return(ctx->sessions->num_items);
+		return(lh_SSL_SESSION_num_items(ctx->sessions));
 	case SSL_CTRL_SESS_CONNECT:
 		return(ctx->stats.sess_connect);
 	case SSL_CTRL_SESS_CONNECT_GOOD:
@@ -1103,6 +1162,11 @@
 		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));
 		}
@@ -1207,8 +1271,8 @@
 	/* 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 
+	 * 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)
@@ -1276,13 +1340,13 @@
 	}
 
 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 (*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);
+	int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
 #endif /* OPENSSL_NO_KRB5 */
 
 	if (sk == NULL) return(0);
@@ -1292,10 +1356,16 @@
 		{
 		c=sk_SSL_CIPHER_value(sk,i);
 #ifndef OPENSSL_NO_KRB5
-                if ((c->algorithms & SSL_KRB5) && nokrb5)
-                    continue;
-#endif /* 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;
 		}
@@ -1306,7 +1376,7 @@
 		{
 		static SSL_CIPHER scsv =
 			{
-			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
+			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;
@@ -1321,7 +1391,7 @@
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,unsigned char *p,int num,
 					       STACK_OF(SSL_CIPHER) **skp)
 	{
-	SSL_CIPHER *c;
+	const SSL_CIPHER *c;
 	STACK_OF(SSL_CIPHER) *sk;
 	int i,n;
 	if (s->s3)
@@ -1384,6 +1454,7 @@
 	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).
@@ -1407,7 +1478,7 @@
 	}
 #endif
 
-unsigned long SSL_SESSION_hash(const SSL_SESSION *a)
+static unsigned long ssl_session_hash(const SSL_SESSION *a)
 	{
 	unsigned long l;
 
@@ -1424,7 +1495,7 @@
  * 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. */
-int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
+static int ssl_session_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
 	{
 	if (a->ssl_version != b->ssl_version)
 		return(1);
@@ -1437,27 +1508,19 @@
  * 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_hash, SSL_SESSION *)
-static IMPLEMENT_LHASH_COMP_FN(SSL_SESSION_cmp, SSL_SESSION *)
+static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION)
+static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION)
 
-SSL_CTX *SSL_CTX_new(SSL_METHOD *meth)
+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);
 		}
 
-#ifdef OPENSSL_FIPS
-	if (FIPS_mode() && (meth->version < TLS1_VERSION))	
-		{
-		SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
-		return NULL;
-		}
-#endif
-
 	if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
 		{
 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
@@ -1520,15 +1583,14 @@
 	ret->app_gen_cookie_cb=0;
 	ret->app_verify_cookie_cb=0;
 
-	ret->sessions=lh_new(LHASH_HASH_FN(SSL_SESSION_hash),
-			LHASH_COMP_FN(SSL_SESSION_cmp));
+	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,
-		SSL_DEFAULT_CIPHER_LIST);
+		meth->version == SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
 	if (ret->cipher_list == NULL
 	    || sk_SSL_CIPHER_num(ret->cipher_list) <= 0)
 		{
@@ -1564,6 +1626,8 @@
 	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;
@@ -1577,7 +1641,29 @@
 	ret->tlsext_status_arg = NULL;
 
 #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
@@ -1616,6 +1702,20 @@
     { 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;
@@ -1653,7 +1753,7 @@
 	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
 
 	if (a->sessions != NULL)
-		lh_free(a->sessions);
+		lh_SSL_SESSION_free(a->sessions);
 
 	if (a->cert_store != NULL)
 		X509_STORE_free(a->cert_store);
@@ -1673,10 +1773,23 @@
 #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);
 	}
 
@@ -1707,13 +1820,13 @@
 	X509_VERIFY_PARAM_set_depth(ctx->param, depth);
 	}
 
-void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher)
+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,emask;
+	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;
@@ -1760,60 +1873,77 @@
 	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=0;
-	emask=0;
+	mask_k=0;
+	mask_a=0;
+	emask_k=0;
+	emask_a=0;
+
+	
 
 #ifdef CIPHER_DEBUG
-	printf("rt=%d rte=%d dht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
-		rsa_tmp,rsa_tmp_export,dh_tmp,
+	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|=SSL_kRSA;
+		mask_k|=SSL_kRSA;
 	if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
-		emask|=SSL_kRSA;
+		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) && 
+	if (	(dh_tmp || dh_rsa || dh_dsa) &&
 		(rsa_enc || rsa_sign || dsa_sign))
-		mask|=SSL_kEDH;
+		mask_k|=SSL_kEDH;
 	if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
 		(rsa_enc || rsa_sign || dsa_sign))
-		emask|=SSL_kEDH;
+		emask_k|=SSL_kEDH;
 #endif
 
-	if (dh_tmp_export) 
-		emask|=SSL_kEDH;
+	if (dh_tmp_export)
+		emask_k|=SSL_kEDH;
 
 	if (dh_tmp)
-		mask|=SSL_kEDH;
+		mask_k|=SSL_kEDH;
 
-	if (dh_rsa) mask|=SSL_kDHr;
-	if (dh_rsa_export) emask|=SSL_kDHr;
+	if (dh_rsa) mask_k|=SSL_kDHr;
+	if (dh_rsa_export) emask_k|=SSL_kDHr;
 
-	if (dh_dsa) mask|=SSL_kDHd;
-	if (dh_dsa_export) emask|=SSL_kDHd;
+	if (dh_dsa) mask_k|=SSL_kDHd;
+	if (dh_dsa_export) emask_k|=SSL_kDHd;
 
 	if (rsa_enc || rsa_sign)
 		{
-		mask|=SSL_aRSA;
-		emask|=SSL_aRSA;
+		mask_a|=SSL_aRSA;
+		emask_a|=SSL_aRSA;
 		}
 
 	if (dsa_sign)
 		{
-		mask|=SSL_aDSS;
-		emask|=SSL_aDSS;
+		mask_a|=SSL_aDSS;
+		emask_a|=SSL_aDSS;
 		}
 
-	mask|=SSL_aNULL;
-	emask|=SSL_aNULL;
+	mask_a|=SSL_aNULL;
+	emask_a|=SSL_aNULL;
 
 #ifndef OPENSSL_NO_KRB5
-	mask|=SSL_kKRB5|SSL_aKRB5;
-	emask|=SSL_kKRB5|SSL_aKRB5;
+	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
@@ -1821,7 +1951,7 @@
 	 */
 	if (have_ecc_cert)
 		{
-                /* This call populates extension flags (ex_flags) */
+		/* 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) ?
@@ -1829,7 +1959,7 @@
 		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) ? 
+		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))
@@ -1837,27 +1967,41 @@
 #ifndef OPENSSL_NO_ECDH
 		if (ecdh_ok)
 			{
-			if ((signature_nid == NID_md5WithRSAEncryption) ||
-			    (signature_nid == NID_md4WithRSAEncryption) ||
-			    (signature_nid == NID_md2WithRSAEncryption))
+			const char *sig = OBJ_nid2ln(signature_nid);
+			if (sig == NULL)
 				{
-				mask|=SSL_kECDH|SSL_aRSA;
-				if (ecc_pkey_size <= 163)
-					emask|=SSL_kECDH|SSL_aRSA;
+				ERR_clear_error();
+				sig = "unknown";
 				}
+				
+			if (strstr(sig, "WithRSA"))
+				{
+				mask_k|=SSL_kECDHr;
+				mask_a|=SSL_aECDH;
+				if (ecc_pkey_size <= 163)
+					{
+					emask_k|=SSL_kECDHr;
+					emask_a|=SSL_aECDH;
+					}
+				}
+
 			if (signature_nid == NID_ecdsa_with_SHA1)
 				{
-				mask|=SSL_kECDH|SSL_aECDSA;
+				mask_k|=SSL_kECDHe;
+				mask_a|=SSL_aECDH;
 				if (ecc_pkey_size <= 163)
-					emask|=SSL_kECDH|SSL_aECDSA;
+					{
+					emask_k|=SSL_kECDHe;
+					emask_a|=SSL_aECDH;
+					}
 				}
 			}
 #endif
 #ifndef OPENSSL_NO_ECDSA
 		if (ecdsa_ok)
 			{
-			mask|=SSL_aECDSA;
-			emask|=SSL_aECDSA;
+			mask_a|=SSL_aECDSA;
+			emask_a|=SSL_aECDSA;
 			}
 #endif
 		}
@@ -1865,12 +2009,22 @@
 #ifndef OPENSSL_NO_ECDH
 	if (have_ecdh_tmp)
 		{
-		mask|=SSL_kECDHE;
-		emask|=SSL_kECDHE;
+		mask_k|=SSL_kEECDH;
+		emask_k|=SSL_kEECDH;
 		}
 #endif
-	c->mask=mask;
-	c->export_mask=emask;
+
+#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;
 	}
 
@@ -1878,13 +2032,18 @@
 #define ku_reject(x, usage) \
 	(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
 
-int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs)
+#ifndef OPENSSL_NO_EC
+
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, const SSL_CIPHER *cs)
 	{
-	unsigned long alg = cs->algorithms;
+	unsigned long alg_k, alg_a;
 	EVP_PKEY *pkey = NULL;
 	int keysize = 0;
 	int signature_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 */
@@ -1899,37 +2058,46 @@
 	X509_check_purpose(x, -1, 0);
 	if ((x->sig_alg) && (x->sig_alg->algorithm))
 		signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
-	if (alg & SSL_kECDH) 
+	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 & SSL_aECDSA) 
+		if (alg_k & SSL_kECDHe)
 			{
 			/* signature alg must be ECDSA */
 			if (signature_nid != NID_ecdsa_with_SHA1)
 				{
+				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
 				return 0;
 				}
 			}
-		if (alg & SSL_aRSA)
+		if (alg_k & SSL_kECDHr)
 			{
 			/* signature alg must be RSA */
-			if ((signature_nid != NID_md5WithRSAEncryption) &&
-			    (signature_nid != NID_md4WithRSAEncryption) &&
-			    (signature_nid != NID_md2WithRSAEncryption))
+
+			const char *sig = OBJ_nid2ln(signature_nid);
+			if (sig == NULL)
 				{
+				ERR_clear_error();
+				sig = "unknown";
+				}
+			if (strstr(sig, "WithRSA") == NULL)
+				{
+				SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
 				return 0;
 				}
 			}
-		} 
-	else if (alg & SSL_aECDSA)
+		}
+	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;
 			}
 		}
@@ -1937,58 +2105,74 @@
 	return 1;  /* all checks are ok */
 	}
 
+#endif
+
 /* THIS NEEDS CLEANING UP */
 X509 *ssl_get_server_send_cert(SSL *s)
 	{
-	unsigned long alg,mask,kalg;
+	unsigned long alg_k,alg_a,mask_k,mask_a;
 	CERT *c;
 	int i,is_export;
 
 	c=s->cert;
 	ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
-	alg=s->s3->tmp.new_cipher->algorithms;
 	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
-	mask=is_export?c->export_mask:c->mask;
-	kalg=alg&(SSL_MKEY_MASK|SSL_AUTH_MASK);
-
-	if (kalg & SSL_kECDH)
+	if (is_export)
 		{
-		/* we don't need to look at SSL_kECDHE 
+		mask_k = c->export_mask_k;
+		mask_a = c->export_mask_a;
+		}
+	else
+		{
+		mask_k = c->mask_k;
+		mask_a = c->mask_a;
+		}
+	
+	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
-		 * ECDHE, the check for the auth 
+		 * 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 ECDHE-RSA
+		 * 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 (kalg & SSL_aECDSA)
+	else if (alg_a & SSL_aECDSA)
 		{
 		i=SSL_PKEY_ECC;
 		}
-	else if (kalg & SSL_kDHr)
+	else if (alg_k & SSL_kDHr)
 		i=SSL_PKEY_DH_RSA;
-	else if (kalg & SSL_kDHd)
+	else if (alg_k & SSL_kDHd)
 		i=SSL_PKEY_DH_DSA;
-	else if (kalg & SSL_aDSS)
+	else if (alg_a & SSL_aDSS)
 		i=SSL_PKEY_DSA_SIGN;
-	else if (kalg & SSL_aRSA)
+	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 (kalg & SSL_aKRB5)
+	else if (alg_a & SSL_aKRB5)
 		{
 		/* VRS something else here? */
 		return(NULL);
 		}
-	else /* if (kalg & SSL_aNULL) */
+	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);
@@ -1998,18 +2182,18 @@
 	return(c->pkeys[i].x509);
 	}
 
-EVP_PKEY *ssl_get_sign_pkey(SSL *s,SSL_CIPHER *cipher)
+EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher)
 	{
-	unsigned long alg;
+	unsigned long alg_a;
 	CERT *c;
 
-	alg=cipher->algorithms;
+	alg_a = cipher->algorithm_auth;
 	c=s->cert;
 
-	if ((alg & SSL_aDSS) &&
+	if ((alg_a & SSL_aDSS) &&
 		(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
 		return(c->pkeys[SSL_PKEY_DSA_SIGN].privatekey);
-	else if (alg & SSL_aRSA)
+	else if (alg_a & SSL_aRSA)
 		{
 		if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
 			return(c->pkeys[SSL_PKEY_RSA_SIGN].privatekey);
@@ -2018,10 +2202,10 @@
 		else
 			return(NULL);
 		}
-	else if ((alg & SSL_aECDSA) &&
+	else if ((alg_a & SSL_aECDSA) &&
 	         (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
 		return(c->pkeys[SSL_PKEY_ECC].privatekey);
-	else /* if (alg & SSL_aNULL) */
+	else /* if (alg_a & SSL_aNULL) */
 		{
 		SSLerr(SSL_F_SSL_GET_SIGN_PKEY,ERR_R_INTERNAL_ERROR);
 		return(NULL);
@@ -2036,14 +2220,14 @@
 	 * and it would be rather hard to do anyway :-) */
 	if (s->session->session_id_length == 0) return;
 
-	i=s->ctx->session_cache_mode;
+	i=s->session_ctx->session_cache_mode;
 	if ((i & mode) && (!s->hit)
 		&& ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
-		    || SSL_CTX_add_session(s->ctx,s->session))
-		&& (s->ctx->new_session_cb != NULL))
+		    || 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->ctx->new_session_cb(s,s->session))
+		if (!s->session_ctx->new_session_cb(s,s->session))
 			SSL_SESSION_free(s->session);
 		}
 
@@ -2052,20 +2236,20 @@
 		((i & mode) == mode))
 		{
 		if (  (((mode & SSL_SESS_CACHE_CLIENT)
-			?s->ctx->stats.sess_connect_good
-			:s->ctx->stats.sess_accept_good) & 0xff) == 0xff)
+			?s->session_ctx->stats.sess_connect_good
+			:s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff)
 			{
-			SSL_CTX_flush_sessions(s->ctx,(unsigned long)time(NULL));
+			SSL_CTX_flush_sessions(s->session_ctx,(unsigned long)time(NULL));
 			}
 		}
 	}
 
-SSL_METHOD *SSL_get_ssl_method(SSL *s)
+const SSL_METHOD *SSL_get_ssl_method(SSL *s)
 	{
 	return(s->method);
 	}
 
-int SSL_set_ssl_method(SSL *s,SSL_METHOD *meth)
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
 	{
 	int conn= -1;
 	int ret=1;
@@ -2208,6 +2392,8 @@
 	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)
@@ -2218,6 +2404,8 @@
 	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)
@@ -2262,7 +2450,7 @@
 	X509_NAME *xn;
 	SSL *ret;
 	int i;
-		 
+	
 	if ((ret=SSL_new(SSL_get_SSL_CTX(s))) == NULL)
 	    return(NULL);
 
@@ -2432,7 +2620,7 @@
 		return(NULL);
 	}
 
-SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
 	{
 	if ((s->session != NULL) && (s->session->cipher != NULL))
 		return(s->session->cipher);
@@ -2510,7 +2698,7 @@
 		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	
+#endif
 	}
 	BIO_free(s->bbio);
 	s->bbio=NULL;
@@ -2595,7 +2783,7 @@
 
 /* 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*/) 
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL * /*ssl*/,int /*type*/,int /*val*/)
 	{
 	return ssl->info_callback;
 	}
@@ -2716,13 +2904,13 @@
 
 #ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,DH *(*dh)(SSL *ssl,int is_export,
-							int keylength))
+                                                        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))
+                                                int keylength))
 	{
 	SSL_callback_ctrl(ssl,SSL_CTRL_SET_TMP_DH_CB,(void (*)(void))dh);
 	}
@@ -2730,18 +2918,109 @@
 
 #ifndef OPENSSL_NO_ECDH
 void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,EC_KEY *(*ecdh)(SSL *ssl,int is_export,
-							int keylength))
+                                                                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))
+                                                        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))
 	{
@@ -2752,7 +3031,25 @@
 	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
 	}
 
+/* 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"
@@ -2760,3 +3057,6 @@
 
 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/ssl/ssl_locl.h b/ssl/ssl_locl.h
index e305db4..4c78393 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -113,6 +113,32 @@
  * 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
@@ -251,58 +277,84 @@
  * that the different entities within are mutually exclusive:
  * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
  */
-#define SSL_MKEY_MASK		0x000000FFL
+
+/* Bits for algorithm_mkey (key exchange algorithm) */
 #define SSL_kRSA		0x00000001L /* RSA key exchange */
-#define SSL_kDHr		0x00000002L /* DH cert RSA CA cert */
-#define SSL_kDHd		0x00000004L /* DH cert DSA CA cert */
-#define SSL_kFZA		0x00000008L
-#define SSL_kEDH		0x00000010L /* tmp DH key no DH cert */
-#define SSL_kKRB5		0x00000020L /* Kerberos5 key exchange */
-#define SSL_kECDH               0x00000040L /* ECDH w/ long-term keys */
-#define SSL_kECDHE              0x00000080L /* ephemeral ECDH */
-#define SSL_EDH			(SSL_kEDH|(SSL_AUTH_MASK^SSL_aNULL))
+#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 */
 
-#define SSL_AUTH_MASK		0x00007F00L
-#define SSL_aRSA		0x00000100L /* Authenticate with RSA */
-#define SSL_aDSS 		0x00000200L /* Authenticate with DSS */
-#define SSL_DSS 		SSL_aDSS
-#define SSL_aFZA 		0x00000400L
-#define SSL_aNULL 		0x00000800L /* no Authenticate, ADH */
-#define SSL_aDH 		0x00001000L /* no Authenticate, ADH */
-#define SSL_aKRB5               0x00002000L /* Authenticate with KRB5 */
-#define SSL_aECDSA              0x00004000L /* Authenticate with ECDSA */
+/* 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 */
 
-#define SSL_NULL		(SSL_eNULL)
-#define SSL_ADH			(SSL_kEDH|SSL_aNULL)
-#define SSL_RSA			(SSL_kRSA|SSL_aRSA)
-#define SSL_DH			(SSL_kDHr|SSL_kDHd|SSL_kEDH)
-#define SSL_ECDH		(SSL_kECDH|SSL_kECDHE)
-#define SSL_FZA			(SSL_aFZA|SSL_kFZA|SSL_eFZA)
-#define SSL_KRB5                (SSL_kKRB5|SSL_aKRB5)
 
-#define SSL_ENC_MASK		0x1C3F8000L
-#define SSL_DES			0x00008000L
-#define SSL_3DES		0x00010000L
-#define SSL_RC4			0x00020000L
-#define SSL_RC2			0x00040000L
-#define SSL_IDEA		0x00080000L
-#define SSL_eFZA		0x00100000L
-#define SSL_eNULL		0x00200000L
-#define SSL_AES			0x04000000L
-#define SSL_CAMELLIA		0x08000000L
-#define SSL_SEED          	0x10000000L
+/* 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_MAC_MASK		0x00c00000L
-#define SSL_MD5			0x00400000L
-#define SSL_SHA1		0x00800000L
-#define SSL_SHA			(SSL_SHA1)
+#define SSL_AES        		(SSL_AES128|SSL_AES256)
+#define SSL_CAMELLIA		(SSL_CAMELLIA128|SSL_CAMELLIA256)
 
-#define SSL_SSL_MASK		0x03000000L
-#define SSL_SSLV2		0x01000000L
-#define SSL_SSLV3		0x02000000L
+
+/* 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 */
 
-/* we have used 1fffffff - 3 bits left to go. */
+
+/* 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
@@ -320,10 +372,11 @@
  * be possible.
  */
 #define SSL_EXP_MASK		0x00000003L
+#define SSL_STRONG_MASK		0x000001fcL
+
 #define SSL_NOT_EXP		0x00000001L
 #define SSL_EXPORT		0x00000002L
 
-#define SSL_STRONG_MASK		0x000000fcL
 #define SSL_STRONG_NONE		0x00000004L
 #define SSL_EXP40		0x00000008L
 #define SSL_MICRO		(SSL_EXP40)
@@ -357,17 +410,14 @@
 #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_ENC_MASK) == SSL_DES ? 8 : 7)
+				 (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)->algorithms, \
+#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)
 
 
-#define SSL_ALL			0xffffffffL
-#define SSL_ALL_CIPHERS		(SSL_MKEY_MASK|SSL_AUTH_MASK|SSL_ENC_MASK|\
-				SSL_MAC_MASK)
-#define SSL_ALL_STRENGTHS	(SSL_EXP_MASK|SSL_STRONG_MASK)
+
 
 /* Mostly for SSLv3 */
 #define SSL_PKEY_RSA_ENC	0
@@ -376,7 +426,9 @@
 #define SSL_PKEY_DH_RSA		3
 #define SSL_PKEY_DH_DSA		4
 #define SSL_PKEY_ECC            5
-#define SSL_PKEY_NUM		6
+#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)
@@ -417,8 +469,10 @@
 	/* The following masks are for the key and auth
 	 * algorithms that are supported by the certs below */
 	int valid;
-	unsigned long mask;
-	unsigned long export_mask;
+	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);
@@ -492,9 +546,9 @@
 	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 *, EVP_MD_CTX *, EVP_MD_CTX *, const char *, int, unsigned char *);
+	int (*final_finish_mac)(SSL *,  const char *, int, unsigned char *);
 	int finish_mac_length;
-	int (*cert_verify_mac)(SSL *, EVP_MD_CTX *, unsigned char *);
+	int (*cert_verify_mac)(SSL *, int, unsigned char *);
 	const char *client_finished_label;
 	int client_finished_label_len;
 	const char *server_finished_label;
@@ -512,24 +566,35 @@
 	} 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 SSL_CIPHER ssl2_ciphers[];
+OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[];
 OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[];
 
 
 SSL_METHOD *ssl_bad_method(int ver);
-SSL_METHOD *sslv2_base_method(void);
-SSL_METHOD *sslv23_base_method(void);
-SSL_METHOD *sslv3_base_method(void);
 
 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) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		TLS1_VERSION, \
 		tls1_new, \
 		tls1_clear, \
@@ -564,9 +629,9 @@
 	}
 
 #define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		SSL3_VERSION, \
 		ssl3_new, \
 		ssl3_clear, \
@@ -601,9 +666,9 @@
 	}
 
 #define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 	TLS1_VERSION, \
 	tls1_new, \
 	tls1_clear, \
@@ -638,9 +703,9 @@
 	}
 
 #define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		SSL2_VERSION, \
 		ssl2_new,	/* local */ \
 		ssl2_clear,	/* local */ \
@@ -675,9 +740,9 @@
 	}
 
 #define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
-SSL_METHOD *func_name(void)  \
+const SSL_METHOD *func_name(void)  \
 	{ \
-	static SSL_METHOD func_name##_data= { \
+	static const SSL_METHOD func_name##_data= { \
 		DTLS1_VERSION, \
 		dtls1_new, \
 		dtls1_clear, \
@@ -723,6 +788,8 @@
 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,
@@ -735,15 +802,16 @@
 					     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,SSL_COMP **comp);
+		       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 *,SSL_CIPHER *);
+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, SSL_CIPHER *cipher);
+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);
@@ -752,7 +820,7 @@
 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);
-SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
+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);
@@ -760,7 +828,7 @@
 void ssl2_return_error(SSL *s,int reason);
 void ssl2_write_error(SSL *s);
 int ssl2_num_ciphers(void);
-SSL_CIPHER *ssl2_get_cipher(unsigned int u);
+const SSL_CIPHER *ssl2_get_cipher(unsigned int u);
 int	ssl2_new(SSL *s);
 void	ssl2_free(SSL *s);
 int	ssl2_accept(SSL *s);
@@ -777,7 +845,7 @@
 int	ssl2_pending(const SSL *s);
 long	ssl2_default_timeout(void );
 
-SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
+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);
@@ -796,22 +864,27 @@
 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);
-SSL_CIPHER *ssl3_get_cipher(unsigned int u);
+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, EVP_MD_CTX *ctx1, EVP_MD_CTX *ctx2,
-	const char *sender, int slen,unsigned char *p);
-int ssl3_cert_verify_mac(SSL *s, EVP_MD_CTX *in, unsigned char *p);
+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 ssl3_mac(SSL *ssl, unsigned char *md, 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);
@@ -832,12 +905,12 @@
 long ssl3_default_timeout(void );
 
 int ssl23_num_ciphers(void );
-SSL_CIPHER *ssl23_get_cipher(unsigned int u);
+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);
-SSL_CIPHER *ssl23_get_cipher_by_char(const 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);
@@ -871,14 +944,13 @@
 long dtls1_default_timeout(void);
 struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
 int dtls1_handle_timeout(SSL *s);
-SSL_CIPHER *dtls1_get_cipher(unsigned int u);
+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);
 
-
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
 int ssl3_get_server_hello(SSL *s);
@@ -887,8 +959,8 @@
 int ssl3_get_cert_status(SSL *s);
 int ssl3_get_server_done(SSL *s);
 int ssl3_send_client_verify(SSL *s);
-int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
 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);
@@ -933,7 +1005,6 @@
 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));
-SSL_METHOD *tlsv1_base_method(void );
 
 int dtls1_new(SSL *s);
 int	dtls1_accept(SSL *s);
@@ -941,7 +1012,6 @@
 void dtls1_free(SSL *s);
 void dtls1_clear(SSL *s);
 long dtls1_ctrl(SSL *s,int cmd, long larg, void *parg);
-SSL_METHOD *dtlsv1_base_method(void );
 
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 int dtls1_get_record(SSL *s);
@@ -956,9 +1026,9 @@
 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, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
+int tls1_final_finish_mac(SSL *s,
 	const char *str, int slen, unsigned char *p);
-int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in, 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);
@@ -966,10 +1036,17 @@
 int ssl3_alert_code(int code);
 int ssl_ok(SSL *s);
 
-int check_srvr_ecc_cert_and_alg(X509 *x, SSL_CIPHER *cs);
+#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); 
@@ -987,9 +1064,9 @@
 #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,
@@ -999,5 +1076,3 @@
 int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
 					  int *al);
 #endif
-
-#endif
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index e7802e1..8e5d8a0 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -55,6 +55,85 @@
  * 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>
@@ -127,8 +206,18 @@
 	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);
 	}
 
@@ -183,10 +272,10 @@
 	if ((ss=SSL_SESSION_new()) == NULL) return(0);
 
 	/* If the context has a default timeout, use it */
-	if (s->ctx->session_timeout == 0)
+	if (s->session_ctx->session_timeout == 0)
 		ss->timeout=SSL_get_default_timeout(s);
 	else
-		ss->timeout=s->ctx->session_timeout;
+		ss->timeout=s->session_ctx->session_timeout;
 
 	if (s->session != NULL)
 		{
@@ -239,8 +328,8 @@
 		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
 		if(s->generate_session_id)
 			cb = s->generate_session_id;
-		else if(s->ctx->generate_session_id)
-			cb = s->ctx->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;
@@ -286,6 +375,32 @@
 				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
@@ -318,15 +433,15 @@
 #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);
+	r = tls1_process_ticket(s, session_id, len, limit, &ret);
 	if (r == -1)
 		{
 		fatal = 1;
- 		goto err;
+		goto err;
 		}
 	else if (r == 0 || (!ret && !len))
 		goto err;
@@ -334,7 +449,7 @@
 #else
 	if (len == 0)
 		goto err;
-	if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+	if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
 #endif
 		{
 		SSL_SESSION data;
@@ -342,9 +457,9 @@
 		data.session_id_length=len;
 		if (len == 0)
 			return 0;
- 		memcpy(data.session_id,session_id,len);
+		memcpy(data.session_id,session_id,len);
 		CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
-		ret=(SSL_SESSION *)lh_retrieve(s->ctx->sessions,&data);
+		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);
@@ -355,13 +470,13 @@
 		{
 		int copy=1;
 	
-		s->ctx->stats.sess_miss++;
+		s->session_ctx->stats.sess_miss++;
 		ret=NULL;
-		if (s->ctx->get_session_cb != NULL
-		    && (ret=s->ctx->get_session_cb(s,session_id,len,&copy))
+		if (s->session_ctx->get_session_cb != NULL
+		    && (ret=s->session_ctx->get_session_cb(s,session_id,len,&copy))
 		       != NULL)
 			{
-			s->ctx->stats.sess_cb_hit++;
+			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
@@ -373,10 +488,10 @@
 
 			/* Add the externally cached session to the internal
 			 * cache as well if and only if we are supposed to. */
-			if(!(s->ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_STORE))
+			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->ctx,ret);
+				SSL_CTX_add_session(s->session_ctx,ret);
 			}
 		if (ret == NULL)
 			goto err;
@@ -443,13 +558,13 @@
 
 	if (ret->timeout < (long)(time(NULL) - ret->time)) /* timeout */
 		{
-		s->ctx->stats.sess_timeout++;
+		s->session_ctx->stats.sess_timeout++;
 		/* remove it from the cache */
-		SSL_CTX_remove_session(s->ctx,ret);
+		SSL_CTX_remove_session(s->session_ctx,ret);
 		goto err;
 		}
 
-	s->ctx->stats.sess_hit++;
+	s->session_ctx->stats.sess_hit++;
 
 	/* ret->time=time(NULL); */ /* rezero timeout? */
 	/* again, just leave the session 
@@ -482,7 +597,7 @@
 	/* if session c is in already in cache, we take back the increment later */
 
 	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-	s=(SSL_SESSION *)lh_insert(ctx->sessions,c);
+	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
@@ -548,10 +663,10 @@
 	if ((c != NULL) && (c->session_id_length != 0))
 		{
 		if(lck) CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-		if ((r = (SSL_SESSION *)lh_retrieve(ctx->sessions,c)) == c)
+		if ((r = lh_SSL_SESSION_retrieve(ctx->sessions,c)) == c)
 			{
 			ret=1;
-			r=(SSL_SESSION *)lh_delete(ctx->sessions,c);
+			r=lh_SSL_SESSION_delete(ctx->sessions,c);
 			SSL_SESSION_list_remove(ctx,c);
 			}
 
@@ -601,6 +716,18 @@
 #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);
@@ -609,7 +736,7 @@
 int SSL_set_session(SSL *s, SSL_SESSION *session)
 	{
 	int ret=0;
-	SSL_METHOD *meth;
+	const SSL_METHOD *meth;
 
 	if (session != NULL)
 		{
@@ -712,20 +839,75 @@
 	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 *cache;
+	LHASH_OF(SSL_SESSION) *cache;
 	} TIMEOUT_PARAM;
 
-static void timeout(SSL_SESSION *s, TIMEOUT_PARAM *p)
+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 */
-		lh_delete(p->cache,s);
+		(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)
@@ -734,7 +916,7 @@
 		}
 	}
 
-static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION *, TIMEOUT_PARAM *)
+static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM)
 
 void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
 	{
@@ -746,10 +928,11 @@
 	if (tp.cache == NULL) return;
 	tp.time=t;
 	CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
-	i=tp.cache->down_load;
-	tp.cache->down_load=0;
-	lh_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), &tp);
-	tp.cache->down_load=i;
+	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);
 	}
 
@@ -909,3 +1092,4 @@
 	ctx->app_verify_cookie_cb=cb;
 	}
 
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c
index e7509f0..144b81e 100644
--- a/ssl/ssl_stat.c
+++ b/ssl/ssl_stat.c
@@ -55,6 +55,32 @@
  * 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"
@@ -414,6 +440,12 @@
 	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);
@@ -497,6 +529,24 @@
 	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);
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index 81c1361..3122440 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -55,6 +55,32 @@
  * 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>
@@ -155,6 +181,12 @@
 			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)
 		{
@@ -170,12 +202,13 @@
 			goto err;
 		}
 #endif
+
 #ifndef OPENSSL_NO_COMP
 	if (x->compress_meth != 0)
 		{
 		SSL_COMP *comp = NULL;
 
-		ssl_cipher_get_evp(x,NULL,NULL,&comp);
+		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;
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 09d3502..39cb541 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -113,6 +113,32 @@
  * 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. */
@@ -128,8 +154,11 @@
 #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>
@@ -207,6 +236,16 @@
 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;
 
@@ -229,9 +268,6 @@
 	{
 	fprintf(stderr,"usage: ssltest [args ...]\n");
 	fprintf(stderr,"\n");
-#ifdef OPENSSL_FIPS
-	fprintf(stderr,"-F             - run test in FIPS mode\n");
-#endif
 	fprintf(stderr," -server_auth  - check server certificate\n");
 	fprintf(stderr," -client_auth  - do client authentication\n");
 	fprintf(stderr," -proxy        - allow proxy certificates\n");
@@ -250,6 +286,9 @@
 #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
@@ -283,7 +322,7 @@
 
 static void print_details(SSL *c_ssl, const char *prefix)
 	{
-	SSL_CIPHER *ciph;
+	const SSL_CIPHER *ciph;
 	X509 *cert;
 		
 	ciph=SSL_get_current_cipher(c_ssl);
@@ -388,6 +427,28 @@
 		}
 	}
 
+#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 main(int argc, char *argv[])
 	{
@@ -409,19 +470,20 @@
 #endif
 	SSL_CTX *s_ctx=NULL;
 	SSL_CTX *c_ctx=NULL;
-	SSL_METHOD *meth=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 = 1, dhe1024dsa = 0;
+	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;
@@ -430,18 +492,12 @@
 #endif
 	STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
 	int test_cipherlist = 0;
-#ifdef OPENSSL_FIPS
-	int fips_mode=0;
-#endif
-	int ssl_mode = 0;
-	int c_small_records=0;
-	int s_small_records=0;
 
 	verbose = 0;
 	debug = 0;
 	cipher = 0;
 
-	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);	
+	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT);	
 
 	CRYPTO_set_locking_callback(lock_dbg_cb);
 
@@ -460,23 +516,14 @@
 
 	RAND_seed(rnd_seed, sizeof rnd_seed);
 
-	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
+	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT);
 
 	argc--;
 	argv++;
 
 	while (argc >= 1)
 		{
-		if(!strcmp(*argv,"-F"))
-			{
-#ifdef OPENSSL_FIPS
-			fips_mode=1;
-#else
-			fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
-			EXIT(0);
-#endif
-			}
-		else if	(strcmp(*argv,"-server_auth") == 0)
+		if	(strcmp(*argv,"-server_auth") == 0)
 			server_auth=1;
 		else if	(strcmp(*argv,"-client_auth") == 0)
 			client_auth=1;
@@ -516,6 +563,20 @@
 			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)
@@ -666,20 +727,6 @@
 		EXIT(1);
 		}
 
-#ifdef OPENSSL_FIPS
-	if(fips_mode)
-		{
-		if(!FIPS_mode_set(1))
-			{
-			ERR_load_crypto_strings();
-			ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
-			EXIT(1);
-			}
-		else
-			fprintf(stderr,"*** IN FIPS MODE ***\n");
-		}
-#endif
-
 	if (print_time)
 		{
 		if (!bio_pair)
@@ -839,6 +886,13 @@
 	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);
@@ -890,6 +944,31 @@
 		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);
 
@@ -966,7 +1045,7 @@
 #endif
 	CRYPTO_cleanup_all_ex_data();
 	ERR_free_strings();
-	ERR_remove_state(0);
+	ERR_remove_thread_state(NULL);
 	EVP_cleanup();
 	CRYPTO_mem_leaks(bio_err);
 	if (bio_err != NULL) BIO_free(bio_err);
@@ -2116,7 +2195,15 @@
 		}
 
 #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)
@@ -2285,11 +2372,74 @@
 	}
 #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;
-	SSL_CIPHER *ci, *tci = NULL;
+	const SSL_CIPHER *ci, *tci = NULL;
 
 #ifndef OPENSSL_NO_SSL2
 	fprintf(stderr, "testing SSLv2 cipher list order: ");
diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c
index 4d1e198..c87af17 100644
--- a/ssl/t1_clnt.c
+++ b/ssl/t1_clnt.c
@@ -63,8 +63,8 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
-static SSL_METHOD *tls1_get_client_method(int ver);
-static SSL_METHOD *tls1_get_client_method(int ver)
+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());
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index dab6e44..d9cb059 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * 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
@@ -108,6 +108,32 @@
  * 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"
@@ -121,8 +147,14 @@
 #include <openssl/des.h>
 #endif
 
+/* seed1 through seed5 are virtually concatenated */
 static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
-			int sec_len, unsigned char *seed, int seed_len,
+			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,n;
@@ -133,14 +165,17 @@
 	unsigned int A1_len;
 	
 	chunk=EVP_MD_size(md);
+	OPENSSL_assert(chunk >= 0);
 
 	HMAC_CTX_init(&ctx);
 	HMAC_CTX_init(&ctx_tmp);
-	HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 	HMAC_Init_ex(&ctx,sec,sec_len,md, NULL);
 	HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL);
-	HMAC_Update(&ctx,seed,seed_len);
+	if (seed1 != NULL) HMAC_Update(&ctx,seed1,seed1_len);
+	if (seed2 != NULL) HMAC_Update(&ctx,seed2,seed2_len);
+	if (seed3 != NULL) HMAC_Update(&ctx,seed3,seed3_len);
+	if (seed4 != NULL) HMAC_Update(&ctx,seed4,seed4_len);
+	if (seed5 != NULL) HMAC_Update(&ctx,seed5,seed5_len);
 	HMAC_Final(&ctx,A1,&A1_len);
 
 	n=0;
@@ -150,7 +185,11 @@
 		HMAC_Init_ex(&ctx_tmp,NULL,0,NULL,NULL); /* re-init */
 		HMAC_Update(&ctx,A1,A1_len);
 		HMAC_Update(&ctx_tmp,A1,A1_len);
-		HMAC_Update(&ctx,seed,seed_len);
+		if (seed1 != NULL) HMAC_Update(&ctx,seed1,seed1_len);
+		if (seed2 != NULL) HMAC_Update(&ctx,seed2,seed2_len);
+		if (seed3 != NULL) HMAC_Update(&ctx,seed3,seed3_len);
+		if (seed4 != NULL) HMAC_Update(&ctx,seed4,seed4_len);
+		if (seed5 != NULL) HMAC_Update(&ctx,seed5,seed5_len);
 
 		if (olen > chunk)
 			{
@@ -171,44 +210,57 @@
 	OPENSSL_cleanse(A1,sizeof(A1));
 	}
 
-static void tls1_PRF(const EVP_MD *md5, const EVP_MD *sha1,
-		     unsigned char *label, int label_len,
-		     const unsigned char *sec, int slen, unsigned char *out1,
+/* seed1 through seed5 are virtually concatenated */
+static void 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;
-	const unsigned char *S1,*S2;
+	int len,i,idx,count;
+	const unsigned char *S1;
+	long m;
+	const EVP_MD *md;
 
-	len=slen/2;
+	/* 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;
-	S2= &(sec[len]);
-	len+=(slen&1); /* add for odd, make longer */
-
-	
-	tls1_P_hash(md5 ,S1,len,label,label_len,out1,olen);
-	tls1_P_hash(sha1,S2,len,label,label_len,out2,olen);
-
-	for (i=0; i<olen; i++)
-		out1[i]^=out2[i];
+	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);
+				return;				
+			}
+			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);
+			S1+=len;
+			for (i=0; i<olen; i++)
+			{
+				out1[i]^=out2[i];
+			}
+		}
 	}
 
+}
 static void tls1_generate_key_block(SSL *s, unsigned char *km,
 	     unsigned char *tmp, int num)
 	{
-	unsigned char *p;
-	unsigned char buf[SSL3_RANDOM_SIZE*2+
-		TLS_MD_MAX_CONST_SIZE];
-	p=buf;
-
-	memcpy(p,TLS_MD_KEY_EXPANSION_CONST,
-		TLS_MD_KEY_EXPANSION_CONST_SIZE);
-	p+=TLS_MD_KEY_EXPANSION_CONST_SIZE;
-	memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
-	p+=SSL3_RANDOM_SIZE;
-	memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-	p+=SSL3_RANDOM_SIZE;
-
-	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),
+	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
@@ -228,8 +280,7 @@
 	{
 	static const unsigned char empty[]="";
 	unsigned char *p,*key_block,*mac_secret;
-	unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+
-		SSL3_RANDOM_SIZE*2];
+	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];
@@ -242,12 +293,17 @@
 	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
@@ -255,21 +311,28 @@
 
 #ifdef KSSL_DEBUG
 	printf("tls1_change_cipher_state(which= %d) w/\n", which);
-	printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms,
-                (void *)comp);
-	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)c);
+	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 ki;
-        for (ki=0; ki<s->s3->tmp.key_block_length; ki++)
-		printf("%02x", key_block[ki]);  printf("\n");
+        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)
@@ -278,7 +341,7 @@
 			/* 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;
-		s->read_hash=m;
+		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
 #ifndef OPENSSL_NO_COMP
 		if (s->expand != NULL)
 			{
@@ -304,9 +367,14 @@
  		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)
@@ -315,7 +383,7 @@
 			/* 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;
-		s->write_hash=m;
+		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
 #ifndef OPENSSL_NO_COMP
 		if (s->compress != NULL)
 			{
@@ -336,13 +404,15 @@
  		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=EVP_MD_size(m);
+	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;
@@ -378,6 +448,10 @@
 		}
 
 	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'); }
@@ -387,29 +461,22 @@
 		/* In here I set both the read and write key/iv to the
 		 * same value since only the correct one will be used :-).
 		 */
-		p=buf;
-		memcpy(p,exp_label,exp_label_len);
-		p+=exp_label_len;
-		memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-		p+=SSL3_RANDOM_SIZE;
-		memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
-		p+=SSL3_RANDOM_SIZE;
-		tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j,
-			 tmp1,tmp2,EVP_CIPHER_key_length(c));
+		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));
 		key=tmp1;
 
 		if (k > 0)
 			{
-			p=buf;
-			memcpy(p,TLS_MD_IV_BLOCK_CONST,
-				TLS_MD_IV_BLOCK_CONST_SIZE);
-			p+=TLS_MD_IV_BLOCK_CONST_SIZE;
-			memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE);
-			p+=SSL3_RANDOM_SIZE;
-			memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
-			p+=SSL3_RANDOM_SIZE;
-			tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0,
-				 iv1,iv2,k*2);
+			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);
 			if (client_write)
 				iv=iv1;
 			else
@@ -420,13 +487,11 @@
 	s->session->key_arg_length=0;
 #ifdef KSSL_DEBUG
 	{
-        int ki;
+        int i;
 	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
-	printf("\tkey= ");
-	for (ki=0; ki<c->key_len; ki++) printf("%02x", key[ki]);
+	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
 	printf("\n");
-	printf("\t iv= ");
-	for (ki=0; ki<c->iv_len; ki++) printf("%02x", iv[ki]);
+	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
 	printf("\n");
 	}
 #endif	/* KSSL_DEBUG */
@@ -458,6 +523,7 @@
 	const EVP_MD *hash;
 	int num;
 	SSL_COMP *comp;
+	int mac_type= NID_undef,mac_secret_size=0;
 
 #ifdef KSSL_DEBUG
 	printf ("tls1_setup_key_block()\n");
@@ -466,7 +532,7 @@
 	if (s->s3->tmp.key_block_length != 0)
 		return(1);
 
-	if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp))
+	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);
@@ -474,8 +540,9 @@
 
 	s->s3->tmp.new_sym_enc=c;
 	s->s3->tmp.new_hash=hash;
-
-	num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c);
+	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);
@@ -514,11 +581,11 @@
 
 		if (s->session->cipher != NULL)
 			{
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL)
+			if (s->session->cipher->algorithm_enc == SSL_eNULL)
 				s->s3->need_empty_fragments = 0;
 			
 #ifndef OPENSSL_NO_RC4
-			if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4)
+			if (s->session->cipher->algorithm_enc == SSL_RC4)
 				s->s3->need_empty_fragments = 0;
 #endif
 			}
@@ -540,8 +607,11 @@
 
 	if (send)
 		{
-		if (s->write_hash != NULL)
-			n=EVP_MD_size(s->write_hash);
+		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)
@@ -551,8 +621,11 @@
 		}
 	else
 		{
-		if (s->read_hash != NULL)
-			n=EVP_MD_size(s->read_hash);
+		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)
@@ -599,11 +672,10 @@
 		{
                 unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
-                        (void *)ds,rec->data,rec->input,l);
-		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\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,
-                        (unsigned long)DES_KEY_SZ,
-			(unsigned long)DES_SCHEDULE_SZ,
+                        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]);
@@ -628,10 +700,10 @@
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long ki;
+                unsigned long i;
                 printf("\trec->data=");
-		for (ki=0; ki<l; i++)
-                        printf(" %02x", rec->data[ki]);  printf("\n");
+		for (i=0; i<l; i++)
+                        printf(" %02x", rec->data[i]);  printf("\n");
                 }
 #endif	/* KSSL_DEBUG */
 
@@ -679,56 +751,100 @@
 		}
 	return(1);
 	}
-
-int tls1_cert_verify_mac(SSL *s, EVP_MD_CTX *in_ctx, unsigned char *out)
+int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
 	{
 	unsigned int ret;
-	EVP_MD_CTX ctx;
+	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,in_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, EVP_MD_CTX *in1_ctx, EVP_MD_CTX *in2_ctx,
+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[TLS_MD_MAX_CONST_SIZE+MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH];
+	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;
-	memcpy(q,str,slen);
-	q+=slen;
+
+	if (s->s3->handshake_buffer) 
+		if (!ssl3_digest_cached_records(s))
+			return 0;
 
 	EVP_MD_CTX_init(&ctx);
-	EVP_MD_CTX_copy_ex(&ctx,in1_ctx);
-	EVP_DigestFinal_ex(&ctx,q,&i);
-	q+=i;
-	EVP_MD_CTX_copy_ex(&ctx,in2_ctx);
-	EVP_DigestFinal_ex(&ctx,q,&i);
-	q+=i;
 
-	tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(q-buf),
-		s->session->master_key,s->session->master_key_length,
-		out,buf2,sizeof buf2);
+	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;
+				}
+			}
+		}
+		
+	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);
 	EVP_MD_CTX_cleanup(&ctx);
 
-	return sizeof buf2;
+	if (err)
+		return 0;
+	else
+		return sizeof buf2;
 	}
 
 int tls1_mac(SSL *ssl, unsigned char *md, int send)
 	{
 	SSL3_RECORD *rec;
 	unsigned char *mac_sec,*seq;
-	const EVP_MD *hash;
-	unsigned int md_size;
+	EVP_MD_CTX *hash;
+	size_t md_size;
 	int i;
-	HMAC_CTX hmac;
+	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)
 		{
@@ -745,43 +861,45 @@
 		hash=ssl->read_hash;
 		}
 
-	md_size=EVP_MD_size(hash);
+	t=EVP_MD_CTX_size(hash);
+	OPENSSL_assert(t >= 0);
+	md_size=t;
 
 	buf[0]=rec->type;
-	if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER)
-		{
-		buf[1]=TLS1_VERSION_MAJOR;
-		buf[2]=TLS1_VERSION_MINOR;
-		}
-	else	{
-		buf[1]=(unsigned char)(ssl->version>>8);
-		buf[2]=(unsigned char)(ssl->version);
-		}
-
+	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 */
-	HMAC_CTX_init(&hmac);
-	HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL);
+	if (stream_mac) 
+		{
+			mac_ctx = hash;
+		}
+		else
+		{
+			EVP_MD_CTX_copy(&hmac,hash);
+			mac_ctx = &hmac;
+		}
 
-	if (ssl->version == DTLS1_BAD_VER ||
-	    (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER))
+	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);
 
-		HMAC_Update(&hmac,dtlsseq,8);
+		EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
 		}
 	else
-		HMAC_Update(&hmac,seq,8);
+		EVP_DigestSignUpdate(mac_ctx,seq,8);
 
-	HMAC_Update(&hmac,buf,5);
-	HMAC_Update(&hmac,rec->input,rec->length);
-	HMAC_Final(&hmac,md,&md_size);
-	HMAC_CTX_cleanup(&hmac);
-
+	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"); }
@@ -793,7 +911,7 @@
 {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
 #endif
 
-	if ( SSL_version(ssl) != DTLS1_VERSION && SSL_version(ssl) != DTLS1_BAD_VER)
+	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
 		{
 		for (i=7; i>=0; i--)
 			{
@@ -811,23 +929,35 @@
 int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
 	     int len)
 	{
-	unsigned char buf[SSL3_RANDOM_SIZE*2+TLS_MD_MASTER_SECRET_CONST_SIZE];
 	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", (void *)s,out, p,len);
+	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
 #endif	/* KSSL_DEBUG */
 
-	/* Setup the stuff to munge */
-	memcpy(buf,TLS_MD_MASTER_SECRET_CONST,
-		TLS_MD_MASTER_SECRET_CONST_SIZE);
-	memcpy(&(buf[TLS_MD_MASTER_SECRET_CONST_SIZE]),
-		s->s3->client_random,SSL3_RANDOM_SIZE);
-	memcpy(&(buf[SSL3_RANDOM_SIZE+TLS_MD_MASTER_SECRET_CONST_SIZE]),
-		s->s3->server_random,SSL3_RANDOM_SIZE);
-	tls1_PRF(s->ctx->md5,s->ctx->sha1,
-		buf,TLS_MD_MASTER_SECRET_CONST_SIZE+SSL3_RANDOM_SIZE*2,p,len,
+#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 */
@@ -862,7 +992,13 @@
 	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);
-#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+	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
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 8b53112..e8bc34c 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -55,6 +55,59 @@
  * 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>
@@ -92,11 +145,6 @@
 	return(60*60*2);
 	}
 
-IMPLEMENT_tls1_meth_func(tlsv1_base_method,
-			ssl_undefined_function,
-			ssl_undefined_function,
-			ssl_bad_method)
-
 int tls1_new(SSL *s)
 	{
 	if (!ssl3_new(s)) return(0);
@@ -106,6 +154,12 @@
 
 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);
 	}
 
@@ -115,17 +169,105 @@
 	s->version=TLS1_VERSION;
 	}
 
-#if 0
-long tls1_ctrl(SSL *s, int cmd, long larg, char *parg)
+#ifndef OPENSSL_NO_EC
+static int nid_list[] =
 	{
-	return(0);
+		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];
 	}
 
-long tls1_callback_ctrl(SSL *s, int cmd, void *(*fp)())
+int tls1_ec_nid2curve_id(int nid)
 	{
-	return(0);
+	/* 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
+#endif /* OPENSSL_NO_EC */
 
 #ifndef OPENSSL_NO_TLSEXT
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit)
@@ -157,7 +299,7 @@
 		*/
 		   
 		if ((lenmax = limit - ret - 9) < 0 
-		|| (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
+		    || (size_str = strlen(s->tlsext_hostname)) > (unsigned long)lenmax) 
 			return NULL;
 			
 		/* extension type and length */
@@ -172,9 +314,8 @@
 		s2n(size_str,ret);
 		memcpy(ret, s->tlsext_hostname, size_str);
 		ret+=size_str;
-
 		}
- 
+
         /* Add RI if renegotiating */
         if (s->new_session)
           {
@@ -200,19 +341,81 @@
           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 (limit - ret - 4 - ticklen < 0)
-			return NULL;
+		if ((long)(limit - ret - 4 - ticklen) < 0) return NULL;
 		s2n(TLSEXT_TYPE_session_ticket,ret); 
 		s2n(ticklen,ret);
 		if (ticklen)
@@ -221,6 +424,26 @@
 			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)
@@ -292,7 +515,7 @@
 
 	if (!s->hit && s->servername_done == 1 && s->session->tlsext_hostname != NULL)
 		{ 
-		if (limit - ret - 4 < 0) return NULL; 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
 
 		s2n(TLSEXT_TYPE_server_name,ret);
 		s2n(0,ret);
@@ -321,11 +544,36 @@
 
           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 (limit - ret - 4 < 0) return NULL; 
+		if ((long)(limit - ret - 4) < 0) return NULL; 
 		s2n(TLSEXT_TYPE_session_ticket,ret);
 		s2n(0,ret);
 		}
@@ -337,6 +585,39 @@
 		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;
+
+		}
+
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
 
@@ -357,7 +638,6 @@
 
 	if (data >= (d+n-2))
 		goto ri_check;
-
 	n2s(data,len);
 
 	if (data > (d+n-len)) 
@@ -370,7 +650,9 @@
 
 		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);
@@ -470,6 +752,106 @@
 				}
 
 			}
+
+#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_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;
+				}
+			s->session->tlsext_ellipticcurvelist_length = 0;
+			if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist);
+			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))
@@ -578,9 +960,9 @@
 			}
 
 		/* session ticket processed earlier */
-
-		data+=size;		
+		data+=size;
 		}
+				
 	*p = data;
 
 	ri_check:
@@ -634,8 +1016,46 @@
 				}
 			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))
 				{
@@ -644,6 +1064,38 @@
 				}
 			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)
 			{
@@ -718,11 +1170,142 @@
 	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) 		
@@ -732,7 +1315,7 @@
  	 * Note: this must be called after servername callbacks in case 
  	 * the certificate has changed.
  	 */
-	if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb)
+	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);
@@ -758,7 +1341,65 @@
 		}
 	else
 		s->tlsext_status_expected = 0;
-	err:
+
+#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:
@@ -781,16 +1422,75 @@
 	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 server
+	 * must return a an EC point formats lists containing 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) && 
+	    ((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;
+		if ((s->session->tlsext_ecpointformatlist == NULL) || (s->session->tlsext_ecpointformatlist_length == 0))
+			{
+			SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+			return -1;
+			}
+		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->tlsext_status_cb)
+			&& s->ctx && s->ctx->tlsext_status_cb)
 		{
 		int r;
 		/* Set resp to NULL, resplen to -1 so callback knows
@@ -885,6 +1585,11 @@
 			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
  			 */
@@ -893,6 +1598,15 @@
 				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);
 			}
@@ -945,6 +1659,11 @@
  	 * 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);
diff --git a/ssl/t1_meth.c b/ssl/t1_meth.c
index f5d8df6..6ce7c0b 100644
--- a/ssl/t1_meth.c
+++ b/ssl/t1_meth.c
@@ -60,8 +60,8 @@
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
-static SSL_METHOD *tls1_get_method(int ver);
-static SSL_METHOD *tls1_get_method(int ver)
+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());
diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c
index b75636a..42525e9 100644
--- a/ssl/t1_srvr.c
+++ b/ssl/t1_srvr.c
@@ -64,8 +64,8 @@
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 
-static SSL_METHOD *tls1_get_server_method(int ver);
-static SSL_METHOD *tls1_get_server_method(int ver)
+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());
diff --git a/ssl/tls1.h b/ssl/tls1.h
index afe4807..b3cc8f0 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -56,6 +56,59 @@
  * [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 
@@ -68,6 +121,32 @@
  * 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 
@@ -104,16 +183,23 @@
 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
 #define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
 
-/* ExtensionType values from RFC 3546 */
+/* 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
@@ -123,6 +209,13 @@
 /* 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
@@ -182,17 +275,31 @@
 #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
 
-/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
+/* 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. */
-#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060
-#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061
+ * 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
@@ -330,6 +437,12 @@
 #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"
@@ -353,6 +466,7 @@
 #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
@@ -360,7 +474,11 @@
 #define TLS_CT_ECDSA_SIGN		64
 #define TLS_CT_RSA_FIXED_ECDH		65
 #define TLS_CT_ECDSA_FIXED_ECDH 	66
-#define TLS_CT_NUMBER			7
+#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
 
@@ -401,10 +519,14 @@
 #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
-
-
-