Add SRP support.
diff --git a/Configure b/Configure
index 227a634..ad3e51f 100755
--- a/Configure
+++ b/Configure
@@ -1015,6 +1015,12 @@
 	$disabled{"gost"} = "forced";
 	}
 
+# SRP requires TLSEXT
+if (defined($disabled{"tlsext"}))
+	{
+	$disabled{"srp"} = "forced";
+	}
+
 if ($target eq "TABLE") {
 	foreach $target (sort keys %table) {
 		print_table_entry($target);
diff --git a/Makefile.org b/Makefile.org
index 00ccc32..b1ad7cb 100644
--- a/Makefile.org
+++ b/Makefile.org
@@ -148,7 +148,7 @@
 	bn ec rsa dsa ecdsa dh ecdh dso engine \
 	buffer bio stack lhash rand err \
 	evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
-	cms pqueue ts jpake store cmac
+	cms pqueue ts jpake srp store cmac
 # keep in mind that the above list is adjusted by ./Configure
 # according to no-xxx arguments...
 
diff --git a/apps/Makefile b/apps/Makefile
index d4d7d30..6ade445 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -39,7 +39,7 @@
 	ca crl rsa rsautl dsa dsaparam ec ecparam \
 	x509 genrsa gendsa genpkey s_server s_client speed \
 	s_time version pkcs7 cms crl2pkcs7 sess_id ciphers nseq pkcs12 \
-	pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts
+	pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts srp
 
 PROGS= $(PROGRAM).c
 
@@ -56,7 +56,7 @@
 	x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
 	s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
 	ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \
-	spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o
+	spkac.o smime.o cms.o rand.o engine.o ocsp.o prime.o ts.o srp.o
 
 E_SRC=	verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
 	pkcs7.c crl2p7.c crl.c \
@@ -64,7 +64,7 @@
 	x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \
 	s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
 	ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \
-	spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c
+	spkac.c smime.c cms.c rand.c engine.c ocsp.c prime.c ts.c srp.c
 
 SRC=$(E_SRC)
 
@@ -334,19 +334,20 @@
 dsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 dsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 dsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-dsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-dsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-dsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-dsa.o: ../include/openssl/err.h ../include/openssl/evp.h
-dsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-dsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-dsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-dsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-dsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-dsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-dsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-dsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-dsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dsa.c
+dsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+dsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+dsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+dsa.o: ../include/openssl/engine.h ../include/openssl/err.h
+dsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+dsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dsa.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+dsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+dsa.o: ../include/openssl/x509v3.h apps.h dsa.c
 dsaparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 dsaparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 dsaparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -359,13 +360,11 @@
 dsaparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
 dsaparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 dsaparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-dsaparam.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-dsaparam.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+dsaparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
 dsaparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
 dsaparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-dsaparam.o: ../include/openssl/ui.h ../include/openssl/x509.h
-dsaparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-dsaparam.o: dsaparam.c
+dsaparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+dsaparam.o: ../include/openssl/x509v3.h apps.h dsaparam.c
 ec.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ec.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 ec.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
@@ -458,39 +457,37 @@
 gendh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 gendh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 gendh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-gendh.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-gendh.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-gendh.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-gendh.o: ../include/openssl/engine.h ../include/openssl/err.h
-gendh.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-gendh.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-gendh.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-gendh.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-gendh.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-gendh.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-gendh.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+gendh.o: ../include/openssl/dh.h ../include/openssl/e_os2.h
+gendh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+gendh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+gendh.o: ../include/openssl/err.h ../include/openssl/evp.h
+gendh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+gendh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+gendh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+gendh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+gendh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+gendh.o: ../include/openssl/rand.h ../include/openssl/safestack.h
 gendh.o: ../include/openssl/sha.h ../include/openssl/stack.h
 gendh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-gendh.o: ../include/openssl/ui.h ../include/openssl/x509.h
-gendh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-gendh.o: gendh.c
+gendh.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+gendh.o: ../include/openssl/x509v3.h apps.h gendh.c
 gendsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 gendsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 gendsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-gendsa.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-gendsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-gendsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-gendsa.o: ../include/openssl/err.h ../include/openssl/evp.h
-gendsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-gendsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-gendsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-gendsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-gendsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-gendsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-gendsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-gendsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-gendsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-gendsa.o: gendsa.c
+gendsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+gendsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+gendsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+gendsa.o: ../include/openssl/engine.h ../include/openssl/err.h
+gendsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+gendsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+gendsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+gendsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+gendsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+gendsa.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+gendsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+gendsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+gendsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+gendsa.o: ../include/openssl/x509v3.h apps.h gendsa.c
 genpkey.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 genpkey.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 genpkey.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
@@ -510,7 +507,6 @@
 genrsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 genrsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 genrsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-genrsa.o: ../include/openssl/dh.h ../include/openssl/dsa.h
 genrsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 genrsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 genrsa.o: ../include/openssl/engine.h ../include/openssl/err.h
@@ -523,9 +519,8 @@
 genrsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
 genrsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
 genrsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-genrsa.o: ../include/openssl/ui.h ../include/openssl/x509.h
-genrsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-genrsa.o: genrsa.c
+genrsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+genrsa.o: ../include/openssl/x509v3.h apps.h genrsa.c
 nseq.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 nseq.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 nseq.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
@@ -738,11 +733,10 @@
 req.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
 req.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 req.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-req.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-req.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-req.o: ../include/openssl/sha.h ../include/openssl/stack.h
-req.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-req.o: ../include/openssl/ui.h ../include/openssl/x509.h
+req.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+req.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+req.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+req.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
 req.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h req.c
 rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
@@ -761,21 +755,22 @@
 rsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
 rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rsa.c
 rsautl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-rsautl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
-rsautl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-rsautl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-rsautl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-rsautl.o: ../include/openssl/err.h ../include/openssl/evp.h
-rsautl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-rsautl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-rsautl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-rsautl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-rsautl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-rsautl.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-rsautl.o: ../include/openssl/sha.h ../include/openssl/stack.h
-rsautl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-rsautl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-rsautl.o: ../include/openssl/x509v3.h apps.h rsautl.c
+rsautl.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+rsautl.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+rsautl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+rsautl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+rsautl.o: ../include/openssl/engine.h ../include/openssl/err.h
+rsautl.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+rsautl.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+rsautl.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+rsautl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rsautl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+rsautl.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+rsautl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+rsautl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+rsautl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+rsautl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+rsautl.o: rsautl.c
 s_cb.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s_cb.o: ../include/openssl/buffer.h ../include/openssl/comp.h
 s_cb.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -812,37 +807,36 @@
 s_client.o: ../include/openssl/pem.h ../include/openssl/pem2.h
 s_client.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
 s_client.o: ../include/openssl/rand.h ../include/openssl/safestack.h
-s_client.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s_client.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s_client.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s_client.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s_client.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-s_client.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-s_client.o: s_apps.h s_client.c timeouts.h
+s_client.o: ../include/openssl/sha.h ../include/openssl/srp.h
+s_client.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s_client.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s_client.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s_client.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
+s_client.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+s_client.o: ../include/openssl/x509v3.h apps.h s_apps.h s_client.c timeouts.h
 s_server.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s_server.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 s_server.o: ../include/openssl/comp.h ../include/openssl/conf.h
 s_server.o: ../include/openssl/crypto.h ../include/openssl/dh.h
-s_server.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s_server.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s_server.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s_server.o: ../include/openssl/engine.h ../include/openssl/err.h
-s_server.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-s_server.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s_server.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-s_server.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-s_server.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s_server.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s_server.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
-s_server.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s_server.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s_server.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s_server.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s_server.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s_server.o: ../include/openssl/err.h ../include/openssl/evp.h
+s_server.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s_server.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+s_server.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+s_server.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s_server.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s_server.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s_server.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s_server.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s_server.o: ../include/openssl/sha.h ../include/openssl/srp.h
 s_server.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
 s_server.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
 s_server.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 s_server.o: ../include/openssl/tls1.h ../include/openssl/txt_db.h
-s_server.o: ../include/openssl/ui.h ../include/openssl/x509.h
-s_server.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-s_server.o: s_apps.h s_server.c timeouts.h
+s_server.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+s_server.o: ../include/openssl/x509v3.h apps.h s_apps.h s_server.c timeouts.h
 s_socket.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s_socket.o: ../include/openssl/buffer.h ../include/openssl/comp.h
 s_socket.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -927,26 +921,27 @@
 speed.o: ../include/openssl/camellia.h ../include/openssl/cast.h
 speed.o: ../include/openssl/conf.h ../include/openssl/crypto.h
 speed.o: ../include/openssl/des.h ../include/openssl/des_old.h
-speed.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-speed.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-speed.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-speed.o: ../include/openssl/err.h ../include/openssl/evp.h
-speed.o: ../include/openssl/hmac.h ../include/openssl/idea.h
-speed.o: ../include/openssl/lhash.h ../include/openssl/md4.h
-speed.o: ../include/openssl/md5.h ../include/openssl/mdc2.h
-speed.o: ../include/openssl/modes.h ../include/openssl/obj_mac.h
-speed.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-speed.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-speed.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
-speed.o: ../include/openssl/rand.h ../include/openssl/rc2.h
-speed.o: ../include/openssl/rc4.h ../include/openssl/ripemd.h
-speed.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-speed.o: ../include/openssl/seed.h ../include/openssl/sha.h
-speed.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-speed.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-speed.o: ../include/openssl/ui_compat.h ../include/openssl/whrlpool.h
-speed.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-speed.o: ../include/openssl/x509v3.h apps.h speed.c testdsa.h testrsa.h
+speed.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+speed.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+speed.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+speed.o: ../include/openssl/engine.h ../include/openssl/err.h
+speed.o: ../include/openssl/evp.h ../include/openssl/hmac.h
+speed.o: ../include/openssl/idea.h ../include/openssl/lhash.h
+speed.o: ../include/openssl/md4.h ../include/openssl/md5.h
+speed.o: ../include/openssl/mdc2.h ../include/openssl/modes.h
+speed.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+speed.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+speed.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+speed.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+speed.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
+speed.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h
+speed.o: ../include/openssl/safestack.h ../include/openssl/seed.h
+speed.o: ../include/openssl/sha.h ../include/openssl/stack.h
+speed.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+speed.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
+speed.o: ../include/openssl/whrlpool.h ../include/openssl/x509.h
+speed.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+speed.o: speed.c testdsa.h testrsa.h
 spkac.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 spkac.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 spkac.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
@@ -963,6 +958,21 @@
 spkac.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
 spkac.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
 spkac.o: spkac.c
+srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+srp.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+srp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+srp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+srp.o: ../include/openssl/engine.h ../include/openssl/err.h
+srp.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+srp.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+srp.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+srp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+srp.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+srp.o: ../include/openssl/sha.h ../include/openssl/srp.h
+srp.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+srp.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+srp.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h srp.c
 ts.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ts.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ts.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -1018,17 +1028,17 @@
 x509.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 x509.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 x509.o: ../include/openssl/conf.h ../include/openssl/crypto.h
-x509.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-x509.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-x509.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-x509.o: ../include/openssl/err.h ../include/openssl/evp.h
-x509.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-x509.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-x509.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-x509.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-x509.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-x509.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-x509.o: ../include/openssl/sha.h ../include/openssl/stack.h
-x509.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-x509.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-x509.o: ../include/openssl/x509v3.h apps.h x509.c
+x509.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+x509.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+x509.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+x509.o: ../include/openssl/engine.h ../include/openssl/err.h
+x509.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+x509.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+x509.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+x509.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+x509.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+x509.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+x509.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+x509.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+x509.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+x509.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h x509.c
diff --git a/apps/progs.h b/apps/progs.h
index 79e479a..e91b884 100644
--- a/apps/progs.h
+++ b/apps/progs.h
@@ -44,6 +44,7 @@
 extern int rand_main(int argc,char *argv[]);
 extern int engine_main(int argc,char *argv[]);
 extern int ocsp_main(int argc,char *argv[]);
+extern int srp_main(int argc,char *argv[]);
 extern int prime_main(int argc,char *argv[]);
 extern int ts_main(int argc,char *argv[]);
 
@@ -145,6 +146,9 @@
 #ifndef OPENSSL_NO_OCSP
 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
 #endif
+#ifndef OPENSSL_NO_SRP
+	{FUNC_TYPE_GENERAL,"srp",srp_main},
+#endif
 	{FUNC_TYPE_GENERAL,"prime",prime_main},
 	{FUNC_TYPE_GENERAL,"ts",ts_main},
 #ifndef OPENSSL_NO_MD2
diff --git a/apps/s_client.c b/apps/s_client.c
index 8cd5a38..5e2a5ef 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -163,6 +163,9 @@
 #include <openssl/rand.h>
 #include <openssl/ocsp.h>
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
 #include "s_apps.h"
 #include "timeouts.h"
 
@@ -316,6 +319,13 @@
 	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
 # endif
 #endif
+#ifndef OPENSSL_NO_SRP
+	BIO_printf(bio_err," -srpuser user     - SRP authentification for 'user'\n");
+	BIO_printf(bio_err," -srppass arg      - password for 'user'\n");
+	BIO_printf(bio_err," -srp_lateuser     - SRP username into second ClientHello message\n");
+	BIO_printf(bio_err," -srp_moregroups   - Tolerate other than the known g N values.\n");
+	BIO_printf(bio_err," -srp_strength int - minimal mength in bits for N (default %d).\n",SRP_MINIMAL_N);
+#endif
 	BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
 	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
 	BIO_printf(bio_err," -tls1_1       - just use TLSv1.1\n");
@@ -371,6 +381,112 @@
 	return SSL_TLSEXT_ERR_OK;
 	}
 
+#ifndef OPENSSL_NO_SRP
+
+/* This is a context that we pass to all callbacks */
+typedef struct srp_arg_st
+	{
+	char *srppassin;
+	char *srplogin;
+	int msg;   /* copy from c_msg */
+	int debug; /* copy from c_debug */
+	int amp;   /* allow more groups */
+	int strength /* minimal size for N */ ;
+	} SRP_ARG;
+
+#define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
+
+static int SRP_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g)
+	{
+	BN_CTX *bn_ctx = BN_CTX_new();
+	BIGNUM *p = BN_new();
+	BIGNUM *r = BN_new();
+	int ret =
+		g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
+		BN_is_prime(N,SRP_NUMBER_ITERATIONS_FOR_PRIME,NULL,bn_ctx,NULL) &&
+		p != NULL && BN_rshift1(p, N) &&
+
+		/* p = (N-1)/2 */
+		BN_is_prime(p,SRP_NUMBER_ITERATIONS_FOR_PRIME,NULL,bn_ctx,NULL) &&
+		r != NULL &&
+
+		/* verify g^((N-1)/2) == -1 (mod N) */
+		BN_mod_exp(r, g, p, N, bn_ctx) &&
+		BN_add_word(r, 1) &&
+		BN_cmp(r, N) == 0;
+
+	if(r)
+		BN_free(r);
+	if(p)
+		BN_free(p);
+	if(bn_ctx)
+		BN_CTX_free(bn_ctx);
+	return ret;
+	}
+
+static int MS_CALLBACK ssl_srp_verify_param_cb(SSL *s, void *arg)
+	{
+	SRP_ARG *srp_arg = (SRP_ARG *)arg;
+	BIGNUM *N = NULL, *g = NULL;
+	if (!(N = SSL_get_srp_N(s)) || !(g = SSL_get_srp_g(s)))
+		return 0;
+	if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1)
+		{
+    		BIO_printf(bio_err, "SRP parameters:\n"); 
+		BIO_printf(bio_err,"\tN="); BN_print(bio_err,N);
+		BIO_printf(bio_err,"\n\tg="); BN_print(bio_err,g);
+		BIO_printf(bio_err,"\n");
+		}
+
+	if (SRP_check_known_gN_param(g,N))
+		return 1;
+
+	if (srp_arg->amp == 1)
+		{
+		if (srp_arg->debug)
+			BIO_printf(bio_err, "SRP param N and g are not known params, going to check deeper.\n");
+
+/* The srp_moregroups must be used with caution, testing primes costs time. 
+   Implementors should rather add the value to the known ones.
+   The minimal size has already been tested.
+*/
+		if (BN_num_bits(g) <= BN_BITS && SRP_Verify_N_and_g(N,g))
+			return 1;
+		}	
+	BIO_printf(bio_err, "SRP param N and g rejected.\n");
+	return 0;
+	}
+
+#define PWD_STRLEN 1024
+
+static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+	{
+	SRP_ARG *srp_arg = (SRP_ARG *)arg;
+	char *pass = (char *)OPENSSL_malloc(PWD_STRLEN+1);
+	PW_CB_DATA cb_tmp;
+	int l;
+
+	cb_tmp.password = (char *)srp_arg->srppassin;
+	cb_tmp.prompt_info = "SRP user";
+	if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp))<0)
+		{
+		BIO_printf (bio_err, "Can't read Password\n");
+		OPENSSL_free(pass);
+		return NULL;
+		}
+	*(pass+l)= '\0';
+
+	return pass;
+	}
+
+static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
+	{
+	SRP_ARG *srp_arg = (SRP_ARG *)arg;
+	return BUF_strdup(srp_arg->srplogin);
+	}
+
+#endif
+
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /* This the context that we pass to next_proto_cb */
 typedef struct tlsextnextprotoctx_st {
@@ -480,6 +596,11 @@
 #ifndef OPENSSL_NO_JPAKE
 	char *jpake_secret = NULL;
 #endif
+#ifndef OPENSSL_NO_SRP
+	char * srppass = NULL;
+	int srp_lateuser = 0;
+	SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
+#endif
 
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
 	meth=SSLv23_client_method();
@@ -629,6 +750,37 @@
                                 }
 			}
 #endif
+#ifndef OPENSSL_NO_SRP
+		else if (strcmp(*argv,"-srpuser") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srp_arg.srplogin= *(++argv);
+			meth=TLSv1_client_method();
+			}
+		else if (strcmp(*argv,"-srppass") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srppass= *(++argv);
+			meth=TLSv1_client_method();
+			}
+		else if (strcmp(*argv,"-srp_strength") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srp_arg.strength=atoi(*(++argv));
+			BIO_printf(bio_err,"SRP minimal length for N is %d\n",srp_arg.strength);
+			meth=TLSv1_client_method();
+			}
+		else if (strcmp(*argv,"-srp_lateuser") == 0)
+			{
+			srp_lateuser= 1;
+			meth=TLSv1_client_method();
+			}
+		else if	(strcmp(*argv,"-srp_moregroups") == 0)
+			{
+			srp_arg.amp=1;
+			meth=TLSv1_client_method();
+			}
+#endif
 #ifndef OPENSSL_NO_SSL2
 		else if	(strcmp(*argv,"-ssl2") == 0)
 			meth=SSLv2_client_method();
@@ -902,6 +1054,14 @@
 			}
 		}
 
+#ifndef OPENSSL_NO_SRP
+	if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+#endif
+
 	ctx=SSL_CTX_new(meth);
 	if (ctx == NULL)
 		{
@@ -986,6 +1146,26 @@
 		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
 		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
 		}
+#ifndef OPENSSL_NO_SRP
+        if (srp_arg.srplogin)
+		{
+		if (srp_lateuser) 
+			SSL_CTX_set_srp_missing_srp_username_callback(ctx,missing_srp_username_callback);
+		else if (!SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
+			{
+			BIO_printf(bio_err,"Unable to set SRP username\n");
+			goto end;
+			}
+		srp_arg.msg = c_msg;
+		srp_arg.debug = c_debug ;
+		SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
+		SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
+		SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
+		if (c_msg || c_debug || srp_arg.amp == 0)
+			SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
+		}
+
+#endif
 #endif
 
 	con=SSL_new(ctx);
diff --git a/apps/s_server.c b/apps/s_server.c
index f5d313c..97389cd 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -186,6 +186,9 @@
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
 #include "s_apps.h"
 #include "timeouts.h"
 
@@ -373,6 +376,40 @@
         }
 #endif
 
+#ifndef OPENSSL_NO_SRP
+/* This is a context that we pass to callbacks */
+typedef struct srpsrvparm_st
+	{
+	int verbose;
+	char *login;
+	SRP_VBASE *vb;
+	} srpsrvparm;
+
+static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+	{
+	srpsrvparm *p = arg;
+	SRP_user_pwd *user;
+
+	p->login = BUF_strdup(SSL_get_srp_username(s));
+	BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
+
+	user = SRP_VBASE_get_by_user(p->vb, p->login);	
+	if (user == NULL)
+		{
+		BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
+		return SSL3_AL_FATAL;
+		}
+	if (SSL_set_srp_server_param(s, user->N, user->g, user->s, user->v,
+				     user->info) < 0)
+		{
+		*ad = SSL_AD_INTERNAL_ERROR;
+		return SSL3_AL_FATAL;
+		}
+	return SSL_ERROR_NONE;
+	}
+
+#endif
+
 #ifdef MONOLITH
 static void s_server_init(void)
 	{
@@ -460,6 +497,10 @@
 	BIO_printf(bio_err," -jpake arg    - JPAKE secret to use\n");
 # endif
 #endif
+#ifndef OPENSSL_NO_SRP
+	BIO_printf(bio_err," -srpvfile file      - The verifier file for SRP\n");
+	BIO_printf(bio_err," -srpuserseed string - A seed string for a default user salt.\n");
+#endif
 	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
 	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
 	BIO_printf(bio_err," -tls1_1       - Just talk TLSv1.1\n");
@@ -910,12 +951,21 @@
 	/* by default do not send a PSK identity hint */
 	static char *psk_identity_hint=NULL;
 #endif
+#ifndef OPENSSL_NO_SRP
+	char *srpuserseed = NULL;
+	char *srp_verifier_file = NULL;
+	srpsrvparm p;
+#endif
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
 	meth=SSLv23_server_method();
 #elif !defined(OPENSSL_NO_SSL3)
 	meth=SSLv3_server_method();
 #elif !defined(OPENSSL_NO_SSL2)
 	meth=SSLv2_server_method();
+#elif !defined(OPENSSL_NO_TLS1)
+	meth=TLSv1_server_method();
+#else
+  /*  #error no SSL version enabled */
 #endif
 
 	local_argc=argc;
@@ -1152,6 +1202,20 @@
 				}
 			}
 #endif
+#ifndef OPENSSL_NO_SRP
+		else if (strcmp(*argv, "-srpvfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srp_verifier_file = *(++argv);
+			meth = TLSv1_server_method();
+			}
+		else if (strcmp(*argv, "-srpuserseed") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srpuserseed = *(++argv);
+			meth = TLSv1_server_method();
+			}
+#endif
 		else if	(strcmp(*argv,"-www") == 0)
 			{ www=1; }
 		else if	(strcmp(*argv,"-WWW") == 0)
@@ -1771,6 +1835,23 @@
 		}
 #endif
 
+#ifndef OPENSSL_NO_SRP
+	if (srp_verifier_file != NULL)
+		{
+		p.vb = SRP_VBASE_new(srpuserseed);
+		if ((ret = SRP_VBASE_init(p.vb, srp_verifier_file)) != SRP_NO_ERROR)
+			{
+			BIO_printf(bio_err,
+					   "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
+					   srp_verifier_file,ret);
+				goto end;
+			}
+		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
+		SSL_CTX_set_srp_cb_arg(ctx, &p);  			
+		SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
+		}
+	else
+#endif
 	if (CAfile != NULL)
 		{
 		SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
diff --git a/apps/srp.c b/apps/srp.c
new file mode 100644
index 0000000..5e1b23c
--- /dev/null
+++ b/apps/srp.c
@@ -0,0 +1,763 @@
+/* apps/srp.c */
+/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)  
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_SRP
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/conf.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/txt_db.h>
+#include <openssl/buffer.h>
+#include <openssl/srp.h>
+
+#include "apps.h"
+
+#undef PROG
+#define PROG srp_main
+
+#define BASE_SECTION	"srp"
+#define CONFIG_FILE "openssl.cnf"
+
+#define ENV_RANDFILE		"RANDFILE"
+
+#define ENV_DATABASE		"srpvfile"
+#define ENV_DEFAULT_SRP		"default_srp"
+
+static char *srp_usage[]={
+"usage: srp [args] [user] \n",
+"\n",
+" -verbose        Talk alot while doing things\n",
+" -config file    A config file\n",
+" -name arg       The particular srp definition to use\n",
+" -srpvfile arg   The srp verifier file name\n",
+" -add            add an user and srp verifier\n",
+" -modify         modify the srp verifier of an existing user\n",
+" -delete         delete user from verifier file\n",
+" -list           list user\n",
+" -gn arg         g and N values to be used for new verifier\n",
+" -userinfo arg   additional info to be set for user\n",
+" -passin arg     input file pass phrase source\n",
+" -passout arg    output file pass phrase source\n",
+#ifndef OPENSSL_NO_ENGINE
+" -engine e         - use engine e, possibly a hardware device.\n",
+#endif
+NULL
+};
+
+#ifdef EFENCE
+extern int EF_PROTECT_FREE;
+extern int EF_PROTECT_BELOW;
+extern int EF_ALIGNMENT;
+#endif
+
+static CONF *conf=NULL;
+static char *section=NULL;
+
+#define VERBOSE if (verbose) 
+#define VVERBOSE if (verbose>1) 
+
+
+int MAIN(int, char **);
+
+static int get_index(CA_DB *db, char* id, char type)
+	{
+	char ** pp;
+	int i;
+	if (id == NULL) return -1;
+	if (type == DB_SRP_INDEX) 
+	for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+		{
+		pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+		if (pp[DB_srptype][0] == DB_SRP_INDEX  && !strcmp(id,pp[DB_srpid])) 
+			return i;
+		}
+	else for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+		{
+		pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+
+		if (pp[DB_srptype][0] != DB_SRP_INDEX && !strcmp(id,pp[DB_srpid])) 
+			return i;
+		}
+
+	return -1 ; 
+	}
+
+static void print_entry(CA_DB *db, BIO * bio, int index, int verbose, char * s)
+	{
+	if (index >= 0 && verbose)
+		{
+		int j;
+		char **pp=sk_OPENSSL_PSTRING_value(db->db->data,index);
+		BIO_printf(bio,"%s \"%s\"\n",s,pp[DB_srpid]);
+		for (j = 0; j < DB_NUMBER; j++)
+			{
+			BIO_printf(bio_err,"  %d = \"%s\"\n",j,pp[j]);
+			}
+		}
+	}
+
+static void print_index(CA_DB *db, BIO * bio, int indexindex, int verbose)
+	{
+	print_entry(db,bio,indexindex, verbose, "g N entry") ;
+	}
+
+static void print_user(CA_DB *db, BIO * bio, int userindex, int verbose)
+	{
+	if (verbose > 0)
+		{
+		char **pp= sk_OPENSSL_PSTRING_value(db->db->data,userindex);
+
+		if (pp[DB_srptype][0] != 'I')
+			{
+			print_entry(db,bio,userindex, verbose, "User entry");
+			print_entry(db,bio,get_index(db, pp[DB_srpgN],'I'),verbose,"g N entry") ;
+			}
+
+		}
+	}
+
+static int update_index(CA_DB *db, BIO * bio, char ** row)
+	{
+	char ** irow;
+	int i;
+
+	if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL)
+		{
+		BIO_printf(bio_err,"Memory allocation failure\n");
+		return 0;
+		}
+
+	for (i=0; i<DB_NUMBER; i++)
+		{
+		irow[i]=row[i];
+		row[i]=NULL;
+		}
+	irow[DB_NUMBER]=NULL;
+
+	if (!TXT_DB_insert(db->db,irow))
+		{
+		BIO_printf(bio,"failed to update srpvfile\n");
+		BIO_printf(bio,"TXT_DB error number %ld\n",db->db->error);
+		OPENSSL_free(irow);
+		return 0;
+		}
+	return 1;
+	}
+
+static void lookup_fail(const char *name, const char *tag)
+	{
+	BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
+	}
+
+
+static char *srp_verify_user(const char *user, const char *srp_verifier,
+							 char *srp_usersalt, const char *g,
+							 const char * N, const char *passin, BIO *bio,
+							 int verbose)
+	{
+ 	char password[1024];
+	PW_CB_DATA cb_tmp;
+	char *verifier = NULL;
+	char *gNid = NULL;
+
+	cb_tmp.prompt_info = user;
+	cb_tmp.password = passin;
+
+ 	if (password_callback(password, 1024, 0, &cb_tmp) >0)
+		{
+		VERBOSE BIO_printf(bio,"Validating\n   user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,srp_verifier,srp_usersalt,g,N);
+		BIO_printf(bio,"Pass %s\n",password);
+
+		OPENSSL_assert(srp_usersalt != NULL);
+		if (!(gNid=SRP_create_verifier(user, password, &srp_usersalt, &verifier,
+									   N, g)))
+			{
+			BIO_printf(bio,"Internal error validating SRP verifier\n");
+			}
+		else
+			{
+			if (strcmp(verifier, srp_verifier))
+				gNid = NULL;
+			OPENSSL_free(verifier);
+			}
+		}
+	return gNid;
+	}
+
+static char *srp_create_user(char * user, char **srp_verifier,
+							 char **srp_usersalt,char *g, char *N,
+							 char *passout, BIO *bio, int verbose)
+	{
+ 	char password[1024];
+        PW_CB_DATA cb_tmp;
+	char *gNid = NULL;
+	char *salt = NULL;
+        cb_tmp.prompt_info = user;
+        cb_tmp.password = passout;
+
+	if (password_callback(password,1024,1,&cb_tmp) >0)
+		{
+		VERBOSE BIO_printf(bio,"Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",user,g,N);
+		if (!(gNid =SRP_create_verifier(user, password, &salt, srp_verifier, N, g)))
+			{
+			BIO_printf(bio,"Internal error creating SRP verifier\n");
+			}
+		else 
+			*srp_usersalt = salt;
+		VVERBOSE BIO_printf(bio,"gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,salt, *srp_verifier);
+
+		}
+	return gNid;
+	}
+
+int MAIN(int argc, char **argv)
+	{
+	int add_user = 0;
+	int list_user= 0;
+	int delete_user= 0;
+	int modify_user= 0;
+	char * user = NULL;
+
+	char *passargin = NULL, *passargout = NULL;
+	char *passin = NULL, *passout = NULL;
+        char * gN = NULL;
+	int gNindex = -1;
+	char ** gNrow = NULL;
+	int maxgN = -1;
+
+	char * userinfo = NULL;
+
+	int badops=0;
+	int ret=1;
+	int errors=0;
+	int verbose=0;
+	int doupdatedb=0;
+	char *configfile=NULL;
+	char *dbfile=NULL;
+	CA_DB *db=NULL;
+	char **pp ;
+	int i;
+	long errorline = -1;
+	char *randfile=NULL;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine = NULL;
+#endif
+	char *tofree=NULL;
+	DB_ATTR db_attr;
+
+#ifdef EFENCE
+EF_PROTECT_FREE=1;
+EF_PROTECT_BELOW=1;
+EF_ALIGNMENT=0;
+#endif
+
+	apps_startup();
+
+	conf = NULL;
+	section = NULL;
+
+	if (bio_err == NULL)
+		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
+	argc--;
+	argv++;
+	while (argc >= 1 && badops == 0)
+		{
+		if	(strcmp(*argv,"-verbose") == 0)
+			verbose++;
+		else if	(strcmp(*argv,"-config") == 0)
+			{
+			if (--argc < 1) goto bad;
+			configfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-name") == 0)
+			{
+			if (--argc < 1) goto bad;
+			section= *(++argv);
+			}
+		else if	(strcmp(*argv,"-srpvfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			dbfile= *(++argv);
+			}
+		else if (strcmp(*argv,"-add") == 0)
+			add_user=1;
+		else if (strcmp(*argv,"-delete") == 0)
+			delete_user=1;
+		else if (strcmp(*argv,"-modify") == 0)
+			modify_user=1;
+		else if (strcmp(*argv,"-list") == 0)
+			list_user=1;
+		else if (strcmp(*argv,"-gn") == 0)
+			{
+			if (--argc < 1) goto bad;
+			gN= *(++argv);
+			}
+		else if (strcmp(*argv,"-userinfo") == 0)
+			{
+			if (--argc < 1) goto bad;
+			userinfo= *(++argv);
+			}
+		else if (strcmp(*argv,"-passin") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-passout") == 0)
+			{
+			if (--argc < 1) goto bad;
+			passargout= *(++argv);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*argv,"-engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			engine= *(++argv);
+			}
+#endif
+
+		else if (**argv == '-')
+			{
+bad:
+			BIO_printf(bio_err,"unknown option %s\n",*argv);
+			badops=1;
+			break;
+			}
+		else 
+			break;
+	
+		argc--;
+		argv++;
+		}
+
+	if (dbfile && configfile)
+		{
+		BIO_printf(bio_err,"-dbfile and -configfile cannot be specified together.\n");
+		badops = 1;
+		}
+	if (add_user+delete_user+modify_user+list_user != 1)
+		{
+		BIO_printf(bio_err,"Exactly one of the options -add, -delete, -modify -list must be specified.\n");
+		badops = 1;
+		}
+	if (delete_user+modify_user+delete_user== 1 && argc <= 0)
+		{
+		BIO_printf(bio_err,"Need at least one user for options -add, -delete, -modify. \n");
+		badops = 1;
+		}
+	if ((passin || passout) && argc != 1 )
+		{
+		BIO_printf(bio_err,"-passin, -passout arguments only valid with one user.\n");
+		badops = 1;
+		}
+
+	if (badops)
+		{
+		for (pp=srp_usage; (*pp != NULL); pp++)
+			BIO_printf(bio_err,"%s",*pp);
+
+		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+		BIO_printf(bio_err,"                 load the file (or the files in the directory) into\n");
+		BIO_printf(bio_err,"                 the random number generator\n");
+		goto err;
+		}
+
+	ERR_load_crypto_strings();
+
+#ifndef OPENSSL_NO_ENGINE
+	setup_engine(bio_err, engine, 0);
+#endif
+
+	if(!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+		{
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto err;
+		}
+
+        if (!dbfile)
+		{
+
+
+	/*****************************************************************/
+		tofree=NULL;
+		if (configfile == NULL) configfile = getenv("OPENSSL_CONF");
+		if (configfile == NULL) configfile = getenv("SSLEAY_CONF");
+		if (configfile == NULL)
+			{
+			const char *s=X509_get_default_cert_area();
+			size_t len;
+
+#ifdef OPENSSL_SYS_VMS
+			len = strlen(s)+sizeof(CONFIG_FILE);
+			tofree=OPENSSL_malloc(len);
+			strcpy(tofree,s);
+#else
+			len = strlen(s)+sizeof(CONFIG_FILE)+1;
+			tofree=OPENSSL_malloc(len);
+			BUF_strlcpy(tofree,s,len);
+			BUF_strlcat(tofree,"/",len);
+#endif
+			BUF_strlcat(tofree,CONFIG_FILE,len);
+			configfile=tofree;
+			}
+
+		VERBOSE BIO_printf(bio_err,"Using configuration from %s\n",configfile);
+		conf = NCONF_new(NULL);
+		if (NCONF_load(conf,configfile,&errorline) <= 0)
+			{
+			if (errorline <= 0)
+				BIO_printf(bio_err,"error loading the config file '%s'\n",
+					configfile);
+			else
+				BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
+					,errorline,configfile);
+			goto err;
+			}
+		if(tofree)
+			{
+			OPENSSL_free(tofree);
+			tofree = NULL;
+			}
+
+		if (!load_config(bio_err, conf))
+			goto err;
+
+	/* Lets get the config section we are using */
+		if (section == NULL)
+			{
+			VERBOSE BIO_printf(bio_err,"trying to read " ENV_DEFAULT_SRP " in \" BASE_SECTION \"\n");
+
+			section=NCONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_SRP);
+			if (section == NULL)
+				{
+				lookup_fail(BASE_SECTION,ENV_DEFAULT_SRP);
+				goto err;
+				}
+			}
+         
+		if (randfile == NULL && conf)
+	        	randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+
+	
+		VERBOSE BIO_printf(bio_err,"trying to read " ENV_DATABASE " in section \"%s\"\n",section);
+
+		if ((dbfile=NCONF_get_string(conf,section,ENV_DATABASE)) == NULL)
+			{
+			lookup_fail(section,ENV_DATABASE);
+			goto err;
+			}
+
+        	}
+	if (randfile == NULL)
+		ERR_clear_error();
+       	else 
+		app_RAND_load_file(randfile, bio_err, 0);
+
+	VERBOSE BIO_printf(bio_err,"Trying to read SRP verifier file \"%s\"\n",dbfile);
+
+	db = load_index(dbfile, &db_attr);
+	if (db == NULL) goto err;
+
+	/* Lets check some fields */
+	for (i=0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+		{
+		pp=sk_OPENSSL_PSTRING_value(db->db->data, i);
+	
+		if (pp[DB_srptype][0] == DB_SRP_INDEX)
+			{
+			maxgN = i;
+			if (gNindex < 0 && gN != NULL && !strcmp(gN, pp[DB_srpid]))
+				gNindex = i;
+
+			print_index(db, bio_err, i, verbose > 1) ;
+			}
+		}
+	
+	VERBOSE BIO_printf(bio_err,"Database initialised\n");
+
+	if (gNindex >= 0)
+		{
+		gNrow=sk_OPENSSL_PSTRING_value(db->db->data,gNindex);
+		print_entry(db,bio_err,gNindex,verbose>1,"Default g and N") ;
+		}
+	else if (maxgN > 0 && !SRP_get_default_gN(gN))
+		{
+		BIO_printf(bio_err,"No g and N value for index \"%s\"\n",gN);
+		goto err;
+		}
+	else
+		{
+		VERBOSE BIO_printf(bio_err,"Database has no g N information.\n");
+		gNrow = NULL;
+		}
+	
+
+	VVERBOSE BIO_printf(bio_err,"Starting user processing\n");
+
+	if (argc > 0)
+		user = *(argv++) ;
+
+	while (list_user || user)
+		{
+		int userindex = -1;
+		if (user) 
+			VVERBOSE BIO_printf(bio_err, "Processing user \"%s\"\n",user);
+		if ((userindex = get_index(db, user, 'U')) >= 0)
+			{
+			print_user(db,bio_err,userindex,(verbose > 0) || list_user) ;
+			}
+		
+		if (list_user)
+			{
+			if (user == NULL)
+				{
+				BIO_printf(bio_err,"List all users\n");
+
+				for (i=0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+					{
+					print_user(db,bio_err,i,1) ;
+					}
+				list_user = 0;
+				}
+			else if (userindex < 0)
+				{
+				BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n",
+						   user);
+				errors++;
+				}
+			}
+		else if (add_user)
+			{
+			if (userindex >= 0)
+				{
+				/* reactivation of a new user */
+				char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+				BIO_printf(bio_err,"user \"%s\" reactivated.\n", user);
+				row[DB_srptype][0] = 'V' ;
+
+				doupdatedb = 1;
+				}
+			else
+				{
+				char *row[DB_NUMBER] ; char * gNid;
+				row[DB_srpverifier] = NULL;
+				row[DB_srpsalt] = NULL;
+				row[DB_srpinfo] = NULL;
+				if (!(gNid = srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:gN,gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
+					{
+						BIO_printf(bio_err,"Cannot create srp verifier for user \"%s\", operation abandoned .\n",user);
+						errors++ ;
+						goto err;
+					}
+				row[DB_srpid] = BUF_strdup(user);
+				row[DB_srptype] = BUF_strdup("v");
+				row[DB_srpgN] = BUF_strdup(gNid);
+
+				if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
+					(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))) || 
+					!update_index(db, bio_err, row))
+					{
+					if (row[DB_srpid]) OPENSSL_free(row[DB_srpid]);
+					if (row[DB_srpgN]) OPENSSL_free(row[DB_srpgN]);
+					if (row[DB_srpinfo]) OPENSSL_free(row[DB_srpinfo]);
+					if (row[DB_srptype]) OPENSSL_free(row[DB_srptype]);
+					if (row[DB_srpverifier]) OPENSSL_free(row[DB_srpverifier]);
+					if (row[DB_srpsalt]) OPENSSL_free(row[DB_srpsalt]);
+					goto err;
+					}
+				doupdatedb = 1;
+				}
+			}
+		else if (modify_user)
+			{
+			if (userindex<0)
+				{
+				BIO_printf(bio_err,"user \"%s\" does not exist, operation ignored.\n",user);
+				errors++ ;
+				}
+			else
+				{
+
+				char **row=sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+				char type = row[DB_srptype][0] ;
+				if (type == 'v')
+					{
+					BIO_printf(bio_err,"user \"%s\" already updated, operation ignored.\n",user);
+					errors++ ;
+					}
+				else
+					{
+					char * gNid ;
+
+					if (row[DB_srptype][0] == 'V')
+						{
+						int user_gN ;
+						char ** irow = NULL;
+						VERBOSE BIO_printf(bio_err,"Verifying password for user \"%s\"\n",user);
+						if ( (user_gN = get_index(db, row[DB_srpgN],DB_SRP_INDEX)) >= 0)
+							irow = sk_OPENSSL_PSTRING_value(db->db->data,
+															userindex);
+
+ 						if (!srp_verify_user(user,row[DB_srpverifier], row[DB_srpsalt],irow?irow[DB_srpsalt]:row[DB_srpgN], irow?irow[DB_srpverifier]:NULL, passin, bio_err,verbose))
+							{
+							BIO_printf(bio_err,"Invalid password for user \"%s\", operation abandoned.\n",user);
+							errors++ ;
+							goto err;
+							}
+						} 
+					VERBOSE BIO_printf(bio_err,"Password for user \"%s\" ok.\n",user);
+
+					if (!(gNid=srp_create_user(user,&(row[DB_srpverifier]), &(row[DB_srpsalt]),gNrow?gNrow[DB_srpsalt]:NULL, gNrow?gNrow[DB_srpverifier]:NULL, passout, bio_err,verbose)))
+						{
+							BIO_printf(bio_err,
+									   "Cannot create srp verifier for user "
+									   "\"%s\", operation abandonned .\n",
+									   user);
+							errors++;
+							goto err;
+						}
+
+					row[DB_srptype][0] = 'v';
+					row[DB_srpgN] = BUF_strdup(gNid);
+ 
+					if (!row[DB_srpid] || !row[DB_srpgN] || !row[DB_srptype] || !row[DB_srpverifier] || !row[DB_srpsalt] ||
+						(userinfo && (!(row[DB_srpinfo] = BUF_strdup(userinfo)))))  
+						goto err;
+
+					doupdatedb = 1;
+					}
+				}
+			}
+		else if (delete_user)
+			{
+			if (userindex < 0)
+				{
+				BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user);
+				errors++;
+				}
+			else
+				{
+				char ** pp = sk_OPENSSL_PSTRING_value(db->db->data,userindex);
+				BIO_printf(bio_err,"user \"%s\" revoked. t\n",user);
+
+				pp[DB_srptype][0] = 'R' ;
+				
+				doupdatedb = 1;
+				}
+			}
+		if (--argc > 0)
+			user = *(argv++) ;
+		else
+			{
+			user = NULL;
+			list_user = 0;
+			}
+		}
+
+	VERBOSE BIO_printf(bio_err,"User procession done.\n");
+
+
+	if (doupdatedb)
+		{
+		/* Lets check some fields */
+		for (i=0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
+			{
+			pp=sk_OPENSSL_PSTRING_value(db->db->data,i);
+	
+			if (pp[DB_srptype][0] == 'v')
+				{
+				pp[DB_srptype][0] = 'V';
+				print_user(db,bio_err,i,verbose) ;
+				}
+			}
+
+		VERBOSE BIO_printf(bio_err,"Trying to update srpvfile.\n");
+		if (!save_index(dbfile,"new",db)) goto err;
+				
+		VERBOSE BIO_printf(bio_err,"Temporary srpvfile created.\n");
+		if (!rotate_index(dbfile,"new","old")) goto err;
+
+		VERBOSE BIO_printf(bio_err,"srpvfile updated.\n");
+		}
+
+	ret = (errors != 0);
+err:
+	if (errors != 0)
+	VERBOSE BIO_printf(bio_err,"User errors %d.\n",errors);
+
+	VERBOSE BIO_printf(bio_err,"SRP terminating with code %d.\n",ret);
+	if(tofree)
+		OPENSSL_free(tofree);
+	if (ret) ERR_print_errors(bio_err);
+	if (randfile) app_RAND_write_file(randfile, bio_err);
+	if (conf) NCONF_free(conf);
+	if (db) free_index(db);
+
+	OBJ_cleanup();
+	apps_shutdown();
+	OPENSSL_EXIT(ret);
+	}
+
+
+
+#endif
+
diff --git a/crypto/Makefile b/crypto/Makefile
index be0cf89..87c82fd 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -177,20 +177,14 @@
 ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
 ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
 ex_data.o: ex_data.c
-fips_ers.o: ../include/openssl/bio.h ../include/openssl/crypto.h
-fips_ers.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-fips_ers.o: ../include/openssl/fips.h ../include/openssl/lhash.h
-fips_ers.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-fips_ers.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-fips_ers.o: ../include/openssl/stack.h ../include/openssl/symhacks.h fips_err.h
-fips_ers.o: fips_ers.c
+fips_ers.o: ../include/openssl/opensslconf.h fips_ers.c
 lock.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
 lock.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-lock.o: ../include/openssl/err.h ../include/openssl/fips.h
-lock.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
-lock.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-lock.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-lock.o: ../include/openssl/symhacks.h cryptlib.h lock.c
+lock.o: ../include/openssl/err.h ../include/openssl/lhash.h
+lock.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+lock.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+lock.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
+lock.o: lock.c
 mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
 mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 mem.o: ../include/openssl/err.h ../include/openssl/lhash.h
diff --git a/crypto/bn/Makefile b/crypto/bn/Makefile
index 74bc4f7..17a117e 100644
--- a/crypto/bn/Makefile
+++ b/crypto/bn/Makefile
@@ -169,11 +169,10 @@
 bn_add.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_add.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_add.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_add.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_add.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_add.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_add.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_add.o: ../cryptlib.h bn_add.c bn_lcl.h
+bn_add.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_add.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_add.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_add.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_add.c bn_lcl.h
 bn_asm.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_asm.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_asm.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -184,8 +183,7 @@
 bn_blind.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_blind.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_blind.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_blind.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_blind.o: ../../include/openssl/opensslconf.h
+bn_blind.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 bn_blind.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 bn_blind.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 bn_blind.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_blind.c bn_lcl.h
@@ -197,11 +195,10 @@
 bn_ctx.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_ctx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_ctx.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_ctx.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_ctx.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_ctx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_ctx.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_ctx.o: ../cryptlib.h bn_ctx.c bn_lcl.h
+bn_ctx.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_ctx.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_ctx.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_ctx.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_ctx.c bn_lcl.h
 bn_depr.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_depr.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -213,11 +210,10 @@
 bn_div.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_div.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_div.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_div.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_div.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_div.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_div.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_div.o: ../cryptlib.h bn_div.c bn_lcl.h
+bn_div.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_div.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_div.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_div.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_div.c bn_lcl.h
 bn_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 bn_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
@@ -228,35 +224,31 @@
 bn_exp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_exp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_exp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_exp.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_exp.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_exp.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_exp.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_exp.o: ../cryptlib.h bn_exp.c bn_lcl.h
+bn_exp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_exp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_exp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_exp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp.c bn_lcl.h
 bn_exp2.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_exp2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_exp2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_exp2.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_exp2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_exp2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_exp2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_exp2.o: ../cryptlib.h bn_exp2.c bn_lcl.h
+bn_exp2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_exp2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_exp2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_exp2.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_exp2.c bn_lcl.h
 bn_gcd.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_gcd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_gcd.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_gcd.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_gcd.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_gcd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_gcd.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_gcd.o: ../cryptlib.h bn_gcd.c bn_lcl.h
+bn_gcd.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_gcd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_gcd.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_gcd.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gcd.c bn_lcl.h
 bn_gf2m.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_gf2m.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_gf2m.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_gf2m.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_gf2m.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_gf2m.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_gf2m.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_gf2m.o: ../cryptlib.h bn_gf2m.c bn_lcl.h
+bn_gf2m.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_gf2m.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_gf2m.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_gf2m.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_gf2m.c bn_lcl.h
 bn_kron.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_kron.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_kron.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -267,27 +259,24 @@
 bn_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_lib.o: ../cryptlib.h bn_lcl.h bn_lib.c
+bn_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_lib.c
 bn_mod.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_mod.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_mod.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_mod.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_mod.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_mod.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_mod.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_mod.o: ../cryptlib.h bn_lcl.h bn_mod.c
+bn_mod.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_mod.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_mod.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mod.c
 bn_mont.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_mont.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_mont.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_mont.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_mont.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_mont.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_mont.o: ../cryptlib.h bn_lcl.h bn_mont.c
+bn_mont.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_mont.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_mont.c
 bn_mpi.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_mpi.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_mpi.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -327,19 +316,18 @@
 bn_rand.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_rand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_rand.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-bn_rand.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bn_rand.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_rand.c
+bn_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+bn_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bn_rand.o: ../cryptlib.h bn_lcl.h bn_rand.c
 bn_recp.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_recp.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_recp.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bn_recp.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-bn_recp.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bn_recp.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bn_recp.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bn_recp.o: ../cryptlib.h bn_lcl.h bn_recp.c
+bn_recp.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_recp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_recp.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_recp.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_recp.c
 bn_shift.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_shift.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_shift.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/buffer/Makefile b/crypto/buffer/Makefile
index 7f58d05..9e0f46e 100644
--- a/crypto/buffer/Makefile
+++ b/crypto/buffer/Makefile
@@ -84,11 +84,10 @@
 buf_str.o: ../../e_os.h ../../include/openssl/bio.h
 buf_str.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 buf_str.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-buf_str.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-buf_str.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-buf_str.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-buf_str.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-buf_str.o: ../cryptlib.h buf_str.c
+buf_str.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+buf_str.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+buf_str.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+buf_str.o: ../../include/openssl/symhacks.h ../cryptlib.h buf_str.c
 buffer.o: ../../e_os.h ../../include/openssl/bio.h
 buffer.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 buffer.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/dh/Makefile b/crypto/dh/Makefile
index 3a9ee37..173bf09 100644
--- a/crypto/dh/Makefile
+++ b/crypto/dh/Makefile
@@ -127,20 +127,19 @@
 dh_gen.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 dh_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dh_gen.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_gen.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-dh_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-dh_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dh_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dh_gen.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_gen.c
+dh_gen.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+dh_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dh_gen.o: ../cryptlib.h dh_gen.c
 dh_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 dh_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dh_key.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
-dh_key.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-dh_key.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-dh_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dh_key.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-dh_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dh_key.o: ../cryptlib.h dh_key.c
+dh_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dh_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dh_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_key.c
 dh_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 dh_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
diff --git a/crypto/dsa/Makefile b/crypto/dsa/Makefile
index 0c6d653..f64130b 100644
--- a/crypto/dsa/Makefile
+++ b/crypto/dsa/Makefile
@@ -125,20 +125,16 @@
 dsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-dsa_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-dsa_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-dsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-dsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_gen.o: ../cryptlib.h dsa_gen.c dsa_locl.h
-dsa_key.o: ../../e_os.h ../../include/openssl/asn1.h
-dsa_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_gen.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+dsa_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_gen.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_gen.c dsa_locl.h
+dsa_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-dsa_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-dsa_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dsa_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
 dsa_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
 dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
 dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -162,8 +158,8 @@
 dsa_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_ossl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+dsa_ossl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_ossl.o: ../../include/openssl/opensslconf.h
 dsa_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -197,8 +193,8 @@
 dsa_sign.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_sign.o: ../../include/openssl/opensslconf.h
 dsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 dsa_sign.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
diff --git a/crypto/ec/Makefile b/crypto/ec/Makefile
index ca8ce9b..4491fb5 100644
--- a/crypto/ec/Makefile
+++ b/crypto/ec/Makefile
@@ -84,9 +84,8 @@
 ec2_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec2_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec2_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ec2_mult.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec2_mult.o: ../../include/openssl/opensslconf.h
+ec2_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec2_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
 ec2_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ec2_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ec2_mult.o: ../../include/openssl/symhacks.h ec2_mult.c ec_lcl.h
@@ -101,9 +100,8 @@
 ec2_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec2_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec2_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ec2_smpl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec2_smpl.o: ../../include/openssl/opensslconf.h
+ec2_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec2_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
 ec2_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ec2_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ec2_smpl.o: ../../include/openssl/symhacks.h ec2_smpl.c ec_lcl.h
@@ -142,21 +140,19 @@
 ec_curve.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_curve.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec_curve.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_curve.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ec_curve.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec_curve.o: ../../include/openssl/opensslconf.h
+ec_curve.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_curve.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
 ec_curve.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ec_curve.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ec_curve.o: ../../include/openssl/symhacks.h ec_curve.c ec_lcl.h
 ec_cvt.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_cvt.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec_cvt.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ec_cvt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec_cvt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ec_cvt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ec_cvt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ec_cvt.o: ec_cvt.c ec_lcl.h
+ec_cvt.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_cvt.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_cvt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_cvt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_cvt.o: ../../include/openssl/symhacks.h ec_cvt.c ec_lcl.h
 ec_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 ec_err.o: ../../include/openssl/ec.h ../../include/openssl/err.h
@@ -167,31 +163,27 @@
 ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-ec_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-ec_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ec_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ec_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ec_key.o: ec_key.c ec_lcl.h
+ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
 ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_lib.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ec_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ec_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ec_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ec_lib.o: ec_lcl.h ec_lib.c
+ec_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_lib.o: ../../include/openssl/symhacks.h ec_lcl.h ec_lib.c
 ec_mult.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_mult.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec_mult.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ec_mult.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ec_mult.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ec_mult.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ec_mult.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-ec_mult.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-ec_mult.o: ec_lcl.h ec_mult.c
+ec_mult.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_mult.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_mult.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_mult.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_mult.o: ../../include/openssl/symhacks.h ec_lcl.h ec_mult.c
 ec_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ec_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ec_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -234,22 +226,19 @@
 ecp_mont.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ecp_mont.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ecp_mont.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ecp_mont.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ecp_mont.o: ../../include/openssl/opensslconf.h
+ecp_mont.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_mont.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
 ecp_mont.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ecp_mont.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ecp_mont.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_mont.c
 ecp_nist.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ecp_nist.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ecp_nist.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ecp_nist.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ecp_nist.o: ../../include/openssl/opensslconf.h
+ecp_nist.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_nist.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
 ecp_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ecp_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ecp_nist.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_nist.c
-ecp_nistp224.o: ecp_nistp224.c
 ecp_oct.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ecp_oct.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ecp_oct.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
@@ -261,9 +250,8 @@
 ecp_smpl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ecp_smpl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ecp_smpl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/fips.h
-ecp_smpl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ecp_smpl.o: ../../include/openssl/opensslconf.h
+ecp_smpl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecp_smpl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
 ecp_smpl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ecp_smpl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ecp_smpl.o: ../../include/openssl/symhacks.h ec_lcl.h ecp_smpl.c
diff --git a/crypto/ecdsa/Makefile b/crypto/ecdsa/Makefile
index 554a053..48e8cee 100644
--- a/crypto/ecdsa/Makefile
+++ b/crypto/ecdsa/Makefile
@@ -108,8 +108,8 @@
 ecs_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 ecs_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 ecs_ossl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ecs_ossl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-ecs_ossl.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ecs_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ecs_ossl.o: ../../include/openssl/opensslconf.h
 ecs_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ecs_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ecs_ossl.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_ossl.c
diff --git a/crypto/engine/Makefile b/crypto/engine/Makefile
index c8a71b7..5a2e4ef 100644
--- a/crypto/engine/Makefile
+++ b/crypto/engine/Makefile
@@ -126,6 +126,8 @@
 eng_cnf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 eng_cnf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 eng_cnf.o: ../cryptlib.h eng_cnf.c eng_int.h
+eng_cryptodev.o: ../../crypto/dh/dh.h ../../crypto/dsa/dsa.h
+eng_cryptodev.o: ../../crypto/err/err.h ../../crypto/rsa/rsa.h
 eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/crypto/err/Makefile b/crypto/err/Makefile
index edabdf0..57bed29 100644
--- a/crypto/err/Makefile
+++ b/crypto/err/Makefile
@@ -90,18 +90,17 @@
 err_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 err_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
 err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-err_all.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-err_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-err_all.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
-err_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-err_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
-err_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-err_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-err_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-err_all.o: ../../include/openssl/symhacks.h ../../include/openssl/ts.h
-err_all.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
-err_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-err_all.o: err_all.c
+err_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+err_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+err_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem2.h
+err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+err_all.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+err_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+err_all.o: ../../include/openssl/ts.h ../../include/openssl/ui.h
+err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+err_all.o: ../../include/openssl/x509v3.h err_all.c
 err_prn.o: ../../e_os.h ../../include/openssl/bio.h
 err_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile
index 4b809c0..62e9954 100644
--- a/crypto/evp/Makefile
+++ b/crypto/evp/Makefile
@@ -188,14 +188,13 @@
 e_aes.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
 e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_aes.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-e_aes.o: ../../include/openssl/lhash.h ../../include/openssl/modes.h
-e_aes.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_aes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_aes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-e_aes.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_aes.o: ../../include/openssl/symhacks.h ../modes/modes_lcl.h e_aes.c
-e_aes.o: evp_locl.h
+e_aes.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+e_aes.o: ../../include/openssl/modes.h ../../include/openssl/obj_mac.h
+e_aes.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_aes.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_aes.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_aes.o: ../modes/modes_lcl.h e_aes.c evp_locl.h
 e_bf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_bf.o: ../../include/openssl/blowfish.h ../../include/openssl/buffer.h
 e_bf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -263,7 +262,6 @@
 e_null.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
 e_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 e_null.o: ../cryptlib.h e_null.c
-e_old.o: e_old.c
 e_rc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_rc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_rc2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -529,13 +527,13 @@
 m_sha1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_sha1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-m_sha1.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-m_sha1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-m_sha1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-m_sha1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-m_sha1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-m_sha1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-m_sha1.o: ../../include/openssl/symhacks.h ../cryptlib.h m_sha1.c
+m_sha1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+m_sha1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_sha1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_sha1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+m_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_sha1.o: ../cryptlib.h m_sha1.c
 m_sigver.o: ../../e_os.h ../../include/openssl/asn1.h
 m_sigver.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 m_sigver.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
diff --git a/crypto/hmac/Makefile b/crypto/hmac/Makefile
index 974a08c..1b39f10 100644
--- a/crypto/hmac/Makefile
+++ b/crypto/hmac/Makefile
@@ -102,10 +102,9 @@
 hmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 hmac.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-hmac.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
-hmac.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-hmac.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-hmac.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-hmac.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-hmac.o: ../cryptlib.h hmac.c
+hmac.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
+hmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+hmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+hmac.o: ../../include/openssl/symhacks.h ../cryptlib.h hmac.c
diff --git a/crypto/modes/Makefile b/crypto/modes/Makefile
index c3221be..81e7688 100644
--- a/crypto/modes/Makefile
+++ b/crypto/modes/Makefile
@@ -117,11 +117,10 @@
 cts128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 cts128.o: ../../include/openssl/symhacks.h cts128.c modes_lcl.h
 gcm128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-gcm128.o: ../../include/openssl/fips.h ../../include/openssl/modes.h
-gcm128.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-gcm128.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-gcm128.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-gcm128.o: gcm128.c modes_lcl.h
+gcm128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
+gcm128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+gcm128.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+gcm128.o: ../../include/openssl/symhacks.h gcm128.c modes_lcl.h
 ofb128.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 ofb128.o: ../../include/openssl/modes.h ../../include/openssl/opensslconf.h
 ofb128.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
diff --git a/crypto/rand/Makefile b/crypto/rand/Makefile
index 17de6ea..e353c1a 100644
--- a/crypto/rand/Makefile
+++ b/crypto/rand/Makefile
@@ -79,13 +79,13 @@
 md_rand.o: ../../e_os.h ../../include/openssl/asn1.h
 md_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 md_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-md_rand.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-md_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-md_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-md_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-md_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-md_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-md_rand.o: ../../include/openssl/symhacks.h md_rand.c rand_lcl.h
+md_rand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+md_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+md_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+md_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+md_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+md_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+md_rand.o: md_rand.c rand_lcl.h
 rand_egd.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rand_egd.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
 rand_egd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
@@ -99,14 +99,19 @@
 rand_err.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 rand_err.o: rand_err.c
-rand_lib.o: ../../e_os.h ../../include/openssl/bio.h
-rand_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rand_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rand_lib.o: ../../include/openssl/opensslconf.h
+rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rand_lib.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 rand_lib.o: ../cryptlib.h rand_lib.c
 rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
 rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
@@ -145,9 +150,8 @@
 rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_win.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rand_win.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rand_win.o: ../../include/openssl/opensslconf.h
+rand_win.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_win.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/crypto/rsa/Makefile b/crypto/rsa/Makefile
index caba7c4..59c5fcc 100644
--- a/crypto/rsa/Makefile
+++ b/crypto/rsa/Makefile
@@ -123,8 +123,7 @@
 rsa_crpt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_crpt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_crpt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_crpt.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_crpt.o: ../../include/openssl/opensslconf.h
+rsa_crpt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 rsa_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_crpt.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -142,12 +141,11 @@
 rsa_eay.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_eay.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_eay.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_eay.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_eay.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_eay.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_eay.o: ../cryptlib.h rsa_eay.c
+rsa_eay.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_eay.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_eay.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_eay.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_eay.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_eay.c
 rsa_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 rsa_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
@@ -159,9 +157,7 @@
 rsa_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_gen.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 rsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_gen.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 rsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
@@ -185,8 +181,7 @@
 rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_none.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_none.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_none.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_none.o: ../../include/openssl/opensslconf.h
+rsa_none.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 rsa_none.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_none.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_none.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -204,9 +199,9 @@
 rsa_oaep.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_oaep.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_oaep.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-rsa_oaep.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_oaep.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_oaep.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_oaep.o: ../../include/openssl/opensslconf.h
 rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -216,12 +211,11 @@
 rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_pk1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_pk1.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_pk1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_pk1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rsa_pk1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_pk1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_pk1.o: ../cryptlib.h rsa_pk1.c
+rsa_pk1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
 rsa_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_pmeth.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 rsa_pmeth.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -251,14 +245,13 @@
 rsa_pss.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_pss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_pss.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_pss.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-rsa_pss.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_pss.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-rsa_pss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rsa_pss.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-rsa_pss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-rsa_pss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_pss.o: ../cryptlib.h rsa_locl.h rsa_pss.c
+rsa_pss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+rsa_pss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_pss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rsa_pss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+rsa_pss.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_pss.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rsa_pss.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_locl.h rsa_pss.c
 rsa_saos.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_saos.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_saos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -291,19 +284,17 @@
 rsa_ssl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_ssl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_ssl.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_ssl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_ssl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_ssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rsa_ssl.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_ssl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_ssl.o: ../cryptlib.h rsa_ssl.c
+rsa_ssl.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_ssl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_ssl.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_ssl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+rsa_ssl.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_ssl.c
 rsa_x931.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_x931.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_x931.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_x931.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_x931.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_x931.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rsa_x931.o: ../../include/openssl/opensslconf.h
+rsa_x931.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_x931.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 rsa_x931.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_x931.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_x931.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -311,8 +302,7 @@
 rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
 rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-rsa_x931g.o: ../../include/openssl/opensslconf.h
+rsa_x931g.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 rsa_x931g.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_x931g.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
 rsa_x931g.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
diff --git a/crypto/srp/.cvsignore b/crypto/srp/.cvsignore
new file mode 100644
index 0000000..695fdd0
--- /dev/null
+++ b/crypto/srp/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.save
+lib
diff --git a/crypto/srp/Makefile b/crypto/srp/Makefile
new file mode 100644
index 0000000..d37d46c
--- /dev/null
+++ b/crypto/srp/Makefile
@@ -0,0 +1,96 @@
+DIR=	srp
+TOP=	../..
+CC=	cc
+INCLUDES= -I.. -I$(TOP) -I../../include
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR=     /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG=	makedepend
+MAKEDEPEND=	$(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE=	Makefile.ssl
+AR=		ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=srptest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=srp_lib.c srp_vfy.c
+LIBOBJ=srp_lib.o srp_vfy.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= srp.h
+HEADER=	$(EXHEADER)
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(AR) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+	@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install:
+	@for i in $(EXHEADER) ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+tags:
+	ctags $(SRC)
+
+tests:
+
+srptest: top srptest.c $(LIB)
+	$(CC) $(CFLAGS) -Wall -Werror -g -o srptest srptest.c $(LIB)
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+srp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+srp_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+srp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+srp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+srp_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+srp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+srp_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+srp_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+srp_lib.o: ../../include/openssl/sha.h ../../include/openssl/srp.h
+srp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+srp_lib.o: ../cryptlib.h srp_grps.h srp_lcl.h srp_lib.c
+srp_vfy.o: ../../e_os.h ../../include/openssl/asn1.h
+srp_vfy.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+srp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+srp_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+srp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+srp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+srp_vfy.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+srp_vfy.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+srp_vfy.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+srp_vfy.o: ../../include/openssl/srp.h ../../include/openssl/stack.h
+srp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h
+srp_vfy.o: ../cryptlib.h srp_lcl.h srp_vfy.c
diff --git a/crypto/srp/srp.h b/crypto/srp/srp.h
new file mode 100644
index 0000000..7ec7825
--- /dev/null
+++ b/crypto/srp/srp.h
@@ -0,0 +1,172 @@
+/* crypto/srp/srp.h */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef __SRP_H__
+#define __SRP_H__
+
+#ifndef OPENSSL_NO_SRP
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/safestack.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+
+typedef struct SRP_gN_cache_st
+	{
+	char *b64_bn;
+	BIGNUM *bn;
+	} SRP_gN_cache;
+
+
+DECLARE_STACK_OF(SRP_gN_cache)
+
+typedef struct SRP_user_pwd_st
+	{
+	char *id;
+	BIGNUM *s;
+	BIGNUM *v;
+	const BIGNUM *g;
+	const BIGNUM *N;
+	char *info;
+	} SRP_user_pwd;
+
+DECLARE_STACK_OF(SRP_user_pwd)
+
+typedef struct SRP_VBASE_st
+	{
+	STACK_OF(SRP_user_pwd) *users_pwd;
+	STACK_OF(SRP_gN_cache) *gN_cache;
+/* to simulate a user */
+	char *seed_key;
+	BIGNUM *default_g;
+	BIGNUM *default_N;
+	} SRP_VBASE;
+
+
+/*Structure interne pour retenir les couples N et g*/
+typedef struct SRP_gN_st
+	{
+	char *id;
+	BIGNUM *g;
+	BIGNUM *N;
+	} SRP_gN;
+
+DECLARE_STACK_OF(SRP_gN)
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key);
+int SRP_VBASE_free(SRP_VBASE *vb);
+int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file);
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username);
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+			  char **verifier, const char *N, const char *g);
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g);
+
+
+#define SRP_NO_ERROR 0
+#define SRP_ERR_VBASE_INCOMPLETE_FILE 1
+#define SRP_ERR_VBASE_BN_LIB 2
+#define SRP_ERR_OPEN_FILE 3
+#define SRP_ERR_MEMORY 4
+
+#define DB_srptype	0
+#define DB_srpverifier	1
+#define DB_srpsalt 	2
+#define DB_srpid	3              
+#define DB_srpgN	4       
+#define DB_srpinfo	5 
+#undef  DB_NUMBER      
+#define DB_NUMBER       6
+
+#define DB_SRP_INDEX	'I'
+#define DB_SRP_VALID	'V'
+#define DB_SRP_REVOKED	'R'
+#define DB_SRP_MODIF	'v'
+
+
+/* see srp.c */
+char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N); 
+SRP_gN *SRP_get_default_gN(const char * id) ;
+
+/* server side .... */
+BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N);
+BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v);
+int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N);
+BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) ;
+
+
+
+/* client side .... */
+BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass);
+BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g);
+BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u);
+int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N);
+
+#define SRP_MINIMAL_N 1024
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+#endif
diff --git a/crypto/srp/srp_grps.h b/crypto/srp/srp_grps.h
new file mode 100644
index 0000000..d77c9ff
--- /dev/null
+++ b/crypto/srp/srp_grps.h
@@ -0,0 +1,517 @@
+/* start of generated data */
+
+static BN_ULONG bn_group_1024_value[] = {
+	bn_pack4(9FC6,1D2F,C0EB,06E3),
+	bn_pack4(FD51,38FE,8376,435B),
+	bn_pack4(2FD4,CBF4,976E,AA9A),
+	bn_pack4(68ED,BC3C,0572,6CC0),
+	bn_pack4(C529,F566,660E,57EC),
+	bn_pack4(8255,9B29,7BCF,1885),
+	bn_pack4(CE8E,F4AD,69B1,5D49),
+	bn_pack4(5DC7,D7B4,6154,D6B6),
+	bn_pack4(8E49,5C1D,6089,DAD1),
+	bn_pack4(E0D5,D8E2,50B9,8BE4),
+	bn_pack4(383B,4813,D692,C6E0),
+	bn_pack4(D674,DF74,96EA,81D3),
+	bn_pack4(9EA2,314C,9C25,6576),
+	bn_pack4(6072,6187,75FF,3C0B),
+	bn_pack4(9C33,F80A,FA8F,C5E8),
+	bn_pack4(EEAF,0AB9,ADB3,8DD6)
+};
+static BIGNUM bn_group_1024 = {
+	bn_group_1024_value,
+	(sizeof bn_group_1024_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_1024_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_1536_value[] = {
+	bn_pack4(CF76,E3FE,D135,F9BB),
+	bn_pack4(1518,0F93,499A,234D),
+	bn_pack4(8CE7,A28C,2442,C6F3),
+	bn_pack4(5A02,1FFF,5E91,479E),
+	bn_pack4(7F8A,2FE9,B8B5,292E),
+	bn_pack4(837C,264A,E3A9,BEB8),
+	bn_pack4(E442,734A,F7CC,B7AE),
+	bn_pack4(6577,2E43,7D6C,7F8C),
+	bn_pack4(DB2F,D53D,24B7,C486),
+	bn_pack4(6EDF,0195,3934,9627),
+	bn_pack4(158B,FD3E,2B9C,8CF5),
+	bn_pack4(764E,3F4B,53DD,9DA1),
+	bn_pack4(4754,8381,DBC5,B1FC),
+	bn_pack4(9B60,9E0B,E3BA,B63D),
+	bn_pack4(8134,B1C8,B979,8914),
+	bn_pack4(DF02,8A7C,EC67,F0D0),
+	bn_pack4(80B6,55BB,9A22,E8DC),
+	bn_pack4(1558,903B,A0D0,F843),
+	bn_pack4(51C6,A94B,E460,7A29),
+	bn_pack4(5F4F,5F55,6E27,CBDE),
+	bn_pack4(BEEE,A961,4B19,CC4D),
+	bn_pack4(DBA5,1DF4,99AC,4C80),
+	bn_pack4(B1F1,2A86,17A4,7BBB),
+	bn_pack4(9DEF,3CAF,B939,277A)
+};
+static BIGNUM bn_group_1536 = {
+	bn_group_1536_value,
+	(sizeof bn_group_1536_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_1536_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_2048_value[] = {
+	bn_pack4(0FA7,111F,9E4A,FF73),
+	bn_pack4(9B65,E372,FCD6,8EF2),
+	bn_pack4(35DE,236D,525F,5475),
+	bn_pack4(94B5,C803,D89F,7AE4),
+	bn_pack4(71AE,35F8,E9DB,FBB6),
+	bn_pack4(2A56,98F3,A8D0,C382),
+	bn_pack4(9CCC,041C,7BC3,08D8),
+	bn_pack4(AF87,4E73,03CE,5329),
+	bn_pack4(6160,2790,04E5,7AE6),
+	bn_pack4(032C,FBDB,F52F,B378),
+	bn_pack4(5EA7,7A27,75D2,ECFA),
+	bn_pack4(5445,23B5,24B0,D57D),
+	bn_pack4(5B9D,32E6,88F8,7748),
+	bn_pack4(F1D2,B907,8717,461A),
+	bn_pack4(76BD,207A,436C,6481),
+	bn_pack4(CA97,B43A,23FB,8016),
+	bn_pack4(1D28,1E44,6B14,773B),
+	bn_pack4(7359,D041,D5C3,3EA7),
+	bn_pack4(A80D,740A,DBF4,FF74),
+	bn_pack4(55F9,7993,EC97,5EEA),
+	bn_pack4(2918,A996,2F0B,93B8),
+	bn_pack4(661A,05FB,D5FA,AAE8),
+	bn_pack4(CF60,9517,9A16,3AB3),
+	bn_pack4(E808,3969,EDB7,67B0),
+	bn_pack4(CD7F,48A9,DA04,FD50),
+	bn_pack4(D523,12AB,4B03,310D),
+	bn_pack4(8193,E075,7767,A13D),
+	bn_pack4(A373,29CB,B4A0,99ED),
+	bn_pack4(FC31,9294,3DB5,6050),
+	bn_pack4(AF72,B665,1987,EE07),
+	bn_pack4(F166,DE5E,1389,582F),
+	bn_pack4(AC6B,DB41,324A,9A9B)
+};
+static BIGNUM bn_group_2048 = {
+	bn_group_2048_value,
+	(sizeof bn_group_2048_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_2048_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_3072_value[] = {
+	bn_pack4(FFFF,FFFF,FFFF,FFFF),
+	bn_pack4(4B82,D120,A93A,D2CA),
+	bn_pack4(43DB,5BFC,E0FD,108E),
+	bn_pack4(08E2,4FA0,74E5,AB31),
+	bn_pack4(7709,88C0,BAD9,46E2),
+	bn_pack4(BBE1,1757,7A61,5D6C),
+	bn_pack4(521F,2B18,177B,200C),
+	bn_pack4(D876,0273,3EC8,6A64),
+	bn_pack4(F12F,FA06,D98A,0864),
+	bn_pack4(CEE3,D226,1AD2,EE6B),
+	bn_pack4(1E8C,94E0,4A25,619D),
+	bn_pack4(ABF5,AE8C,DB09,33D7),
+	bn_pack4(B397,0F85,A6E1,E4C7),
+	bn_pack4(8AEA,7157,5D06,0C7D),
+	bn_pack4(ECFB,8504,58DB,EF0A),
+	bn_pack4(A855,21AB,DF1C,BA64),
+	bn_pack4(AD33,170D,0450,7A33),
+	bn_pack4(1572,8E5A,8AAA,C42D),
+	bn_pack4(15D2,2618,98FA,0510),
+	bn_pack4(3995,497C,EA95,6AE5),
+	bn_pack4(DE2B,CBF6,9558,1718),
+	bn_pack4(B5C5,5DF0,6F4C,52C9),
+	bn_pack4(9B27,83A2,EC07,A28F),
+	bn_pack4(E39E,772C,180E,8603),
+	bn_pack4(3290,5E46,2E36,CE3B),
+	bn_pack4(F174,6C08,CA18,217C),
+	bn_pack4(670C,354E,4ABC,9804),
+	bn_pack4(9ED5,2907,7096,966D),
+	bn_pack4(1C62,F356,2085,52BB),
+	bn_pack4(8365,5D23,DCA3,AD96),
+	bn_pack4(6916,3FA8,FD24,CF5F),
+	bn_pack4(98DA,4836,1C55,D39A),
+	bn_pack4(C200,7CB8,A163,BF05),
+	bn_pack4(4928,6651,ECE4,5B3D),
+	bn_pack4(AE9F,2411,7C4B,1FE6),
+	bn_pack4(EE38,6BFB,5A89,9FA5),
+	bn_pack4(0BFF,5CB6,F406,B7ED),
+	bn_pack4(F44C,42E9,A637,ED6B),
+	bn_pack4(E485,B576,625E,7EC6),
+	bn_pack4(4FE1,356D,6D51,C245),
+	bn_pack4(302B,0A6D,F25F,1437),
+	bn_pack4(EF95,19B3,CD3A,431B),
+	bn_pack4(514A,0879,8E34,04DD),
+	bn_pack4(020B,BEA6,3B13,9B22),
+	bn_pack4(2902,4E08,8A67,CC74),
+	bn_pack4(C4C6,628B,80DC,1CD1),
+	bn_pack4(C90F,DAA2,2168,C234),
+	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_3072 = {
+	bn_group_3072_value,
+	(sizeof bn_group_3072_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_3072_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_4096_value[] = {
+	bn_pack4(FFFF,FFFF,FFFF,FFFF),
+	bn_pack4(4DF4,35C9,3406,3199),
+	bn_pack4(86FF,B7DC,90A6,C08F),
+	bn_pack4(93B4,EA98,8D8F,DDC1),
+	bn_pack4(D006,9127,D5B0,5AA9),
+	bn_pack4(B81B,DD76,2170,481C),
+	bn_pack4(1F61,2970,CEE2,D7AF),
+	bn_pack4(233B,A186,515B,E7ED),
+	bn_pack4(99B2,964F,A090,C3A2),
+	bn_pack4(287C,5947,4E6B,C05D),
+	bn_pack4(2E8E,FC14,1FBE,CAA6),
+	bn_pack4(DBBB,C2DB,04DE,8EF9),
+	bn_pack4(2583,E9CA,2AD4,4CE8),
+	bn_pack4(1A94,6834,B615,0BDA),
+	bn_pack4(99C3,2718,6AF4,E23C),
+	bn_pack4(8871,9A10,BDBA,5B26),
+	bn_pack4(1A72,3C12,A787,E6D7),
+	bn_pack4(4B82,D120,A921,0801),
+	bn_pack4(43DB,5BFC,E0FD,108E),
+	bn_pack4(08E2,4FA0,74E5,AB31),
+	bn_pack4(7709,88C0,BAD9,46E2),
+	bn_pack4(BBE1,1757,7A61,5D6C),
+	bn_pack4(521F,2B18,177B,200C),
+	bn_pack4(D876,0273,3EC8,6A64),
+	bn_pack4(F12F,FA06,D98A,0864),
+	bn_pack4(CEE3,D226,1AD2,EE6B),
+	bn_pack4(1E8C,94E0,4A25,619D),
+	bn_pack4(ABF5,AE8C,DB09,33D7),
+	bn_pack4(B397,0F85,A6E1,E4C7),
+	bn_pack4(8AEA,7157,5D06,0C7D),
+	bn_pack4(ECFB,8504,58DB,EF0A),
+	bn_pack4(A855,21AB,DF1C,BA64),
+	bn_pack4(AD33,170D,0450,7A33),
+	bn_pack4(1572,8E5A,8AAA,C42D),
+	bn_pack4(15D2,2618,98FA,0510),
+	bn_pack4(3995,497C,EA95,6AE5),
+	bn_pack4(DE2B,CBF6,9558,1718),
+	bn_pack4(B5C5,5DF0,6F4C,52C9),
+	bn_pack4(9B27,83A2,EC07,A28F),
+	bn_pack4(E39E,772C,180E,8603),
+	bn_pack4(3290,5E46,2E36,CE3B),
+	bn_pack4(F174,6C08,CA18,217C),
+	bn_pack4(670C,354E,4ABC,9804),
+	bn_pack4(9ED5,2907,7096,966D),
+	bn_pack4(1C62,F356,2085,52BB),
+	bn_pack4(8365,5D23,DCA3,AD96),
+	bn_pack4(6916,3FA8,FD24,CF5F),
+	bn_pack4(98DA,4836,1C55,D39A),
+	bn_pack4(C200,7CB8,A163,BF05),
+	bn_pack4(4928,6651,ECE4,5B3D),
+	bn_pack4(AE9F,2411,7C4B,1FE6),
+	bn_pack4(EE38,6BFB,5A89,9FA5),
+	bn_pack4(0BFF,5CB6,F406,B7ED),
+	bn_pack4(F44C,42E9,A637,ED6B),
+	bn_pack4(E485,B576,625E,7EC6),
+	bn_pack4(4FE1,356D,6D51,C245),
+	bn_pack4(302B,0A6D,F25F,1437),
+	bn_pack4(EF95,19B3,CD3A,431B),
+	bn_pack4(514A,0879,8E34,04DD),
+	bn_pack4(020B,BEA6,3B13,9B22),
+	bn_pack4(2902,4E08,8A67,CC74),
+	bn_pack4(C4C6,628B,80DC,1CD1),
+	bn_pack4(C90F,DAA2,2168,C234),
+	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_4096 = {
+	bn_group_4096_value,
+	(sizeof bn_group_4096_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_4096_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_6144_value[] = {
+	bn_pack4(FFFF,FFFF,FFFF,FFFF),
+	bn_pack4(E694,F91E,6DCC,4024),
+	bn_pack4(12BF,2D5B,0B74,74D6),
+	bn_pack4(043E,8F66,3F48,60EE),
+	bn_pack4(387F,E8D7,6E3C,0468),
+	bn_pack4(DA56,C9EC,2EF2,9632),
+	bn_pack4(EB19,CCB1,A313,D55C),
+	bn_pack4(F550,AA3D,8A1F,BFF0),
+	bn_pack4(06A1,D58B,B7C5,DA76),
+	bn_pack4(A797,15EE,F29B,E328),
+	bn_pack4(14CC,5ED2,0F80,37E0),
+	bn_pack4(CC8F,6D7E,BF48,E1D8),
+	bn_pack4(4BD4,07B2,2B41,54AA),
+	bn_pack4(0F1D,45B7,FF58,5AC5),
+	bn_pack4(23A9,7A7E,36CC,88BE),
+	bn_pack4(59E7,C97F,BEC7,E8F3),
+	bn_pack4(B5A8,4031,900B,1C9E),
+	bn_pack4(D55E,702F,4698,0C82),
+	bn_pack4(F482,D7CE,6E74,FEF6),
+	bn_pack4(F032,EA15,D172,1D03),
+	bn_pack4(5983,CA01,C64B,92EC),
+	bn_pack4(6FB8,F401,378C,D2BF),
+	bn_pack4(3320,5151,2BD7,AF42),
+	bn_pack4(DB7F,1447,E6CC,254B),
+	bn_pack4(44CE,6CBA,CED4,BB1B),
+	bn_pack4(DA3E,DBEB,CF9B,14ED),
+	bn_pack4(1797,27B0,865A,8918),
+	bn_pack4(B06A,53ED,9027,D831),
+	bn_pack4(E5DB,382F,4130,01AE),
+	bn_pack4(F8FF,9406,AD9E,530E),
+	bn_pack4(C975,1E76,3DBA,37BD),
+	bn_pack4(C1D4,DCB2,6026,46DE),
+	bn_pack4(36C3,FAB4,D27C,7026),
+	bn_pack4(4DF4,35C9,3402,8492),
+	bn_pack4(86FF,B7DC,90A6,C08F),
+	bn_pack4(93B4,EA98,8D8F,DDC1),
+	bn_pack4(D006,9127,D5B0,5AA9),
+	bn_pack4(B81B,DD76,2170,481C),
+	bn_pack4(1F61,2970,CEE2,D7AF),
+	bn_pack4(233B,A186,515B,E7ED),
+	bn_pack4(99B2,964F,A090,C3A2),
+	bn_pack4(287C,5947,4E6B,C05D),
+	bn_pack4(2E8E,FC14,1FBE,CAA6),
+	bn_pack4(DBBB,C2DB,04DE,8EF9),
+	bn_pack4(2583,E9CA,2AD4,4CE8),
+	bn_pack4(1A94,6834,B615,0BDA),
+	bn_pack4(99C3,2718,6AF4,E23C),
+	bn_pack4(8871,9A10,BDBA,5B26),
+	bn_pack4(1A72,3C12,A787,E6D7),
+	bn_pack4(4B82,D120,A921,0801),
+	bn_pack4(43DB,5BFC,E0FD,108E),
+	bn_pack4(08E2,4FA0,74E5,AB31),
+	bn_pack4(7709,88C0,BAD9,46E2),
+	bn_pack4(BBE1,1757,7A61,5D6C),
+	bn_pack4(521F,2B18,177B,200C),
+	bn_pack4(D876,0273,3EC8,6A64),
+	bn_pack4(F12F,FA06,D98A,0864),
+	bn_pack4(CEE3,D226,1AD2,EE6B),
+	bn_pack4(1E8C,94E0,4A25,619D),
+	bn_pack4(ABF5,AE8C,DB09,33D7),
+	bn_pack4(B397,0F85,A6E1,E4C7),
+	bn_pack4(8AEA,7157,5D06,0C7D),
+	bn_pack4(ECFB,8504,58DB,EF0A),
+	bn_pack4(A855,21AB,DF1C,BA64),
+	bn_pack4(AD33,170D,0450,7A33),
+	bn_pack4(1572,8E5A,8AAA,C42D),
+	bn_pack4(15D2,2618,98FA,0510),
+	bn_pack4(3995,497C,EA95,6AE5),
+	bn_pack4(DE2B,CBF6,9558,1718),
+	bn_pack4(B5C5,5DF0,6F4C,52C9),
+	bn_pack4(9B27,83A2,EC07,A28F),
+	bn_pack4(E39E,772C,180E,8603),
+	bn_pack4(3290,5E46,2E36,CE3B),
+	bn_pack4(F174,6C08,CA18,217C),
+	bn_pack4(670C,354E,4ABC,9804),
+	bn_pack4(9ED5,2907,7096,966D),
+	bn_pack4(1C62,F356,2085,52BB),
+	bn_pack4(8365,5D23,DCA3,AD96),
+	bn_pack4(6916,3FA8,FD24,CF5F),
+	bn_pack4(98DA,4836,1C55,D39A),
+	bn_pack4(C200,7CB8,A163,BF05),
+	bn_pack4(4928,6651,ECE4,5B3D),
+	bn_pack4(AE9F,2411,7C4B,1FE6),
+	bn_pack4(EE38,6BFB,5A89,9FA5),
+	bn_pack4(0BFF,5CB6,F406,B7ED),
+	bn_pack4(F44C,42E9,A637,ED6B),
+	bn_pack4(E485,B576,625E,7EC6),
+	bn_pack4(4FE1,356D,6D51,C245),
+	bn_pack4(302B,0A6D,F25F,1437),
+	bn_pack4(EF95,19B3,CD3A,431B),
+	bn_pack4(514A,0879,8E34,04DD),
+	bn_pack4(020B,BEA6,3B13,9B22),
+	bn_pack4(2902,4E08,8A67,CC74),
+	bn_pack4(C4C6,628B,80DC,1CD1),
+	bn_pack4(C90F,DAA2,2168,C234),
+	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_6144 = {
+	bn_group_6144_value,
+	(sizeof bn_group_6144_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_6144_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_group_8192_value[] = {
+	bn_pack4(FFFF,FFFF,FFFF,FFFF),
+	bn_pack4(60C9,80DD,98ED,D3DF),
+	bn_pack4(C81F,56E8,80B9,6E71),
+	bn_pack4(9E30,50E2,7656,94DF),
+	bn_pack4(9558,E447,5677,E9AA),
+	bn_pack4(C919,0DA6,FC02,6E47),
+	bn_pack4(889A,002E,D5EE,382B),
+	bn_pack4(4009,438B,481C,6CD7),
+	bn_pack4(3590,46F4,EB87,9F92),
+	bn_pack4(FAF3,6BC3,1ECF,A268),
+	bn_pack4(B1D5,10BD,7EE7,4D73),
+	bn_pack4(F9AB,4819,5DED,7EA1),
+	bn_pack4(64F3,1CC5,0846,851D),
+	bn_pack4(4597,E899,A025,5DC1),
+	bn_pack4(DF31,0EE0,74AB,6A36),
+	bn_pack4(6D2A,13F8,3F44,F82D),
+	bn_pack4(062B,3CF5,B3A2,78A6),
+	bn_pack4(7968,3303,ED5B,DD3A),
+	bn_pack4(FA9D,4B7F,A2C0,87E8),
+	bn_pack4(4BCB,C886,2F83,85DD),
+	bn_pack4(3473,FC64,6CEA,306B),
+	bn_pack4(13EB,57A8,1A23,F0C7),
+	bn_pack4(2222,2E04,A403,7C07),
+	bn_pack4(E3FD,B8BE,FC84,8AD9),
+	bn_pack4(238F,16CB,E39D,652D),
+	bn_pack4(3423,B474,2BF1,C978),
+	bn_pack4(3AAB,639C,5AE4,F568),
+	bn_pack4(2576,F693,6BA4,2466),
+	bn_pack4(741F,A7BF,8AFC,47ED),
+	bn_pack4(3BC8,32B6,8D9D,D300),
+	bn_pack4(D8BE,C4D0,73B9,31BA),
+	bn_pack4(3877,7CB6,A932,DF8C),
+	bn_pack4(74A3,926F,12FE,E5E4),
+	bn_pack4(E694,F91E,6DBE,1159),
+	bn_pack4(12BF,2D5B,0B74,74D6),
+	bn_pack4(043E,8F66,3F48,60EE),
+	bn_pack4(387F,E8D7,6E3C,0468),
+	bn_pack4(DA56,C9EC,2EF2,9632),
+	bn_pack4(EB19,CCB1,A313,D55C),
+	bn_pack4(F550,AA3D,8A1F,BFF0),
+	bn_pack4(06A1,D58B,B7C5,DA76),
+	bn_pack4(A797,15EE,F29B,E328),
+	bn_pack4(14CC,5ED2,0F80,37E0),
+	bn_pack4(CC8F,6D7E,BF48,E1D8),
+	bn_pack4(4BD4,07B2,2B41,54AA),
+	bn_pack4(0F1D,45B7,FF58,5AC5),
+	bn_pack4(23A9,7A7E,36CC,88BE),
+	bn_pack4(59E7,C97F,BEC7,E8F3),
+	bn_pack4(B5A8,4031,900B,1C9E),
+	bn_pack4(D55E,702F,4698,0C82),
+	bn_pack4(F482,D7CE,6E74,FEF6),
+	bn_pack4(F032,EA15,D172,1D03),
+	bn_pack4(5983,CA01,C64B,92EC),
+	bn_pack4(6FB8,F401,378C,D2BF),
+	bn_pack4(3320,5151,2BD7,AF42),
+	bn_pack4(DB7F,1447,E6CC,254B),
+	bn_pack4(44CE,6CBA,CED4,BB1B),
+	bn_pack4(DA3E,DBEB,CF9B,14ED),
+	bn_pack4(1797,27B0,865A,8918),
+	bn_pack4(B06A,53ED,9027,D831),
+	bn_pack4(E5DB,382F,4130,01AE),
+	bn_pack4(F8FF,9406,AD9E,530E),
+	bn_pack4(C975,1E76,3DBA,37BD),
+	bn_pack4(C1D4,DCB2,6026,46DE),
+	bn_pack4(36C3,FAB4,D27C,7026),
+	bn_pack4(4DF4,35C9,3402,8492),
+	bn_pack4(86FF,B7DC,90A6,C08F),
+	bn_pack4(93B4,EA98,8D8F,DDC1),
+	bn_pack4(D006,9127,D5B0,5AA9),
+	bn_pack4(B81B,DD76,2170,481C),
+	bn_pack4(1F61,2970,CEE2,D7AF),
+	bn_pack4(233B,A186,515B,E7ED),
+	bn_pack4(99B2,964F,A090,C3A2),
+	bn_pack4(287C,5947,4E6B,C05D),
+	bn_pack4(2E8E,FC14,1FBE,CAA6),
+	bn_pack4(DBBB,C2DB,04DE,8EF9),
+	bn_pack4(2583,E9CA,2AD4,4CE8),
+	bn_pack4(1A94,6834,B615,0BDA),
+	bn_pack4(99C3,2718,6AF4,E23C),
+	bn_pack4(8871,9A10,BDBA,5B26),
+	bn_pack4(1A72,3C12,A787,E6D7),
+	bn_pack4(4B82,D120,A921,0801),
+	bn_pack4(43DB,5BFC,E0FD,108E),
+	bn_pack4(08E2,4FA0,74E5,AB31),
+	bn_pack4(7709,88C0,BAD9,46E2),
+	bn_pack4(BBE1,1757,7A61,5D6C),
+	bn_pack4(521F,2B18,177B,200C),
+	bn_pack4(D876,0273,3EC8,6A64),
+	bn_pack4(F12F,FA06,D98A,0864),
+	bn_pack4(CEE3,D226,1AD2,EE6B),
+	bn_pack4(1E8C,94E0,4A25,619D),
+	bn_pack4(ABF5,AE8C,DB09,33D7),
+	bn_pack4(B397,0F85,A6E1,E4C7),
+	bn_pack4(8AEA,7157,5D06,0C7D),
+	bn_pack4(ECFB,8504,58DB,EF0A),
+	bn_pack4(A855,21AB,DF1C,BA64),
+	bn_pack4(AD33,170D,0450,7A33),
+	bn_pack4(1572,8E5A,8AAA,C42D),
+	bn_pack4(15D2,2618,98FA,0510),
+	bn_pack4(3995,497C,EA95,6AE5),
+	bn_pack4(DE2B,CBF6,9558,1718),
+	bn_pack4(B5C5,5DF0,6F4C,52C9),
+	bn_pack4(9B27,83A2,EC07,A28F),
+	bn_pack4(E39E,772C,180E,8603),
+	bn_pack4(3290,5E46,2E36,CE3B),
+	bn_pack4(F174,6C08,CA18,217C),
+	bn_pack4(670C,354E,4ABC,9804),
+	bn_pack4(9ED5,2907,7096,966D),
+	bn_pack4(1C62,F356,2085,52BB),
+	bn_pack4(8365,5D23,DCA3,AD96),
+	bn_pack4(6916,3FA8,FD24,CF5F),
+	bn_pack4(98DA,4836,1C55,D39A),
+	bn_pack4(C200,7CB8,A163,BF05),
+	bn_pack4(4928,6651,ECE4,5B3D),
+	bn_pack4(AE9F,2411,7C4B,1FE6),
+	bn_pack4(EE38,6BFB,5A89,9FA5),
+	bn_pack4(0BFF,5CB6,F406,B7ED),
+	bn_pack4(F44C,42E9,A637,ED6B),
+	bn_pack4(E485,B576,625E,7EC6),
+	bn_pack4(4FE1,356D,6D51,C245),
+	bn_pack4(302B,0A6D,F25F,1437),
+	bn_pack4(EF95,19B3,CD3A,431B),
+	bn_pack4(514A,0879,8E34,04DD),
+	bn_pack4(020B,BEA6,3B13,9B22),
+	bn_pack4(2902,4E08,8A67,CC74),
+	bn_pack4(C4C6,628B,80DC,1CD1),
+	bn_pack4(C90F,DAA2,2168,C234),
+	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+};
+static BIGNUM bn_group_8192 = {
+	bn_group_8192_value,
+	(sizeof bn_group_8192_value)/sizeof(BN_ULONG),
+	(sizeof bn_group_8192_value)/sizeof(BN_ULONG),
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static BN_ULONG bn_generator_19_value[] = {19} ;
+static BIGNUM bn_generator_19 = {
+	bn_generator_19_value,
+	1,
+	1,
+	0,
+	BN_FLG_STATIC_DATA
+};
+static BN_ULONG bn_generator_5_value[] = {5} ;
+static BIGNUM bn_generator_5 = {
+	bn_generator_5_value,
+	1,
+	1,
+	0,
+	BN_FLG_STATIC_DATA
+};
+static BN_ULONG bn_generator_2_value[] = {2} ;
+static BIGNUM bn_generator_2 = {
+	bn_generator_2_value,
+	1,
+	1,
+	0,
+	BN_FLG_STATIC_DATA
+};
+
+static SRP_gN knowngN[] = {
+	{"8192",&bn_generator_19 , &bn_group_8192},
+	{"6144",&bn_generator_5 , &bn_group_6144},
+	{"4096",&bn_generator_5 , &bn_group_4096},
+	{"3072",&bn_generator_5 , &bn_group_3072},
+	{"2048",&bn_generator_2 , &bn_group_2048},
+	{"1536",&bn_generator_2 , &bn_group_1536},
+	{"1024",&bn_generator_2 , &bn_group_1024},
+};
+#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
+
+/* end of generated data */
diff --git a/crypto/srp/srp_lcl.h b/crypto/srp/srp_lcl.h
new file mode 100644
index 0000000..42bda3f
--- /dev/null
+++ b/crypto/srp/srp_lcl.h
@@ -0,0 +1,83 @@
+/* crypto/srp/srp_lcl.h */
+/* Written by Peter Sylvester (peter.sylvester@edelweb.fr)  
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_SRP_LCL_H
+#define HEADER_SRP_LCL_H
+
+#include <openssl/srp.h>
+#include <openssl/sha.h>
+
+#if 0
+#define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \
+   fprintf(stderr,"\n");}
+#else
+#define   srp_bn_print(a)
+#endif
+
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/crypto/srp/srp_lib.c b/crypto/srp/srp_lib.c
new file mode 100644
index 0000000..dbf464b
--- /dev/null
+++ b/crypto/srp/srp_lib.c
@@ -0,0 +1,357 @@
+/* crypto/srp/srp_lib.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef OPENSSL_NO_SRP
+#include "cryptlib.h"
+#include "srp_lcl.h"
+#include <openssl/srp.h>
+#include <openssl/evp.h>
+
+#if (BN_BYTES == 8)
+#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul
+#endif
+#if (BN_BYTES == 4)
+#define bn_pack4(a1,a2,a3,a4)  0x##a3##a4##ul, 0x##a1##a2##ul
+#endif
+#if (BN_BYTES == 2)
+#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u
+#endif
+
+
+#include "srp_grps.h"
+
+static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
+	{
+	/* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
+
+	unsigned char digest[SHA_DIGEST_LENGTH];
+	unsigned char *tmp;
+	EVP_MD_CTX ctxt;
+	int longg ;
+	int longN = BN_num_bytes(N);
+
+	if ((tmp = OPENSSL_malloc(longN)) == NULL)
+		return NULL;
+	BN_bn2bin(N,tmp) ;
+
+	EVP_MD_CTX_init(&ctxt);
+	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+	EVP_DigestUpdate(&ctxt, tmp, longN);
+
+	memset(tmp, 0, longN);
+	longg = BN_bn2bin(g,tmp) ;
+        /* use the zeros behind to pad on left */
+	EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg);
+	EVP_DigestUpdate(&ctxt, tmp, longg);
+	OPENSSL_free(tmp);
+
+	EVP_DigestFinal_ex(&ctxt, digest, NULL);
+	EVP_MD_CTX_cleanup(&ctxt);
+	return BN_bin2bn(digest, sizeof(digest), NULL);	
+	}
+
+BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
+	{
+	/* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
+
+	BIGNUM *u;	
+	unsigned char cu[SHA_DIGEST_LENGTH];
+	unsigned char *cAB;
+	EVP_MD_CTX ctxt;
+	int longN;  
+	if ((A == NULL) ||(B == NULL) || (N == NULL))
+		return NULL;
+
+	longN= BN_num_bytes(N);
+
+	if ((cAB = OPENSSL_malloc(2*longN)) == NULL) 
+		return NULL;
+
+	memset(cAB, 0, longN);
+
+	EVP_MD_CTX_init(&ctxt);
+	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+	EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN);
+	EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN);
+	OPENSSL_free(cAB);
+	EVP_DigestFinal_ex(&ctxt, cu, NULL);
+	EVP_MD_CTX_cleanup(&ctxt);
+
+	if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
+		return NULL;
+	if (!BN_is_zero(u))
+		return u;
+	BN_free(u);
+	return NULL;
+}
+
+BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N)
+	{
+	BIGNUM *tmp = NULL, *S = NULL;
+	BN_CTX *bn_ctx; 
+	
+	if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
+		return NULL; 
+
+	if ((bn_ctx = BN_CTX_new()) == NULL ||
+		(tmp = BN_new()) == NULL ||
+		(S = BN_new()) == NULL )
+		goto err;
+
+	/* S = (A*v**u) ** b */ 
+
+	if (!BN_mod_exp(tmp,v,u,N,bn_ctx))
+		goto err;
+	if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx))
+		goto err;
+	if (!BN_mod_exp(S,tmp,b,N,bn_ctx))
+		goto err;
+err:
+	BN_CTX_free(bn_ctx);
+	BN_clear_free(tmp);
+	return S;
+	}
+
+BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
+	{
+	BIGNUM  *kv = NULL, *gb = NULL;
+	BIGNUM *B = NULL, *k = NULL;
+	BN_CTX *bn_ctx;
+
+	if (b == NULL || N == NULL || g == NULL || v == NULL ||
+		(bn_ctx = BN_CTX_new()) == NULL)
+		return NULL; 
+
+	if ( (kv = BN_new()) == NULL ||
+		(gb = BN_new()) == NULL ||
+		(B = BN_new())== NULL)
+		goto err;
+
+	/* B = g**b + k*v */
+
+	if (!BN_mod_exp(gb,g,b,N,bn_ctx) ||
+	   !(k = srp_Calc_k(N,g)) ||
+	   !BN_mod_mul(kv,v,k,N,bn_ctx) || 
+	   !BN_mod_add(B,gb,kv,N,bn_ctx))
+		{
+		BN_free(B);
+		B = NULL;
+		}
+err:
+	BN_CTX_free(bn_ctx);
+	BN_clear_free(kv);
+	BN_clear_free(gb);
+	BN_free(k); 
+	return B;
+	}
+
+BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
+	{
+	unsigned char dig[SHA_DIGEST_LENGTH];
+	EVP_MD_CTX ctxt;
+	unsigned char *cs;
+
+	if ((s == NULL) ||
+		(user == NULL) ||
+		(pass == NULL))
+		return NULL;
+
+	if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
+		return NULL;
+
+	EVP_MD_CTX_init(&ctxt);
+	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+	EVP_DigestUpdate(&ctxt, user, strlen(user));
+	EVP_DigestUpdate(&ctxt, ":", 1);
+	EVP_DigestUpdate(&ctxt, pass, strlen(pass));
+	EVP_DigestFinal_ex(&ctxt, dig, NULL);
+
+	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+	BN_bn2bin(s,cs);
+	EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
+	OPENSSL_free(cs);
+	EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
+	EVP_DigestFinal_ex(&ctxt, dig, NULL);
+	EVP_MD_CTX_cleanup(&ctxt);
+
+	return BN_bin2bn(dig, sizeof(dig), NULL);
+	}
+
+BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
+	{
+	BN_CTX *bn_ctx; 
+	BIGNUM * A = NULL;
+
+	if (a == NULL || N == NULL || g == NULL ||
+		(bn_ctx = BN_CTX_new()) == NULL) 
+		return NULL;
+
+	if ((A = BN_new()) != NULL &&
+	   !BN_mod_exp(A,g,a,N,bn_ctx))
+		{
+		BN_free(A);
+		A = NULL;
+		}
+	BN_CTX_free(bn_ctx);
+	return A;
+	}
+
+
+BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u)
+	{
+	BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL;
+	BN_CTX *bn_ctx;
+
+	if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL ||
+		(bn_ctx = BN_CTX_new()) == NULL)
+		return NULL; 
+
+	if ((tmp = BN_new()) == NULL ||
+		(tmp2 = BN_new())== NULL ||
+		(tmp3 = BN_new())== NULL ||
+		(K = BN_new()) == NULL)
+		goto err;
+	
+	if (!BN_mod_exp(tmp,g,x,N,bn_ctx))
+		goto err;
+	if (!(k = srp_Calc_k(N,g)))
+		goto err;
+	if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx))
+		goto err;
+	if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx))
+		goto err;
+
+	if (!BN_mod_mul(tmp3,u,x,N,bn_ctx))
+		goto err;
+	if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx))
+		goto err;
+	if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx))
+		goto err;
+
+err :
+	BN_CTX_free(bn_ctx);
+	BN_clear_free(tmp);
+	BN_clear_free(tmp2);
+	BN_clear_free(tmp3);
+	BN_free(k);
+	return K;	
+	}
+
+int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
+	{
+	BIGNUM *r;
+	BN_CTX *bn_ctx; 
+	int ret = 0;
+
+	if (B == NULL || N == NULL ||
+		(bn_ctx = BN_CTX_new()) == NULL)
+		return 0;
+
+	if ((r = BN_new()) == NULL)
+		goto err;
+	/* Checks if B % N == 0 */
+	if (!BN_nnmod(r,B,N,bn_ctx))
+		goto err;
+	ret = !BN_is_zero(r);
+err:
+	BN_CTX_free(bn_ctx);
+	BN_free(r);
+	return ret;
+	}
+
+int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
+	{
+	/* Checks if A % N == 0 */
+	return SRP_Verify_B_mod_N(A,N) ;
+	}
+
+
+/* Check if G and N are kwown parameters. 
+   The values have been generated from the ietf-tls-srp draft version 8
+*/
+char *  SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N)
+	{
+	int i;
+	if ((g == NULL) || (N == NULL))
+		return 0;
+
+	srp_bn_print(g);
+	srp_bn_print(N);
+
+	for(i = 0; i < KNOWN_GN_NUMBER; i++)
+		{
+		if (BN_cmp(knowngN[i].g,g) == 0 && BN_cmp(knowngN[i].N,N) == 0) 
+			return knowngN[i].id;
+		}
+	return NULL;
+	}
+
+SRP_gN *SRP_get_default_gN(const char * id)
+	{
+	int i; 
+
+	if (id == NULL) 
+		return knowngN;
+	for(i = 0; i < KNOWN_GN_NUMBER; i++)
+		{
+		if (strcmp(knowngN[i].id,id)==0)
+			return knowngN+i;
+		}
+	return NULL;
+	}
+#endif
diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c
new file mode 100644
index 0000000..8b96a20
--- /dev/null
+++ b/crypto/srp/srp_vfy.c
@@ -0,0 +1,660 @@
+/* crypto/srp/srp_vfy.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef OPENSSL_NO_SRP
+#include "cryptlib.h"
+#include "srp_lcl.h"
+#include <openssl/srp.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/txt_db.h>
+
+#define SRP_RANDOM_SALT_LEN 20
+#define MAX_LEN 2500
+
+static char b64table[] =
+  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+
+/* the following two conversion routines have been inspired by code from Stanford */ 
+
+/*
+ * Convert a base64 string into raw byte array representation.
+ */
+static int t_fromb64(unsigned char *a, const char *src)
+	{
+	char *loc;
+	int i, j;
+	int size;
+
+	while(*src && (*src == ' ' || *src == '\t' || *src == '\n'))
+		++src;
+	size = strlen((const char *)src);
+	i = 0;
+	while(i < size)
+		{
+		loc = strchr(b64table, src[i]);
+		if(loc == (char *) 0) break;
+		else a[i] = loc - b64table;
+		++i;
+		}
+	size = i;
+	i = size - 1;
+	j = size;
+	while(1)
+		{
+		a[j] = a[i];
+		if(--i < 0) break;
+		a[j] |= (a[i] & 3) << 6;
+		--j;
+		a[j] = (unsigned char) ((a[i] & 0x3c) >> 2);
+		if(--i < 0) break;
+		a[j] |= (a[i] & 0xf) << 4;
+		--j;
+		a[j] = (unsigned char) ((a[i] & 0x30) >> 4);
+		if(--i < 0) break;
+		a[j] |= (a[i] << 2);
+
+		a[--j] = 0;
+		if(--i < 0) break;
+		}
+	while(a[j] == 0 && j <= size) ++j;
+	i = 0;
+	while (j <= size) a[i++] = a[j++];
+	return i;
+	}
+
+
+/*
+ * Convert a raw byte string into a null-terminated base64 ASCII string.
+ */
+static char *t_tob64(char *dst, const unsigned char *src, int size)
+	{
+	int c, pos = size % 3;
+	unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
+	char *olddst = dst;
+
+	switch(pos)
+		{
+	case 1:
+		b2 = src[0];
+		break;
+	case 2:
+		b1 = src[0];
+		b2 = src[1];
+		break;
+		}
+
+	while(1)
+		{
+		c = (b0 & 0xfc) >> 2;
+		if(notleading || c != 0)
+			{
+			*dst++ = b64table[c];
+			notleading = 1;
+			}
+		c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
+		if(notleading || c != 0)
+			{
+			*dst++ = b64table[c];
+			notleading = 1;
+			}
+		c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
+		if(notleading || c != 0)
+			{
+			*dst++ = b64table[c];
+			notleading = 1;
+			}
+		c = b2 & 0x3f;
+		if(notleading || c != 0)
+			{
+			*dst++ = b64table[c];
+			notleading = 1;
+			}
+		if(pos >= size) break;
+		else
+			{
+			b0 = src[pos++];
+			b1 = src[pos++];
+			b2 = src[pos++];
+			}
+		}
+
+	*dst++ = '\0';
+	return olddst;
+	}
+
+static void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
+	{
+	if (user_pwd == NULL) 
+		return;
+	BN_free(user_pwd->s);
+	BN_clear_free(user_pwd->v);
+	OPENSSL_free(user_pwd->id);
+	OPENSSL_free(user_pwd->info);
+	OPENSSL_free(user_pwd);
+	}
+
+static SRP_user_pwd * SRP_user_pwd_new(void)
+	{
+	SRP_user_pwd * ret = OPENSSL_malloc(sizeof(SRP_user_pwd));
+	if (ret == NULL)
+		return NULL;								
+	ret->N = NULL;
+	ret->g = NULL;	
+	ret->s = NULL;
+	ret->v = NULL;
+	ret->id = NULL ;
+	ret->info = NULL;
+	return ret;
+	}
+
+static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
+								const BIGNUM *N)
+	{
+	vinfo->N = N;
+	vinfo->g = g;	
+	}
+
+static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
+								const char *info)
+	{
+	if (id != NULL && NULL == (vinfo->id = BUF_strdup(id)))
+		return 0;
+	return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))) ;
+	}
+
+static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
+							   const char *v)
+	{
+	unsigned char tmp[MAX_LEN]; 
+	int len;
+
+	if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN) 
+		return 0; 
+	len = t_fromb64(tmp, v);
+	if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)) )
+		return 0;
+	len = t_fromb64(tmp, s);
+	return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL) ;
+	}
+
+static int SRP_user_pwd_set_sv_BN(SRP_user_pwd * vinfo, BIGNUM * s, BIGNUM * v)
+	{
+	vinfo->v = v;
+	vinfo->s = s;
+	return (vinfo->s != NULL && vinfo->v != NULL) ;
+	}
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key)
+	{
+	SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE));
+
+	if (vb == NULL)
+		return NULL;
+	if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) ||
+		!(vb->gN_cache = sk_SRP_gN_cache_new_null()))
+		{
+		OPENSSL_free(vb);
+		return NULL;
+		}
+	vb->default_g = NULL;
+	vb->default_N = NULL;
+	vb->seed_key = NULL;
+	if ((seed_key != NULL) && 
+		(vb->seed_key = BUF_strdup(seed_key)) == NULL)
+		{
+		sk_SRP_user_pwd_free(vb->users_pwd);
+		sk_SRP_gN_cache_free(vb->gN_cache);
+		OPENSSL_free(vb);
+		return NULL;
+		}
+	return vb;
+	}
+
+
+int SRP_VBASE_free(SRP_VBASE *vb)
+	{
+	sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free);
+	sk_SRP_gN_cache_free(vb->gN_cache);
+	OPENSSL_free(vb->seed_key);
+	OPENSSL_free(vb);
+	return 0;
+	}
+
+
+static SRP_gN_cache *SRP_gN_new_init(const char *ch)
+	{
+	unsigned char tmp[MAX_LEN];
+	int len;
+
+	SRP_gN_cache *newgN = (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache));
+	if (newgN == NULL)
+		return NULL;
+
+	if ((newgN->b64_bn = BUF_strdup(ch)) == NULL)
+		goto err;
+
+	len = t_fromb64(tmp, ch);
+	if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
+		return newgN;
+
+	OPENSSL_free(newgN->b64_bn);
+err:
+	OPENSSL_free(newgN);
+	return NULL;
+	}
+
+
+static void SRP_gN_free(SRP_gN_cache *gN_cache)
+	{
+	if (gN_cache == NULL)
+		return;
+	OPENSSL_free(gN_cache->b64_bn);
+	BN_free(gN_cache->bn);
+	OPENSSL_free(gN_cache);
+	}
+
+static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
+	{
+	int i;
+
+	SRP_gN *gN;
+	if (gN_tab != NULL) 
+	for(i = 0; i < sk_SRP_gN_num(gN_tab); i++)
+		{
+		gN = sk_SRP_gN_value(gN_tab, i);
+		if (gN && (id == NULL || strcmp(gN->id,id)==0))
+			return gN;
+		}
+	
+	return SRP_get_default_gN(id);
+	}
+
+static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
+	{
+	int i;
+	if (gN_cache == NULL)
+		return NULL;
+
+	/* search if we have already one... */
+	for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++)
+		{
+		SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
+		if (strcmp(cache->b64_bn,ch)==0)
+			return cache->bn;
+		}
+		{		/* it is the first time that we find it */
+		SRP_gN_cache *newgN = SRP_gN_new_init(ch);
+		if (newgN)
+			{
+			if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0)
+				return newgN->bn;
+			SRP_gN_free(newgN);
+			}
+		}
+	return NULL;
+	}
+
+/* this function parses verifier file. Format is:
+ * string(index):base64(N):base64(g):0
+ * string(username):base64(v):base64(salt):int(index)
+ */
+
+
+int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
+	{
+	int error_code ;
+	STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
+	char *last_index = NULL;
+	int i;
+	char **pp;
+
+	SRP_gN *gN = NULL;
+	SRP_user_pwd *user_pwd = NULL ;
+
+	TXT_DB *tmpdb = NULL;
+	BIO *in = BIO_new(BIO_s_file());
+
+	error_code = SRP_ERR_OPEN_FILE;
+
+	if (in == NULL || BIO_read_filename(in,verifier_file) <= 0)
+		goto err;
+
+	error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
+
+	if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL)
+		goto err;
+
+	error_code = SRP_ERR_MEMORY;
+
+
+	if (vb->seed_key)
+		{
+		last_index = SRP_get_default_gN(NULL)->id;
+		}
+	for (i=0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++)
+		{
+		pp=sk_OPENSSL_PSTRING_value(tmpdb->data,i);
+		if (pp[DB_srptype][0] == DB_SRP_INDEX)
+			{
+			/*we add this couple in the internal Stack */
+
+			if ((gN = (SRP_gN *)OPENSSL_malloc(sizeof(SRP_gN))) == NULL) 
+ 				goto err;
+
+			if  (!(gN->id = BUF_strdup(pp[DB_srpid]))
+	                ||  !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier]))
+			||  !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt]))
+			||  sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0)
+				goto err;
+
+			gN = NULL;
+
+			if (vb->seed_key != NULL)
+				{
+				last_index = pp[DB_srpid];
+				}
+			}
+		else if (pp[DB_srptype][0] == DB_SRP_VALID)
+			{
+			/* it is a user .... */
+			SRP_gN *gN;
+			if ((gN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL)
+				{
+				error_code = SRP_ERR_MEMORY;
+				if ((user_pwd = SRP_user_pwd_new()) == NULL) 
+					goto err;
+				
+				SRP_user_pwd_set_gN(user_pwd,gN->g,gN->N);
+				if (!SRP_user_pwd_set_ids(user_pwd, pp[DB_srpid],
+										  pp[DB_srpinfo]))
+					goto err;
+				
+				error_code = SRP_ERR_VBASE_BN_LIB;
+				if (!SRP_user_pwd_set_sv(user_pwd, pp[DB_srpsalt],
+										 pp[DB_srpverifier]))
+					goto err;
+
+				if (sk_SRP_user_pwd_insert(vb->users_pwd,user_pwd,0) == 0)
+					goto err;
+				user_pwd = NULL; /* abandon responsability */
+				}
+			}
+		}
+	
+	if (last_index != NULL)
+		{
+		/* this means that we want to simulate a default user */
+
+		if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL))
+			{
+			error_code = SRP_ERR_VBASE_BN_LIB;
+			goto err;
+			}
+		vb->default_g = gN->g ;
+		vb->default_N = gN->N ;
+		gN = NULL ;
+		}
+	error_code = SRP_NO_ERROR;
+
+ err:
+	/* there may be still some leaks to fix, if this fails, the application terminates most likely */
+
+	if (gN != NULL)
+		{
+		OPENSSL_free(gN->id);
+		OPENSSL_free(gN);
+		}
+
+	SRP_user_pwd_free(user_pwd);
+
+	if (tmpdb) TXT_DB_free(tmpdb);
+	if (in) BIO_free_all(in);
+
+	sk_SRP_gN_free(SRP_gN_tab);
+
+	return error_code;
+
+	}
+
+
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+	{
+	int i;
+	SRP_user_pwd *user;
+	unsigned char digv[SHA_DIGEST_LENGTH];
+	unsigned char digs[SHA_DIGEST_LENGTH];
+	EVP_MD_CTX ctxt;
+
+	if (vb == NULL)
+		return NULL;
+	for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++)
+		{
+		user = sk_SRP_user_pwd_value(vb->users_pwd, i);
+		if (strcmp(user->id,username)==0)
+			return user;
+		}
+	if ((vb->seed_key == NULL) ||
+		(vb->default_g == NULL) ||
+		(vb->default_N == NULL))
+		return NULL;
+
+/* if the user is unknown we set parameters as well if we have a seed_key */
+
+	if ((user = SRP_user_pwd_new()) == NULL) 
+		return NULL;
+
+	SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N);
+				
+	if (!SRP_user_pwd_set_ids(user,username,NULL))
+		goto err;
+		
+	RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH);
+	EVP_MD_CTX_init(&ctxt);
+	EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
+	EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
+	EVP_DigestUpdate(&ctxt, username, strlen(username));
+	EVP_DigestFinal_ex(&ctxt, digs, NULL);
+	EVP_MD_CTX_cleanup(&ctxt);
+	if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL))) 
+		return user;
+
+err:    SRP_user_pwd_free(user);
+	return NULL;
+	}
+
+
+/*
+   create a verifier (*salt,*verifier,g and N are in base64)
+*/
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+						  char **verifier, const char *N, const char *g)
+	{
+	int len;
+	char * result=NULL;
+	char *vf;
+	BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
+	unsigned char tmp[MAX_LEN];
+	unsigned char tmp2[MAX_LEN];
+	char * defgNid = NULL;
+
+	if ((user == NULL)||
+		(pass == NULL)||
+		(salt == NULL)||
+		(verifier == NULL))
+		goto err;
+
+	if (N)
+		{
+		if (!(len = t_fromb64(tmp, N))) goto err;
+		N_bn = BN_bin2bn(tmp,len,NULL);
+		if (!(len = t_fromb64(tmp, g))) goto err;
+		g_bn = BN_bin2bn(tmp, len, NULL);
+		defgNid = "*";
+		}
+	else
+		{ 
+		SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ;
+		if (gN == NULL)
+			goto err;
+		N_bn = gN->N;
+		g_bn = gN->g;
+		defgNid = gN->id;
+		}
+
+	if (*salt == NULL)
+		{
+		RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
+
+		s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
+		}
+	else
+		{
+		if (!(len = t_fromb64(tmp2, *salt)))
+			goto err;
+		s = BN_bin2bn(tmp2,len,NULL);
+		}
+
+
+	if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err;
+
+	BN_bn2bin(v,tmp);
+	if (((vf = OPENSSL_malloc(BN_num_bytes(v)*2)) == NULL))
+		goto err;
+	t_tob64(vf, tmp, BN_num_bytes(v));
+
+	*verifier = vf;
+	if (*salt == NULL)
+		{
+		char *tmp_salt;
+
+		if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN*2)) == NULL)
+			{
+			OPENSSL_free(vf);
+			goto err;
+			}
+		t_tob64(tmp_salt,tmp2,SRP_RANDOM_SALT_LEN);
+		*salt = tmp_salt;
+		}
+
+	result=defgNid;
+
+err:
+	if(N)
+		{
+		BN_free(N_bn);
+		BN_free(g_bn);
+		}
+	return result;
+	}
+
+/*
+   create a verifier (*salt,*verifier,g and N are BIGNUMs)
+*/
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g)
+	{
+	int result=0;
+	BIGNUM *x = NULL;
+	BN_CTX *bn_ctx = BN_CTX_new();
+	unsigned char tmp2[MAX_LEN];
+
+	if ((user == NULL)||
+		(pass == NULL)||
+		(salt == NULL)||
+		(verifier == NULL)||
+		(N == NULL)||
+		(g == NULL)||
+		(bn_ctx == NULL))
+		goto err;
+
+	srp_bn_print(N);
+	srp_bn_print(g);
+
+	if (*salt == NULL)
+		{
+		RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN);
+
+		*salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL);
+		}
+
+	x = SRP_Calc_x(*salt,user,pass);
+
+	*verifier = BN_new();
+	if(*verifier == NULL) goto err;
+
+	if (!BN_mod_exp(*verifier,g,x,N,bn_ctx))
+		{
+		BN_clear_free(*verifier);
+		goto err;
+		}
+
+	srp_bn_print(*verifier);
+
+	result=1;
+
+err:
+
+	BN_clear_free(x);
+	BN_CTX_free(bn_ctx);
+	return result;
+	}
+
+
+
+#endif
diff --git a/crypto/srp/srptest.c b/crypto/srp/srptest.c
new file mode 100644
index 0000000..04b66b4
--- /dev/null
+++ b/crypto/srp/srptest.c
@@ -0,0 +1,162 @@
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_SRP
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+	{
+	printf("No SRP support\n");
+	return(0);
+	}
+
+#else
+
+#include <openssl/srp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+static void showbn(const char *name, const BIGNUM *bn)
+	{
+	fputs(name, stdout);
+	fputs(" = ", stdout);
+	BN_print_fp(stdout, bn);
+	putc('\n', stdout);
+	}
+
+#define RANDOM_SIZE 32	/* use 256 bits on each side */
+
+static int run_srp(const char *username, const char *client_pass, const char *server_pass)
+	{
+	int ret=-1;
+	BIGNUM *s = NULL;
+	BIGNUM *v = NULL;
+	BIGNUM *a = NULL;
+	BIGNUM *b = NULL;
+	BIGNUM *u = NULL;
+	BIGNUM *x = NULL;
+	BIGNUM *Apub = NULL;
+	BIGNUM *Bpub = NULL;
+	BIGNUM *Kclient = NULL;
+	BIGNUM *Kserver = NULL;
+	unsigned char rand_tmp[RANDOM_SIZE];
+	/* use builtin 1024-bit params */
+	SRP_gN *GN = SRP_get_default_gN("1024");
+
+	if(GN == NULL)
+		{
+		fprintf(stderr, "Failed to get SRP parameters\n");
+		return -1;
+		}
+	/* Set up server's password entry */
+	if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g))
+		{
+		fprintf(stderr, "Failed to create SRP verifier\n");
+		return -1;
+		}
+
+	showbn("N", GN->N);
+	showbn("g", GN->g);
+	showbn("Salt", s);
+	showbn("Verifier", v);
+
+	/* Server random */
+	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
+	b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
+	/* TODO - check b != 0 */
+	showbn("b", b);
+
+	/* Server's first message */
+	Bpub = SRP_Calc_B(b, GN->N, GN->g, v);
+	showbn("B", Bpub);
+
+	if(!SRP_Verify_B_mod_N(Bpub, GN->N))
+		{
+		fprintf(stderr, "Invalid B\n");
+		return -1;
+		}
+
+	/* Client random */
+	RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp));
+	a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL);
+	/* TODO - check a != 0 */
+	showbn("a", a);
+
+	/* Client's response */
+	Apub = SRP_Calc_A(a, GN->N, GN->g);
+	showbn("A", Apub);
+
+	if(!SRP_Verify_A_mod_N(Apub, GN->N))
+		{
+		fprintf(stderr, "Invalid A\n");
+		return -1;
+		}
+
+	/* Both sides calculate u */
+	u = SRP_Calc_u(Apub, Bpub, GN->N);
+
+	/* Client's key */
+	x = SRP_Calc_x(s, username, client_pass);
+	Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u);
+	showbn("Client's key", Kclient);
+
+	/* Server's key */
+	Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N);
+	showbn("Server's key", Kserver);
+
+	if(BN_cmp(Kclient, Kserver) == 0)
+		{
+		ret = 0;
+		}
+	else
+		{
+		fprintf(stderr, "Keys mismatch\n");
+		ret = 1;
+		}
+
+	BN_clear_free(Kclient);
+	BN_clear_free(Kserver);
+	BN_clear_free(x);
+	BN_free(u);
+	BN_free(Apub);
+	BN_clear_free(a);
+	BN_free(Bpub);
+	BN_clear_free(b);
+	BN_free(s);
+	BN_clear_free(v);
+
+	return ret;
+	}
+
+int main(int argc, char **argv)
+	{
+	BIO *bio_err;
+	bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	CRYPTO_malloc_debug_init();
+	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+	ERR_load_crypto_strings();
+
+	/* "Negative" test, expect a mismatch */
+	if(run_srp("alice", "password1", "password2") == 0)
+		{
+		fprintf(stderr, "Mismatched SRP run failed\n");
+		return 1;
+		}
+
+	/* "Positive" test, should pass */
+	if(run_srp("alice", "password", "password") != 0)
+		{
+		fprintf(stderr, "Plain SRP run failed\n");
+		return 1;
+		}
+
+	CRYPTO_cleanup_all_ex_data();
+	ERR_remove_thread_state(NULL);
+	ERR_free_strings();
+	CRYPTO_mem_leaks(bio_err);
+
+	return 0;
+	}
+#endif
diff --git a/crypto/stack/safestack.h b/crypto/stack/safestack.h
index a8ebb75..7c5ebe0 100644
--- a/crypto/stack/safestack.h
+++ b/crypto/stack/safestack.h
@@ -1459,6 +1459,66 @@
 #define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
 #define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
 
+#define sk_SRP_gN_new(st) SKM_sk_new(SRP_gN, (st))
+#define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN)
+#define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st))
+#define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st))
+#define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i))
+#define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val))
+#define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st))
+#define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val))
+#define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val))
+#define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val))
+#define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i))
+#define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr))
+#define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i))
+#define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp))
+#define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st)
+#define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func))
+#define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st))
+#define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st))
+#define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st))
+
+#define sk_SRP_gN_cache_new(st) SKM_sk_new(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache)
+#define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i))
+#define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val))
+#define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val))
+#define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i))
+#define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr))
+#define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i))
+#define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp))
+#define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st)
+#define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func))
+#define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st))
+#define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st))
+
+#define sk_SRP_user_pwd_new(st) SKM_sk_new(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd)
+#define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i))
+#define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val))
+#define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val))
+#define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i))
+#define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr))
+#define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i))
+#define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp))
+#define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st)
+#define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func))
+#define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st))
+#define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st))
+
 #define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp))
 #define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
 #define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
diff --git a/ssl/Makefile b/ssl/Makefile
index 1c73dcc..f046035 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -30,7 +30,7 @@
 	ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
 	ssl_ciph.c ssl_stat.c ssl_rsa.c \
 	ssl_asn1.c ssl_txt.c ssl_algs.c \
-	bio_ssl.c ssl_err.c kssl.c t1_reneg.c
+	bio_ssl.c ssl_err.c kssl.c t1_reneg.c tls_srp.c
 LIBOBJ= \
 	s2_meth.o  s2_srvr.o  s2_clnt.o  s2_lib.o  s2_enc.o s2_pkt.o \
 	s3_meth.o  s3_srvr.o  s3_clnt.o  s3_lib.o  s3_enc.o s3_pkt.o s3_both.o \
@@ -41,7 +41,7 @@
 	ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
 	ssl_ciph.o ssl_stat.o ssl_rsa.o \
 	ssl_asn1.o ssl_txt.o ssl_algs.o \
-	bio_ssl.o ssl_err.o kssl.o t1_reneg.o
+	bio_ssl.o ssl_err.o kssl.o t1_reneg.o tls_srp.o
 
 SRC= $(LIBSRC)
 
@@ -163,7 +163,7 @@
 d1_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
 d1_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 d1_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_clnt.o: ../include/openssl/x509_vfy.h d1_clnt.c kssl_lcl.h ssl_locl.h
+d1_clnt.o: ../include/openssl/x509_vfy.h d1_clnt.c ssl_locl.h
 d1_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 d1_enc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
 d1_enc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -625,20 +625,19 @@
 s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
 s3_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
-s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
-s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
-s3_srvr.o: s3_srvr.c ssl_locl.h
+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/pqueue.h
+s3_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+s3_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
 ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssl_algs.o: ../include/openssl/buffer.h ../include/openssl/comp.h
 ssl_algs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
@@ -974,3 +973,24 @@
 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
+tls_srp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+tls_srp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+tls_srp.o: ../include/openssl/comp.h ../include/openssl/crypto.h
+tls_srp.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+tls_srp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+tls_srp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+tls_srp.o: ../include/openssl/err.h ../include/openssl/evp.h
+tls_srp.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+tls_srp.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+tls_srp.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+tls_srp.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+tls_srp.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+tls_srp.o: ../include/openssl/pkcs7.h ../include/openssl/pqueue.h
+tls_srp.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+tls_srp.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+tls_srp.o: ../include/openssl/srp.h ../include/openssl/ssl.h
+tls_srp.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+tls_srp.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+tls_srp.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+tls_srp.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+tls_srp.o: tls_srp.c
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index fe33013..e0b9d91 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -278,6 +278,20 @@
 		case SSL3_ST_CR_SRVR_HELLO_A:
 		case SSL3_ST_CR_SRVR_HELLO_B:
 			ret=ssl3_get_server_hello(s);
+#ifndef OPENSSL_NO_SRP
+			if ((ret == 0) && (s->s3->warn_alert == SSL_AD_MISSING_SRP_USERNAME))
+				{
+				if (!SRP_have_to_put_srp_username(s))
+					{
+					SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_MISSING_SRP_USERNAME);
+					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_USER_CANCELLED);
+					goto end;
+					}
+				s->state=SSL3_ST_CW_CLNT_HELLO_A;
+				if (!ssl_init_wbio_buffer(s,0)) { ret= -1; goto end; }
+				break;
+				}
+#endif
 			if (ret <= 0) goto end;
 
 			if (s->hit)
@@ -359,6 +373,17 @@
 		case SSL3_ST_CR_SRVR_DONE_B:
 			ret=ssl3_get_server_done(s);
 			if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_SRP
+			if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP)
+				{
+				if ((ret = SRP_Calc_A_param(s))<=0)
+					{
+					SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_SRP_A_CALC);
+					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+					goto end;
+					}
+				}
+#endif
 			if (s->s3->tmp.cert_req)
 				s->state=SSL3_ST_CW_CERT_A;
 			else
@@ -1301,6 +1326,86 @@
 		}
 	else
 #endif /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+	if (alg_k & SSL_kSRP)
+		{
+		n2s(p,i);
+		param_len=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_N_LENGTH);
+			goto f_err;
+			}
+		if (!(s->srp_ctx.N=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+
+		n2s(p,i);
+		param_len+=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_G_LENGTH);
+			goto f_err;
+			}
+		if (!(s->srp_ctx.g=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+
+		i = (unsigned int)(p[0]);
+		p++;
+		param_len+=i+1;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_S_LENGTH);
+			goto f_err;
+			}
+		if (!(s->srp_ctx.s=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+
+		n2s(p,i);
+		param_len+=i+2;
+		if (param_len > n)
+			{
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_B_LENGTH);
+			goto f_err;
+			}
+		if (!(s->srp_ctx.B=BN_bin2bn(p,i,NULL)))
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+			goto err;
+			}
+		p+=i;
+		n-=param_len;
+
+/* We must check if there is a certificate */
+#ifndef OPENSSL_NO_RSA
+		if (alg_a & SSL_aRSA)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
+#else
+		if (0)
+			;
+#endif
+#ifndef OPENSSL_NO_DSA
+		else if (alg_a & SSL_aDSS)
+			pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].x509);
+#endif
+		}
+	else
+#endif /* !OPENSSL_NO_SRP */
 #ifndef OPENSSL_NO_RSA
 	if (alg_k & SSL_kRSA)
 		{
@@ -2570,6 +2675,39 @@
 			EVP_PKEY_free(pub_key);
 
 			}
+#ifndef OPENSSL_NO_SRP
+		else if (alg_k & SSL_kSRP)
+			{
+			if (s->srp_ctx.A != NULL)
+				{
+				/* send off the data */
+				n=BN_num_bytes(s->srp_ctx.A);
+				s2n(n,p);
+				BN_bn2bin(s->srp_ctx.A,p);
+				n+=2;
+				}
+			else
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			if (s->session->srp_username != NULL)
+				OPENSSL_free(s->session->srp_username);
+			s->session->srp_username = BUF_strdup(s->srp_ctx.login);
+			if (s->session->srp_username == NULL)
+				{
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			if ((s->session->master_key_length = SRP_generate_client_master_secret(s,s->session->master_key))<0)
+				{
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+			}
+#endif
 #ifndef OPENSSL_NO_PSK
 		else if (alg_k & SSL_kPSK)
 			{
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 53bf4c2..f3d230b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -2012,6 +2012,152 @@
 	},
 #endif	/* OPENSSL_NO_ECDH */
 
+#ifndef OPENSSL_NO_SRP
+	/* Cipher C01A */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+	TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+	SSL_kSRP,
+	SSL_aNULL,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C01B */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+	TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+	SSL_kSRP,
+	SSL_aRSA,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C01C */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+	TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+	SSL_kSRP,
+	SSL_aDSS,
+	SSL_3DES,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	168,
+	168,
+	},
+
+	/* Cipher C01D */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
+	SSL_kSRP,
+	SSL_aNULL,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C01E */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+	TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+	SSL_kSRP,
+	SSL_aRSA,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C01F */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+	TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+	SSL_kSRP,
+	SSL_aDSS,
+	SSL_AES128,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	128,
+	128,
+	},
+
+	/* Cipher C020 */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
+	SSL_kSRP,
+	SSL_aNULL,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher C021 */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+	TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+	SSL_kSRP,
+	SSL_aRSA,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+
+	/* Cipher C022 */
+	{
+	1,
+	TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+	TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+	SSL_kSRP,
+	SSL_aDSS,
+	SSL_AES256,
+	SSL_SHA1,
+	SSL_TLSV1,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+	256,
+	256,
+	},
+#endif  /* OPENSSL_NO_SRP */
+
 #ifdef TEMP_GOST_TLS
 /* Cipher FF00 */
 	{
@@ -2128,6 +2274,9 @@
 
 	s->s3=s3;
 
+#ifndef OPENSSL_NO_SRP
+	SSL_SRP_CTX_init(s);
+#endif
 	s->method->ssl_clear(s);
 	return(1);
 err:
@@ -2168,6 +2317,9 @@
 		BIO_free(s->s3->handshake_buffer);
 	}
 	if (s->s3->handshake_dgst) ssl3_free_digest_list(s);
+#ifndef OPENSSL_NO_SRP
+	SSL_SRP_CTX_free(s);
+#endif
 	OPENSSL_cleanse(s->s3,sizeof *s->s3);
 	OPENSSL_free(s->s3);
 	s->s3=NULL;
@@ -2241,6 +2393,13 @@
 #endif
 	}
 
+#ifndef OPENSSL_NO_SRP
+static char * MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg)
+	{
+	return BUF_strdup(s->srp_ctx.info) ;
+	}
+#endif
+
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 	{
 	int ret=0;
@@ -2723,6 +2882,38 @@
 		return 1;
 		break;
 
+#ifndef OPENSSL_NO_SRP
+	case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
+		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+		if (ctx->srp_ctx.login != NULL)
+			OPENSSL_free(ctx->srp_ctx.login);
+		ctx->srp_ctx.login = NULL;
+		if (parg == NULL)
+			break;
+		if (strlen((char *)parg) > 254)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
+			return 0;
+			} 
+		if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL)
+			{
+			SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
+			return 0;
+			}
+		break;
+	case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
+		ctx->srp_ctx.SRP_give_srp_client_pwd_callback=srp_password_from_info_cb;
+		ctx->srp_ctx.info=parg;
+		break;
+	case SSL_CTRL_SET_SRP_ARG:
+		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+		ctx->srp_ctx.SRP_cb_arg=parg;
+		break;
+
+	case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
+		ctx->srp_ctx.strength=larg;
+		break;
+#endif
 #endif /* !OPENSSL_NO_TLSEXT */
 
 	/* A Thawte special :-) */
@@ -2792,6 +2983,24 @@
 						HMAC_CTX *, int))fp;
 		break;
 
+#ifndef OPENSSL_NO_SRP
+	case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
+		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+		ctx->srp_ctx.SRP_verify_param_callback=(int (*)(SSL *,void *))fp;
+		break;
+	case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
+		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+		ctx->srp_ctx.TLS_ext_srp_username_callback=(int (*)(SSL *,int *,void *))fp;
+		break;
+	case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
+		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+		ctx->srp_ctx.SRP_give_srp_client_pwd_callback=(char *(*)(SSL *,void *))fp;
+		break;
+	case SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB:
+		ctx->srp_ctx.srp_Mask|=SSL_kSRP;
+		ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback=(char *(*)(SSL *,void *))fp;
+		break;
+#endif
 #endif
 	case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
 		{
@@ -2897,6 +3106,10 @@
 		mask_a = cert->mask_a;
 		emask_k = cert->export_mask_k;
 		emask_a = cert->export_mask_a;
+#ifndef OPENSSL_NO_SRP
+		mask_k=cert->mask_k | s->srp_ctx.srp_Mask;
+		emask_k=cert->export_mask_k | s->srp_ctx.srp_Mask;
+#endif
 			
 #ifdef KSSL_DEBUG
 /*		printf("ssl3_choose_cipher %d alg= %lx\n", i,c->algorithms);*/
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index a168f93..536d094 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -1203,6 +1203,10 @@
 				SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_NO_RENEGOTIATION);
 				goto f_err;
 				}
+#ifdef SSL_AD_MISSING_SRP_USERNAME
+			else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
+				return(0);
+#endif
 			}
 		else if (alert_level == 2) /* fatal */
 			{
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index fed90bc..3a3e7f9 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -180,6 +180,31 @@
 		return(NULL);
 	}
 
+#ifndef OPENSSL_NO_SRP
+static int SSL_check_srp_ext_ClientHello(SSL *s,int *ad)
+	{
+	int ret = SSL_ERROR_NONE;
+
+	*ad = SSL_AD_UNRECOGNIZED_NAME;
+
+	if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
+	    (s->srp_ctx.TLS_ext_srp_username_callback != NULL))
+		{
+		if(s->srp_ctx.login == NULL)
+			{
+			/* There isn't any srp login extension !!! */
+			ret = SSL3_AL_WARNING;
+			*ad = SSL_AD_MISSING_SRP_USERNAME;
+			}
+		else
+			{
+			ret = SSL_srp_server_param_with_username(s,ad);
+			}
+		}
+	return ret;
+	}
+#endif
+
 IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
 			ssl3_accept,
 			ssl_undefined_function,
@@ -192,6 +217,9 @@
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 	int ret= -1;
 	int new_state,state,skip=0;
+#ifndef OPENSSL_NO_SRP
+	int srp_no_username =0;
+#endif
 
 	RAND_add(&Time,sizeof(Time),0);
 	ERR_clear_error();
@@ -312,10 +340,37 @@
 		case SSL3_ST_SR_CLNT_HELLO_A:
 		case SSL3_ST_SR_CLNT_HELLO_B:
 		case SSL3_ST_SR_CLNT_HELLO_C:
+#ifndef OPENSSL_NO_SRP
+		case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME:
+#endif
 
 			s->shutdown=0;
 			ret=ssl3_get_client_hello(s);
 			if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_SRP
+			{
+			int extension_error = 0,al;
+
+			if ((al = SSL_check_srp_ext_ClientHello(s,&extension_error)) != SSL_ERROR_NONE)
+				{
+				ssl3_send_alert(s,al,extension_error);
+				if (extension_error == SSL_AD_MISSING_SRP_USERNAME)
+					{
+					if (srp_no_username) goto end;
+					ERR_clear_error();
+					srp_no_username = 1;
+					s->state=SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME;
+					if (cb != NULL) cb(s,SSL_CB_HANDSHAKE_START,1);
+					if ((ret=BIO_flush(s->wbio)) <= 0) goto end;
+					s->init_num=0;
+					break;
+					}
+				ret = -1;
+				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+				goto end;
+				}
+			}
+#endif
 			
 			s->renegotiate = 2;
 			s->state=SSL3_ST_SW_SRVR_HELLO_A;
@@ -346,7 +401,7 @@
 		case SSL3_ST_SW_CERT_A:
 		case SSL3_ST_SW_CERT_B:
 			/* Check if it is anon DH or anon ECDH, */
-			/* normal PSK or KRB5 */
+			/* normal PSK or KRB5 or SRP */
 			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))
@@ -411,6 +466,10 @@
 #ifndef OPENSSL_NO_PSK
 			    || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
 #endif
+#ifndef OPENSSL_NO_SRP
+			    /* SRP: send ServerKeyExchange */
+			    || (alg_k & SSL_kSRP)
+#endif
 			    || (alg_k & (SSL_kDHr|SSL_kDHd|SSL_kEDH))
 			    || (alg_k & SSL_kEECDH)
 			    || ((alg_k & SSL_kRSA)
@@ -837,7 +896,11 @@
 	 * If we are SSLv3, we will respond with SSLv3, even if prompted with
 	 * TLSv1.
 	 */
-	if (s->state == SSL3_ST_SR_CLNT_HELLO_A)
+	if (s->state == SSL3_ST_SR_CLNT_HELLO_A
+#ifndef OPENSSL_NO_SRP
+		|| (s->state == SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME)
+#endif
+		)
 		{
 		s->state=SSL3_ST_SR_CLNT_HELLO_B;
 		}
@@ -1710,14 +1773,37 @@
 				}
 			else
 #endif /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+		if (type & SSL_kSRP)
+			{
+			if ((s->srp_ctx.N == NULL) ||
+				(s->srp_ctx.g == NULL) ||
+				(s->srp_ctx.s == NULL) ||
+				(s->srp_ctx.B == NULL))
+				{
+				SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_MISSING_SRP_PARAM);
+				goto err;
+				}
+			r[0]=s->srp_ctx.N;
+			r[1]=s->srp_ctx.g;
+			r[2]=s->srp_ctx.s;
+			r[3]=s->srp_ctx.B;
+			}
+		else 
+#endif
 			{
 			al=SSL_AD_HANDSHAKE_FAILURE;
 			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
 			goto f_err;
 			}
-		for (i=0; r[i] != NULL; i++)
+		for (i=0; r[i] != NULL && i<4; i++)
 			{
 			nr[i]=BN_num_bytes(r[i]);
+#ifndef OPENSSL_NO_SRP
+			if ((i == 2) && (type & SSL_kSRP))
+				n+=1+nr[i];
+			else
+#endif
 			n+=2+nr[i];
 			}
 
@@ -1746,8 +1832,16 @@
 		d=(unsigned char *)s->init_buf->data;
 		p= &(d[4]);
 
-		for (i=0; r[i] != NULL; i++)
+		for (i=0; r[i] != NULL && i<4; i++)
 			{
+#ifndef OPENSSL_NO_SRP
+			if ((i == 2) && (type & SSL_kSRP))
+				{
+				*p = nr[i];
+				p++;
+				}
+			else
+#endif
 			s2n(nr[i],p);
 			BN_bn2bin(r[i],p);
 			p+=nr[i];
@@ -2623,6 +2717,44 @@
 			}
 		else
 #endif
+#ifndef OPENSSL_NO_SRP
+		if (alg_k & SSL_kSRP)
+			{
+			int param_len;
+
+			n2s(p,i);
+			param_len=i+2;
+			if (param_len > n)
+				{
+				al=SSL_AD_DECODE_ERROR;
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_A_LENGTH);
+				goto f_err;
+				}
+			if (!(s->srp_ctx.A=BN_bin2bn(p,i,NULL)))
+				{
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
+				goto err;
+				}
+			if (s->session->srp_username != NULL)
+				OPENSSL_free(s->session->srp_username);
+			s->session->srp_username = BUF_strdup(s->srp_ctx.login);
+			if (s->session->srp_username == NULL)
+				{
+				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
+					ERR_R_MALLOC_FAILURE);
+				goto err;
+				}
+
+			if ((s->session->master_key_length = SRP_generate_server_master_secret(s,s->session->master_key))<0)
+				{
+				SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+				goto err;
+				}
+
+			p+=i;
+			}
+		else
+#endif	/* OPENSSL_NO_SRP */
 		if (alg_k & SSL_kGOST) 
 			{
 			int ret = 0;
@@ -2706,7 +2838,7 @@
 	return(1);
 f_err:
 	ssl3_send_alert(s,SSL3_AL_FATAL,al);
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
 err:
 #endif
 #ifndef OPENSSL_NO_ECDH
diff --git a/ssl/ssl.h b/ssl/ssl.h
index e036390..de5027f 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -252,6 +252,7 @@
 #define SSL_TXT_kEECDH		"kEECDH"
 #define SSL_TXT_kPSK            "kPSK"
 #define SSL_TXT_kGOST		"kGOST"
+#define SSL_TXT_kSRP		"kSRP"
 
 #define	SSL_TXT_aRSA		"aRSA"
 #define	SSL_TXT_aDSS		"aDSS"
@@ -275,6 +276,7 @@
 #define SSL_TXT_ECDSA		"ECDSA"
 #define SSL_TXT_KRB5      	"KRB5"
 #define SSL_TXT_PSK             "PSK"
+#define SSL_TXT_SRP		"SRP"
 
 #define SSL_TXT_DES		"DES"
 #define SSL_TXT_3DES		"3DES"
@@ -437,6 +439,7 @@
  *	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
+ *	SRP_username [ 11 ] EXPLICIT OCTET STRING -- optional SRP username
  *	}
  * Look in ssl/ssl_asn1.c for more details
  * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
@@ -516,6 +519,9 @@
 	size_t	tlsext_ticklen;		/* Session ticket length */	
 	long tlsext_tick_lifetime_hint;	/* Session lifetime hint in seconds */
 #endif
+#ifndef OPENSSL_NO_SRP
+	char *srp_username;
+#endif
 	} SSL_SESSION;
 
 
@@ -647,7 +653,42 @@
 #define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
 #define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
 
+#ifndef OPENSSL_NO_SRP
 
+typedef struct srp_ctx_st
+	{
+	/* param for all the callbacks */
+	void *SRP_cb_arg;
+	/* set client Hello login callback */
+	int (*TLS_ext_srp_username_callback)(SSL *, int *, void *);
+	/* set SRP N/g param callback for verification */
+	int (*SRP_verify_param_callback)(SSL *, void *);
+	/* set SRP client passwd callback */
+	char *(*SRP_give_srp_client_pwd_callback)(SSL *, void *);
+	/* set SRP client username callback */
+	char *(*SRP_TLS_ext_missing_srp_client_username_callback)(SSL *, void *);
+
+	char *login;
+	BIGNUM *N,*g,*s,*B,*A;
+	BIGNUM *a,*b,*v;
+	char *info;
+	int strength;
+
+	unsigned long srp_Mask;
+	} SRP_CTX;
+
+/* see tls_srp.c */
+int SSL_SRP_CTX_init(SSL *s);
+int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
+int SSL_SRP_CTX_free(SSL *ctx);
+int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
+int SSL_srp_server_param_with_username(SSL *s, int *ad);
+int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key);
+int SRP_Calc_A_param(SSL *s);
+int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key);
+int SRP_have_to_put_srp_username(SSL *s);
+
+#endif
 
 #if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
 #define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
@@ -895,6 +936,9 @@
 	struct ssl3_buf_freelist_st *wbuf_freelist;
 	struct ssl3_buf_freelist_st *rbuf_freelist;
 #endif
+#ifndef OPENSSL_NO_SRP
+	SRP_CTX srp_ctx; /* ctx for SRP authentication */
+#endif
 	};
 
 #define SSL_SESS_CACHE_OFF			0x0000
@@ -1247,6 +1291,9 @@
 	unsigned char *next_proto_negotiated;
 	unsigned char next_proto_negotiated_len;
 #endif
+#ifndef OPENSSL_NO_SRP
+	SRP_CTX srp_ctx; /* ctx for SRP authentication */
+#endif
 
 #define session_ctx initial_ctx
 #else
@@ -1396,6 +1443,8 @@
 #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_AD_UNKNOWN_SRP_USERNAME	TLS1_AD_UNKNOWN_SRP_USERNAME
+#define SSL_AD_MISSING_SRP_USERNAME	TLS1_AD_MISSING_SRP_USERNAME
 
 #define SSL_ERROR_NONE			0
 #define SSL_ERROR_SSL			1
@@ -1479,6 +1528,15 @@
 #define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP	71
 
 #define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB	72
+
+#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB	75
+#define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB		76
+#define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB		77
+#define SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB		78
+#define SSL_CTRL_SET_SRP_ARG		79
+#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME		80
+#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH		81
+#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD		82
 #endif
 
 #define DTLS_CTRL_GET_TIMEOUT		73
@@ -1684,6 +1742,32 @@
 int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
 int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
 
+#ifndef OPENSSL_NO_SRP
+int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name);
+int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password);
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
+					char *(*cb)(SSL *,void *));
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
+					  int (*cb)(SSL *,void *));
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+				      int (*cb)(SSL *,int *,void *));
+int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
+						  char *(*cb)(SSL *,void *));
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+			     BIGNUM *sa, BIGNUM *v, char *info);
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
+				const char *grp);
+
+BIGNUM *SSL_get_srp_g(SSL *s);
+BIGNUM *SSL_get_srp_N(SSL *s);
+
+char *SSL_get_srp_username(SSL *s);
+char *SSL_get_srp_userinfo(SSL *s);
+#endif
+
 void	SSL_free(SSL *ssl);
 int 	SSL_accept(SSL *ssl);
 int 	SSL_connect(SSL *ssl);
@@ -2083,6 +2167,7 @@
 #define SSL_F_SSL_SET_TRUST				 228
 #define SSL_F_SSL_SET_WFD				 196
 #define SSL_F_SSL_SHUTDOWN				 224
+#define SSL_F_SSL_SRP_CTX_INIT				 293
 #define SSL_F_SSL_UNDEFINED_CONST_FUNCTION		 243
 #define SSL_F_SSL_UNDEFINED_FUNCTION			 197
 #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
@@ -2141,6 +2226,11 @@
 #define SSL_R_BAD_RSA_MODULUS_LENGTH			 121
 #define SSL_R_BAD_RSA_SIGNATURE				 122
 #define SSL_R_BAD_SIGNATURE				 123
+#define SSL_R_BAD_SRP_A_LENGTH				 2096
+#define SSL_R_BAD_SRP_B_LENGTH				 2097
+#define SSL_R_BAD_SRP_G_LENGTH				 2098
+#define SSL_R_BAD_SRP_N_LENGTH				 2099
+#define SSL_R_BAD_SRP_S_LENGTH				 2100
 #define SSL_R_BAD_SSL_FILETYPE				 124
 #define SSL_R_BAD_SSL_SESSION_ID_LENGTH			 125
 #define SSL_R_BAD_STATE					 126
@@ -2157,6 +2247,7 @@
 #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_SRP_TLS_EXT			 2101
 #define SSL_R_CLIENTHELLO_TLSEXT			 226
 #define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
 #define SSL_R_COMPRESSION_DISABLED			 343
@@ -2195,6 +2286,7 @@
 #define SSL_R_INVALID_COMMAND				 280
 #define SSL_R_INVALID_COMPRESSION_ALGORITHM		 341
 #define SSL_R_INVALID_PURPOSE				 278
+#define SSL_R_INVALID_SRP_USERNAME			 2107
 #define SSL_R_INVALID_STATUS_RESPONSE			 328
 #define SSL_R_INVALID_TICKET_KEYS_LENGTH		 325
 #define SSL_R_INVALID_TRUST				 279
@@ -2224,6 +2316,8 @@
 #define SSL_R_MISSING_RSA_CERTIFICATE			 168
 #define SSL_R_MISSING_RSA_ENCRYPTING_CERT		 169
 #define SSL_R_MISSING_RSA_SIGNING_CERT			 170
+#define SSL_R_MISSING_SRP_PARAM				 2103
+#define SSL_R_MISSING_SRP_USERNAME			 2104
 #define SSL_R_MISSING_TMP_DH_KEY			 171
 #define SSL_R_MISSING_TMP_ECDH_KEY			 311
 #define SSL_R_MISSING_TMP_RSA_KEY			 172
@@ -2296,6 +2390,7 @@
 #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_SRP_A_CALC				 2105
 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
 #define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 299
 #define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT		 321
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index 7c0a595..4ff7c80 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -576,6 +576,8 @@
 #define SSL3_ST_SR_CLNT_HELLO_A		(0x110|SSL_ST_ACCEPT)
 #define SSL3_ST_SR_CLNT_HELLO_B		(0x111|SSL_ST_ACCEPT)
 #define SSL3_ST_SR_CLNT_HELLO_C		(0x112|SSL_ST_ACCEPT)
+/* a new state to remember that we have already receive a ClientHello without srp username extension */
+#define SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME (0x1E2|SSL_ST_ACCEPT)
 /* write to client */
 #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
 #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 74c238a..d02c3af 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -115,6 +115,9 @@
 	ASN1_OCTET_STRING psk_identity_hint;
 	ASN1_OCTET_STRING psk_identity;
 #endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+	ASN1_OCTET_STRING srp_username;
+#endif /* OPENSSL_NO_SRP */
 	} SSL_SESSION_ASN1;
 
 int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
@@ -131,6 +134,9 @@
 	unsigned char cbuf;
 	int v11=0;
 #endif
+#ifndef OPENSSL_NO_SRP
+	int v12=0;
+#endif
 	long l;
 	SSL_SESSION_ASN1 a;
 	M_ASN1_I2D_vars(in);
@@ -268,6 +274,14 @@
 		a.psk_identity.data=(unsigned char *)(in->psk_identity);
 		}
 #endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+	if (in->srp_username)
+		{
+		a.srp_username.length=strlen(in->srp_username);
+		a.srp_username.type=V_ASN1_OCTET_STRING;
+		a.srp_username.data=(unsigned char *)(in->srp_username);
+		}
+#endif /* OPENSSL_NO_SRP */
 
 	M_ASN1_I2D_len(&(a.version),		i2d_ASN1_INTEGER);
 	M_ASN1_I2D_len(&(a.ssl_version),	i2d_ASN1_INTEGER);
@@ -308,6 +322,10 @@
 	if (in->psk_identity)
         	M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING,8,v8);
 #endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+	if (in->srp_username)
+        	M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
+#endif /* OPENSSL_NO_SRP */
 
 	M_ASN1_I2D_seq_total();
 
@@ -352,6 +370,10 @@
 	if (in->compress_meth)
         	M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING,11,v11);
 #endif
+#ifndef OPENSSL_NO_SRP
+	if (in->srp_username)
+		M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING,12,v12);
+#endif /* OPENSSL_NO_SRP */
 	M_ASN1_I2D_finish();
 	}
 
@@ -589,5 +611,20 @@
 		}
 #endif
 
+#ifndef OPENSSL_NO_SRP
+	os.length=0;
+	os.data=NULL;
+	M_ASN1_D2I_get_EXP_opt(osp,d2i_ASN1_OCTET_STRING,11);
+	if (os.data)
+		{
+		ret->srp_username = BUF_strndup((char *)os.data, os.length);
+		OPENSSL_free(os.data);
+		os.data = NULL;
+		os.length = 0;
+		}
+	else
+		ret->srp_username=NULL;
+#endif /* OPENSSL_NO_SRP */
+
 	M_ASN1_D2I_Finish(a,SSL_SESSION_free,SSL_F_D2I_SSL_SESSION);
 	}
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index a8ce186..bbab6a9 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -247,6 +247,7 @@
 	{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_kSRP,0,    SSL_kSRP,  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 */
@@ -273,6 +274,7 @@
 	{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},
+	{0,SSL_TXT_SRP,0,     SSL_kSRP,0,0,0,0,0,0,0,0},
 
 
 	/* symmetric encryption aliases */
@@ -661,6 +663,9 @@
 	*mkey |= SSL_kPSK;
 	*auth |= SSL_aPSK;
 #endif
+#ifdef OPENSSL_NO_SRP
+	*mkey |= SSL_kSRP;
+#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")) {
@@ -1511,6 +1516,9 @@
 	case SSL_kPSK:
 		kx="PSK";
 		break;
+	case SSL_kSRP:
+		kx="SRP";
+		break;
 	default:
 		kx="unknown";
 		}
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 414f9d9..492920c 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -251,6 +251,7 @@
 {ERR_FUNC(SSL_F_SSL_SET_TRUST),	"SSL_set_trust"},
 {ERR_FUNC(SSL_F_SSL_SET_WFD),	"SSL_set_wfd"},
 {ERR_FUNC(SSL_F_SSL_SHUTDOWN),	"SSL_shutdown"},
+{ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT),	"SSL_SRP_CTX_INIT"},
 {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION),	"SSL_UNDEFINED_CONST_FUNCTION"},
 {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION),	"SSL_UNDEFINED_FUNCTION"},
 {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION),	"SSL_UNDEFINED_VOID_FUNCTION"},
@@ -312,6 +313,11 @@
 {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH),"bad rsa modulus length"},
 {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE)     ,"bad rsa signature"},
 {ERR_REASON(SSL_R_BAD_SIGNATURE)         ,"bad signature"},
+{ERR_REASON(SSL_R_BAD_SRP_A_LENGTH)      ,"bad srp a length"},
+{ERR_REASON(SSL_R_BAD_SRP_B_LENGTH)      ,"bad srp b length"},
+{ERR_REASON(SSL_R_BAD_SRP_G_LENGTH)      ,"bad srp g length"},
+{ERR_REASON(SSL_R_BAD_SRP_N_LENGTH)      ,"bad srp n length"},
+{ERR_REASON(SSL_R_BAD_SRP_S_LENGTH)      ,"bad srp s length"},
 {ERR_REASON(SSL_R_BAD_SSL_FILETYPE)      ,"bad ssl filetype"},
 {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"},
 {ERR_REASON(SSL_R_BAD_STATE)             ,"bad state"},
@@ -328,6 +334,7 @@
 {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
 {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),"cipher or hash unavailable"},
 {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR),"cipher table src error"},
+{ERR_REASON(SSL_R_CLIENTHELLO_SRP_TLS_EXT),"error with the SRP username"},
 {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"},
@@ -366,6 +373,7 @@
 {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_SRP_USERNAME)  ,"invalid srp username"},
 {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"},
 {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),"invalid ticket keys length"},
 {ERR_REASON(SSL_R_INVALID_TRUST)         ,"invalid trust"},
@@ -395,6 +403,8 @@
 {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE),"missing rsa certificate"},
 {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),"missing rsa encrypting cert"},
 {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT),"missing rsa signing cert"},
+{ERR_REASON(SSL_R_MISSING_SRP_PARAM)     ,"can't find SRP server param"},
+{ERR_REASON(SSL_R_MISSING_SRP_USERNAME)  ,"missing srp username"},
 {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY)    ,"missing tmp dh key"},
 {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY)  ,"missing tmp ecdh key"},
 {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY)   ,"missing tmp rsa key"},
@@ -467,6 +477,7 @@
 {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
 {ERR_REASON(SSL_R_SHORT_READ)            ,"short read"},
 {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
+{ERR_REASON(SSL_R_SRP_A_CALC)            ,"error with the srp params"},
 {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"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index dff6082..7fb4bdf 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1789,6 +1789,9 @@
 	ret->psk_client_callback=NULL;
 	ret->psk_server_callback=NULL;
 #endif
+#ifndef OPENSSL_NO_SRP
+	SSL_CTX_SRP_CTX_init(ret);
+#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));
@@ -1921,6 +1924,9 @@
 	if (a->psk_identity_hint)
 		OPENSSL_free(a->psk_identity_hint);
 #endif
+#ifndef OPENSSL_NO_SRP
+	SSL_CTX_SRP_CTX_free(a);
+#endif
 #ifndef OPENSSL_NO_ENGINE
 	if (a->client_cert_engine)
 		ENGINE_finish(a->client_cert_engine);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 45a567d..444e6f5 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -289,6 +289,7 @@
 #define SSL_kEECDH		0x00000080L /* ephemeral ECDH */
 #define SSL_kPSK		0x00000100L /* PSK */
 #define SSL_kGOST       0x00000200L /* GOST key exchange */
+#define SSL_kSRP        0x00000400L /* SRP */
 
 /* Bits for algorithm_auth (server authentication) */
 #define SSL_aRSA		0x00000001L /* RSA auth */
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 56b9e15..a3ce652 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -218,6 +218,9 @@
 	ss->psk_identity_hint=NULL;
 	ss->psk_identity=NULL;
 #endif
+#ifndef OPENSSL_NO_SRP
+	ss->srp_username=NULL;
+#endif
 	return(ss);
 	}
 
@@ -734,6 +737,10 @@
 	if (ss->psk_identity != NULL)
 		OPENSSL_free(ss->psk_identity);
 #endif
+#ifndef OPENSSL_NO_SRP
+	if (ss->srp_username != NULL)
+		OPENSSL_free(ss->srp_username);
+#endif
 	OPENSSL_cleanse(ss,sizeof(*ss));
 	OPENSSL_free(ss);
 	}
diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c
index 144b81e..2f57296 100644
--- a/ssl/ssl_stat.c
+++ b/ssl/ssl_stat.c
@@ -210,6 +210,9 @@
 case SSL3_ST_SR_KEY_EXCH_B:	str="SSLv3 read client key exchange B"; break;
 case SSL3_ST_SR_CERT_VRFY_A:	str="SSLv3 read certificate verify A"; break;
 case SSL3_ST_SR_CERT_VRFY_B:	str="SSLv3 read certificate verify B"; break;
+#ifndef OPENSSL_NO_SRP
+case SSL3_ST_SR_CLNT_HELLO_SRP_USERNAME:	str="SSLv3 waiting for a SRP username"; break;
+#endif
 #endif
 
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
@@ -547,6 +550,11 @@
 	case TLS1_AD_UNKNOWN_PSK_IDENTITY:
 		str="unknown PSK identity";
 		break;
+#ifndef OPENSSL_NO_SRP
+	case TLS1_AD_MISSING_SRP_USERNAME:
+		str="no srp username";
+		break;
+#endif
 	default: str="unknown"; break;
 		}
 	return(str);
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index cab712b..552ec2b 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -189,6 +189,10 @@
 	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_SRP
+	if (BIO_puts(bp,"\n    SRP username: ") <= 0) goto err;
+	if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) goto err;
+#endif
 #ifndef OPENSSL_NO_TLSEXT
 	if (x->tlsext_tick_lifetime_hint)
 		{
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 79af27b..977e12b 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -181,6 +181,9 @@
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
+#ifndef OPENSSL_NO_SRP
+#include <openssl/srp.h>
+#endif
 #include <openssl/bn.h>
 
 #define _XOPEN_SOURCE_EXTENDED	1 /* Or gethostname won't be declared properly
@@ -246,6 +249,55 @@
 	unsigned int max_psk_len);
 #endif
 
+#ifndef OPENSSL_NO_SRP
+/* SRP client */
+/* This is a context that we pass to all callbacks */
+typedef struct srp_client_arg_st
+	{
+	char *srppassin;
+	char *srplogin;
+	} SRP_CLIENT_ARG;
+
+#define PWD_STRLEN 1024
+
+static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+	{
+	SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
+	return BUF_strdup((char *)srp_client_arg->srppassin);
+	}
+
+static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
+	{
+	SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg;
+	return BUF_strdup(srp_client_arg->srplogin);
+	}
+
+/* SRP server */
+/* This is a context that we pass to SRP server callbacks */
+typedef struct srp_server_arg_st
+	{
+	char *expected_user;
+	char *pass;
+	} SRP_SERVER_ARG;
+
+static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+	{
+	SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg;
+
+	if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0)
+		{
+		fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s));
+		return SSL3_AL_FATAL;
+		}
+	if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0)
+		{
+		*ad = SSL_AD_INTERNAL_ERROR;
+		return SSL3_AL_FATAL;
+		}
+	return SSL_ERROR_NONE;
+	}
+#endif
+
 static BIO *bio_err=NULL;
 static BIO *bio_stdout=NULL;
 
@@ -364,6 +416,10 @@
 #ifndef OPENSSL_NO_PSK
 	fprintf(stderr," -psk arg      - PSK in hex (without 0x)\n");
 #endif
+#ifndef OPENSSL_NO_SRP
+	fprintf(stderr," -srpuser user  - SRP username to use\n");
+	fprintf(stderr," -srppass arg   - password for 'user'\n");
+#endif
 #ifndef OPENSSL_NO_SSL2
 	fprintf(stderr," -ssl2         - use SSLv2\n");
 #endif
@@ -556,6 +612,13 @@
 #ifndef OPENSSL_NO_ECDH
 	EC_KEY *ecdh = NULL;
 #endif
+#ifndef OPENSSL_NO_SRP
+	/* client */
+	int srp_lateuser = 0;
+	SRP_CLIENT_ARG srp_client_arg = {NULL,NULL};
+	/* server */
+	SRP_SERVER_ARG srp_server_arg = {NULL,NULL};
+#endif
 	int no_dhe = 0;
 	int no_ecdhe = 0;
 	int no_psk = 0;
@@ -652,6 +715,20 @@
 			no_psk=1;
 #endif
 			}
+#ifndef OPENSSL_NO_SRP
+		else if (strcmp(*argv,"-srpuser") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv);
+			tls1=1;
+			}
+		else if (strcmp(*argv,"-srppass") == 0)
+			{
+			if (--argc < 1) goto bad;
+			srp_server_arg.pass = srp_client_arg.srppassin= *(++argv);
+			tls1=1;
+			}
+#endif
 		else if	(strcmp(*argv,"-ssl2") == 0)
 			ssl2=1;
 		else if	(strcmp(*argv,"-tls1") == 0)
@@ -1038,6 +1115,28 @@
 			}
 #endif
 		}
+#ifndef OPENSSL_NO_SRP
+        if (srp_client_arg.srplogin)
+		{
+		if (srp_lateuser) 
+			SSL_CTX_set_srp_missing_srp_username_callback(c_ctx,missing_srp_username_callback);
+		else if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin))
+			{
+			BIO_printf(bio_err,"Unable to set SRP username\n");
+			goto end;
+			}
+		SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg);
+		SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb);
+		/*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/
+		}
+
+	if (srp_server_arg.expected_user != NULL)
+		{
+		SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback);
+		SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg);
+		SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb);
+		}
+#endif
 
 #ifndef OPENSSL_NO_NPN
 	if (npn_client)
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index c418d32..8950700 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -1073,6 +1073,9 @@
 	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);
+#ifndef OPENSSL_NO_SRP
+	case SSL_AD_MISSING_SRP_USERNAME:return(TLS1_AD_MISSING_SRP_USERNAME);
+#endif
 #if 0 /* not appropriate for TLS, not used for DTLS */
 	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
 					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 4f8199f..a732200 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -341,6 +341,30 @@
           ret += el;
         }
 
+#ifndef OPENSSL_NO_SRP
+#define MIN(x,y) (((x)<(y))?(x):(y))
+	/* we add SRP username the first time only if we have one! */
+	if (s->srp_ctx.login != NULL)
+		{/* Add TLS extension SRP username to the Client Hello message */
+		int login_len = MIN(strlen(s->srp_ctx.login) + 1, 255);
+		long lenmax; 
+
+		if ((lenmax = limit - ret - 5) < 0) return NULL; 
+		if (login_len > lenmax) return NULL;
+		if (login_len > 255)
+			{
+			SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+			return NULL;
+			}
+		s2n(TLSEXT_TYPE_srp,ret);
+		s2n(login_len+1,ret);
+
+		(*ret++) = (unsigned char) MIN(strlen(s->srp_ctx.login), 254);
+		memcpy(ret, s->srp_ctx.login, MIN(strlen(s->srp_ctx.login), 254));
+		ret+=login_len;
+		}
+#endif
+
 #ifndef OPENSSL_NO_EC
 	if (s->tlsext_ecpointformatlist != NULL &&
 	    s->version != DTLS1_VERSION)
@@ -799,6 +823,19 @@
 				}
 
 			}
+#ifndef OPENSSL_NO_SRP
+		else if (type == TLSEXT_TYPE_srp)
+			{
+			if (size > 0)
+				{
+				len = data[0];
+				if ((s->srp_ctx.login = OPENSSL_malloc(len+1)) == NULL)
+					return -1;
+				memcpy(s->srp_ctx.login, &data[1], len);
+				s->srp_ctx.login[len]='\0';  
+				}
+			}
+#endif
 
 #ifndef OPENSSL_NO_EC
 		else if (type == TLSEXT_TYPE_ec_point_formats &&
diff --git a/ssl/tls1.h b/ssl/tls1.h
index 0a8d4f7..6f8bb88 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -186,6 +186,8 @@
 #define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
 #define TLS1_AD_UNKNOWN_PSK_IDENTITY	115	/* fatal */
+#define TLS1_AD_UNKNOWN_SRP_USERNAME 120 /* fatal */
+#define TLS1_AD_MISSING_SRP_USERNAME 121
 
 /* ExtensionType values from RFC3546 / RFC4366 */
 #define TLSEXT_TYPE_server_name			0
@@ -197,6 +199,8 @@
 /* ExtensionType values from RFC4492 */
 #define TLSEXT_TYPE_elliptic_curves		10
 #define TLSEXT_TYPE_ec_point_formats		11
+/* ExtensionType value from RFC5054 */
+#define TLSEXT_TYPE_srp				12
 #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 ,
@@ -385,6 +389,17 @@
 #define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
 #define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
 
+/* SRP ciphersuites from RFC 5054 */
+#define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA		0x0300C01A
+#define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA	0x0300C01B
+#define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA	0x0300C01C
+#define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA		0x0300C01D
+#define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA	0x0300C01E
+#define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA	0x0300C01F
+#define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA		0x0300C020
+#define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA	0x0300C021
+#define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA	0x0300C022
+
 /* XXX
  * Inconsistency alert:
  * The OpenSSL names of ciphers with ephemeral DH here include the string
@@ -452,6 +467,17 @@
 #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"
 
+/* SRP ciphersuite from RFC 5054 */
+#define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA		"SRP-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA	"SRP-RSA-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA	"SRP-DSS-3DES-EDE-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA		"SRP-AES-128-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA	"SRP-RSA-AES-128-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA	"SRP-DSS-AES-128-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA		"SRP-AES-256-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA	"SRP-RSA-AES-256-CBC-SHA"
+#define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA	"SRP-DSS-AES-256-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"
diff --git a/ssl/tls_srp.c b/ssl/tls_srp.c
new file mode 100644
index 0000000..de5ee99
--- /dev/null
+++ b/ssl/tls_srp.c
@@ -0,0 +1,529 @@
+/* ssl/tls_srp.c */
+/* Written by Christophe Renou (christophe.renou@edelweb.fr) with 
+ * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) 
+ * for the EdelKey project and contributed to the OpenSSL project 2004.
+ */
+/* ====================================================================
+ * Copyright (c) 2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include "ssl_locl.h"
+#ifndef OPENSSL_NO_SRP
+
+#include <openssl/rand.h>
+#include <openssl/srp.h>
+#include <openssl/err.h>
+
+int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
+	{
+	if (ctx == NULL)
+		return 0;
+	OPENSSL_free(ctx->srp_ctx.login);
+	BN_free(ctx->srp_ctx.N);
+	BN_free(ctx->srp_ctx.g);
+	BN_free(ctx->srp_ctx.s);
+	BN_free(ctx->srp_ctx.B);
+	BN_free(ctx->srp_ctx.A);
+	BN_free(ctx->srp_ctx.a);
+	BN_free(ctx->srp_ctx.b);
+	BN_free(ctx->srp_ctx.v);
+	ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+	ctx->srp_ctx.SRP_cb_arg = NULL;
+	ctx->srp_ctx.SRP_verify_param_callback = NULL;
+	ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+	ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
+	ctx->srp_ctx.N = NULL;
+	ctx->srp_ctx.g = NULL;
+	ctx->srp_ctx.s = NULL;
+	ctx->srp_ctx.B = NULL;
+	ctx->srp_ctx.A = NULL;
+	ctx->srp_ctx.a = NULL;
+	ctx->srp_ctx.b = NULL;
+	ctx->srp_ctx.v = NULL;
+	ctx->srp_ctx.login = NULL;
+	ctx->srp_ctx.info = NULL;
+	ctx->srp_ctx.strength = SRP_MINIMAL_N;
+	ctx->srp_ctx.srp_Mask = 0;
+	return (1);
+	}
+
+int SSL_SRP_CTX_free(struct ssl_st *s)
+	{
+	if (s == NULL)
+		return 0;
+	OPENSSL_free(s->srp_ctx.login);
+	BN_free(s->srp_ctx.N);
+	BN_free(s->srp_ctx.g);
+	BN_free(s->srp_ctx.s);
+	BN_free(s->srp_ctx.B);
+	BN_free(s->srp_ctx.A);
+	BN_free(s->srp_ctx.a);
+	BN_free(s->srp_ctx.b);
+	BN_free(s->srp_ctx.v);
+	s->srp_ctx.TLS_ext_srp_username_callback = NULL;
+	s->srp_ctx.SRP_cb_arg = NULL;
+	s->srp_ctx.SRP_verify_param_callback = NULL;
+	s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+	s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
+	s->srp_ctx.N = NULL;
+	s->srp_ctx.g = NULL;
+	s->srp_ctx.s = NULL;
+	s->srp_ctx.B = NULL;
+	s->srp_ctx.A = NULL;
+	s->srp_ctx.a = NULL;
+	s->srp_ctx.b = NULL;
+	s->srp_ctx.v = NULL;
+	s->srp_ctx.login = NULL;
+	s->srp_ctx.info = NULL;
+	s->srp_ctx.strength = SRP_MINIMAL_N;
+	s->srp_ctx.srp_Mask = 0;
+	return (1);
+	}
+
+int SSL_SRP_CTX_init(struct ssl_st *s)
+	{
+	SSL_CTX *ctx;
+
+	if ((s == NULL) || ((ctx = s->ctx) == NULL))
+		return 0;
+	s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
+	/* set client Hello login callback */
+	s->srp_ctx.TLS_ext_srp_username_callback = ctx->srp_ctx.TLS_ext_srp_username_callback;
+	/* set SRP N/g param callback for verification */
+	s->srp_ctx.SRP_verify_param_callback = ctx->srp_ctx.SRP_verify_param_callback;
+	/* set SRP client passwd callback */
+	s->srp_ctx.SRP_give_srp_client_pwd_callback = ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
+	s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback;
+
+	s->srp_ctx.N = NULL;
+	s->srp_ctx.g = NULL;
+	s->srp_ctx.s = NULL;
+	s->srp_ctx.B = NULL;
+	s->srp_ctx.A = NULL;
+	s->srp_ctx.a = NULL;
+	s->srp_ctx.b = NULL;
+	s->srp_ctx.v = NULL;
+	s->srp_ctx.login = NULL;
+	s->srp_ctx.info = ctx->srp_ctx.info;
+	s->srp_ctx.strength = ctx->srp_ctx.strength;
+
+	if (((ctx->srp_ctx.N != NULL) &&
+		 ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
+		((ctx->srp_ctx.g != NULL) &&
+		 ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
+		((ctx->srp_ctx.s != NULL) &&
+		 ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
+		((ctx->srp_ctx.B != NULL) &&
+		 ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
+		((ctx->srp_ctx.A != NULL) &&
+		 ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
+		((ctx->srp_ctx.a != NULL) &&
+		 ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
+		((ctx->srp_ctx.v != NULL) &&
+		 ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
+		((ctx->srp_ctx.b != NULL) &&
+		 ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL)))
+		{
+		SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_BN_LIB);
+		goto err;
+		}
+	if ((ctx->srp_ctx.login != NULL) && 
+		((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL))
+		{
+		SSLerr(SSL_F_SSL_SRP_CTX_INIT,ERR_R_INTERNAL_ERROR);
+		goto err;
+		}
+	s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
+
+	return (1);
+err:
+	OPENSSL_free(s->srp_ctx.login);
+	BN_free(s->srp_ctx.N);
+	BN_free(s->srp_ctx.g);
+	BN_free(s->srp_ctx.s);
+	BN_free(s->srp_ctx.B);
+	BN_free(s->srp_ctx.A);
+	BN_free(s->srp_ctx.a);
+	BN_free(s->srp_ctx.b);
+	BN_free(s->srp_ctx.v);
+	return (0);
+	}
+
+int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
+	{
+	if (ctx == NULL)
+		return 0;
+
+	ctx->srp_ctx.SRP_cb_arg = NULL;
+	/* set client Hello login callback */
+	ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+	/* set SRP N/g param callback for verification */
+	ctx->srp_ctx.SRP_verify_param_callback = NULL;
+	/* set SRP client passwd callback */
+	ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+	ctx->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback = NULL;
+
+	ctx->srp_ctx.N = NULL;
+	ctx->srp_ctx.g = NULL;
+	ctx->srp_ctx.s = NULL;
+	ctx->srp_ctx.B = NULL;
+	ctx->srp_ctx.A = NULL;
+	ctx->srp_ctx.a = NULL;
+	ctx->srp_ctx.b = NULL;
+	ctx->srp_ctx.v = NULL;
+	ctx->srp_ctx.login = NULL;
+	ctx->srp_ctx.srp_Mask = 0;
+	ctx->srp_ctx.info = NULL;
+	ctx->srp_ctx.strength = SRP_MINIMAL_N;
+
+	return (1);
+	}
+
+/* server side */
+int SSL_srp_server_param_with_username(SSL *s, int *ad)
+	{
+	unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
+	int al;
+
+	*ad = SSL_AD_UNKNOWN_SRP_USERNAME;
+	if ((s->srp_ctx.TLS_ext_srp_username_callback !=NULL) &&
+		((al = s->srp_ctx.TLS_ext_srp_username_callback(s, ad, s->srp_ctx.SRP_cb_arg))!=SSL_ERROR_NONE))
+			return al;
+
+	*ad = SSL_AD_INTERNAL_ERROR;
+	if ((s->srp_ctx.N == NULL) ||
+		(s->srp_ctx.g == NULL) ||
+		(s->srp_ctx.s == NULL) ||
+		(s->srp_ctx.v == NULL))
+		return SSL3_AL_FATAL;
+
+	if (RAND_bytes(b, sizeof(b)) <= 0)
+		return SSL3_AL_FATAL;
+	s->srp_ctx.b = BN_bin2bn(b,sizeof(b),NULL);
+	OPENSSL_cleanse(b,sizeof(b));
+
+	/* Calculate:  B = (kv + g^b) % N  */
+
+	return ((s->srp_ctx.B = SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, s->srp_ctx.v)) != NULL)?
+			SSL_ERROR_NONE:SSL3_AL_FATAL;
+	}
+
+/* If the server just has the raw password, make up a verifier entry on the fly */
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, const char *grp)
+	{
+	SRP_gN *GN = SRP_get_default_gN(grp);
+	if(GN == NULL) return -1;
+	s->srp_ctx.N = BN_dup(GN->N);
+	s->srp_ctx.g = BN_dup(GN->g);
+	if(s->srp_ctx.v != NULL)
+		{
+		BN_clear_free(s->srp_ctx.v);
+		s->srp_ctx.v = NULL;
+		}
+	if(s->srp_ctx.s != NULL)
+		{
+		BN_clear_free(s->srp_ctx.s);
+		s->srp_ctx.s = NULL;
+		}
+	if(!SRP_create_verifier_BN(user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) return -1;
+
+	return 1;
+	}
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+			     BIGNUM *sa, BIGNUM *v, char *info)
+	{
+	if (N!= NULL)
+		{
+		if (s->srp_ctx.N != NULL)
+			{
+			if (!BN_copy(s->srp_ctx.N,N))
+				{
+				BN_free(s->srp_ctx.N);
+				s->srp_ctx.N = NULL;
+				}
+			}
+		else
+			s->srp_ctx.N = BN_dup(N);
+		}
+	if (g!= NULL)
+		{
+		if (s->srp_ctx.g != NULL)
+			{
+			if (!BN_copy(s->srp_ctx.g,g))
+				{
+				BN_free(s->srp_ctx.g);
+				s->srp_ctx.g = NULL;
+				}
+			}
+		else
+			s->srp_ctx.g = BN_dup(g);
+		}
+	if (sa!= NULL)
+		{
+		if (s->srp_ctx.s != NULL)
+			{
+			if (!BN_copy(s->srp_ctx.s,sa))
+				{
+				BN_free(s->srp_ctx.s);
+				s->srp_ctx.s = NULL;
+				}
+			}
+		else
+			s->srp_ctx.s = BN_dup(sa);
+		}
+	if (v!= NULL)
+		{
+		if (s->srp_ctx.v != NULL)
+			{
+			if (!BN_copy(s->srp_ctx.v,v))
+				{
+				BN_free(s->srp_ctx.v);
+				s->srp_ctx.v = NULL;
+				}
+			}
+		else
+			s->srp_ctx.v = BN_dup(v);
+		}
+	s->srp_ctx.info = info;
+
+	if (!(s->srp_ctx.N) ||
+		!(s->srp_ctx.g) ||
+		!(s->srp_ctx.s) ||
+		!(s->srp_ctx.v))
+		return -1;
+
+	return 1;
+	}
+
+int SRP_generate_server_master_secret(SSL *s,unsigned char *master_key)
+	{
+	BIGNUM *K = NULL, *u = NULL;
+	int ret = -1, tmp_len;
+	unsigned char *tmp = NULL;
+
+	if (!SRP_Verify_A_mod_N(s->srp_ctx.A,s->srp_ctx.N))
+		goto err;
+	if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N)))
+		goto err;
+	if (!(K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, s->srp_ctx.N)))
+		goto err;
+
+	tmp_len = BN_num_bytes(K);
+	if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
+		goto err;
+	BN_bn2bin(K, tmp);
+	ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
+err:
+	if (tmp)
+		{
+		OPENSSL_cleanse(tmp,tmp_len) ;
+		OPENSSL_free(tmp);
+		}
+	BN_clear_free(K);
+	BN_clear_free(u);
+	return ret;
+	}
+
+/* client side */
+int SRP_generate_client_master_secret(SSL *s,unsigned char *master_key)
+	{
+	BIGNUM *x = NULL, *u = NULL, *K = NULL;
+	int ret = -1, tmp_len;
+	char *passwd = NULL;
+	unsigned char *tmp = NULL;
+
+	/* Checks if b % n == 0
+	 */
+	if (SRP_Verify_B_mod_N(s->srp_ctx.B,s->srp_ctx.N)==0) goto err;
+	if (!(u = SRP_Calc_u(s->srp_ctx.A,s->srp_ctx.B,s->srp_ctx.N))) goto err;
+	if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) goto err;
+	if (!(passwd = s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg))) goto err;
+	if (!(x = SRP_Calc_x(s->srp_ctx.s,s->srp_ctx.login,passwd))) goto err;
+	if (!(K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, s->srp_ctx.a, u))) goto err;
+
+	tmp_len = BN_num_bytes(K);
+	if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) goto err;
+	BN_bn2bin(K, tmp);
+	ret = s->method->ssl3_enc->generate_master_secret(s,master_key,tmp,tmp_len);
+err:
+	if (tmp)
+		{
+		OPENSSL_cleanse(tmp,tmp_len) ;
+		OPENSSL_free(tmp);
+		}
+	BN_clear_free(K);
+	BN_clear_free(x);
+	if (passwd)
+		{
+		OPENSSL_cleanse(passwd,strlen(passwd)) ;
+		OPENSSL_free(passwd);
+		}
+	BN_clear_free(u);
+	return ret;
+	}
+
+int SRP_Calc_A_param(SSL *s)
+	{
+	unsigned char rand[SSL_MAX_MASTER_KEY_LENGTH];
+
+	if (BN_num_bits(s->srp_ctx.N) < s->srp_ctx.strength)
+		return 0;
+
+	if (s->srp_ctx.SRP_verify_param_callback ==NULL && 
+		!SRP_check_known_gN_param(s->srp_ctx.g,s->srp_ctx.N))
+		return 0;
+
+	if (RAND_bytes(rand, sizeof(rand)) <= 0)
+		return 0;
+	s->srp_ctx.a = BN_bin2bn(rand,sizeof(rand), s->srp_ctx.a);
+	OPENSSL_cleanse(rand,sizeof(rand));
+
+	if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a,s->srp_ctx.N,s->srp_ctx.g)))
+		return 0;
+
+	/* We can have a callback to verify SRP param!! */
+	if (s->srp_ctx.SRP_verify_param_callback !=NULL) 
+		return s->srp_ctx.SRP_verify_param_callback(s,s->srp_ctx.SRP_cb_arg);
+
+	return 1;
+	}
+
+int SRP_have_to_put_srp_username(SSL *s)
+	{
+	if (s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback == NULL)
+		return 0;
+	if ((s->srp_ctx.login = s->srp_ctx.SRP_TLS_ext_missing_srp_client_username_callback(s,s->srp_ctx.SRP_cb_arg)) == NULL)
+		return 0;
+	s->srp_ctx.srp_Mask|=SSL_kSRP;
+	return 1;
+	}
+
+BIGNUM *SSL_get_srp_g(SSL *s)
+	{
+	if (s->srp_ctx.g != NULL)
+		return s->srp_ctx.g;
+	return s->ctx->srp_ctx.g;
+	}
+
+BIGNUM *SSL_get_srp_N(SSL *s)
+	{
+	if (s->srp_ctx.N != NULL)
+		return s->srp_ctx.N;
+	return s->ctx->srp_ctx.N;
+	}
+
+char *SSL_get_srp_username(SSL *s)
+	{
+	if (s->srp_ctx.login != NULL)
+		return s->srp_ctx.login;
+	return s->ctx->srp_ctx.login;
+	}
+
+char *SSL_get_srp_userinfo(SSL *s)
+	{
+	if (s->srp_ctx.info != NULL)
+		return s->srp_ctx.info;
+	return s->ctx->srp_ctx.info;
+	}
+
+#define tls1_ctx_ctrl ssl3_ctx_ctrl
+#define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
+
+int SSL_CTX_set_srp_username(SSL_CTX *ctx,char *name)
+	{
+	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME,0,name);
+	}
+
+int SSL_CTX_set_srp_password(SSL_CTX *ctx,char *password)
+	{
+	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD,0,password);
+	}
+
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
+	{
+	return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
+			     NULL);
+	}
+
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, int (*cb)(SSL *,void *))
+	{
+	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
+				      (void (*)(void))cb);
+	}
+
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
+	{
+	return tls1_ctx_ctrl(ctx,SSL_CTRL_SET_SRP_ARG,0,arg);
+	}
+
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+				      int (*cb)(SSL *,int *,void *))
+	{
+	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
+				      (void (*)(void))cb);
+	}
+
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, char *(*cb)(SSL *,void *))
+	{
+	return tls1_ctx_callback_ctrl(ctx,SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
+				      (void (*)(void))cb);
+	}
+
+int SSL_CTX_set_srp_missing_srp_username_callback(SSL_CTX *ctx,
+						  char *(*cb)(SSL *,void *))
+	{
+	return tls1_ctx_callback_ctrl(ctx,
+			    SSL_CTRL_SET_TLS_EXT_SRP_MISSING_CLIENT_USERNAME_CB,
+				      (void (*)(void))cb);
+	}
+#endif
diff --git a/test/Makefile b/test/Makefile
index 5ca4754..9836ce0 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -62,6 +62,7 @@
 EVPTEST=	evp_test
 IGETEST=	igetest
 JPAKETEST=	jpaketest
+SRPTEST=	srptest
 FIPS_SHATEST=	fips_shatest
 FIPS_DESTEST=	fips_desmovs
 FIPS_RANDTEST=	fips_randtest
@@ -90,7 +91,7 @@
 	$(RANDTEST)$(EXE_EXT) $(DHTEST)$(EXE_EXT) $(ENGINETEST)$(EXE_EXT) \
 	$(BFTEST)$(EXE_EXT) $(CASTTEST)$(EXE_EXT) $(SSLTEST)$(EXE_EXT) \
 	$(EXPTEST)$(EXE_EXT) $(DSATEST)$(EXE_EXT) $(RSATEST)$(EXE_EXT) \
-	$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT)
+	$(EVPTEST)$(EXE_EXT) $(IGETEST)$(EXE_EXT) $(JPAKETEST)$(EXE_EXT) $(SRPTEST)$(EXE_EXT)
 
 FIPSEXE=$(FIPS_SHATEST)$(EXE_EXT) $(FIPS_DESTEST)$(EXE_EXT) \
 	$(FIPS_RANDTEST)$(EXE_EXT) $(FIPS_AESTEST)$(EXE_EXT) \
@@ -175,7 +176,7 @@
 	test_enc test_x509 test_rsa test_crl test_sid \
 	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
 	test_ss test_ca test_engine test_evp test_ssl test_tsa test_ige \
-	test_jpake test_cms
+	test_jpake test_srp test_cms
 
 test_evp:
 	../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
@@ -349,6 +350,10 @@
 	@echo "CMS consistency test"
 	$(PERL) cms-test.pl
 
+test_srp: $(SRPTEST)$(EXE_EXT)
+	@echo "Test SRP"
+	../util/shlib_wrap.sh ./srptest
+
 lint:
 	lint -DLINT $(INCLUDES) $(SRC)>fluff
 
@@ -562,6 +567,9 @@
 $(JPAKETEST)$(EXE_EXT): $(JPAKETEST).o $(DLIBCRYPTO)
 	@target=$(JPAKETEST); $(BUILD_CMD)
 
+$(SRPTEST)$(EXE_EXT): $(SRPTEST).o $(DLIBCRYPTO)
+	@target=$(SRPTEST); $(BUILD_CMD)
+
 #$(AESTEST).o: $(AESTEST).c
 #	$(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
 
@@ -628,7 +636,8 @@
 ecdhtest.o: ../include/openssl/symhacks.h ecdhtest.c
 ecdsatest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
 ecdsatest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ecdsatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ecdsatest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+ecdsatest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
 ecdsatest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ecdsatest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 ecdsatest.o: ../include/openssl/err.h ../include/openssl/evp.h
@@ -636,13 +645,15 @@
 ecdsatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 ecdsatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 ecdsatest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-ecdsatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ecdsatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ecdsatest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ecdsatest.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ecdsatest.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
 ecdsatest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
 ecdsatest.o: ecdsatest.c
 ectest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ectest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-ectest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+ectest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+ectest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
 ectest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ectest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 ectest.o: ../include/openssl/err.h ../include/openssl/evp.h
@@ -650,34 +661,41 @@
 ectest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 ectest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 ectest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-ectest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ectest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ectest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ectest.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ectest.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
 ectest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ectest.c
 enginetest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-enginetest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
-enginetest.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-enginetest.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-enginetest.o: ../include/openssl/engine.h ../include/openssl/err.h
-enginetest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-enginetest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-enginetest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-enginetest.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
-enginetest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-enginetest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+enginetest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+enginetest.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+enginetest.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
+enginetest.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+enginetest.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+enginetest.o: ../include/openssl/err.h ../include/openssl/evp.h
+enginetest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+enginetest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+enginetest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+enginetest.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+enginetest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+enginetest.o: ../include/openssl/sha.h ../include/openssl/stack.h
+enginetest.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
 enginetest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
 enginetest.o: enginetest.c
 evp_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-evp_test.o: ../include/openssl/buffer.h ../include/openssl/conf.h
-evp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-evp_test.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-evp_test.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-evp_test.o: ../include/openssl/err.h ../include/openssl/evp.h
-evp_test.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-evp_test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-evp_test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-evp_test.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-evp_test.o: ../include/openssl/sha.h ../include/openssl/stack.h
-evp_test.o: ../include/openssl/symhacks.h ../include/openssl/x509.h
+evp_test.o: ../include/openssl/bn.h ../include/openssl/buffer.h
+evp_test.o: ../include/openssl/conf.h ../include/openssl/crypto.h
+evp_test.o: ../include/openssl/dh.h ../include/openssl/dsa.h
+evp_test.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+evp_test.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+evp_test.o: ../include/openssl/engine.h ../include/openssl/err.h
+evp_test.o: ../include/openssl/evp.h ../include/openssl/lhash.h
+evp_test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+evp_test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+evp_test.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+evp_test.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+evp_test.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+evp_test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+evp_test.o: ../include/openssl/ui.h ../include/openssl/x509.h
 evp_test.o: ../include/openssl/x509_vfy.h evp_test.c
 exptest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
 exptest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
@@ -686,169 +704,116 @@
 exptest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
 exptest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
 exptest.o: ../include/openssl/symhacks.h exptest.c
-fips_aesavs.o: ../e_os.h ../fips/fips_utl.h ../include/openssl/aes.h
-fips_aesavs.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-fips_aesavs.o: ../include/openssl/bn.h ../include/openssl/crypto.h
-fips_aesavs.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-fips_aesavs.o: ../include/openssl/evp.h ../include/openssl/fips.h
+fips_aesavs.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h
+fips_aesavs.o: ../include/openssl/bio.h ../include/openssl/bn.h
+fips_aesavs.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+fips_aesavs.o: ../include/openssl/err.h ../include/openssl/evp.h
 fips_aesavs.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 fips_aesavs.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 fips_aesavs.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 fips_aesavs.o: ../include/openssl/safestack.h ../include/openssl/stack.h
 fips_aesavs.o: ../include/openssl/symhacks.h fips_aesavs.c
-fips_desmovs.o: ../e_os.h ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_desmovs.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_desmovs.o: ../include/openssl/crypto.h ../include/openssl/des.h
-fips_desmovs.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
-fips_desmovs.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_desmovs.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+fips_desmovs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_desmovs.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_desmovs.o: ../include/openssl/des.h ../include/openssl/des_old.h
+fips_desmovs.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_desmovs.o: ../include/openssl/evp.h ../include/openssl/lhash.h
 fips_desmovs.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 fips_desmovs.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
 fips_desmovs.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
 fips_desmovs.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 fips_desmovs.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
 fips_desmovs.o: fips_desmovs.c
-fips_dsatest.o: ../e_os.h ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_dsatest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_dsatest.o: ../include/openssl/crypto.h ../include/openssl/des.h
-fips_dsatest.o: ../include/openssl/des_old.h ../include/openssl/dsa.h
+fips_dhvs.o: ../include/openssl/opensslconf.h fips_dhvs.c
+fips_drbgvs.o: ../include/openssl/opensslconf.h fips_drbgvs.c
+fips_dsatest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_dsatest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
 fips_dsatest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-fips_dsatest.o: ../include/openssl/evp.h ../include/openssl/fips.h
-fips_dsatest.o: ../include/openssl/fips_rand.h ../include/openssl/lhash.h
+fips_dsatest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
 fips_dsatest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 fips_dsatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
 fips_dsatest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
 fips_dsatest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-fips_dsatest.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
-fips_dsatest.o: ../include/openssl/ui_compat.h fips_dsatest.c
-fips_dssvs.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_dssvs.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_dssvs.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-fips_dssvs.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-fips_dssvs.o: ../include/openssl/evp.h ../include/openssl/fips.h
-fips_dssvs.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-fips_dssvs.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-fips_dssvs.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-fips_dssvs.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-fips_dssvs.o: ../include/openssl/symhacks.h fips_dssvs.c
-fips_ecdsavs.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_ecdsavs.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_ecdsavs.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-fips_ecdsavs.o: ../include/openssl/ec.h ../include/openssl/ecdsa.h
-fips_ecdsavs.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_ecdsavs.o: ../include/openssl/fips.h ../include/openssl/lhash.h
-fips_ecdsavs.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-fips_ecdsavs.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-fips_ecdsavs.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-fips_ecdsavs.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-fips_ecdsavs.o: fips_ecdsavs.c
-fips_gcmtest.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_gcmtest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_gcmtest.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
-fips_gcmtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-fips_gcmtest.o: ../include/openssl/evp.h ../include/openssl/fips.h
-fips_gcmtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-fips_gcmtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-fips_gcmtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-fips_gcmtest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-fips_gcmtest.o: ../include/openssl/symhacks.h fips_gcmtest.c
-fips_hmactest.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_hmactest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_hmactest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-fips_hmactest.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_hmactest.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+fips_dsatest.o: ../include/openssl/symhacks.h fips_dsatest.c
+fips_dssvs.o: ../include/openssl/opensslconf.h fips_dssvs.c
+fips_ecdhvs.o: ../include/openssl/opensslconf.h fips_ecdhvs.c
+fips_ecdsavs.o: ../include/openssl/opensslconf.h fips_ecdsavs.c
+fips_gcmtest.o: ../include/openssl/opensslconf.h fips_gcmtest.c
+fips_hmactest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_hmactest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_hmactest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_hmactest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
 fips_hmactest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 fips_hmactest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 fips_hmactest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 fips_hmactest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
 fips_hmactest.o: ../include/openssl/symhacks.h fips_hmactest.c
-fips_randtest.o: ../e_os.h ../fips/fips_utl.h ../include/openssl/bio.h
-fips_randtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
-fips_randtest.o: ../include/openssl/des.h ../include/openssl/des_old.h
-fips_randtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
-fips_randtest.o: ../include/openssl/fips.h ../include/openssl/fips_rand.h
+fips_randtest.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/bn.h
+fips_randtest.o: ../include/openssl/crypto.h ../include/openssl/des.h
+fips_randtest.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
+fips_randtest.o: ../include/openssl/err.h ../include/openssl/fips_rand.h
 fips_randtest.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
 fips_randtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 fips_randtest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
 fips_randtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 fips_randtest.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
 fips_randtest.o: fips_randtest.c
-fips_rngvs.o: ../fips/fips_utl.h ../include/openssl/bio.h
-fips_rngvs.o: ../include/openssl/bn.h ../include/openssl/crypto.h
-fips_rngvs.o: ../include/openssl/des.h ../include/openssl/des_old.h
-fips_rngvs.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-fips_rngvs.o: ../include/openssl/err.h ../include/openssl/fips.h
-fips_rngvs.o: ../include/openssl/fips_rand.h ../include/openssl/lhash.h
-fips_rngvs.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-fips_rngvs.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
-fips_rngvs.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-fips_rngvs.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
-fips_rngvs.o: ../include/openssl/ui_compat.h fips_rngvs.c
-fips_rsagtest.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_rsagtest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_rsagtest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-fips_rsagtest.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_rsagtest.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+fips_rngvs.o: ../include/openssl/opensslconf.h fips_rngvs.c
+fips_rsagtest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_rsagtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_rsagtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_rsagtest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
 fips_rsagtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 fips_rsagtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 fips_rsagtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-fips_rsagtest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-fips_rsagtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-fips_rsagtest.o: fips_rsagtest.c
-fips_rsastest.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_rsastest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_rsastest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-fips_rsastest.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_rsastest.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+fips_rsagtest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+fips_rsagtest.o: ../include/openssl/symhacks.h fips_rsagtest.c
+fips_rsastest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_rsastest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_rsastest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_rsastest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
 fips_rsastest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 fips_rsastest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 fips_rsastest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-fips_rsastest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-fips_rsastest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-fips_rsastest.o: fips_rsastest.c
-fips_rsavtest.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_rsavtest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_rsavtest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-fips_rsavtest.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_rsavtest.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+fips_rsastest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+fips_rsastest.o: ../include/openssl/symhacks.h fips_rsastest.c
+fips_rsavtest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_rsavtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_rsavtest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_rsavtest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
 fips_rsavtest.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 fips_rsavtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 fips_rsavtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-fips_rsavtest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-fips_rsavtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-fips_rsavtest.o: fips_rsavtest.c
-fips_shatest.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_shatest.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_shatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-fips_shatest.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_shatest.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+fips_rsavtest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+fips_rsavtest.o: ../include/openssl/symhacks.h fips_rsavtest.c
+fips_shatest.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_shatest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_shatest.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_shatest.o: ../include/openssl/evp.h ../include/openssl/lhash.h
 fips_shatest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 fips_shatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
 fips_shatest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
 fips_shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 fips_shatest.o: fips_shatest.c
-fips_test_suite.o: ../fips/fips_utl.h ../include/openssl/asn1.h
-fips_test_suite.o: ../include/openssl/bio.h ../include/openssl/bn.h
-fips_test_suite.o: ../include/openssl/crypto.h ../include/openssl/dh.h
-fips_test_suite.o: ../include/openssl/dsa.h ../include/openssl/e_os2.h
-fips_test_suite.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips_test_suite.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+fips_test_suite.o: ../include/openssl/asn1.h ../include/openssl/bio.h
+fips_test_suite.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+fips_test_suite.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_test_suite.o: ../include/openssl/evp.h ../include/openssl/hmac.h
 fips_test_suite.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 fips_test_suite.o: ../include/openssl/objects.h
 fips_test_suite.o: ../include/openssl/opensslconf.h
 fips_test_suite.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-fips_test_suite.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-fips_test_suite.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-fips_test_suite.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-fips_test_suite.o: fips_test_suite.c
+fips_test_suite.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+fips_test_suite.o: ../include/openssl/sha.h ../include/openssl/stack.h
+fips_test_suite.o: ../include/openssl/symhacks.h fips_test_suite.c
 hmactest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-hmactest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-hmactest.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-hmactest.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-hmactest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-hmactest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-hmactest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-hmactest.o: ../include/openssl/symhacks.h hmactest.c
+hmactest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+hmactest.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+hmactest.o: ../include/openssl/hmac.h ../include/openssl/md5.h
+hmactest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+hmactest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+hmactest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+hmactest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h hmactest.c
 ideatest.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/idea.h
 ideatest.o: ../include/openssl/opensslconf.h ideatest.c
 igetest.o: ../include/openssl/aes.h ../include/openssl/crypto.h
@@ -856,39 +821,35 @@
 igetest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
 igetest.o: ../include/openssl/rand.h ../include/openssl/safestack.h
 igetest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h igetest.c
-jpaketest.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
-jpaketest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
-jpaketest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-jpaketest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-jpaketest.o: ../include/openssl/symhacks.h jpaketest.c
-md2test.o: ../include/openssl/buffer.h ../include/openssl/crypto.h
-md2test.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
-md2test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-md2test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
-md2test.o: ../include/openssl/symhacks.h md2test.c
+jpaketest.o: ../include/openssl/opensslconf.h jpaketest.c
+md2test.o: ../e_os.h ../include/openssl/e_os2.h
+md2test.o: ../include/openssl/opensslconf.h md2test.c
 md4test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-md4test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-md4test.o: ../include/openssl/evp.h ../include/openssl/md4.h
-md4test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-md4test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-md4test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-md4test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md4test.c
+md4test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+md4test.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+md4test.o: ../include/openssl/md4.h ../include/openssl/obj_mac.h
+md4test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+md4test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+md4test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+md4test.o: ../include/openssl/symhacks.h md4test.c
 md5test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-md5test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-md5test.o: ../include/openssl/evp.h ../include/openssl/md5.h
-md5test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-md5test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-md5test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-md5test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h md5test.c
+md5test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+md5test.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+md5test.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+md5test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+md5test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+md5test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+md5test.o: ../include/openssl/symhacks.h md5test.c
 mdc2test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-mdc2test.o: ../include/openssl/crypto.h ../include/openssl/des.h
-mdc2test.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
-mdc2test.o: ../include/openssl/evp.h ../include/openssl/mdc2.h
-mdc2test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-mdc2test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-mdc2test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
-mdc2test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-mdc2test.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h mdc2test.c
+mdc2test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+mdc2test.o: ../include/openssl/des.h ../include/openssl/des_old.h
+mdc2test.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+mdc2test.o: ../include/openssl/mdc2.h ../include/openssl/obj_mac.h
+mdc2test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+mdc2test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+mdc2test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+mdc2test.o: ../include/openssl/symhacks.h ../include/openssl/ui.h
+mdc2test.o: ../include/openssl/ui_compat.h mdc2test.c
 randtest.o: ../e_os.h ../include/openssl/crypto.h ../include/openssl/e_os2.h
 randtest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
 randtest.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
@@ -907,12 +868,13 @@
 rc5test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
 rc5test.o: ../include/openssl/symhacks.h rc5test.c
 rmdtest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-rmdtest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-rmdtest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
-rmdtest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-rmdtest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-rmdtest.o: ../include/openssl/ripemd.h ../include/openssl/safestack.h
-rmdtest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h rmdtest.c
+rmdtest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+rmdtest.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+rmdtest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+rmdtest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+rmdtest.o: ../include/openssl/ossl_typ.h ../include/openssl/ripemd.h
+rmdtest.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+rmdtest.o: ../include/openssl/symhacks.h rmdtest.c
 rsa_test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 rsa_test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
 rsa_test.o: ../include/openssl/e_os2.h ../include/openssl/err.h
@@ -922,19 +884,21 @@
 rsa_test.o: ../include/openssl/safestack.h ../include/openssl/stack.h
 rsa_test.o: ../include/openssl/symhacks.h rsa_test.c
 sha1test.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-sha1test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-sha1test.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
-sha1test.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-sha1test.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-sha1test.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-sha1test.o: ../include/openssl/stack.h ../include/openssl/symhacks.h sha1test.c
+sha1test.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+sha1test.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+sha1test.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+sha1test.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+sha1test.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+sha1test.o: ../include/openssl/sha.h ../include/openssl/stack.h
+sha1test.o: ../include/openssl/symhacks.h sha1test.c
 shatest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-shatest.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
-shatest.o: ../include/openssl/evp.h ../include/openssl/obj_mac.h
-shatest.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-shatest.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-shatest.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-shatest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h shatest.c
+shatest.o: ../include/openssl/bn.h ../include/openssl/crypto.h
+shatest.o: ../include/openssl/e_os2.h ../include/openssl/evp.h
+shatest.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+shatest.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+shatest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+shatest.o: ../include/openssl/sha.h ../include/openssl/stack.h
+shatest.o: ../include/openssl/symhacks.h shatest.c
 ssltest.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssltest.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ssltest.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -951,10 +915,11 @@
 ssltest.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
 ssltest.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
 ssltest.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssltest.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssltest.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssltest.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssltest.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssltest.o: ../include/openssl/sha.h ../include/openssl/srp.h
+ssltest.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssltest.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssltest.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssltest.o: ../include/openssl/tls1.h ../include/openssl/ui.h
 ssltest.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
 ssltest.o: ../include/openssl/x509v3.h ssltest.c
 wp_test.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
diff --git a/test/testssl b/test/testssl
index ad32bcc..530a252 100644
--- a/test/testssl
+++ b/test/testssl
@@ -159,4 +159,14 @@
 $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 || exit 1
 $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 -reuse || exit 1
 
+if ../util/shlib_wrap.sh ../apps/openssl no-srp; then
+  echo skipping SRP tests
+else
+  echo test tls1 with SRP
+  $ssltest -tls1 -cipher SRP -srpuser test -srppass abc123
+
+  echo test tls1 with SRP via BIO pair
+  $ssltest -bio_pair -tls1 -cipher SRP -srpuser test -srppass abc123
+fi
+
 exit 0
diff --git a/util/libeay.num b/util/libeay.num
index 531b50f..d5cf594 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -4260,3 +4260,19 @@
 CRYPTO_gcm128_tag                       4631	EXIST::FUNCTION:
 EVP_aes_192_gcm                         4632	EXIST::FUNCTION:AES
 EVP_aes_256_gcm                         4633	EXIST::FUNCTION:AES
+SRP_VBASE_get_by_user                   4634	EXIST::FUNCTION:SRP
+SRP_Calc_server_key                     4635	EXIST::FUNCTION:SRP
+SRP_create_verifier                     4636	EXIST::FUNCTION:SRP
+SRP_create_verifier_BN                  4637	EXIST::FUNCTION:SRP
+SRP_Calc_u                              4638	EXIST::FUNCTION:SRP
+SRP_VBASE_free                          4639	EXIST::FUNCTION:SRP
+SRP_Calc_client_key                     4640	EXIST::FUNCTION:SRP
+SRP_get_default_gN                      4641	EXIST::FUNCTION:SRP
+SRP_Calc_x                              4642	EXIST::FUNCTION:SRP
+SRP_Calc_B                              4643	EXIST::FUNCTION:SRP
+SRP_VBASE_new                           4644	EXIST::FUNCTION:SRP
+SRP_check_known_gN_param                4645	EXIST::FUNCTION:SRP
+SRP_Calc_A                              4646	EXIST::FUNCTION:SRP
+SRP_Verify_A_mod_N                      4647	EXIST::FUNCTION:SRP
+SRP_VBASE_init                          4648	EXIST::FUNCTION:SRP
+SRP_Verify_B_mod_N                      4649	EXIST::FUNCTION:SRP
diff --git a/util/mk1mf.pl b/util/mk1mf.pl
index cb104f8..afad229 100755
--- a/util/mk1mf.pl
+++ b/util/mk1mf.pl
@@ -121,6 +121,7 @@
 	just-ssl				- remove all non-ssl keys/digest
 	no-asm 					- No x86 asm
 	no-krb5					- No KRB5
+	no-srp					- No SRP
 	no-ec					- No EC
 	no-ecdsa				- No ECDSA
 	no-ecdh					- No ECDH
@@ -278,6 +279,7 @@
 $cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
 $cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
 $cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
+$cflags.=" -DOPENSSL_NO_SRP" if $no_srp;
 $cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
 $cflags.=" -DOPENSSL_NO_ERR"  if $no_err;
 $cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
@@ -1029,6 +1031,8 @@
 	@a=grep(!/(^sha1)|(_sha1$)|(m_dss1$)/,@a) if $no_sha1;
 	@a=grep(!/_mdc2$/,@a) if $no_mdc2;
 
+	@a=grep(!/(srp)/,@a) if $no_srp;
+
 	@a=grep(!/^engine$/,@a) if $no_engine;
 	@a=grep(!/^hw$/,@a) if $no_hw;
 	@a=grep(!/(^rsa$)|(^genrsa$)/,@a) if $no_rsa;
@@ -1308,6 +1312,7 @@
 		"no-ssl2" => \$no_ssl2,
 		"no-ssl3" => \$no_ssl3,
 		"no-tlsext" => \$no_tlsext,
+		"no-srp" => \$no_srp,
 		"no-cms" => \$no_cms,
 		"no-jpake" => \$no_jpake,
 		"no-ec2m" => \$no_ec2m,
@@ -1324,7 +1329,7 @@
 			[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
 			  \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
 			  \$no_ssl2, \$no_err, \$no_ripemd, \$no_rc5,
-			  \$no_aes, \$no_camellia, \$no_seed],
+			  \$no_aes, \$no_camellia, \$no_seed, \$no_srp],
 		"rsaref" => 0,
 		"gcc" => \$gcc,
 		"debug" => \$debug,
diff --git a/util/mkdef.pl b/util/mkdef.pl
index 3ccd542..9bf01ff 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -98,7 +98,7 @@
 			 # RFC3779
 			 "RFC3779",
 			 # TLS
-			 "TLSEXT", "PSK",
+			 "TLSEXT", "PSK", "SRP",
 			 # CMS
 			 "CMS",
 			 # CryptoAPI Engine
@@ -130,6 +130,7 @@
 my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
 my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
 my $no_jpake; my $no_ssl2; my $no_ec2m; my $no_nextprotoneg;
+my $no_srp;
 
 my $fips;
 
@@ -225,6 +226,7 @@
 	elsif (/^no-ssl2$/)	{ $no_ssl2=1; }
 	elsif (/^no-capieng$/)	{ $no_capieng=1; }
 	elsif (/^no-jpake$/)	{ $no_jpake=1; }
+	elsif (/^no-srp$/)	{ $no_srp=1; }
 	}
 
 
@@ -323,6 +325,7 @@
 $crypto.=" crypto/pqueue/pqueue.h";
 $crypto.=" crypto/cms/cms.h";
 $crypto.=" crypto/jpake/jpake.h";
+$crypto.=" crypto/srp/srp.h";
 $crypto.=" crypto/modes/modes.h";
 $crypto.=" fips/fips.h fips/rand/fips_rand.h";
 
@@ -1180,6 +1183,7 @@
 			if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
 			if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
 			if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
+			if ($keyword eq "SRP" && $no_srp) { return 0; }
 			if ($keyword eq "DEPRECATED" && $no_deprecated) { return 0; }
 
 			# Nothing recognise as true
diff --git a/util/mkfiles.pl b/util/mkfiles.pl
index 66b78f4..17b7d46 100755
--- a/util/mkfiles.pl
+++ b/util/mkfiles.pl
@@ -63,6 +63,7 @@
 "crypto/pqueue",
 "crypto/whrlpool",
 "crypto/ts",
+"crypto/srp",
 "fips",
 "fips/aes",
 "fips/des",
diff --git a/util/ssleay.num b/util/ssleay.num
index 54966d7..9f64f99 100755
--- a/util/ssleay.num
+++ b/util/ssleay.num
@@ -274,3 +274,17 @@
 SSL_CTX_set_not_resumbl_sess_cb         320	EXIST:VMS:FUNCTION:
 SSL_set_not_resumable_session_callback  321	EXIST:!VMS:FUNCTION:
 SSL_set_not_resumbl_sess_cb             321	EXIST:VMS:FUNCTION:
+SSL_CTX_set_srp_client_pwd_callback     322	EXIST::FUNCTION:SRP,TLSEXT
+SSL_get_srp_g                           323	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_username_callback       324	EXIST::FUNCTION:SRP,TLSEXT
+SSL_get_srp_userinfo                    325	EXIST::FUNCTION:SRP,TLSEXT
+SSL_set_srp_server_param                326	EXIST::FUNCTION:SRP,TLSEXT
+SSL_set_srp_server_param_pw             327	EXIST::FUNCTION:SRP,TLSEXT
+SSL_get_srp_N                           328	EXIST::FUNCTION:SRP,TLSEXT
+SSL_get_srp_username                    329	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_password                330	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_strength                331	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_verify_param_callback   332	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_missing_srp_username_callback 333	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_cb_arg                  334	EXIST::FUNCTION:SRP,TLSEXT
+SSL_CTX_set_srp_username                335	EXIST::FUNCTION:SRP,TLSEXT