aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl/test
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2010-01-13 10:53:07 +0000
committerErlang/OTP <[email protected]>2010-01-13 14:57:32 +0100
commit405de8c986fd22c05f398036edac809e98149292 (patch)
treeeefd31852cbb80917fe661fbc683ccda62bdd472 /lib/ssl/test
parent009152080c9009498026db17ccee244171423c1c (diff)
downloadotp-405de8c986fd22c05f398036edac809e98149292.tar.gz
otp-405de8c986fd22c05f398036edac809e98149292.tar.bz2
otp-405de8c986fd22c05f398036edac809e98149292.zip
Add test suite for the ssl application
Diffstat (limited to 'lib/ssl/test')
-rw-r--r--lib/ssl/test/Makefile137
-rw-r--r--lib/ssl/test/Makefile.src16
-rw-r--r--lib/ssl/test/make_certs.erl288
-rw-r--r--lib/ssl/test/old_ssl_active_SUITE.erl387
-rw-r--r--lib/ssl/test/old_ssl_active_once_SUITE.erl409
-rw-r--r--lib/ssl/test/old_ssl_dist_SUITE.erl595
-rw-r--r--lib/ssl/test/old_ssl_misc_SUITE.erl105
-rw-r--r--lib/ssl/test/old_ssl_passive_SUITE.erl374
-rw-r--r--lib/ssl/test/old_ssl_peer_cert_SUITE.erl180
-rw-r--r--lib/ssl/test/old_ssl_protocol_SUITE.erl169
-rw-r--r--lib/ssl/test/old_ssl_verify_SUITE.erl141
-rw-r--r--lib/ssl/test/old_transport_accept_SUITE.erl238
-rw-r--r--lib/ssl/test/ssl.cover7
-rw-r--r--lib/ssl/test/ssl.spec1
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl2075
-rw-r--r--lib/ssl/test/ssl_basic_SUITE_data/RANDbin0 -> 512 bytes
-rw-r--r--lib/ssl/test/ssl_packet_SUITE.erl1486
-rw-r--r--lib/ssl/test/ssl_payload_SUITE.erl726
-rw-r--r--lib/ssl/test/ssl_test_MACHINE.erl935
-rw-r--r--lib/ssl/test/ssl_test_MACHINE.hrl39
-rw-r--r--lib/ssl/test/ssl_test_lib.erl408
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl772
22 files changed, 9488 insertions, 0 deletions
diff --git a/lib/ssl/test/Makefile b/lib/ssl/test/Makefile
new file mode 100644
index 0000000000..bd86120c98
--- /dev/null
+++ b/lib/ssl/test/Makefile
@@ -0,0 +1,137 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1999-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+#
+
+# SSL test suite Makefile
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../vsn.mk
+VSN=$(GS_VSN)
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES = \
+ ssl_test_lib \
+ ssl_basic_SUITE \
+ ssl_packet_SUITE \
+ ssl_payload_SUITE \
+ ssl_to_openssl_SUITE \
+ ssl_test_MACHINE \
+ old_ssl_active_SUITE \
+ old_ssl_active_once_SUITE \
+ old_ssl_passive_SUITE \
+ old_ssl_verify_SUITE \
+ old_ssl_peer_cert_SUITE \
+ old_ssl_misc_SUITE \
+ old_ssl_protocol_SUITE \
+ old_transport_accept_SUITE \
+ old_ssl_dist_SUITE \
+ make_certs
+
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES = ssl_test_MACHINE.hrl
+
+HRL_FILES_SRC = \
+ ssl_pkix.hrl \
+ ssl_alert.hrl \
+ ssl_handshake.hrl
+
+HRL_FILES_INC = \
+ OTP-PKIX.hrl
+
+HRL_FILES_NEEDED_IN_TEST = \
+ $(HRL_FILES_SRC:%=../src/%) \
+ $(HRL_FILES_INC:%=../include/%)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+INCLUDES = -I. -I$(ERL_TOP)/lib/test_server/include/
+
+DATADIRS = ssl_basic_SUITE_data
+
+EMAKEFILE=Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+COVER_FILE = ssl.cover
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/ssl_test
+
+# ----------------------------------------------------
+# FLAGS
+# The path to the test_server ebin dir is needed when
+# running the target "targets".
+# ----------------------------------------------------
+ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \
+ $(INCLUDES)
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt: $(BUILDTARGET)
+
+targets: $(TARGET_FILES)
+
+.PHONY: emakebuild
+
+emakebuild: $(EMAKEFILE)
+
+$(EMAKEFILE):
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
+ $(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
+
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES)
+ rm -f core *~
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(HRL_FILES_NEEDED_IN_TEST) $(COVER_FILE) $(RELSYSDIR)
+ $(INSTALL_DATA) ssl.spec $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
+
+# Dependencies
+
+$(TARGET_FILES): $(HRL_FILES)
diff --git a/lib/ssl/test/Makefile.src b/lib/ssl/test/Makefile.src
new file mode 100644
index 0000000000..c70894707c
--- /dev/null
+++ b/lib/ssl/test/Makefile.src
@@ -0,0 +1,16 @@
+# Dummy Makefile.src defined to provide backward compatibility for
+# applications that use both the new SSL (3.0 or later), and older
+# versions of SSL.
+#
+
+SSL_LIB_DIR = @ssl_libdir@
+TARGET = @target@
+SSLEAY_LIB = @SSLEAY_ROOT@/lib
+
+all:
+ -echo "Begin dummy make"
+ -echo SSL_LIB_DIR = $(SSL_LIB_DIR)
+ -echo TARGET = $(TARGET)
+ -echo SSLEAY_LIB = $(SSLEAY_LIB)
+ -echo SSL_LIB_DIR = $(SSL_LIB_DIR)
+ -echo "End dummy make"
diff --git a/lib/ssl/test/make_certs.erl b/lib/ssl/test/make_certs.erl
new file mode 100644
index 0000000000..0cdf33c3e2
--- /dev/null
+++ b/lib/ssl/test/make_certs.erl
@@ -0,0 +1,288 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(make_certs).
+
+-export([all/2]).
+
+-record(dn, {commonName,
+ organizationalUnitName = "Erlang OTP",
+ organizationName = "Ericsson AB",
+ localityName = "Stockholm",
+ countryName = "SE",
+ emailAddress = "[email protected]"}).
+
+all(DataDir, PrivDir) ->
+ OpenSSLCmd = "openssl",
+ create_rnd(DataDir, PrivDir), % For all requests
+ rootCA(PrivDir, OpenSSLCmd, "erlangCA"),
+ intermediateCA(PrivDir, OpenSSLCmd, "otpCA", "erlangCA"),
+ endusers(PrivDir, OpenSSLCmd, "otpCA", ["client", "server"]),
+ collect_certs(PrivDir, ["erlangCA", "otpCA"], ["client", "server"]),
+ %% Create keycert files
+ SDir = filename:join([PrivDir, "server"]),
+ SC = filename:join([SDir, "cert.pem"]),
+ SK = filename:join([SDir, "key.pem"]),
+ SKC = filename:join([SDir, "keycert.pem"]),
+ append_files([SK, SC], SKC),
+ CDir = filename:join([PrivDir, "client"]),
+ CC = filename:join([CDir, "cert.pem"]),
+ CK = filename:join([CDir, "key.pem"]),
+ CKC = filename:join([CDir, "keycert.pem"]),
+ append_files([CK, CC], CKC),
+ remove_rnd(PrivDir).
+
+append_files(FileNames, ResultFileName) ->
+ {ok, ResultFile} = file:open(ResultFileName, [write]),
+ do_append_files(FileNames, ResultFile).
+
+do_append_files([], RF) ->
+ ok = file:close(RF);
+do_append_files([F|Fs], RF) ->
+ {ok, Data} = file:read_file(F),
+ ok = file:write(RF, Data),
+ do_append_files(Fs, RF).
+
+rootCA(Root, OpenSSLCmd, Name) ->
+ create_ca_dir(Root, Name, ca_cnf(Name)),
+ DN = #dn{commonName = Name},
+ create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)),
+ ok.
+
+intermediateCA(Root, OpenSSLCmd, CA, ParentCA) ->
+ CA = "otpCA",
+ create_ca_dir(Root, CA, ca_cnf(CA)),
+ CARoot = filename:join([Root, CA]),
+ DN = #dn{commonName = CA},
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, req_cnf(DN)),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ ReqFile = filename:join([CARoot, "req.pem"]),
+ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile).
+
+endusers(Root, OpenSSLCmd, CA, Users) ->
+ lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users).
+
+enduser(Root, OpenSSLCmd, CA, User) ->
+ UsrRoot = filename:join([Root, User]),
+ file:make_dir(UsrRoot),
+ CnfFile = filename:join([UsrRoot, "req.cnf"]),
+ DN = #dn{commonName = User},
+ file:write_file(CnfFile, req_cnf(DN)),
+ KeyFile = filename:join([UsrRoot, "key.pem"]),
+ ReqFile = filename:join([UsrRoot, "req.pem"]),
+ create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
+ CertFile = filename:join([UsrRoot, "cert.pem"]),
+ sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFile).
+
+collect_certs(Root, CAs, Users) ->
+ Bins = lists:foldr(
+ fun(CA, Acc) ->
+ File = filename:join([Root, CA, "cert.pem"]),
+ {ok, Bin} = file:read_file(File),
+ [Bin, "\n" | Acc]
+ end, [], CAs),
+ lists:foreach(
+ fun(User) ->
+ File = filename:join([Root, User, "cacerts.pem"]),
+ file:write_file(File, Bins)
+ end, Users).
+
+create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) ->
+ CARoot = filename:join([Root, CAName]),
+ CnfFile = filename:join([CARoot, "req.cnf"]),
+ file:write_file(CnfFile, Cnf),
+ KeyFile = filename:join([CARoot, "private", "key.pem"]),
+ CertFile = filename:join([CARoot, "cert.pem"]),
+ Cmd = [OpenSSLCmd, " req"
+ " -new"
+ " -x509"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+create_ca_dir(Root, CAName, Cnf) ->
+ CARoot = filename:join([Root, CAName]),
+ file:make_dir(CARoot),
+ create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
+ create_rnd(Root, filename:join([CAName, "private"])),
+ create_files(CARoot, [{"serial", "01\n"},
+ {"index.txt", ""},
+ {"ca.cnf", Cnf}]).
+
+create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) ->
+ Cmd = [OpenSSLCmd, " req"
+ " -new"
+ " -config ", CnfFile,
+ " -keyout ", KeyFile,
+ " -out ", ReqFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
+ CACnfFile = filename:join([Root, CA, "ca.cnf"]),
+ Cmd = [OpenSSLCmd, " ca"
+ " -batch"
+ " -notext"
+ " -config ", CACnfFile,
+ " -extensions ", CertType,
+ " -in ", ReqFile,
+ " -out ", CertFile],
+ Env = [{"ROOTDIR", Root}],
+ cmd(Cmd, Env).
+
+%%
+%% Misc
+%%
+
+create_dirs(Root, Dirs) ->
+ lists:foreach(fun(Dir) ->
+ file:make_dir(filename:join([Root, Dir])) end,
+ Dirs).
+
+create_files(Root, NameContents) ->
+ lists:foreach(
+ fun({Name, Contents}) ->
+ file:write_file(filename:join([Root, Name]), Contents) end,
+ NameContents).
+
+create_rnd(FromDir, ToDir) ->
+ From = filename:join([FromDir, "RAND"]),
+ To = filename:join([ToDir, "RAND"]),
+ file:copy(From, To).
+
+remove_rnd(Dir) ->
+ File = filename:join([Dir, "RAND"]),
+ file:delete(File).
+
+cmd(Cmd, Env) ->
+ FCmd = lists:flatten(Cmd),
+ Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout,
+ {env, Env}]),
+ eval_cmd(Port).
+
+eval_cmd(Port) ->
+ receive
+ {Port, {data, _}} ->
+ eval_cmd(Port);
+ {Port, eof} ->
+ ok
+ end,
+ receive
+ {Port, {exit_status, Status}} when Status /= 0 ->
+ %% io:fwrite("exit status: ~w~n", [Status]),
+ exit({eval_cmd, Status})
+ after 0 ->
+ ok
+ end.
+
+%%
+%% Contents of configuration files
+%%
+
+req_cnf(DN) ->
+ ["# Purpose: Configuration for requests (end users and CAs)."
+ "\n"
+ "ROOTDIR = $ENV::ROOTDIR\n"
+ "\n"
+
+ "[req]\n"
+ "input_password = secret\n"
+ "output_password = secret\n"
+ "default_bits = 1024\n"
+ "RANDFILE = $ROOTDIR/RAND\n"
+ "encrypt_key = no\n"
+ "default_md = sha1\n"
+ "#string_mask = pkix\n"
+ "x509_extensions = ca_ext\n"
+ "prompt = no\n"
+ "distinguished_name= name\n"
+ "\n"
+
+ "[name]\n"
+ "commonName = ", DN#dn.commonName, "\n"
+ "organizationalUnitName = ", DN#dn.organizationalUnitName, "\n"
+ "organizationName = ", DN#dn.organizationName, "\n"
+ "localityName = ", DN#dn.localityName, "\n"
+ "countryName = ", DN#dn.countryName, "\n"
+ "emailAddress = ", DN#dn.emailAddress, "\n"
+ "\n"
+
+ "[ca_ext]\n"
+ "basicConstraints = critical, CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "subjectAltName = email:copy\n"].
+
+
+ca_cnf(CA) ->
+ ["# Purpose: Configuration for CAs.\n"
+ "\n"
+ "ROOTDIR = $ENV::ROOTDIR\n"
+ "default_ca = ca\n"
+ "\n"
+
+ "[ca]\n"
+ "dir = $ROOTDIR/", CA, "\n"
+ "certs = $dir/certs\n"
+ "crl_dir = $dir/crl\n"
+ "database = $dir/index.txt\n"
+ "new_certs_dir = $dir/newcerts\n"
+ "certificate = $dir/cert.pem\n"
+ "serial = $dir/serial\n"
+ "crl = $dir/crl.pem\n"
+ "private_key = $dir/private/key.pem\n"
+ "RANDFILE = $dir/private/RAND\n"
+ "\n"
+ "x509_extensions = user_cert\n"
+ "default_days = 3600\n"
+ "default_md = sha1\n"
+ "preserve = no\n"
+ "policy = policy_match\n"
+ "\n"
+
+ "[policy_match]\n"
+ "commonName = supplied\n"
+ "organizationalUnitName = optional\n"
+ "organizationName = match\n"
+ "countryName = match\n"
+ "localityName = match\n"
+ "emailAddress = supplied\n"
+ "\n"
+
+ "[user_cert]\n"
+ "basicConstraints = CA:false\n"
+ "keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"
+ "\n"
+
+ "[ca_cert]\n"
+ "basicConstraints = critical,CA:true\n"
+ "keyUsage = cRLSign, keyCertSign\n"
+ "subjectKeyIdentifier = hash\n"
+ "authorityKeyIdentifier = keyid:always,issuer:always\n"
+ "subjectAltName = email:copy\n"
+ "issuerAltName = issuer:copy\n"].
diff --git a/lib/ssl/test/old_ssl_active_SUITE.erl b/lib/ssl/test/old_ssl_active_SUITE.erl
new file mode 100644
index 0000000000..fc44fa23dd
--- /dev/null
+++ b/lib/ssl/test/old_ssl_active_SUITE.erl
@@ -0,0 +1,387 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_active_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ cinit_huge_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in active mode.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains, and record the number of available "
+ "file descriptors";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+ case os:type() of
+ {unix, _} ->
+ ?line io:format("Max fd value: ~s", [os:cmd("ulimit -n")]);
+ _ ->
+ ok
+ end,
+ %% XXX Also record: Erlang/SSL version, version of OpenSSL,
+ %% operating system, version of OTP, Erts, kernel and stdlib.
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_huge_echo_chkclose(doc) ->
+ "Client sends 500000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_huge_echo_chkclose(suite) ->
+ [];
+cinit_huge_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 500000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+%% This case is repeated several times.
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "N client sends 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
diff --git a/lib/ssl/test/old_ssl_active_once_SUITE.erl b/lib/ssl/test/old_ssl_active_once_SUITE.erl
new file mode 100644
index 0000000000..6224b17aa7
--- /dev/null
+++ b/lib/ssl/test/old_ssl_active_once_SUITE.erl
@@ -0,0 +1,409 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_active_once_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ server_accept_timeout/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ cinit_huge_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in passive mode.";
+all(suite) ->
+ {conf,
+ config,
+ [server_accept_timeout,
+ cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ cinit_huge_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+server_accept_timeout(doc) ->
+ "Server has one pending accept with timeout. Checks that return "
+ "value is {error, timeout}.";
+server_accept_timeout(suite) ->
+ [];
+server_accept_timeout(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ AccTimeout = 3000,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, AccTimeout},
+ accept_timeout],
+ ?line test_server_only(NConns, LCmds, ACmds, Timeout, ?MODULE,
+ Config).
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ %% Set {active, false} so that accept is passive to begin with.
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {sockopts, [{active, once}]}, % {active, once} here.
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_huge_echo_chkclose(doc) ->
+ "Client sends 500000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_huge_echo_chkclose(suite) ->
+ [];
+cinit_huge_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 500000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "client send 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, once}]},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
diff --git a/lib/ssl/test/old_ssl_dist_SUITE.erl b/lib/ssl/test/old_ssl_dist_SUITE.erl
new file mode 100644
index 0000000000..56209c3530
--- /dev/null
+++ b/lib/ssl/test/old_ssl_dist_SUITE.erl
@@ -0,0 +1,595 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+
+%%%-------------------------------------------------------------------
+%%% File : ssl_dist_SUITE.erl
+%%% Author : Rickard Green
+%%% Description : Test that the Erlang distribution works over ssl.
+%%%
+%%% Created : 15 Nov 2007 by Rickard Green
+%%%-------------------------------------------------------------------
+-module(old_ssl_dist_SUITE).
+
+-include("test_server.hrl").
+
+-define(DEFAULT_TIMETRAP_SECS, 240).
+
+-define(AWAIT_SLL_NODE_UP_TIMEOUT, 30000).
+
+-export([all/1]).
+-export([init_per_suite/1,
+ end_per_suite/1,
+ init_per_testcase/2,
+ fin_per_testcase/2]).
+-export([cnct2tstsrvr/1]).
+
+-export([basic/1]).
+
+-record(node_handle, {connection_handler, socket, name, nodename}).
+
+all(doc) ->
+ [];
+all(suite) ->
+ [basic].
+
+init_per_suite(Config) ->
+ add_ssl_opts_config(Config).
+
+end_per_suite(Config) ->
+ Config.
+
+init_per_testcase(Case, Config) when list(Config) ->
+ Dog = ?t:timetrap(?t:seconds(?DEFAULT_TIMETRAP_SECS)),
+ [{watchdog, Dog},{testcase, Case}|Config].
+
+fin_per_testcase(_Case, Config) when list(Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Testcases %%
+%% %%
+
+basic(doc) ->
+ ["Test that two nodes can connect via ssl distribution"];
+basic(suite) ->
+ [];
+basic(Config) when is_list(Config) ->
+ ?line NH1 = start_ssl_node(Config),
+ ?line Node1 = NH1#node_handle.nodename,
+ ?line NH2 = start_ssl_node(Config),
+ ?line Node2 = NH2#node_handle.nodename,
+
+ ?line pong = apply_on_ssl_node(NH1, fun () -> net_adm:ping(Node2) end),
+
+ ?line [Node2] = apply_on_ssl_node(NH1, fun () -> nodes() end),
+ ?line [Node1] = apply_on_ssl_node(NH2, fun () -> nodes() end),
+
+ %% The test_server node has the same cookie as the ssl nodes
+ %% but it should not be able to communicate with the ssl nodes
+ %% via the erlang distribution.
+ ?line pang = net_adm:ping(Node1),
+ ?line pang = net_adm:ping(Node2),
+
+
+ %%
+ %% Check that we are able to communicate over the erlang
+ %% distribution between the ssl nodes.
+ %%
+ ?line Ref = make_ref(),
+ ?line spawn(fun () ->
+ apply_on_ssl_node(
+ NH1,
+ fun () ->
+ tstsrvr_format("Hi from ~p!~n",
+ [node()]),
+ send_to_tstcntrl({Ref, self()}),
+ receive
+ {From, ping} ->
+ From ! {self(), pong}
+ end
+ end)
+ end),
+ ?line receive
+ {Ref, SslPid} ->
+ ?line ok = apply_on_ssl_node(
+ NH2,
+ fun () ->
+ tstsrvr_format("Hi from ~p!~n",
+ [node()]),
+ SslPid ! {self(), ping},
+ receive
+ {SslPid, pong} ->
+ ok
+ end
+ end)
+ end,
+
+ ?line stop_ssl_node(NH1),
+ ?line stop_ssl_node(NH2),
+ ?line success(Config).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% %%
+%% Internal functions %%
+%% %%
+
+%%
+%% ssl_node side api
+%%
+
+tstsrvr_format(Fmt, ArgList) ->
+ send_to_tstsrvr({format, Fmt, ArgList}).
+
+send_to_tstcntrl(Message) ->
+ send_to_tstsrvr({message, Message}).
+
+
+%%
+%% test_server side api
+%%
+
+apply_on_ssl_node(Node, M, F, A) when atom(M), atom(F), list(A) ->
+ Ref = make_ref(),
+ send_to_ssl_node(Node, {apply, self(), Ref, M, F, A}),
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+apply_on_ssl_node(Node, Fun) when is_function(Fun, 0) ->
+ Ref = make_ref(),
+ send_to_ssl_node(Node, {apply, self(), Ref, Fun}),
+ receive
+ {Ref, Result} ->
+ Result
+ end.
+
+stop_ssl_node(#node_handle{connection_handler = Handler,
+ socket = Socket,
+ name = Name}) ->
+ ?t:format("Trying to stop ssl node ~s.~n", [Name]),
+ Mon = erlang:monitor(process, Handler),
+ unlink(Handler),
+ case gen_tcp:send(Socket, term_to_binary(stop)) of
+ ok ->
+ receive
+ {'DOWN', Mon, process, Handler, Reason} ->
+ case Reason of
+ normal -> ok;
+ _ -> exit(Reason)
+ end
+ end;
+ Error ->
+ erlang:demonitor(Mon, [flush]),
+ exit(Error)
+ end.
+
+start_ssl_node(Config) ->
+ start_ssl_node(Config, "").
+
+start_ssl_node(Config, XArgs) ->
+ Name = mk_node_name(Config),
+ SSL = ?config(ssl_opts, Config),
+ SSLDistOpts = setup_dist_opts(Name, ?config(priv_dir, Config)),
+ start_ssl_node_raw(Name, SSL ++ " " ++ SSLDistOpts ++ XArgs).
+
+start_ssl_node_raw(Name, Args) ->
+ {ok, LSock} = gen_tcp:listen(0,
+ [binary, {packet, 4}, {active, false}]),
+ {ok, ListenPort} = inet:port(LSock),
+ CmdLine = mk_node_cmdline(ListenPort, Name, Args),
+ ?t:format("Attempting to start ssl node ~s: ~s~n", [Name, CmdLine]),
+ case open_port({spawn, CmdLine}, []) of
+ Port when port(Port) ->
+ unlink(Port),
+ erlang:port_close(Port),
+ case await_ssl_node_up(Name, LSock) of
+ #node_handle{} = NodeHandle ->
+ ?t:format("Ssl node ~s started.~n", [Name]),
+ NodeName = list_to_atom(Name ++ "@" ++ host_name()),
+ NodeHandle#node_handle{nodename = NodeName};
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end;
+ Error ->
+ exit({failed_to_start_node, Name, Error})
+ end.
+
+%%
+%% command line creation
+%%
+
+host_name() ->
+ [$@ | Host] = lists:dropwhile(fun ($@) -> false; (_) -> true end,
+ atom_to_list(node())),
+ Host.
+
+mk_node_name(Config) ->
+ {A, B, C} = erlang:now(),
+ Case = ?config(testcase, Config),
+ atom_to_list(?MODULE)
+ ++ "_"
+ ++ atom_to_list(Case)
+ ++ "_"
+ ++ integer_to_list(A)
+ ++ "-"
+ ++ integer_to_list(B)
+ ++ "-"
+ ++ integer_to_list(C).
+
+mk_node_cmdline(ListenPort, Name, Args) ->
+ Static = "-detached -noinput",
+ Pa = filename:dirname(code:which(?MODULE)),
+ Prog = case catch init:get_argument(progname) of
+ {ok,[[P]]} -> P;
+ _ -> exit(no_progname_argument_found)
+ end,
+ NameSw = case net_kernel:longnames() of
+ false -> "-sname ";
+ _ -> "-name "
+ end,
+ {ok, Pwd} = file:get_cwd(),
+ Prog ++ " "
+ ++ Static ++ " "
+ ++ NameSw ++ " " ++ Name ++ " "
+ ++ "-pa " ++ Pa ++ " "
+ ++ "-run " ++ atom_to_list(?MODULE) ++ " cnct2tstsrvr "
+ ++ host_name() ++ " "
+ ++ integer_to_list(ListenPort) ++ " "
+ ++ Args ++ " "
+ ++ "-env ERL_CRASH_DUMP " ++ Pwd ++ "/erl_crash_dump." ++ Name ++ " "
+ ++ "-setcookie " ++ atom_to_list(erlang:get_cookie()).
+
+%%
+%% Connection handler test_server side
+%%
+
+await_ssl_node_up(Name, LSock) ->
+ case gen_tcp:accept(LSock, ?AWAIT_SLL_NODE_UP_TIMEOUT) of
+ timeout ->
+ gen_tcp:close(LSock),
+ ?t:format("Timeout waiting for ssl node ~s to come up~n",
+ [Name]),
+ timeout;
+ {ok, Socket} ->
+ gen_tcp:close(LSock),
+ case gen_tcp:recv(Socket, 0) of
+ {ok, Bin} ->
+ check_ssl_node_up(Socket, Name, Bin);
+ {error, closed} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node_before_up, Name})
+ end;
+ {error, Error} ->
+ gen_tcp:close(LSock),
+ exit({accept_failed, Error})
+ end.
+
+check_ssl_node_up(Socket, Name, Bin) ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {ssl_node_up, NodeName} ->
+ case list_to_atom(Name++"@"++host_name()) of
+ NodeName ->
+ Parent = self(),
+ Go = make_ref(),
+ %% Spawn connection handler on test server side
+ Pid = spawn_link(
+ fun () ->
+ receive Go -> ok end,
+ tstsrvr_con_loop(Name, Socket, Parent)
+ end),
+ ok = gen_tcp:controlling_process(Socket, Pid),
+ Pid ! Go,
+ #node_handle{connection_handler = Pid,
+ socket = Socket,
+ name = Name};
+ _ ->
+ exit({unexpected_ssl_node_connected, NodeName})
+ end;
+ Msg ->
+ exit({unexpected_msg_instead_of_ssl_node_up, Name, Msg})
+ end.
+
+send_to_ssl_node(#node_handle{connection_handler = Hndlr}, Term) ->
+ Hndlr ! {relay_to_ssl_node, term_to_binary(Term)},
+ ok.
+
+tstsrvr_con_loop(Name, Socket, Parent) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_ssl_node, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ exit({failed_to_relay_data_to_ssl_node, Name, Data})
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ exit({bad_data_received_from_ssl_node, Name, Bin});
+ {format, FmtStr, ArgList} ->
+ ?t:format(FmtStr, ArgList);
+ {message, Msg} ->
+ Parent ! Msg;
+ {apply_res, To, Ref, Res} ->
+ To ! {Ref, Res};
+ bye ->
+ ?t:format("Ssl node ~s stopped.~n", [Name]),
+ gen_tcp:close(Socket),
+ exit(normal);
+ Unknown ->
+ exit({unexpected_message_from_ssl_node, Name, Unknown})
+ end;
+ {tcp_closed, Socket} ->
+ gen_tcp:close(Socket),
+ exit({lost_connection_with_ssl_node, Name})
+ end,
+ tstsrvr_con_loop(Name, Socket, Parent).
+
+%%
+%% Connection handler ssl_node side
+%%
+
+% cnct2tstsrvr() is called via command line arg -run ...
+cnct2tstsrvr([Host, Port]) when list(Host), list(Port) ->
+ %% Spawn connection handler on ssl node side
+ ConnHandler
+ = spawn(fun () ->
+ case catch gen_tcp:connect(Host,
+ list_to_integer(Port),
+ [binary,
+ {packet, 4},
+ {active, false}]) of
+ {ok, Socket} ->
+ notify_ssl_node_up(Socket),
+ ets:new(test_server_info,
+ [set,
+ public,
+ named_table,
+ {keypos, 1}]),
+ ets:insert(test_server_info,
+ {test_server_handler, self()}),
+ ssl_node_con_loop(Socket);
+ _Error ->
+ halt("Failed to connect to test server")
+ end
+ end),
+ spawn(fun () ->
+ Mon = erlang:monitor(process, ConnHandler),
+ receive
+ {'DOWN', Mon, process, ConnHandler, Reason} ->
+ receive after 1000 -> ok end,
+ halt("test server connection handler terminated: "
+ ++
+ lists:flatten(io_lib:format("~p", [Reason])))
+ end
+ end).
+
+notify_ssl_node_up(Socket) ->
+ case catch gen_tcp:send(Socket,
+ term_to_binary({ssl_node_up, node()})) of
+ ok -> ok;
+ _ -> halt("Failed to notify test server that I'm up")
+ end.
+
+send_to_tstsrvr(Term) ->
+ case catch ets:lookup_element(test_server_info, test_server_handler, 2) of
+ Hndlr when pid(Hndlr) ->
+ Hndlr ! {relay_to_test_server, term_to_binary(Term)}, ok;
+ _ ->
+ receive after 200 -> ok end,
+ send_to_tstsrvr(Term)
+ end.
+
+ssl_node_con_loop(Socket) ->
+ inet:setopts(Socket,[{active,once}]),
+ receive
+ {relay_to_test_server, Data} when is_binary(Data) ->
+ case gen_tcp:send(Socket, Data) of
+ ok ->
+ ok;
+ _Error ->
+ gen_tcp:close(Socket),
+ halt("Failed to relay data to test server")
+ end;
+ {tcp, Socket, Bin} ->
+ case catch binary_to_term(Bin) of
+ {'EXIT', _} ->
+ gen_tcp:close(Socket),
+ halt("test server sent me bad data");
+ {apply, From, Ref, M, F, A} ->
+ spawn_link(
+ fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch apply(M, F, A))})
+ end);
+ {apply, From, Ref, Fun} ->
+ spawn_link(fun () ->
+ send_to_tstsrvr({apply_res,
+ From,
+ Ref,
+ (catch Fun())})
+ end);
+ stop ->
+ gen_tcp:send(Socket, term_to_binary(bye)),
+ gen_tcp:close(Socket),
+ init:stop(),
+ receive after infinity -> ok end;
+ _Unknown ->
+ halt("test server sent me an unexpected message")
+ end;
+ {tcp_closed, Socket} ->
+ halt("Lost connection to test server")
+ end,
+ ssl_node_con_loop(Socket).
+
+%%
+%% Setup ssl dist info
+%%
+
+rand_bin(N) ->
+ rand_bin(N, []).
+
+rand_bin(0, Acc) ->
+ Acc;
+rand_bin(N, Acc) ->
+ rand_bin(N-1, [random:uniform(256)-1|Acc]).
+
+make_randfile(Dir) ->
+ {ok, IoDev} = file:open(filename:join([Dir, "RAND"]), [write]),
+ {A, B, C} = erlang:now(),
+ random:seed(A, B, C),
+ ok = file:write(IoDev, rand_bin(1024)),
+ file:close(IoDev).
+
+append_files(FileNames, ResultFileName) ->
+ {ok, ResultFile} = file:open(ResultFileName, [write]),
+ do_append_files(FileNames, ResultFile).
+
+do_append_files([], RF) ->
+ ok = file:close(RF);
+do_append_files([F|Fs], RF) ->
+ {ok, Data} = file:read_file(F),
+ ok = file:write(RF, Data),
+ do_append_files(Fs, RF).
+
+setup_dist_opts(Name, PrivDir) ->
+ NodeDir = filename:join([PrivDir, Name]),
+ RGenDir = filename:join([NodeDir, "rand_gen"]),
+ ok = file:make_dir(NodeDir),
+ ok = file:make_dir(RGenDir),
+ make_randfile(RGenDir),
+ make_certs:all(RGenDir, NodeDir),
+ SDir = filename:join([NodeDir, "server"]),
+ SC = filename:join([SDir, "cert.pem"]),
+ SK = filename:join([SDir, "key.pem"]),
+ SKC = filename:join([SDir, "keycert.pem"]),
+ append_files([SK, SC], SKC),
+ CDir = filename:join([NodeDir, "client"]),
+ CC = filename:join([CDir, "cert.pem"]),
+ CK = filename:join([CDir, "key.pem"]),
+ CKC = filename:join([CDir, "keycert.pem"]),
+ append_files([CK, CC], CKC),
+ "-proto_dist inet_ssl "
+ ++ "-ssl_dist_opt server_certfile " ++ SKC ++ " "
+ ++ "-ssl_dist_opt client_certfile " ++ CKC ++ " "
+.% ++ "-ssl_dist_opt verify 1 depth 1".
+
+%%
+%% Start scripts etc...
+%%
+
+add_ssl_opts_config(Config) ->
+ %%
+ %% Start with boot scripts if on an installed system; otherwise,
+ %% just point out ssl ebin with -pa.
+ %%
+ try
+ Dir = ?config(priv_dir, Config),
+ LibDir = code:lib_dir(),
+ Apps = application:which_applications(),
+ {value, {stdlib, _, STDL_VSN}} = lists:keysearch(stdlib, 1, Apps),
+ {value, {kernel, _, KRNL_VSN}} = lists:keysearch(kernel, 1, Apps),
+ StdlDir = filename:join([LibDir, "stdlib-" ++ STDL_VSN]),
+ KrnlDir = filename:join([LibDir, "kernel-" ++ KRNL_VSN]),
+ {ok, _} = file:read_file_info(StdlDir),
+ {ok, _} = file:read_file_info(KrnlDir),
+ SSL_VSN = case lists:keysearch(ssl, 1, Apps) of
+ {value, {ssl, _, VSN}} ->
+ VSN;
+ _ ->
+ application:start(ssl),
+ try
+ {value,
+ {ssl,
+ _,
+ VSN}} = lists:keysearch(ssl,
+ 1,
+ application:which_applications()),
+ VSN
+ after
+ application:stop(ssl)
+ end
+ end,
+ SslDir = filename:join([LibDir, "ssl-" ++ SSL_VSN]),
+ {ok, _} = file:read_file_info(SslDir),
+ %% We are using an installed otp system, create the boot script.
+ Script = filename:join(Dir, atom_to_list(?MODULE)),
+ {ok, RelFile} = file:open(Script ++ ".rel", [write]),
+ io:format(RelFile,
+ "{release, ~n"
+ " {\"SSL distribution test release\", \"~s\"},~n"
+ " {erts, \"~s\"},~n"
+ " [{kernel, \"~s\"},~n"
+ " {stdlib, \"~s\"},~n"
+ " {ssl, \"~s\"}]}.~n",
+ [case catch erlang:system_info(otp_release) of
+ {'EXIT', _} -> "R11B";
+ Rel -> Rel
+ end,
+ erlang:system_info(version),
+ KRNL_VSN,
+ STDL_VSN,
+ SSL_VSN]),
+ ok = file:close(RelFile),
+ ok = systools:make_script(Script, []),
+ [{ssl_opts, "-boot " ++ Script} | Config]
+ catch
+ _:_ ->
+ [{ssl_opts, "-pa " ++ filename:dirname(code:which(ssl))}
+ | add_comment_config(
+ "Bootscript wasn't used since the test wasn't run on an "
+ "installed OTP system.",
+ Config)]
+ end.
+
+%%
+%% Add common comments to config
+%%
+
+add_comment_config(Comment, []) ->
+ [{comment, Comment}];
+add_comment_config(Comment, [{comment, OldComment} | Cs]) ->
+ [{comment, Comment ++ " " ++ OldComment} | Cs];
+add_comment_config(Comment, [C|Cs]) ->
+ [C|add_comment_config(Comment, Cs)].
+
+%%
+%% Call when test case success
+%%
+
+success(Config) ->
+ case lists:keysearch(comment, 1, Config) of
+ {value, {comment, _} = Res} -> Res;
+ _ -> ok
+ end.
diff --git a/lib/ssl/test/old_ssl_misc_SUITE.erl b/lib/ssl/test/old_ssl_misc_SUITE.erl
new file mode 100644
index 0000000000..55d1b71025
--- /dev/null
+++ b/lib/ssl/test/old_ssl_misc_SUITE.erl
@@ -0,0 +1,105 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_misc_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ seed/1,
+ app/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, 5).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of misc in ssl.erl interface.";
+all(suite) ->
+ {conf,
+ config,
+ [seed, app],
+ finish
+ }.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+seed(doc) ->
+ "Test that ssl:seed/1 works.";
+seed(suite) ->
+ [];
+seed(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{seed, "tjosan"},
+ {sockopts, [{backlog, NConns}, {active, once}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ?line test_server_only(NConns, LCmds, [], Timeout, ?MODULE,
+ Config).
+
+app(doc) ->
+ "Test that the ssl app file is ok";
+app(suite) ->
+ [];
+app(Config) when list(Config) ->
+ ?line ok = test_server:app_test(ssl).
+
+
diff --git a/lib/ssl/test/old_ssl_passive_SUITE.erl b/lib/ssl/test/old_ssl_passive_SUITE.erl
new file mode 100644
index 0000000000..4cb8c1f0cd
--- /dev/null
+++ b/lib/ssl/test/old_ssl_passive_SUITE.erl
@@ -0,0 +1,374 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_passive_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ server_accept_timeout/1,
+ cinit_return_chkclose/1,
+ sinit_return_chkclose/1,
+ cinit_big_return_chkclose/1,
+ sinit_big_return_chkclose/1,
+ cinit_big_echo_chkclose/1,
+ sinit_big_echo_chkclose/1,
+ cinit_few_echo_chkclose/1,
+ cinit_many_echo_chkclose/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(MANYCONNS, ssl_test_MACHINE:many_conns()).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in passive mode.";
+all(suite) ->
+ {conf,
+ config,
+ [server_accept_timeout,
+ cinit_return_chkclose,
+ sinit_return_chkclose,
+ cinit_big_return_chkclose,
+ sinit_big_return_chkclose,
+ cinit_big_echo_chkclose,
+ sinit_big_echo_chkclose,
+ cinit_few_echo_chkclose,
+ cinit_many_echo_chkclose,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+server_accept_timeout(doc) ->
+ "Server has one pending accept with timeout. Checks that return "
+ "value is {error, timeout}.";
+server_accept_timeout(suite) ->
+ [];
+server_accept_timeout(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ AccTimeout = 3000,
+
+ ?line {ok, {_, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, AccTimeout},
+ accept_timeout],
+ ?line test_server_only(NConns, LCmds, ACmds, Timeout, ?MODULE, Config).
+
+cinit_return_chkclose(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_return_chkclose(suite) ->
+ [];
+cinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_return_chkclose(doc) ->
+ "Server sends 1000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_return_chkclose(suite) ->
+ [];
+sinit_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_return_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+cinit_big_return_chkclose(suite) ->
+ [];
+cinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_return_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that receives them, sends them "
+ "back, and closes. Server waits for close. Both have certs.";
+sinit_big_return_chkclose(suite) ->
+ [];
+sinit_big_return_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {recv, DataSize}, {send, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_big_echo_chkclose(doc) ->
+ "Client sends 50000 bytes to server, that echoes them back "
+ "and closes. Client waits for close. Both have certs.";
+cinit_big_echo_chkclose(suite) ->
+ [];
+cinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+sinit_big_echo_chkclose(doc) ->
+ "Server sends 50000 bytes to client, that echoes them back "
+ "and closes. Server waits for close. Both have certs.";
+sinit_big_echo_chkclose(suite) ->
+ [];
+sinit_big_echo_chkclose(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 50000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {echo, DataSize},
+ close],
+
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+
+cinit_few_echo_chkclose(X) -> cinit_many_echo_chkclose(X, 7).
+
+cinit_many_echo_chkclose(X) -> cinit_many_echo_chkclose(X, ?MANYCONNS).
+
+cinit_many_echo_chkclose(doc, _NConns) ->
+ "clients send 10000 bytes to server, that echoes them back "
+ "and closes. Clients wait for close. All have certs.";
+cinit_many_echo_chkclose(suite, _NConns) ->
+ [];
+cinit_many_echo_chkclose(Config, NConns) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 10000, LPort = 3456,
+ Timeout = 80000,
+
+ io:format("~w connections", [NConns]),
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {echo, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
+cinit_cnocert(doc) ->
+ "Client sends 1000 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Client has no cert, "
+ "but server has.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}, {active, false}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize}, {send, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sockopts, [{active, false}]},
+ {connect, {Host, LPort}},
+ {send, DataSize}, {recv, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, ?MODULE,
+ Config).
+
diff --git a/lib/ssl/test/old_ssl_peer_cert_SUITE.erl b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
new file mode 100644
index 0000000000..f0b8db2607
--- /dev/null
+++ b/lib/ssl/test/old_ssl_peer_cert_SUITE.erl
@@ -0,0 +1,180 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_peer_cert_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_plain/1,
+ cinit_both_verify/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl verification and peer certificate retrieval.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_plain,
+ cinit_both_verify,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_plain(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "but both use the defaults for verify and depth, but still tries "
+ "to retreive each others certificates.";
+cinit_plain(suite) ->
+ [];
+cinit_plain(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts, SsslOpts}} = mk_ssl_cert_opts(Config),
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ nopeercert,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_both_verify(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "and both verify each other.";
+cinit_both_verify(suite) ->
+ [];
+cinit_both_verify(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts0, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line CsslOpts = [{verify, 2}, {depth, 2} | CsslOpts0],
+ ?line SsslOpts = [{verify, 2}, {depth, 3} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ peercert,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_cnocert(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ peercert,
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+
diff --git a/lib/ssl/test/old_ssl_protocol_SUITE.erl b/lib/ssl/test/old_ssl_protocol_SUITE.erl
new file mode 100644
index 0000000000..7bde5d6749
--- /dev/null
+++ b/lib/ssl/test/old_ssl_protocol_SUITE.erl
@@ -0,0 +1,169 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_protocol_SUITE).
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2, config/1,
+ finish/1, sslv2/1, sslv3/1, tlsv1/1, sslv2_sslv3/1,
+ sslv2_tlsv1/1, sslv3_tlsv1/1, sslv2_sslv3_tlsv1/1]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = test_server:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of configuration protocol_version.";
+all(suite) ->
+ {conf,
+ config,
+ [sslv2, sslv3, tlsv1, sslv2_sslv3, sslv2_tlsv1, sslv3_tlsv1,
+ sslv2_sslv3_tlsv1],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no other purpose than closing the conf case.";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+%%%%%
+
+sslv2(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose SSLv2.";
+sslv2(suite) ->
+ [];
+sslv2(Config) when list(Config) ->
+ do_run_test(Config, [sslv2]).
+
+sslv3(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose SSLv3.";
+sslv3(suite) ->
+ [];
+sslv3(Config) when list(Config) ->
+ do_run_test(Config, [sslv3]).
+
+tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose TLSv1.";
+tlsv1(suite) ->
+ [];
+tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [tlsv1]).
+
+sslv2_sslv3(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2 and SSLv3.";
+sslv2_sslv3(suite) ->
+ [];
+sslv2_sslv3(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, sslv3]).
+
+sslv2_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2 and TLSv1.";
+sslv2_tlsv1(suite) ->
+ [];
+sslv2_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, tlsv1]).
+
+sslv3_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv3 and TLSv1.";
+sslv3_tlsv1(suite) ->
+ [];
+sslv3_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv3, tlsv1]).
+
+sslv2_sslv3_tlsv1(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close. "
+ "Client and server choose between SSLv2, SSLv3, and TLSv1.";
+sslv2_sslv3_tlsv1(suite) ->
+ [];
+sslv2_sslv3_tlsv1(Config) when list(Config) ->
+ do_run_test(Config, [sslv2, sslv3, tlsv1]).
+
+%%%%
+
+do_run_test(Config0, Protocols) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ Timeout = 40000, NConns = 1,
+ DataSize = 10,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config0),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ connection_info,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ connection_info,
+ {send, DataSize},
+ await_close],
+ Config1 = [{env, [{protocol_version, Protocols}]} | Config0],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config1).
+
+
diff --git a/lib/ssl/test/old_ssl_verify_SUITE.erl b/lib/ssl/test/old_ssl_verify_SUITE.erl
new file mode 100644
index 0000000000..5db964526f
--- /dev/null
+++ b/lib/ssl/test/old_ssl_verify_SUITE.erl
@@ -0,0 +1,141 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_ssl_verify_SUITE).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ finish/1,
+ cinit_both_verify/1,
+ cinit_cnocert/1
+ ]).
+
+-import(ssl_test_MACHINE, [mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?DEFAULT_TIMEOUT),
+ [{watchdog, WatchDog}| Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test of ssl.erl interface in active mode.";
+all(suite) ->
+ {conf,
+ config,
+ [cinit_both_verify,
+ cinit_cnocert],
+ finish}.
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+
+ %% Check if SSL exists. If this case fails, all other cases are skipped
+ case ssl:start() of
+ ok -> ssl:stop();
+ {error, {already_started, _}} -> ssl:stop();
+ Error -> ?t:fail({failed_starting_ssl,Error})
+ end,
+ Config.
+
+finish(doc) ->
+ "This test case has no mission other than closing the conf case";
+finish(suite) ->
+ [];
+finish(Config) ->
+ Config.
+
+cinit_both_verify(doc) ->
+ "Server closes after accept, Client waits for close. Both have certs "
+ "and both verify each other.";
+cinit_both_verify(suite) ->
+ [];
+cinit_both_verify(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3456,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {CsslOpts0, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line CsslOpts = [{verify, 2}, {depth, 2} | CsslOpts0],
+ ?line SsslOpts = [{verify, 2}, {depth, 3} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {sslopts, CsslOpts},
+ {connect, {Host, LPort}},
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+cinit_cnocert(doc) ->
+ "Client has no cert. Nor the client, nor the server is verifying its "
+ "peer. Server closes, client waits for close.";
+cinit_cnocert(suite) ->
+ [];
+cinit_cnocert(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ DataSize = 1000, LPort = 3457,
+ Timeout = 40000, NConns = 1,
+
+ ?line {ok, {_, SsslOpts0}} = mk_ssl_cert_opts(Config),
+ ?line SsslOpts = [{verify, 0}, {depth, 2} | SsslOpts0],
+
+ ?line {ok, Host} = inet:gethostname(),
+
+ LCmds = [{sockopts, [{backlog, NConns}]},
+ {sslopts, SsslOpts},
+ {listen, LPort},
+ wait_sync,
+ lclose],
+ ACmds = [{timeout, Timeout},
+ accept,
+ {recv, DataSize},
+ close],
+ CCmds = [{timeout, Timeout},
+ {connect, {Host, LPort}},
+ {send, DataSize},
+ await_close],
+ ?line test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout,
+ ?MODULE, Config).
+
+
diff --git a/lib/ssl/test/old_transport_accept_SUITE.erl b/lib/ssl/test/old_transport_accept_SUITE.erl
new file mode 100644
index 0000000000..4bb09cee19
--- /dev/null
+++ b/lib/ssl/test/old_transport_accept_SUITE.erl
@@ -0,0 +1,238 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(old_transport_accept_SUITE).
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Default timetrap timeout (set in init_per_testcase).
+-define(default_timeout, ?t:minutes(1)).
+-define(application, ssh).
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ config/1,
+ echo_once/1,
+ echo_twice/1,
+ close_before_ssl_accept/1,
+ server/5,
+ tolerant_server/5,
+ client/5
+ ]).
+
+init_per_testcase(_Case, Config) ->
+ WatchDog = ssl_test_lib:timetrap(?default_timeout),
+ [{watchdog, WatchDog}, {protomod, gen_tcp}, {serialize_accept, true}|
+ Config].
+
+fin_per_testcase(_Case, Config) ->
+ WatchDog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(WatchDog).
+
+all(doc) ->
+ "Test transport_accept and ssl_accept";
+all(suite) ->
+ [config, echo_once, echo_twice, close_before_ssl_accept].
+
+config(doc) ->
+ "Want to se what Config contains.";
+config(suite) ->
+ [];
+config(Config) ->
+ io:format("Config: ~p~n", [Config]),
+ ok.
+
+echo_once(doc) ->
+ "Client sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+echo_once(suite) ->
+ [];
+echo_once(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ N = 1,
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, server, [Self, LPort, SOpts, Msg, N]),
+ Client = spawn_link(Node, ?MODULE, client, [Host, LPort, COpts, Msg, N]),
+ ok = receive
+ {Server, listening} ->
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (1) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+close_before_ssl_accept(doc) ->
+ "Client sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+close_before_ssl_accept(suite) ->
+ [];
+close_before_ssl_accept(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, tolerant_server,
+ [Self, LPort, SOpts, Msg, 2]),
+ Client = spawn_link(Node, ?MODULE, client,
+ [Host, LPort, COpts, Msg, 1]),
+ ok = receive
+ {Server, listening} ->
+ {ok, S} = gen_tcp:connect(Host, LPort, []),
+ gen_tcp:close(S),
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (1) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+client(Host, LPort, COpts, Msg, N) ->
+ ok = receive
+ {_Server, listening} ->
+ ok;
+ E ->
+ io:format("bad receive (2) ~p\n", [E]),
+ E
+ end,
+ Opts = COpts ++ [{packet, raw}, {active, false}],
+ app(),
+ lists:foreach(fun(_) ->
+ {ok, S} = ssl:connect(Host, LPort, Opts),
+ ssl:send(S, Msg),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ssl:close(S)
+ end, lists:seq(1, N)).
+
+echo_twice(doc) ->
+ "Two clients sends 256 bytes to server, that receives them, sends them "
+ "back, and closes. Client waits for close. Both have certs.";
+echo_twice(suite) ->
+ [];
+echo_twice(Config) when list(Config) ->
+ process_flag(trap_exit, true),
+ LPort = 3456,
+ {ok, Host} = inet:gethostname(),
+ {ok, {COpts, SOpts}} = ssl_test_MACHINE:mk_ssl_cert_opts(Config),
+ N = 2,
+ Msg = lists:seq(0, 255),
+ Self = self(),
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ Node = start_node(server, Params),
+ CNode = start_node(client, Params),
+ Server = spawn_link(Node, ?MODULE, server,
+ [Self, LPort, SOpts, Msg, N]),
+ Client = spawn_link(Node, ?MODULE, client,
+ [Host, LPort, COpts, Msg, N]),
+ ok = receive
+ {Server, listening} ->
+ Client ! {Server, listening},
+ ok;
+ E ->
+ io:format("bad receive (3) ~p\n", [E]),
+ E
+ end,
+ receive
+ {Server, done} ->
+ ok
+ end,
+ test_server:stop_node(Node),
+ test_server:stop_node(CNode).
+
+server(Client, Port, SOpts, Msg, N) ->
+ app(),
+ process_flag(trap_exit, true),
+ Opts = SOpts ++ [{packet, raw}, {active, false}],
+ {ok, LSock} = ssl:listen(Port, Opts),
+ Client ! {self(), listening},
+ server_loop(Client, LSock, Msg, N).
+
+server_loop(Client, _, _, 0) ->
+ Client ! {self(), done};
+server_loop(Client, LSock, Msg, N) ->
+ {ok, S} = ssl:transport_accept(LSock),
+ ok = ssl:ssl_accept(S),
+ %% P = ssl:controlling_process(S, Proxy),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ok = ssl:send(S, Msg),
+ ok = ssl:close(S),
+ server_loop(Client, LSock, Msg, N-1).
+
+tolerant_server(Client, Port, SOpts, Msg, N) ->
+ app(),
+ process_flag(trap_exit, true),
+ Opts = SOpts ++ [{packet, raw}, {active, false}],
+ {ok, LSock} = ssl:listen(Port, Opts),
+ Client ! {self(), listening},
+ tolerant_server_loop(Client, LSock, Msg, N).
+
+tolerant_server_loop(Client, _, _, 0) ->
+ Client ! {self(), done};
+tolerant_server_loop(Client, LSock, Msg, N) ->
+ {ok, S} = ssl:transport_accept(LSock),
+ case ssl:ssl_accept(S) of
+ ok ->
+ %% P = ssl:controlling_process(S, Proxy),
+ {ok, Msg} = ssl:recv(S, length(Msg)),
+ ok = ssl:send(S, Msg),
+ ok = ssl:close(S);
+ E ->
+ io:format("ssl_accept error: ~p\n", [E])
+ end,
+ tolerant_server_loop(Client, LSock, Msg, N-1).
+
+app() ->
+ case application:get_application(ssl) of
+ undefined ->
+ application:start(ssl);
+ _ ->
+ ok
+ end.
+
+start_node(Kind, Params) ->
+ S = atom_to_list(?MODULE)++"_" ++ atom_to_list(Kind),
+ {ok, Node} = test_server:start_node(list_to_atom(S), slave, [{args, Params}]),
+ Node.
+
diff --git a/lib/ssl/test/ssl.cover b/lib/ssl/test/ssl.cover
new file mode 100644
index 0000000000..138bf96b9d
--- /dev/null
+++ b/lib/ssl/test/ssl.cover
@@ -0,0 +1,7 @@
+{exclude, [ssl_pkix_oid,
+ 'PKIX1Algorithms88',
+ 'PKIX1Explicit88',
+ 'PKIX1Implicit88',
+ 'PKIXAttributeCertificate',
+ 'SSL-PKIX']}.
+
diff --git a/lib/ssl/test/ssl.spec b/lib/ssl/test/ssl.spec
new file mode 100644
index 0000000000..6ef4fb73db
--- /dev/null
+++ b/lib/ssl/test/ssl.spec
@@ -0,0 +1 @@
+{topcase, {dir, "../ssl_test"}}.
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
new file mode 100644
index 0000000000..2b247532ee
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -0,0 +1,2075 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_basic_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-define('24H_in_sec', 86400).
+-define(TIMEOUT, 60000).
+-define(EXPIRE, 10).
+
+-behaviour(ssl_session_cache_api).
+
+%% For the session cache tests
+-export([init/0, terminate/1, lookup/2, update/3,
+ delete/2, foldl/3, select_session/2]).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(session_cache_process_list, Config) ->
+ init_customized_session_cache(Config);
+
+init_per_testcase(session_cache_process_mnesia, Config) ->
+ mnesia:start(),
+ init_customized_session_cache(Config);
+
+init_per_testcase(reuse_session_expired, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?EXPIRE * 1000 * 5),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_lifetime, ?EXPIRE),
+ ssl:start(),
+ [{watchdog, Dog} | Config];
+
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+init_customized_session_cache(Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, session_cb, ?MODULE),
+ ssl:start(),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(session_cache_process_list, Config) ->
+ application:unset_env(ssl, session_cb),
+ end_per_testcase(default_action, Config);
+end_per_testcase(session_cache_process_mnesia, Config) ->
+ application:unset_env(ssl, session_cb),
+ mnesia:stop(),
+ end_per_testcase(default_action, Config);
+end_per_testcase(reuse_session_expired, Config) ->
+ application:unset_env(ssl, session_lifetime),
+ end_per_testcase(default_action, Config);
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test the basic ssl functionality"];
+
+all(suite) ->
+ [app, connection_info, controlling_process, controller_dies,
+ peercert, connect_dist,
+ peername, sockname, socket_options, versions, cipher_suites, upgrade,
+ upgrade_with_timeout,
+ ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown,
+ shutdown_write, shutdown_both, shutdown_error, ciphers,
+ send_close,
+ server_verify_peer_passive,
+ server_verify_peer_active, server_verify_peer_active_once,
+ server_verify_none_passive, server_verify_none_active,
+ server_verify_none_active_once,
+ server_verify_no_cacerts, client_verify_none_passive,
+ client_verify_none_active, client_verify_none_active_once
+ %%, session_cache_process_list, session_cache_process_mnesia
+ ,reuse_session, reuse_session_expired, server_does_not_want_to_reuse_session
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+app(doc) ->
+ "Test that the ssl app file is ok";
+app(suite) ->
+ [];
+app(Config) when is_list(Config) ->
+ ok = test_server:app_test(ssl).
+
+connection_info(doc) ->
+ ["Test the API function ssl:connection_info/1"];
+connection_info(suite) ->
+ [];
+connection_info(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[{rsa,rc4_128,sha,no_export}]} |
+ ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha,no_export}}},
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connection_info_result(Socket) ->
+ ssl:connection_info(Socket).
+
+%%--------------------------------------------------------------------
+
+controlling_process(doc) ->
+ ["Test API function controlling_process/2"];
+
+controlling_process(suite) ->
+ [];
+
+controlling_process(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controlling_process_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ receive
+ {ssl, _, ServerMsg} ->
+ receive
+ {ssl, _, ClientMsg} ->
+ ok
+ end;
+ {ssl, _, ClientMsg} ->
+ receive
+ {ssl, _, ServerMsg} ->
+ ok
+ end;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+controlling_process_result(Socket, Pid, Msg) ->
+ ok = ssl:controlling_process(Socket, Pid),
+ %% Make sure other side has evaluated controlling_process
+ %% before message is sent
+ test_server:sleep(100),
+ ssl:send(Socket, Msg),
+ no_result_msg.
+
+
+controller_dies(doc) ->
+ ["Test that the socket is closed after controlling process dies"];
+controller_dies(suite) -> [];
+controller_dies(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ ClientMsg = "Hello server",
+ ServerMsg = "Hello client",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ServerMsg]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n", [self(), Client, Server]),
+ timer:sleep(200), %% so that they are connected
+
+ process_flag(trap_exit, true),
+
+ %% Test that clients die
+ exit(Client, killed),
+ get_close(Client, ?LINE),
+
+ %% Test that clients die when process disappear
+ Server ! listen, timer:sleep(200),
+ Tester = self(),
+ Connect = fun(Pid) ->
+ {ok, Socket} = ssl:connect(Hostname, Port,
+ [{reuseaddr,true},{ssl_imp,new}]),
+ Pid ! {self(), connected, Socket},
+ receive die_nice -> normal end
+ end,
+ Client2 = spawn_link(fun() -> Connect(Tester) end),
+ receive {Client2, connected, _Socket} -> Client2 ! die_nice end,
+
+ get_close(Client2, ?LINE),
+
+ %% Test that clients die when the controlling process have changed
+ Server ! listen, timer:sleep(200),
+
+ Client3 = spawn_link(fun() -> Connect(Tester) end),
+ Controller = spawn_link(fun() -> receive die_nice -> normal end end),
+ receive
+ {Client3, connected, Socket} ->
+ ok = ssl:controlling_process(Socket, Controller),
+ Client3 ! die_nice
+ end,
+
+ test_server:format("Wating on exit ~p~n",[Client3]),
+ receive {'EXIT', Client3, normal} -> ok end,
+
+ receive %% Client3 is dead but that doesn't matter, socket should not be closed.
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 1000 ->
+ ok
+ end,
+ Controller ! die_nice,
+ get_close(Controller, ?LINE),
+
+ %% Test that servers die
+ Server ! listen, timer:sleep(200),
+ LastClient = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ controller_dies_result, [self(),
+ ClientMsg]}},
+ {options, [{reuseaddr,true}|ClientOpts]}]),
+ timer:sleep(200), %% so that they are connected
+
+ exit(Server, killed),
+ get_close(Server, ?LINE),
+ process_flag(trap_exit, false),
+ ssl_test_lib:close(LastClient).
+
+controller_dies_result(_Socket, _Pid, _Msg) ->
+ receive Result -> Result end.
+
+get_close(Pid, Where) ->
+ receive
+ {'EXIT', Pid, _Reason} ->
+ receive
+ {_, {ssl_closed, Socket}} ->
+ test_server:format("Socket closed ~p~n",[Socket]);
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 5000 ->
+ test_server:fail({timeout, {line, ?LINE, Where}})
+ end;
+ Unexpected ->
+ test_server:format("Unexpected ~p~n",[Unexpected]),
+ test_server:fail({line, ?LINE-1})
+ after 5000 ->
+ test_server:fail({timeout, {line, ?LINE, Where}})
+ end.
+
+%%--------------------------------------------------------------------
+peercert(doc) ->
+ [""];
+
+peercert(suite) ->
+ [];
+
+peercert(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peercert_result, []}},
+ {options, ClientOpts}]),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ {ok, [{cert, BinCert, _}]} = public_key:pem_to_der(CertFile),
+ {ok, ErlCert} = public_key:pkix_decode_cert(BinCert, otp),
+
+ ServerMsg = {{error, no_peercert}, {error, no_peercert}},
+ ClientMsg = {{ok, BinCert}, {ok, ErlCert}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+peercert_result(Socket) ->
+ Result1 = ssl:peercert(Socket),
+ Result2 = ssl:peercert(Socket, [ssl]),
+ {Result1, Result2}.
+
+%%--------------------------------------------------------------------
+connect_dist(doc) ->
+ ["Test a simple connect as is used by distribution"];
+
+connect_dist(suite) ->
+ [];
+
+connect_dist(Config) when is_list(Config) ->
+ ClientOpts0 = ?config(client_kc_opts, Config),
+ ClientOpts = [{ssl_imp, new},{active, false}, {packet,4}|ClientOpts0],
+ ServerOpts0 = ?config(server_kc_opts, Config),
+ ServerOpts = [{ssl_imp, new},{active, false}, {packet,4}|ServerOpts0],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connect_dist_s, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connect_dist_c, []}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+connect_dist_s(S) ->
+ Msg = term_to_binary({erlang,term}),
+ ok = ssl:send(S, <<(size(Msg)):32, Msg/binary>>).
+
+connect_dist_c(S) ->
+ Test = binary_to_list(term_to_binary({erlang,term})),
+ {ok, Test} = ssl:recv(S, 0, 10000),
+ ok.
+
+
+%%--------------------------------------------------------------------
+peername(doc) ->
+ ["Test API function peername/1"];
+
+peername(suite) ->
+ [];
+
+peername(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, peername_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode),
+ ServerMsg = {ok, {ClientIp, ClientPort}},
+ ClientMsg = {ok, {ServerIp, Port}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+peername_result(S) ->
+ ssl:peername(S).
+
+%%--------------------------------------------------------------------
+sockname(doc) ->
+ ["Test API function sockname/1"];
+
+sockname(suite) ->
+ [];
+
+sockname(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, sockname_result, []}},
+ {options, [{port, 0} | ClientOpts]}]),
+ ClientPort = ssl_test_lib:inet_port(Client),
+ ServerIp = ssl_test_lib:node_to_hostip(ServerNode),
+ ClientIp = ssl_test_lib:node_to_hostip(ClientNode),
+ ServerMsg = {ok, {ServerIp, Port}},
+ ClientMsg = {ok, {ClientIp, ClientPort}},
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+sockname_result(S) ->
+ ssl:sockname(S).
+
+%%--------------------------------------------------------------------
+cipher_suites(doc) ->
+ ["Test API function cipher_suites/0"];
+
+cipher_suites(suite) ->
+ [];
+
+cipher_suites(Config) when is_list(Config) ->
+ MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha,no_export},
+ [_|_] = Suites = ssl:cipher_suites(),
+ true = lists:member(MandatoryCipherSuite, Suites).
+%%--------------------------------------------------------------------
+socket_options(doc) ->
+ ["Test API function getopts/2 and setopts/2"];
+
+socket_options(suite) ->
+ [];
+
+socket_options(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Values = [{mode, list}, {packet, 0}, {header, 0},
+ {active, true}],
+ %% Shall be the reverse order of Values!
+ Options = [active, header, packet, mode],
+
+ NewValues = [{mode, binary}, {active, once}],
+ %% Shall be the reverse order of NewValues!
+ NewOptions = [active, mode],
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, socket_options_result,
+ [Options, Values, NewOptions, NewValues]}},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
+ %% Test get/set emulated opts
+ {ok, DefaultValues} = ssl:getopts(Socket, Options),
+ ssl:setopts(Socket, NewValues),
+ {ok, NewValues} = ssl:getopts(Socket, NewOptions),
+ %% Test get/set inet opts
+ {ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
+ ok.
+
+%%--------------------------------------------------------------------
+versions(doc) ->
+ ["Test API function versions/0"];
+
+versions(suite) ->
+ [];
+
+versions(Config) when is_list(Config) ->
+ [_|_] = Versions = ssl:versions(),
+ test_server:format("~p~n", [Versions]).
+
+%%--------------------------------------------------------------------
+send_recv(doc) ->
+ [""];
+
+send_recv(suite) ->
+ [];
+
+send_recv(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client =
+ ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+send_close(doc) ->
+ [""];
+
+send_close(suite) ->
+ [];
+
+send_close(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ {ok, TcpS} = rpc:call(ClientNode, gen_tcp, connect,
+ [Hostname,Port,[binary, {active, false}, {reuseaddr, true}]]),
+ {ok, SslS} = rpc:call(ClientNode, ssl, connect,
+ [TcpS,[{active, false}|ClientOpts]]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), self(), Server]),
+ ok = ssl:send(SslS, "HejHopp"),
+ {ok,<<"Hejhopp">>} = ssl:recv(SslS, 7),
+ gen_tcp:close(TcpS),
+ {error, _} = ssl:send(SslS, "HejHopp"),
+ ssl_test_lib:close(Server).
+
+%%--------------------------------------------------------------------
+upgrade(doc) ->
+ ["Test that you can upgrade an tcp connection to an ssl connection"];
+
+upgrade(suite) ->
+ [];
+
+upgrade(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+upgrade_result(Socket) ->
+ ok = ssl:send(Socket, "Hejhopp"),
+ %% Make sure binary is inherited from tcp socket and that we do
+ %% not get the list default!
+ receive
+ {ssl, _, <<"Hejhopp">>} ->
+ ok
+ end.
+
+%%--------------------------------------------------------------------
+upgrade_with_timeout(doc) ->
+ ["Test ssl_accept/3"];
+
+upgrade_with_timeout(suite) ->
+ [];
+
+upgrade_with_timeout(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ TcpOpts = [binary, {reuseaddr, true}],
+
+ Server = ssl_test_lib:start_upgrade_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {timeout, 5000},
+ {mfa, {?MODULE,
+ upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_upgrade_client([{node, ClientNode},
+ {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, upgrade_result, []}},
+ {tcp_options, TcpOpts},
+ {ssl_options, ClientOpts}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+ipv6(doc) ->
+ ["Test ipv6."];
+ipv6(suite) ->
+ [];
+ipv6(Config) when is_list(Config) ->
+ {ok, Hostname0} = inet:gethostname(),
+
+ case lists:member(list_to_atom(Hostname0), ?config(ipv6_hosts, Config)) of
+ true ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} =
+ ssl_test_lib:run_where(Config, ipv6),
+ Server = ssl_test_lib:start_server([{node, ServerNode},
+ {port, 0}, {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options,
+ [inet6, {active, false} | ClientOpts]}]),
+
+ test_server:format("Testcase ~p, Client ~p Server ~p ~n",
+ [self(), Client, Server]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client);
+ false ->
+ {skip, "Host does not support IPv6"}
+ end.
+
+%%--------------------------------------------------------------------
+
+ekeyfile(doc) ->
+ ["Test what happens with an invalid key file"];
+
+ekeyfile(suite) ->
+ [];
+
+ekeyfile(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ BadOpts = ?config(server_bad_key, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ Server =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, BadOpts}]),
+ Client =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()}, {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, {error, ekeyfile}, Client,
+ {error, closed}).
+
+%%--------------------------------------------------------------------
+
+ecertfile(doc) ->
+ ["Test what happens with an invalid cert file"];
+
+ecertfile(suite) ->
+ [];
+
+ecertfile(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerBadOpts = ?config(server_bad_cert, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, ServerBadOpts}]),
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server0, {error, ecertfile}, Client0,
+ {error, closed}).
+
+
+%%--------------------------------------------------------------------
+ecacertfile(doc) ->
+ ["Test what happens with an invalid cacert file"];
+
+ecacertfile(suite) ->
+ [];
+
+ecacertfile(Config) when is_list(Config) ->
+ ClientOpts = [{reuseaddr, true}|?config(client_opts, Config)],
+ ServerBadOpts = [{reuseaddr, true}|?config(server_bad_ca, Config)],
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, Port}, {from, self()},
+ {options, ServerBadOpts}]),
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server0, {error, ecacertfile},
+ Client0, {error, closed}),
+
+ File0 = proplists:get_value(cacertfile, ServerBadOpts),
+ File = File0 ++ "do_not_exit.pem",
+ ServerBadOpts1 = [{cacertfile, File}|proplists:delete(cacertfile, ServerBadOpts)],
+
+ Server1 =
+ ssl_test_lib:start_server_error([{node, ServerNode},
+ {port, Port}, {from, self()},
+ {options, ServerBadOpts1}]),
+ Client1 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server1, {error, ecacertfile},
+ Client1, {error, closed}),
+ ok.
+
+
+
+%%--------------------------------------------------------------------
+eoptions(doc) ->
+ ["Test what happens when we give invalid options"];
+
+eoptions(suite) ->
+ [];
+
+eoptions(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Port = ssl_test_lib:inet_port(ServerNode),
+
+ %% Emulated opts
+ Server0 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{active, trice} | ServerOpts]}]),
+ Client0 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, [{active, trice} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server0, {error, {eoptions, {active,trice}}},
+ Client0, {error, {eoptions, {active,trice}}}),
+
+ test_server:sleep(500),
+
+ Server1 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{header, a} | ServerOpts]}]),
+ Client1 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{header, a} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server1, {error, {eoptions, {header, a}}},
+ Client1, {error, {eoptions, {header, a}}}),
+
+ test_server:sleep(500),
+
+
+ Server2 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{mode, a} | ServerOpts]}]),
+
+ Client2 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, [{mode, a} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server2, {error, {eoptions, {mode, a}}},
+ Client2, {error, {eoptions, {mode, a}}}),
+
+
+ test_server:sleep(500),
+
+ Server3 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{packet, 8.0} | ServerOpts]}]),
+ Client3 =
+ ssl_test_lib:start_client_error([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {from, self()},
+ {options, [{packet, 8.0} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server3, {error, {eoptions, {packet, 8.0}}},
+ Client3, {error, {eoptions, {packet, 8.0}}}),
+
+ test_server:sleep(500),
+
+ %% ssl
+ Server4 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{verify, 4} | ServerOpts]}]),
+ Client4 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, 4} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server4, {error, {eoptions, {verify, 4}}},
+ Client4, {error, {eoptions, {verify, 4}}}),
+
+ test_server:sleep(500),
+
+ Server5 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{depth, four} | ServerOpts]}]),
+ Client5 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{depth, four} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server5, {error, {eoptions, {depth, four}}},
+ Client5, {error, {eoptions, {depth, four}}}),
+
+ test_server:sleep(500),
+
+ Server6 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{cacertfile, ""} | ServerOpts]}]),
+ Client6 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{cacertfile, ""} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server6, {error, {eoptions, {cacertfile, ""}}},
+ Client6, {error, {eoptions, {cacertfile, ""}}}),
+
+
+ test_server:sleep(500),
+
+ Server7 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{certfile, 'cert.pem'} | ServerOpts]}]),
+ Client7 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{certfile, 'cert.pem'} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server7,
+ {error, {eoptions, {certfile, 'cert.pem'}}},
+ Client7, {error, {eoptions, {certfile, 'cert.pem'}}}),
+
+ test_server:sleep(500),
+
+ Server8 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{keyfile,'key.pem' } | ServerOpts]}]),
+ Client8 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()}, {options, [{keyfile, 'key.pem'}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server8,
+ {error, {eoptions, {keyfile, 'key.pem'}}},
+ Client8, {error, {eoptions, {keyfile, 'key.pem'}}}),
+
+ test_server:sleep(500),
+
+ Server9 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{key, 'key.pem' } | ServerOpts]}]),
+ Client9 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()}, {options, [{key, 'key.pem'}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server9, {error, {eoptions, {key, 'key.pem'}}},
+ Client9, {error, {eoptions, {key, 'key.pem'}}}),
+
+
+ test_server:sleep(500),
+
+ Server10 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{password, foo} | ServerOpts]}]),
+ Client10 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{password, foo} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server10, {error, {eoptions, {password, foo}}},
+ Client10, {error, {eoptions, {password, foo}}}),
+
+ test_server:sleep(500),
+
+ %% Misc
+ Server11 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{ssl_imp, cool} | ServerOpts]}]),
+ Client11 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{ssl_imp, cool} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server11, {error, {eoptions, {ssl_imp, cool}}},
+ Client11, {error, {eoptions, {ssl_imp, cool}}}),
+
+
+ test_server:sleep(500),
+
+ Server12 =
+ ssl_test_lib:start_server_error([{node, ServerNode}, {port, Port},
+ {from, self()},
+ {options, [{debug, cool} | ServerOpts]}]),
+ Client12 =
+ ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{debug, cool} | ClientOpts]}]),
+ ssl_test_lib:check_result(Server12, {error, {eoptions, {debug, cool}}},
+ Client12, {error, {eoptions, {debug, cool}}}).
+
+%%--------------------------------------------------------------------
+shutdown(doc) ->
+ [""];
+
+shutdown(suite) ->
+ [];
+
+shutdown(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_result, [server]}},
+ {options, [{exit_on_close, false},
+ {active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, shutdown_result, [client]}},
+ {options,
+ [{exit_on_close, false},
+ {active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+shutdown_result(Socket, server) ->
+ ssl:send(Socket, "Hej"),
+ ssl:shutdown(Socket, write),
+ {ok, "Hej hopp"} = ssl:recv(Socket, 8),
+ ok;
+
+shutdown_result(Socket, client) ->
+ {ok, "Hej"} = ssl:recv(Socket, 3),
+ ssl:send(Socket, "Hej hopp"),
+ ssl:shutdown(Socket, write),
+ ok.
+
+%%--------------------------------------------------------------------
+shutdown_write(doc) ->
+ [""];
+
+shutdown_write(suite) ->
+ [];
+
+shutdown_write(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_write_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_write_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+shutdown_write_result(Socket, server) ->
+ test_server:sleep(500),
+ ssl:shutdown(Socket, write);
+shutdown_write_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+%%--------------------------------------------------------------------
+shutdown_both(doc) ->
+ [""];
+
+shutdown_both(suite) ->
+ [];
+
+shutdown_both(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_both_result, [server]}},
+ {options, [{active, false} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, shutdown_both_result, [client]}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, {error, closed}).
+
+shutdown_both_result(Socket, server) ->
+ test_server:sleep(500),
+ ssl:shutdown(Socket, read_write);
+shutdown_both_result(Socket, client) ->
+ ssl:recv(Socket, 0).
+
+%%--------------------------------------------------------------------
+shutdown_error(doc) ->
+ [""];
+
+shutdown_error(suite) ->
+ [];
+
+shutdown_error(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ Port = ssl_test_lib:inet_port(node()),
+ {ok, Listen} = ssl:listen(Port, ServerOpts),
+ {error, enotconn} = ssl:shutdown(Listen, read_write),
+ ok = ssl:close(Listen),
+ {error, closed} = ssl:shutdown(Listen, read_write).
+
+%%--------------------------------------------------------------------
+ciphers(doc) ->
+ [""];
+
+ciphers(suite) ->
+ [];
+
+ciphers(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(),
+ Result = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+cipher(CipherSuite, Version, Config) ->
+ process_flag(trap_exit, true),
+ test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ServerMsg = ClientMsg = {ok, {Version, CipherSuite}},
+
+ Result = ssl_test_lib:wait_for_result(Server, ServerMsg,
+ Client, ClientMsg),
+ ssl_test_lib:close(Server),
+ receive
+ {'EXIT', Server, normal} ->
+ ok
+ end,
+ ssl_test_lib:close(Client),
+ receive
+ {'EXIT', Client, normal} ->
+ ok
+ end,
+ process_flag(trap_exit, false),
+ case Result of
+ ok ->
+ [];
+ Error ->
+ [{CipherSuite, Error}]
+ end.
+
+%%--------------------------------------------------------------------
+reuse_session(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+reuse_session(suite) ->
+ [];
+
+reuse_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ Server ! listen,
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, [{reuse_sessions, false}
+ | ClientOpts]}]),
+ receive
+ {Client2, SessionInfo} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_client);
+ {Client2, _} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
+
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, [{reuse_sessions, false} | ServerOpts]}]),
+
+ Port1 = ssl_test_lib:inet_port(Server1),
+ Client3 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SessionInfo1 =
+ receive
+ {Server1, Info1} ->
+ Info1
+ end,
+
+ Server1 ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client4 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client4, SessionInfo1} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_server);
+ {Client4, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client3),
+ ssl_test_lib:close(Client4),
+ process_flag(trap_exit, false).
+
+
+session_info_result(Socket) ->
+ ssl:session_info(Socket).
+
+%%--------------------------------------------------------------------
+reuse_session_expired(doc) ->
+ ["Test sessions is not reused when it has expired"];
+
+reuse_session_expired(suite) ->
+ [];
+
+reuse_session_expired(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is unregistered due to expiration
+ test_server:sleep((?EXPIRE+1) * 1000),
+
+ Client2 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client2, SessionInfo} ->
+ test_server:fail(session_reused_when_session_expired);
+ {Client2, _} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ ssl_test_lib:close(Client2),
+ process_flag(trap_exit, false).
+%%--------------------------------------------------------------------
+server_does_not_want_to_reuse_session(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+server_does_not_want_to_reuse_session(suite) ->
+ [];
+
+server_does_not_want_to_reuse_session(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options, [{reuse_session, fun(_,_,_,_) ->
+ false
+ end} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ test_server:fail(session_reused_when_server_does_not_want_to);
+ {Client1, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+ process_flag(trap_exit, false).
+
+%%--------------------------------------------------------------------
+
+server_verify_peer_passive(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_passive(suite) ->
+ [];
+
+server_verify_peer_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_peer_active(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_active(suite) ->
+ [];
+
+server_verify_peer_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_verify_peer_active_once(doc) ->
+ ["Test server option verify_peer"];
+
+server_verify_peer_active_once(suite) ->
+ [];
+
+server_verify_peer_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_none_passive(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_passive(suite) ->
+ [];
+
+server_verify_none_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}, {verify, verify_none}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+server_verify_none_active(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_active(suite) ->
+ [];
+
+server_verify_none_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true}, {verify, verify_none} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active, []}},
+ {options, [{active, true} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+server_verify_none_active_once(doc) ->
+ ["Test server option verify_none"];
+
+server_verify_none_active_once(suite) ->
+ [];
+
+server_verify_none_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once}, {verify, verify_none}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+
+server_verify_no_cacerts(doc) ->
+ ["Test server must have cacerts if it wants to verify client"];
+
+server_verify_no_cacerts(suite) ->
+ [];
+
+server_verify_no_cacerts(Config) when is_list(Config) ->
+ ServerOpts = ServerOpts = ?config(server_opts, Config),
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer}
+ | ServerOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, {eoptions, {cacertfile, ""}}}).
+
+%%--------------------------------------------------------------------
+
+client_verify_none_passive(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_passive(suite) ->
+ [];
+
+client_verify_none_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result, []}},
+ {options, [{active, false},
+ {verify, verify_none}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+client_verify_none_active(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_active(suite) ->
+ [];
+
+client_verify_none_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active, []}},
+ {options, [{active, true}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active, []}},
+ {options, [{active, true},
+ {verify, verify_none}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+client_verify_none_active_once(doc) ->
+ ["Test client option verify_none"];
+
+client_verify_none_active_once(suite) ->
+ [];
+
+client_verify_none_active_once(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_recv_result_active_once, []}},
+ {options, [{active, once} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ %% TODO: send message to test process to make sure
+ %% verifyfun has beeen run as it has the same behavior as
+ %% the default fun
+ VerifyFun = fun([{bad_cert, unknown_ca}]) ->
+ true;
+ (_) ->
+ false
+ end,
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ send_recv_result_active_once,
+ []}},
+ {options, [{active, once},
+ {verify, verify_none},
+ {verify_fun, VerifyFun}
+ | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+send_recv_result(Socket) ->
+ ssl:send(Socket, "Hejhopp"),
+ test_server:sleep(100),
+ {ok,"Hejhopp"} = ssl:recv(Socket, 7),
+ ok.
+
+send_recv_result_active(Socket) ->
+ ssl:send(Socket, "Hejhopp"),
+ test_server:sleep(100),
+ receive
+ {ssl, Socket, "Hejhopp"} ->
+ ok
+ end.
+
+send_recv_result_active_once(Socket) ->
+ ssl:send(Socket, "Hejhopp"),
+ test_server:sleep(100),
+ receive
+ {ssl, Socket, "Hejhopp"} ->
+ ok
+ end.
+
+session_cache_process_list(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_list(suite) ->
+ [];
+session_cache_process_list(Config) when is_list(Config) ->
+ session_cache_process(list,Config).
+
+session_cache_process_mnesia(doc) ->
+ ["Test reuse of sessions (short handshake)"];
+
+session_cache_process_mnesia(suite) ->
+ [];
+session_cache_process_mnesia(Config) when is_list(Config) ->
+ session_cache_process(mnesia,Config).
+
+session_cache_process(Type,Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ setup_session_cb(Type),
+
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options,
+ [{session_cache_cb, ?MODULE}|
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ SessionInfo =
+ receive
+ {Server, Info} ->
+ Info
+ end,
+
+ Server ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+ receive
+ {Client1, SessionInfo} ->
+ ok;
+ {Client1, Other} ->
+ test_server:format("Expected: ~p, Unexpected: ~p~n",
+ [SessionInfo, Other]),
+ test_server:fail(session_not_reused)
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client0),
+ ssl_test_lib:close(Client1),
+
+ Server1 =
+ ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, session_info_result, []}},
+ {options,
+ [{reuse_sessions, false} | ServerOpts]}]),
+ Port1 = ssl_test_lib:inet_port(Server1),
+
+ Client3 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ SessionInfo1 =
+ receive
+ {Server1, Info1} ->
+ Info1
+ end,
+
+ Server1 ! listen,
+
+ %% Make sure session is registered
+ test_server:sleep(500),
+
+ Client4 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port1}, {host, Hostname},
+ {mfa, {?MODULE, session_info_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ receive
+ {Client4, SessionInfo1} ->
+ test_server:fail(
+ session_reused_when_session_reuse_disabled_by_server);
+ {Client4, _Other} ->
+ ok
+ end,
+
+ ssl_test_lib:close(Server1),
+ ssl_test_lib:close(Client3),
+ ssl_test_lib:close(Client4),
+ process_flag(trap_exit, false).
+
+setup_session_cb(Type) ->
+ ssl_test = ets:new(ssl_test,[named_table, set,public]),
+ ets:insert(ssl_test, {type,Type}).
+
+session_cb() ->
+ [{type,Type}] = ets:lookup(ssl_test, type),
+ Type.
+
+init() ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ spawn(fun() -> session_loop([]) end);
+ mnesia ->
+ mnesia:start(),
+ {atomic,ok} = mnesia:create_table(sess_cache, [])
+ end.
+
+terminate(Cache) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! terminate;
+ mnesia ->
+ {atomic,ok} = mnesia:delete_table(sess_cache, [])
+ end.
+
+lookup(Cache, Key) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(), lookup, Key},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ case mnesia:transaction(fun() ->
+ mnesia:read(sess_cache,
+ Key, read)
+ end) of
+ {atomic, [Session]} -> Session;
+ _ -> undefined
+ end
+ end.
+
+update(Cache, Key, Value) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {update, Key, Value};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:write(sess_cache,
+ Key, Value)
+ end)
+ end.
+
+delete(Cache, Key) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {delete, Key};
+ mnesia ->
+ {atomic, ok} =
+ mnesia:transaction(fun() ->
+ mnesia:delete(sess_cache, Key)
+ end)
+ end.
+
+foldl(Fun, Acc, Cache) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(),foldl,Fun,Acc},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Foldl = fun() ->
+ mnesia:foldl(Fun, Acc, sess_cache)
+ end,
+ {atomic, Res} = mnesia:transaction(Foldl),
+ Res
+ end.
+
+select_session(Cache, PartialKey) ->
+ io:format("~p~n",[?LINE]),
+ case session_cb() of
+ list ->
+ Cache ! {self(),select_session, PartialKey},
+ receive {Cache, Res} -> Res end;
+ mnesia ->
+ Sel = fun() ->
+ mnesia:select(Cache,
+ [{{{PartialKey,'$1'}, '$2'},
+ [],['$$']}])
+ end,
+ {atomic, Res} = mnesia:transaction(Sel),
+ Res
+ end.
+
+session_loop(Sess) ->
+ receive
+ terminate ->
+ ok;
+ {Pid, lookup, Key} ->
+ case lists:keysearch(Key,1,Sess) of
+ {value, {Key,Value}} ->
+ Pid ! {self(), Value};
+ _ ->
+ Pid ! {self(), undefined}
+ end,
+ session_loop(Sess);
+ {update, Key, Value} ->
+ session_loop([{Key,Value}|Sess]);
+ {delete, Key} ->
+ session_loop(lists:keydelete(Key,1,Sess));
+ {Pid,foldl,Fun,Acc} ->
+ Res = lists:foldl(Fun, Acc,Sess),
+ Pid ! {self(), Res},
+ session_loop(Sess);
+ {Pid,select_session,PKey} ->
+ Sel = fun({{Head, _},Session}, Acc) when Head =:= PKey ->
+ [Session|Acc];
+ (_,Acc) ->
+ Acc
+ end,
+ Pid ! {self(), lists:foldl(Sel, [], Sess)},
+ session_loop(Sess)
+ end.
+
diff --git a/lib/ssl/test/ssl_basic_SUITE_data/RAND b/lib/ssl/test/ssl_basic_SUITE_data/RAND
new file mode 100644
index 0000000000..70997bd01f
--- /dev/null
+++ b/lib/ssl/test/ssl_basic_SUITE_data/RAND
Binary files differ
diff --git a/lib/ssl/test/ssl_packet_SUITE.erl b/lib/ssl/test/ssl_packet_SUITE.erl
new file mode 100644
index 0000000000..929f69c6c6
--- /dev/null
+++ b/lib/ssl/test/ssl_packet_SUITE.erl
@@ -0,0 +1,1486 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_packet_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(BYTE(X), X:8/unsigned-big-integer).
+-define(UINT16(X), X:16/unsigned-big-integer).
+-define(UINT24(X), X:24/unsigned-big-integer).
+-define(UINT32(X), X:32/unsigned-big-integer).
+-define(UINT64(X), X:64/unsigned-big-integer).
+-define(STRING(X), ?UINT32((size(X))), (X)/binary).
+
+-define(byte(X), << ?BYTE(X) >> ).
+-define(uint16(X), << ?UINT16(X) >> ).
+-define(uint24(X), << ?UINT24(X) >> ).
+-define(uint32(X), << ?UINT32(X) >> ).
+-define(uint64(X), << ?UINT64(X) >> ).
+-define(TIMEOUT, 60000).
+
+-define(MANY, 1000).
+-define(SOME, 50).
+
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test that erlang:decode_packet/3 seems to be handled correctly."
+ "We only use the most basic packet types in our tests as testing of"
+ "the packet types are for inet to verify"
+ ];
+
+all(suite) ->
+ [packet_raw_passive_many_small,
+ packet_0_passive_many_small, packet_1_passive_many_small,
+ packet_2_passive_many_small, packet_4_passive_many_small,
+ packet_raw_passive_some_big, packet_0_passive_some_big,
+ packet_1_passive_some_big,
+ packet_2_passive_some_big, packet_4_passive_some_big,
+ packet_raw_active_once_many_small,
+ packet_0_active_once_many_small, packet_1_active_once_many_small,
+ packet_2_active_once_many_small, packet_4_active_once_many_small,
+ packet_raw_active_once_some_big,
+ packet_0_active_once_some_big, packet_1_active_once_some_big,
+ packet_2_active_once_some_big, packet_4_active_once_some_big,
+ packet_raw_active_many_small, packet_0_active_many_small,
+ packet_1_active_many_small,
+ packet_2_active_many_small, packet_4_active_many_small,
+ packet_raw_active_some_big, packet_0_active_some_big,
+ packet_1_active_some_big, packet_2_active_some_big,
+ packet_4_active_some_big,
+ packet_wait_passive, packet_wait_active,
+ packet_baddata_passive, packet_baddata_active,
+ packet_size_passive, packet_size_active
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+packet_raw_passive_many_small(doc) ->
+ ["Test packet option {packet, raw} in passive mode."];
+
+packet_raw_passive_many_small(suite) ->
+ [];
+
+packet_raw_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?MANY]}},
+ {options,
+ [{active, false},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+packet_raw_passive_some_big(doc) ->
+ ["Test packet option {packet, raw} in passive mode."];
+
+packet_raw_passive_some_big(suite) ->
+ [];
+
+packet_raw_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?SOME]}},
+ {options,
+ [{active, false},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_passive_many_small(doc) ->
+ ["Test packet option {packet, 0} in passive mode."];
+
+packet_0_passive_many_small(suite) ->
+ [];
+
+packet_0_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}, equivalent to packet raw.",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_passive_some_big(doc) ->
+ ["Test packet option {packet, 0} in passive mode."];
+
+packet_0_passive_some_big(suite) ->
+ [];
+
+packet_0_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_raw, [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_passive_many_small(doc) ->
+ ["Test packet option {packet, 1} in passive mode."];
+
+packet_1_passive_many_small(suite) ->
+ [];
+
+packet_1_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_passive_some_big(doc) ->
+ ["Test packet option {packet, 1} in passive mode."];
+
+packet_1_passive_some_big(suite) ->
+ [];
+
+packet_1_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_passive_many_small(doc) ->
+ ["Test packet option {packet, 2} in passive mode"];
+
+packet_2_passive_many_small(suite) ->
+ [];
+
+packet_2_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_passive_some_big(doc) ->
+ ["Test packet option {packet, 2} in passive mode"];
+
+packet_2_passive_some_big(suite) ->
+ [];
+
+packet_2_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_passive_many_small(doc) ->
+ ["Test packet option {packet, 4} in passive mode"];
+
+packet_4_passive_many_small(suite) ->
+ [];
+
+packet_4_passive_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, send_4 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?MANY]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_passive_some_big(doc) ->
+ ["Test packet option {packet, 4} in passive mode"];
+
+packet_4_passive_some_big(suite) ->
+ [];
+
+packet_4_passive_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, ?SOME]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_raw_active_once_many_small(doc) ->
+ ["Test packet option {packet, raw} in active once mode."];
+
+packet_raw_active_once_many_small(suite) ->
+ [];
+
+packet_raw_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_once_raw, [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_raw_active_once_some_big(doc) ->
+ ["Test packet option {packet, raw} in active once mode."];
+
+packet_raw_active_once_some_big(suite) ->
+ [];
+
+packet_raw_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_once_raw, [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_once_many_small(doc) ->
+ ["Test packet option {packet, 0} in active once mode."];
+
+packet_0_active_once_many_small(suite) ->
+ [];
+
+packet_0_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_once_raw,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_0_active_once_some_big(doc) ->
+ ["Test packet option {packet, 0} in active once mode."];
+
+packet_0_active_once_some_big(suite) ->
+ [];
+
+packet_0_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,
+ [Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_once_raw,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_once_many_small(doc) ->
+ ["Test packet option {packet, 1} in active once mode."];
+
+packet_1_active_once_many_small(suite) ->
+ [];
+
+packet_1_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_once_some_big(doc) ->
+ ["Test packet option {packet, 1} in active once mode."];
+
+packet_1_active_once_some_big(suite) ->
+ [];
+
+packet_1_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_once_many_small(doc) ->
+ ["Test packet option {packet, 2} in active once mode"];
+
+packet_2_active_once_many_small(suite) ->
+ [];
+
+packet_2_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_2_active_once_some_big(doc) ->
+ ["Test packet option {packet, 2} in active once mode"];
+
+packet_2_active_once_some_big(suite) ->
+ [];
+
+packet_2_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_once_many_small(doc) ->
+ ["Test packet option {packet, 4} in active once mode"];
+
+packet_4_active_once_many_small(suite) ->
+ [];
+
+packet_4_active_once_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?MANY]}},
+ {options, [{active, once},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_once_some_big(doc) ->
+ ["Test packet option {packet, 4} in active once mode"];
+
+packet_4_active_once_some_big(suite) ->
+ [];
+
+packet_4_active_once_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_once_packet,
+ [Data, ?SOME]}},
+ {options, [{active, once},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_raw_active_many_small(doc) ->
+ ["Test packet option {packet, raw} in active mode."];
+
+packet_raw_active_many_small(suite) ->
+ [];
+
+packet_raw_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, raw}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_raw,
+ [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_raw_active_some_big(doc) ->
+ ["Test packet option {packet, raw} in active mode."];
+
+packet_raw_active_some_big(suite) ->
+ [];
+
+packet_raw_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_raw, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, raw} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_many_small(doc) ->
+ ["Test packet option {packet, 0} in active mode."];
+
+packet_0_active_many_small(suite) ->
+ [];
+
+packet_0_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 0}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_raw,
+ [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_0_active_some_big(doc) ->
+ ["Test packet option {packet, 0} in active mode."];
+
+packet_0_active_some_big(suite) ->
+ [];
+
+packet_0_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_raw ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_raw,
+ [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 0} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_1_active_many_small(doc) ->
+ ["Test packet option {packet, 1} in active mode."];
+
+packet_1_active_many_small(suite) ->
+ [];
+
+packet_1_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 1}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_1_active_some_big(doc) ->
+ ["Test packet option {packet, 1} in active mode."];
+
+packet_1_active_some_big(suite) ->
+ [];
+
+packet_1_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(255, "1")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_1 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 1} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_many_small(doc) ->
+ ["Test packet option {packet, 2} in active mode"];
+
+packet_2_active_many_small(suite) ->
+ [];
+
+packet_2_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 2}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_2_active_some_big(doc) ->
+ ["Test packet option {packet, 2} in active mode"];
+
+packet_2_active_some_big(suite) ->
+ [];
+
+packet_2_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_2 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 2} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+packet_4_active_many_small(doc) ->
+ ["Test packet option {packet, 4} in active mode"];
+
+packet_4_active_many_small(suite) ->
+ [];
+
+packet_4_active_many_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "Packet option is {packet, 4}",
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?MANY]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?MANY]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_4_active_some_big(doc) ->
+ ["Test packet option {packet, 4} in active mode"];
+
+packet_4_active_some_big(suite) ->
+ [];
+
+packet_4_active_some_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = lists:append(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_4 ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE,
+ active_packet, [Data, ?SOME]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+
+
+%%--------------------------------------------------------------------
+packet_wait_active(doc) ->
+ ["Test waiting when complete packages have not arrived"];
+
+packet_wait_active(suite) ->
+ [];
+
+packet_wait_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, active_packet,
+ [binary_to_list(Data), ?SOME]}},
+ {options, [{active, true},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+%%--------------------------------------------------------------------
+packet_wait_passive(doc) ->
+ ["Test waiting when complete packages have not arrived"];
+
+packet_wait_passive(suite) ->
+ [];
+
+packet_wait_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, ?SOME]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [binary_to_list(Data), ?SOME]}},
+ {options, [{active, false},
+ {packet, 4} |
+ ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_baddata_active(doc) ->
+ ["Test that if a bad packet arrives error msg is sent and socket is closed"];
+packet_baddata_active(suite) ->
+ [];
+
+packet_baddata_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true},
+ {packet, cdr} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_baddata_passive(doc) ->
+ ["Test that if a bad packet arrives error msg is sent and socket is closed"];
+
+packet_baddata_passive(suite) ->
+ [];
+
+packet_baddata_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet,
+ [Data, 1]}},
+ {options, [{active, false},
+ {packet, cdr} |
+ ClientOpts]}]),
+
+ receive
+ {Client, {other, {error, {invalid_packet, _}},{error,closed}, 1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_size_active(doc) ->
+ ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"];
+packet_size_active(suite) ->
+ [];
+
+packet_size_active(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, active_packet, [Data, 1]}},
+ {options, [{active, true},
+ {packet, 4}, {packet_size, 10} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {ssl_error, _Socket, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+packet_size_passive(doc) ->
+ ["Test that if a packet of size larger than packet_size arrives error msg is sent and socket is closed"];
+packet_size_passive(suite) ->
+ [];
+
+packet_size_passive(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = list_to_binary(lists:duplicate(100, "1234567890")),
+
+ Server = ssl_test_lib:start_server([{node, ClientNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, send_incomplete ,[Data, 1]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ServerNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, passive_recv_packet, [Data, 1]}},
+ {options, [{active, false},
+ {packet, 4}, {packet_size, 30} |
+ ClientOpts]}]),
+ receive
+ {Client, {other, {error, {invalid_packet, _}},{error,closed},1}} -> ok;
+ Unexpected ->
+ test_server:fail({unexpected, Unexpected})
+ end,
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+%%--------------------------------------------------------------------
+%% Internal functions
+
+send_raw(_,_, 0) ->
+ no_result_msg;
+send_raw(Socket, Data, N) ->
+ ssl:send(Socket, Data),
+ send_raw(Socket, Data, N-1).
+
+passive_raw(_, _, 0) ->
+ ok;
+passive_raw(Socket, Data, N) ->
+ Length = length(Data),
+ {ok, Data} = ssl:recv(Socket, Length),
+ passive_raw(Socket, Data, N-1).
+
+passive_recv_packet(_, _, 0) ->
+ ok;
+passive_recv_packet(Socket, Data, N) ->
+ case ssl:recv(Socket, 0) of
+ {ok, Data} ->
+ passive_recv_packet(Socket, Data, N-1);
+ Other ->
+ {other, Other, ssl:session_info(Socket), N}
+ end.
+
+send_1(_,_, 0) ->
+ no_result_msg;
+send_1(Socket, Data, N) ->
+ Length = length(Data),
+ ssl:send(Socket, [?byte(Length), Data]),
+ send_1(Socket, Data, N-1).
+
+send_2(_,_, 0) ->
+ no_result_msg;
+send_2(Socket, Data, N) ->
+ Length = length(Data),
+ ssl:send(Socket, [?uint16(Length), Data]),
+ send_2(Socket, Data, N-1).
+
+send_4(_,_, 0) ->
+ no_result_msg;
+send_4(Socket, Data, N) ->
+ Length = length(Data),
+ ssl:send(Socket, [?uint32(Length), Data]),
+ send_4(Socket, Data, N-1).
+
+send_incomplete(Socket, Data, N) ->
+ send_incomplete(Socket, Data, N, <<>>).
+send_incomplete(Socket, _Data, 0, Prev) ->
+ ssl:send(Socket, Prev),
+ no_result_msg;
+send_incomplete(Socket, Data, N, Prev) ->
+ Length = size(Data),
+ <<Part1:42/binary, Rest/binary>> = Data,
+ ssl:send(Socket, [Prev, ?uint32(Length), Part1]),
+ send_incomplete(Socket, Data, N-1, Rest).
+
+active_once_raw(Socket, Data, N) ->
+ active_once_raw(Socket, Data, N, []).
+
+active_once_raw(_, _, 0, _) ->
+ ok;
+active_once_raw(Socket, Data, N, Acc) ->
+ receive
+ {ssl, Socket, Data} ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N-1, []);
+ {ssl, Socket, Other} ->
+ case Acc ++ Other of
+ Data ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N-1, []);
+ NewAcc ->
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_raw(Socket, Data, N, NewAcc)
+ end
+ end.
+
+active_once_packet(_,_, 0) ->
+ ok;
+active_once_packet(Socket, Data, N) ->
+ receive
+ {ssl, Socket, Data} ->
+ ok
+ end,
+ ssl:setopts(Socket, [{active, once}]),
+ active_once_packet(Socket, Data, N-1).
+
+active_raw(Socket, Data, N) ->
+ active_raw(Socket, Data, N, []).
+
+active_raw(_, _, 0, _) ->
+ ok;
+active_raw(Socket, Data, N, Acc) ->
+ receive
+ {ssl, Socket, Data} ->
+ active_raw(Socket, Data, N-1, []);
+ {ssl, Socket, Other} ->
+ case Acc ++ Other of
+ Data ->
+ active_raw(Socket, Data, N-1, []);
+ NewAcc ->
+ active_raw(Socket, Data, NewAcc)
+ end
+ end.
+
+active_packet(_, _, 0) ->
+ ok;
+active_packet(Socket, Data, N) ->
+ receive
+ {ssl, Socket, Data} ->
+ active_packet(Socket, Data, N -1);
+ Other ->
+ {other, Other, ssl:session_info(Socket),N}
+ end.
diff --git a/lib/ssl/test/ssl_payload_SUITE.erl b/lib/ssl/test/ssl_payload_SUITE.erl
new file mode 100644
index 0000000000..a0aa92bdf2
--- /dev/null
+++ b/lib/ssl/test/ssl_payload_SUITE.erl
@@ -0,0 +1,726 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(ssl_payload_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+
+-define(TIMEOUT, 600000).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ ssl:start(),
+ make_certs:all(?config(data_dir, Config), ?config(priv_dir, Config)),
+ ssl_test_lib:cert_options(Config).
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test payload over ssl in all socket modes, active, active_once,"
+ "and passive mode."];
+
+all(suite) ->
+ [server_echos_passive_small, server_echos_active_once_small,
+ server_echos_active_small,
+ client_echos_passive_small, client_echos_active_once_small,
+ client_echos_active_small,
+ server_echos_passive_big, server_echos_active_once_big,
+ server_echos_active_big,
+ client_echos_passive_big, client_echos_active_once_big,
+ client_echos_active_big,
+ server_echos_passive_huge, server_echos_active_once_huge,
+ server_echos_active_huge,
+ client_echos_passive_huge, client_echos_active_once_huge,
+ client_echos_active_huge
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+server_echos_passive_small(doc) ->
+ ["Client sends 1000 bytes in passive mode to server, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_passive_small(suite) ->
+ [];
+
+server_echos_passive_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_once_small(doc) ->
+ ["Client sends 1000 bytes in active once mode to server, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_active_once_small(suite) ->
+ [];
+
+server_echos_active_once_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_small(doc) ->
+ ["Client sends 1000 bytes in active mode to server, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_active_small(suite) ->
+ [];
+
+server_echos_active_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 1000, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_small(doc) ->
+ ["Server sends 1000 bytes in passive mode to client, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_passive_small(suite) ->
+ [];
+
+client_echos_passive_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_passive(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_small(doc) ->
+ ["Server sends 1000 bytes in active once mode to client, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_active_once_small(suite) ->
+ [];
+
+client_echos_active_once_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active_once(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_small(doc) ->
+ ["Server sends 1000 bytes in active mode to client, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_small(suite) ->
+ [];
+
+client_echos_active_small(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active(Str, 1000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+
+%%--------------------------------------------------------------------
+server_echos_passive_big(doc) ->
+ ["Client sends 50000 bytes to server in passive mode, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_passive_big(suite) ->
+ [];
+
+server_echos_passive_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_once_big(doc) ->
+ ["Client sends 50000 bytes to server in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+server_echos_active_once_big(suite) ->
+ [];
+
+server_echos_active_once_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_active_big(doc) ->
+ ["Client sends 50000 bytes to server in active once mode, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_active_big(suite) ->
+ [];
+
+server_echos_active_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_big(doc) ->
+ ["Server sends 50000 bytes to client in passive mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_passive_big(suite) ->
+ [];
+
+client_echos_passive_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_passive(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_big(doc) ->
+ ["Server sends 50000 bytes to client in active once mode, that receives"
+ " them, sends them back, and closes."];
+
+client_echos_active_once_big(suite) ->
+ [];
+
+client_echos_active_once_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active_once(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_big(doc) ->
+ ["Server sends 50000 bytes to client in active mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_big(suite) ->
+ [];
+
+client_echos_active_big(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ client_echos_active(Str, 50000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_passive_huge(doc) ->
+ ["Client sends 500000 bytes to server in passive mode, that receives "
+ " them, sends them back, and closes."];
+
+server_echos_passive_huge(suite) ->
+ [];
+
+server_echos_passive_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_passive(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_active_once_huge(doc) ->
+ ["Client sends 500000 bytes to server in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+server_echos_active_once_huge(suite) ->
+ [];
+
+server_echos_active_once_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active_once(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+server_echos_active_huge(doc) ->
+ ["Client sends 500000 bytes to server in active mode, that receives them, "
+ "sends them back, and closes."];
+
+server_echos_active_huge(suite) ->
+ [];
+
+server_echos_active_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+
+ server_echos_active(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_passive_huge(doc) ->
+ ["Server sends 500000 bytes to client in passive mode, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_passive_huge(suite) ->
+ [];
+
+client_echos_passive_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_passive(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_once_huge(doc) ->
+ ["Server sends 500000 bytes to client in active once mode, that receives "
+ "them, sends them back, and closes."];
+
+client_echos_active_once_huge(suite) ->
+ [];
+
+client_echos_active_once_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_active_once(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+client_echos_active_huge(doc) ->
+ ["Server sends 500000 bytes to client in active mode, that receives them, "
+ "sends them back, and closes."];
+
+client_echos_active_huge(suite) ->
+ [];
+
+client_echos_active_huge(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Str = "1234567890",
+ client_echos_active(Str, 500000, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname).
+
+%%--------------------------------------------------------------------
+
+server_echos_passive(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer,
+ [Data, Length]}},
+ {options,
+ [{active, false},{mode, binary}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender,
+ [Data,
+ Length]}},
+ {options,
+ [{active, false}, {mode, binary} |
+ ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_echos_active_once(Data, Length, ClientOpts, ServerOpts, ClientNode,
+ ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary}|
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary} |
+ ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+
+server_echos_active(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_active,
+ [Data, Length]}},
+ {options,
+ [{active, true},
+ {mode, binary} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_active,
+ [Data,
+ Length]}},
+ {options,
+ [{active, true}, {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_passive(Data, Length, ClientOpts, ServerOpts,
+ ClientNode, ServerNode, Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender,
+ [Data, Length]}},
+ {options,
+ [{active, false}, {mode, binary} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer,
+ [Data,
+ Length]}},
+ {options,
+ [{active, false}, {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_active_once(Data, Length,
+ ClientOpts, ServerOpts, ClientNode, ServerNode,
+ Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_once,
+ [Data, Length]}},
+ {options, [{active, once},
+ {mode, binary} |
+ ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_once,
+ [Data,
+ Length]}},
+ {options,[{active, once},
+ {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+client_echos_active(Data, Length, ClientOpts, ServerOpts, ClientNode,
+ ServerNode,
+ Hostname) ->
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, sender_active,
+ [Data, Length]}},
+ {options, [{active, true},
+ {mode, binary}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa,
+ {?MODULE, echoer_active,
+ [Data,
+ Length]}},
+ {options, [{active, true},
+ {mode, binary}
+ | ClientOpts]}]),
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+send(_, _, _, 0,_) ->
+ ok;
+send(Socket, Data, Size, Repeate,F) ->
+ NewData = lists:duplicate(Size div 10, Data),
+ ssl:send(Socket, NewData),
+ F(),
+ send(Socket, Data, Size, Repeate - 1,F).
+
+sender(Socket, Data, Size) ->
+ ok = send(Socket, Data, Size, 100, fun() -> do_recv(Socket, Data, Size, <<>>, false) end),
+ test_server:format("Sender recv: ~p~n", [ssl:getopts(Socket, [active])]),
+ ok.
+
+sender_once(Socket, Data, Size) ->
+ send(Socket, Data, Size, 100,
+ fun() -> do_active_once(Socket, Data, Size, <<>>, false) end),
+ test_server:format("Sender active once: ~p~n",
+ [ssl:getopts(Socket, [active])]),
+ ok.
+
+sender_active(Socket, Data, Size) ->
+ F = fun() -> do_active(Socket, Data, Size, <<>>, false) end,
+ send(Socket, Data, Size, 100, F),
+ test_server:format("Sender active: ~p~n", [ssl:getopts(Socket, [active])]),
+ ok.
+
+echoer(Socket, Data, Size) ->
+ test_server:format("Echoer recv: ~p~n", [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_recv(Socket, Data, Size, <<>>, true) end, 100).
+
+echoer_once(Socket, Data, Size) ->
+ test_server:format("Echoer active once: ~p ~n",
+ [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_active_once(Socket, Data, Size, <<>>, true) end, 100).
+
+echoer_active(Socket, Data, Size) ->
+ test_server:format("Echoer active: ~p~n", [ssl:getopts(Socket, [active])]),
+ echo(fun() -> do_active(Socket, Data, Size, <<>>, true) end, 100).
+
+echo(_Fun, 0) -> ok;
+echo(Fun, N) ->
+ Fun(),
+ echo(Fun, N-1).
+
+
+do_recv(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_recv(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_recv(Socket, Data, Size, Acc, Echo) ->
+ {ok, NewData} = ssl:recv(Socket, 0),
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ NewSize = size(NewData),
+ do_recv(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ do_recv(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>, Echo);
+ false ->
+ do_recv(Socket, Data, Size - NewSize, Acc, Echo)
+ end
+ end.
+
+do_active_once(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_active_once(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_active_once(Socket, Data, Size, Acc, Echo) ->
+ receive
+ {ssl, Socket, NewData} ->
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>,
+ Echo);
+ false ->
+ ssl:setopts(Socket, [{active, once}]),
+ do_active_once(Socket, Data,
+ Size - NewSize, Acc, Echo)
+ end
+ end
+ end.
+
+do_active(_Socket, _Data, 0, _Acc, true) ->
+ ok;
+do_active(_Socket, Data, 0, Acc, false) ->
+ Data = lists:sublist(binary_to_list(Acc), 10);
+
+do_active(Socket, Data, Size, Acc, Echo) ->
+ receive
+ {ssl, Socket, NewData} ->
+ NewSize = size(NewData),
+ case Echo of
+ true ->
+ ssl:send(Socket, NewData),
+ do_active(Socket, Data, Size - NewSize, [], Echo);
+ false ->
+ case size(Acc) < 10 of
+ true ->
+ do_active(Socket, Data, Size - NewSize,
+ <<Acc/binary, NewData/binary>>,
+ Echo);
+ false ->
+ do_active(Socket, Data,
+ Size - NewSize, Acc, Echo)
+ end
+ end
+ end.
diff --git a/lib/ssl/test/ssl_test_MACHINE.erl b/lib/ssl/test/ssl_test_MACHINE.erl
new file mode 100644
index 0000000000..e75f7079ed
--- /dev/null
+++ b/lib/ssl/test/ssl_test_MACHINE.erl
@@ -0,0 +1,935 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_test_MACHINE).
+
+-export([many_conns/0, mk_ssl_cert_opts/1, test_one_listener/7,
+ test_server_only/6]).
+
+-export([process_init/3, do_start/1]).
+
+
+-include("test_server.hrl").
+-include("ssl_test_MACHINE.hrl").
+
+-define(WAIT_TIMEOUT, 10000).
+-define(CLOSE_WAIT, 1000).
+
+%%
+%% many_conns() -> ManyConnections
+%%
+%% Choose a suitable number of "many connections" depending on platform
+%% and current limit for file descriptors.
+%%
+many_conns() ->
+ case os:type() of
+ {unix,_} -> many_conns_1();
+ _ -> 10
+ end.
+
+many_conns_1() ->
+ N0 = os:cmd("ulimit -n"),
+ N1 = lists:reverse(N0),
+ N2 = lists:dropwhile(fun($\r) -> true;
+ ($\n) -> true;
+ (_) -> false
+ end, N1),
+ N = list_to_integer(lists:reverse(N2)),
+ lists:min([(N - 10) div 2, 501]).
+
+%%
+%% mk_ssl_cert_opts(Config) -> {ok, {COpts, SOpts}}
+%%
+%%
+mk_ssl_cert_opts(_Config) ->
+ Dir = filename:join([code:lib_dir(ssl), "examples", "certs", "etc"]),
+ COpts = [{cacertfile, filename:join([Dir, "client", "cacerts.pem"])},
+ {certfile, filename:join([Dir, "client", "cert.pem"])},
+ {keyfile, filename:join([Dir, "client", "key.pem"])}],
+ SOpts = [{cacertfile, filename:join([Dir, "server", "cacerts.pem"])},
+ {certfile, filename:join([Dir, "server", "cert.pem"])},
+ {keyfile, filename:join([Dir, "server", "key.pem"])}],
+ {ok, {COpts, SOpts}}.
+
+%%
+%% Cmds:
+%% {protomod, gen_tcp | ssl} default = ssl
+%% {serialize_accept, true | false} default = false
+%% {timeout, Timeout}
+%% {sockopts, Opts}
+%% {sslopts, Opts}
+%% {protocols, Protocols} [sslv2|sslv3|tlsv1]
+%% {listen, Port}
+%% {lsock, LSock} listen socket for acceptor
+%% peercert
+%% accept
+%% {connect, {Host, Port}}
+%% {recv, N}
+%% {send, N}
+%% {echo, N} async echo back
+%% close close connection socket
+%% {close, Time} wait time and then close socket
+%% lclose close listen socket
+%% await_close wait for close
+%% wait_sync listener's wait for sync from parent
+%% connection_info
+%% {exit, Reason} exit
+%%
+%%
+%% We cannot have more than `backlog' acceptors at the same time.
+%%
+
+
+%%
+%% test_one_listener(NConns, LCmds, ACmds, CCmds, Timeout, Suite, Config)
+%%
+%% Creates one client and one server node, and runs one listener on
+%% the server node (according to LCmds), and creates NConns acceptors
+%% on the server node, and the same number of connectors on the client
+%% node. The acceptors and and connectors execute according to ACmds
+%% and CCmds, respectively.
+%%
+%% It is a good idea to have the backlog size in LCmds set to
+%% be at least as large as NConns.
+%%
+test_one_listener(NConns, LCmds0, ACmds0, CCmds0, Timeout, Suite, Config) ->
+ ProtoMod = get_protomod(Config),
+ SerializeAccept = get_serialize_accept(Config),
+ ?line {ok, {CNode, SNode}} = start_client_server_nodes(Suite),
+ case ProtoMod of
+ ssl ->
+ ?line ok = start_ssl([CNode, SNode], Config);
+ gen_tcp ->
+ ok
+ end,
+ LCmds = [{protomod, ProtoMod}| LCmds0],
+ ACmds = [{protomod, ProtoMod}, {serialize_accept, SerializeAccept}|
+ ACmds0],
+ CCmds = [{protomod, ProtoMod}| CCmds0],
+
+ ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener),
+ ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT),
+ ?line {ok, Accs0} = start_processes(NConns, SNode, self(),
+ [{lsock, LSock}| ACmds], acceptor),
+ Accs = case ProtoMod of
+ gen_tcp ->
+ [Acc1| Accs1] = Accs0,
+ Acc1 ! {continue_accept, self()},
+ Accs1;
+ ssl ->
+ Accs0
+ end,
+ ?line {ok, Conns} = start_processes(NConns, CNode, self(),
+ CCmds, connector),
+ ?line case wait_ack(Accs, Accs0 ++ Conns, Timeout) of
+ ok ->
+ ?line sync([Listener]),
+ ?line wait_ack([], [Listener], ?WAIT_TIMEOUT);
+ {error, Reason} ->
+ ?line stop_node(SNode),
+ ?line stop_node(CNode),
+ exit(Reason)
+ end,
+ ?line stop_node(SNode),
+ ?line stop_node(CNode),
+ ok.
+
+%%
+%% test_server_only(NConns, LCmds, ACmds, Timeout, Suite, Config)
+%%
+%% Creates only one server node, and runs one listener on
+%% the server node (according to LCmds), and creates NConns acceptors
+%% on the server node. The acceptors execute according to ACmds.
+%% There are no connectors.
+%%
+test_server_only(NConns, LCmds0, ACmds0, Timeout, Suite, Config) ->
+ ProtoMod = get_protomod(Config),
+ ?line {ok, SNode} = start_server_node(Suite),
+ case ProtoMod of
+ ssl ->
+ ?line ok = start_ssl([SNode], Config);
+ gen_tcp ->
+ ok
+ end,
+ LCmds = [{protomod, ProtoMod}| LCmds0],
+ ACmds = [{protomod, ProtoMod}| ACmds0],
+ ?line {ok, Listener} = start_process(SNode, self(), LCmds, listener),
+ ?line {ok, LSock} = wait_lsock(Listener, ?WAIT_TIMEOUT),
+ ?line {ok, Accs0} = start_processes(NConns, SNode, self(),
+ [{lsock, LSock}| ACmds], acceptor),
+ Accs = case ProtoMod of
+ gen_tcp ->
+ [Acc1| Accs1] = Accs0,
+ Acc1 ! {continue_accept, self()},
+ Accs1;
+ ssl ->
+ Accs0
+ end,
+ ?line case wait_ack(Accs, Accs0, Timeout) of
+ ok ->
+ ?line sync([Listener]),
+ ?line wait_ack([], [Listener], ?WAIT_TIMEOUT);
+ {error, Reason} ->
+ ?line stop_node(SNode),
+ exit(Reason)
+ end,
+ ?line stop_node(SNode),
+ ok.
+
+%%
+%% start_client_server_nodes(Suite) -> {ok, {CNode, SNode}}
+%%
+start_client_server_nodes(Suite) ->
+ {ok, CNode} = start_client_node(Suite),
+ {ok, SNode} = start_server_node(Suite),
+ {ok, {CNode, SNode}}.
+
+start_client_node(Suite) ->
+ start_node(lists:concat([Suite, "_client"])).
+
+start_server_node(Suite) ->
+ start_node(lists:concat([Suite, "_server"])).
+
+%%
+%% start_ssl(Nodes, Config)
+%%
+start_ssl(Nodes, Config) ->
+ Env0 = lists:flatten([Env00 || {env, Env00} <- Config]),
+ Env1 = case os:getenv("SSL_DEBUG") of
+ false ->
+ [];
+ _ ->
+ Dir = ?config(priv_dir, Config),
+ [{debug, true}, {debugdir, Dir}]
+ end,
+ Env = Env0 ++ Env1,
+ lists:foreach(
+ fun(Node) -> rpc:call(Node, ?MODULE, do_start, [Env]) end, Nodes),
+ ok.
+
+do_start(Env) ->
+ application:load(ssl),
+ lists:foreach(
+ fun({Par, Val}) -> application:set_env(ssl, Par, Val) end, Env),
+ application:start(ssl),
+ application:start(crypto).
+
+%%
+%% start_node(Name) -> {ok, Node}
+%% start_node(Name, ExtraParams) -> {ok, Node}
+%%
+start_node(Name) ->
+ start_node(Name, []).
+start_node(Name, ExtraParams) ->
+ Params = "-pa " ++ filename:dirname(code:which(?MODULE)) ++ " " ++
+ ExtraParams,
+ test_server:start_node(Name, slave, [{args, Params}]).
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
+
+%%
+%% start_processes(N, Node, Parent, Cmds, Type) -> {ok, Pids}
+%%
+start_processes(M, Node, Parent, Cmds, Type) ->
+ start_processes1(0, M, Node, Parent, Cmds, Type, []).
+start_processes1(M, M, _, _, _, _, Pids) ->
+ {ok, lists:reverse(Pids)};
+start_processes1(N, M, Node, Parent, Cmds, Type, Pids) ->
+ {ok, Pid} = start_process(Node, Parent, Cmds, {Type, N + 1}),
+ start_processes1(N + 1, M, Node, Parent, Cmds, Type, [Pid| Pids]).
+
+%%
+%% start_process(Node, Parent, Cmds, Type) -> {ok, Pid}
+%%
+start_process(Node, Parent, Cmds0, Type) ->
+ Cmds = case os:type() of
+ {win32, _} ->
+ lists:map(fun(close) -> {close, ?CLOSE_WAIT};
+ (Term) -> Term end, Cmds0);
+ _ ->
+ Cmds0
+ end,
+ Pid = spawn_link(Node, ?MODULE, process_init, [Parent, Cmds, Type]),
+ {ok, Pid}.
+
+process_init(Parent, Cmds, Type) ->
+ ?debug("#### ~w start~n", [{Type, self()}]),
+ pre_main_loop(Cmds, #st{parent = Parent, type = Type}).
+
+%%
+%% pre_main_loop
+%%
+pre_main_loop([], St) ->
+ ?debug("#### ~w end~n", [{St#st.type, self()}]),
+ main_loop([], St);
+pre_main_loop(Cmds, St) ->
+ ?debug("#### ~w -> ~w~n",
+ [{St#st.type, self(), St#st.sock, St#st.port,
+ St#st.peer, St#st.active}, hd(Cmds)]),
+ main_loop(Cmds, St).
+
+%%
+%% main_loop(Cmds, St)
+%%
+main_loop([{protomod, ProtoMod}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{protomod = ProtoMod});
+
+main_loop([{serialize_accept, Bool}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{serialize_accept = Bool});
+
+main_loop([{sockopts, Opts}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{sockopts = Opts});
+
+main_loop([{sslopts, Opts}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{sslopts = Opts});
+
+main_loop([{protocols, Protocols}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{protocols = Protocols});
+
+main_loop([{timeout, T}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{timeout = T});
+
+main_loop([{lsock, LSock}| Cmds], St) ->
+ pre_main_loop(Cmds, St#st{lsock = LSock});
+
+main_loop([{seed, Data}| Cmds], St) ->
+ case ssl:seed("tjosan") of
+ ok ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in seed: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([{listen, Port}| Cmds], St) ->
+ case listen(St, Port) of
+ {ok, LSock} ->
+ ack_lsock(St#st.parent, LSock),
+ NSt = get_active(St#st{port = Port, sock = LSock, lsock = LSock}),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in listen: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([accept| Cmds], St) ->
+ case St#st.serialize_accept of
+ true ->
+ Parent = St#st.parent,
+ receive
+ {continue_accept, Parent} ->
+ ok
+ end;
+ false ->
+ ok
+ end,
+ case accept(St) of
+ {ok, Sock, Port, Peer} ->
+ case St#st.serialize_accept of
+ true ->
+ St#st.parent ! {one_accept_done, self()};
+ false ->
+ ok
+ end,
+ NSt = get_active(St#st{sock = Sock, port = Port, peer = Peer}),
+ pre_main_loop(Cmds, NSt);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in accept: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([accept_timeout| Cmds], St) ->
+ case accept(St) of
+ {error, timeout} ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in accept_timeout: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+
+main_loop([{connect, {Host, Port}}| Cmds], St) ->
+ case connect(St, Host, Port) of
+ {ok, Sock, LPort, Peer} ->
+ NSt = get_active(St#st{sock = Sock, port = LPort, peer = Peer}),
+ pre_main_loop(Cmds, NSt);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in connect: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([connection_info| Cmds], St) ->
+ case connection_info(St) of
+ {ok, ProtoInfo} ->
+ io:fwrite("Got connection_info:~n~p~n", [ProtoInfo]),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in connection_info: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([peercert| Cmds], St) ->
+ case peercert(St) of
+ {ok, Cert} ->
+ io:fwrite("Got cert:~n~p~n", [Cert]),
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in peercert: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([nopeercert| Cmds], St) ->
+ case peercert(St) of
+ {error, Reason} ->
+ io:fwrite("Got no cert as expected. reason:~n~p~n", [Reason]),
+ pre_main_loop(Cmds, St);
+ {ok, Cert} ->
+ ?error("#### ~w(~w) in peercert: error: got cert: ~p~n",
+ [St#st.type, self(), Cert]),
+ exit(peercert)
+ end;
+
+main_loop([{recv, N}| Cmds], St) ->
+ recv_loop([{recv, N}| Cmds], fun recv/1, St); % Returns to main_loop/2.
+
+main_loop([{send, N}| Cmds], St) ->
+ Msg = mk_msg(N),
+ case send(St, Msg) of
+ ok ->
+ pre_main_loop(Cmds, St);
+ {error, Reason} ->
+ ?error("#### ~w(~w) in send: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([{echo, N}| Cmds], St) ->
+ recv_loop([{echo, N}| Cmds], fun echo/1, St); % Returns to main_loop/2.
+
+main_loop([{close, WaitTime}| Cmds], St) ->
+ wait(WaitTime),
+ pre_main_loop([close| Cmds], St);
+
+main_loop([close| Cmds], St) ->
+ case close(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{sock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in close: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([lclose| Cmds], St) ->
+ case lclose(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{lsock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in lclose: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([await_close| Cmds], St) ->
+ case await_close(St) of
+ ok ->
+ pre_main_loop(Cmds, St#st{sock = nil});
+ {error, Reason} ->
+ ?error("#### ~w(~w) in await_close: error: ~w~n",
+ [St#st.type, self(), Reason]),
+ exit(Reason)
+ end;
+
+main_loop([wait_sync| Cmds], St) ->
+ wait_sync(St),
+ pre_main_loop(Cmds, St);
+
+main_loop({exit, Reason}, _St) ->
+ exit(Reason);
+
+main_loop([], _St) ->
+ ok.
+
+%%
+%% recv_loop(Cmds, F, St)
+%%
+%% F = recv/1 | echo/1
+%%
+recv_loop([{_Tag, 0}| Cmds], _, St) ->
+ pre_main_loop(Cmds, St);
+recv_loop([{_Tag, N}| _Cmds], _, St) when N < 0 ->
+ ?error("#### ~w(~w) in recv_loop: error: too much: ~w~n",
+ [St#st.type, self(), N]),
+ exit(toomuch); % XXX or {error, Reason}?
+recv_loop([{Tag, N}| Cmds], F, St) ->
+ case F(St) of
+ {ok, Len} ->
+ NSt = St#st{active = new_active(St#st.active)},
+ if
+ Len == N ->
+ pre_main_loop(Cmds, NSt);
+ true ->
+ ?debug("#### ~w -> ~w~n",
+ [{NSt#st.type, self(), NSt#st.sock, NSt#st.port,
+ NSt#st.peer, NSt#st.active}, {Tag, N - Len}]),
+ recv_loop([{Tag, N - Len}| Cmds], F, NSt)
+ end;
+ {error, Reason} ->
+ ?error("#### ~w(~w) in recv_loop: error: ~w, ~w bytes remain~n",
+ [St#st.type, self(), Reason, N]),
+ exit(Reason)
+ end.
+
+new_active(once) ->
+ false;
+new_active(A) ->
+ A.
+
+get_active(St) ->
+ A = case proplists:get_value(active, St#st.sockopts, undefined) of
+ undefined ->
+ Mod = case St#st.protomod of
+ ssl ->
+ ssl;
+ gen_tcp ->
+ inet
+ end,
+ {ok, [{active, Ax}]} = Mod:getopts(St#st.sock, [active]),
+ Ax;
+ Ay ->
+ Ay
+ end,
+ ?debug("#### ~w(~w) get_active: ~p\n", [St#st.type, self(), A]),
+ St#st{active = A}.
+
+
+%%
+%% SOCKET FUNCTIONS
+%%
+
+%%
+%% ssl
+%%
+
+%%
+%% listen(St, LPort) -> {ok, LSock} | {error, Reason}
+%%
+listen(St, LPort) ->
+ case St#st.protomod of
+ ssl ->
+ ssl:listen(LPort, St#st.sockopts ++ St#st.sslopts);
+ gen_tcp ->
+ gen_tcp:listen(LPort, St#st.sockopts)
+ end.
+
+%%
+%% accept(St) -> {ok, Sock} | {error, Reason}
+%%
+accept(St) ->
+ case St#st.protomod of
+ ssl ->
+ case ssl:transport_accept(St#st.lsock, St#st.timeout) of
+ {ok, Sock} ->
+ case ssl:ssl_accept(Sock, St#st.timeout) of
+ ok ->
+ {ok, Port} = ssl:sockname(Sock),
+ {ok, Peer} = ssl:peername(Sock),
+ {ok, Sock, Port, Peer};
+ Other ->
+ Other
+ end;
+ Other ->
+ Other
+ end;
+ gen_tcp ->
+ case gen_tcp:accept(St#st.lsock, St#st.timeout) of
+ {ok, Sock} ->
+ {ok, Port} = inet:port(Sock),
+ {ok, Peer} = inet:peername(Sock),
+ {ok, Sock, Port, Peer};
+ Other ->
+ Other
+ end
+ end.
+
+%%
+%% connect(St, Host, Port) -> {ok, Sock} | {error, Reason}
+%%
+connect(St, Host, Port) ->
+
+ case St#st.protomod of
+ ssl ->
+ case ssl:connect(Host, Port, St#st.sockopts ++ St#st.sslopts,
+ St#st.timeout) of
+ {ok, Sock} ->
+ {ok, LPort} = ssl:sockname(Sock),
+ {ok, Peer} = ssl:peername(Sock),
+ {ok, Sock, LPort, Peer};
+ Other ->
+ Other
+ end;
+ gen_tcp ->
+ case gen_tcp:connect(Host, Port, St#st.sockopts, St#st.timeout) of
+ {ok, Sock} ->
+ {ok, LPort} = inet:port(Sock),
+ {ok, Peer} = inet:peername(Sock),
+ {ok, Sock, LPort, Peer};
+ Other ->
+ Other
+ end
+ end.
+
+%%
+%% peercert(St) -> {ok, Cert} | {error, Reason}
+%%
+peercert(St) ->
+ case St#st.protomod of
+ ssl ->
+ ssl:peercert(St#st.sock, [ssl]);
+ gen_tcp ->
+ {ok, <<>>}
+ end.
+
+%%
+%% connection_info(St) -> {ok, ProtoInfo} | {error, Reason}
+%%
+connection_info(St) ->
+ case St#st.protomod of
+ ssl ->
+ case ssl:connection_info(St#st.sock) of
+ Res = {ok, {Proto, _}} ->
+ case St#st.protocols of
+ [] ->
+ Res;
+ Protocols ->
+ case lists:member(Proto, Protocols) of
+ true ->
+ Res;
+ false ->
+ {error, Proto}
+ end
+ end;
+ Error ->
+ Error
+ end;
+ gen_tcp ->
+ {ok, <<>>}
+ end.
+
+%%
+%% close(St) -> ok | {error, Reason}
+%%
+
+close(St) ->
+ Mod = St#st.protomod,
+ case St#st.sock of
+ nil ->
+ ok;
+ _ ->
+ Mod:close(St#st.sock)
+ end.
+
+%%
+%% lclose(St) -> ok | {error, Reason}
+%%
+lclose(St) ->
+ Mod = St#st.protomod,
+ case St#st.lsock of
+ nil ->
+ ok;
+ _ ->
+ Mod:close(St#st.lsock)
+ end.
+
+%%
+%% recv(St) = {ok, Len} | {error, Reason}
+%%
+recv(St) ->
+ case do_recv(St) of
+ {ok, Msg} ->
+ {ok, length(Msg)};
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+do_recv(St) when St#st.active == false ->
+ %% First check that we do *not* have any ssl/gen_tcp messages in the
+ %% message queue, then call the receive function.
+ Sock = St#st.sock,
+ case St#st.protomod of
+ ssl ->
+ receive
+ M = {ssl, Sock, _Msg} ->
+ {error, {unexpected_messagex, M}};
+ M = {ssl_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ssl:recv(St#st.sock, 0, St#st.timeout)
+ end;
+ gen_tcp ->
+ receive
+ M = {tcp, Sock, _Msg} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ gen_tcp:recv(St#st.sock, 0, St#st.timeout)
+ end
+ end;
+do_recv(St) ->
+ Sock = St#st.sock,
+ Timeout = St#st.timeout,
+ case St#st.protomod of
+ ssl ->
+ receive
+ {ssl, Sock, Msg} ->
+ {ok, Msg};
+ {ssl_closed, Sock} ->
+ {error, closed};
+ {ssl_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end;
+ gen_tcp ->
+ receive
+ {tcp, Sock, Msg} ->
+ {ok, Msg};
+ {tcp_closed, Sock} ->
+ {error, closed};
+ {tcp_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end
+ end.
+
+%%
+%% echo(St) = {ok, Len} | {error, Reason}
+%%
+echo(St) ->
+ Sock = St#st.sock,
+ case do_recv(St) of
+ {ok, Msg} ->
+ Mod = St#st.protomod,
+ case Mod:send(Sock, Msg) of
+ ok ->
+ {ok, length(Msg)};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+%%
+%% send(St, Msg) -> ok | {error, Reason}
+%%
+send(St, Msg) ->
+ Mod = St#st.protomod,
+ Mod:send(St#st.sock, Msg).
+
+%%
+%% await_close(St) -> ok | {error, Reason}
+%%
+await_close(St) when St#st.active == false ->
+ %% First check that we do *not* have any ssl/gen_tcp messages in the
+ %% message queue, then call the receive function.
+ Sock = St#st.sock,
+ Res = case St#st.protomod of
+ ssl ->
+ receive
+ M = {ssl, Sock, _Msg0} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {ssl_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ok
+ end;
+ gen_tcp ->
+ receive
+ M = {tcp, Sock, _Msg0} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_closed, Sock} ->
+ {error, {unexpected_message, M}};
+ M = {tcp_error, Sock, _Reason} ->
+ {error, {unexpected_message, M}}
+ after 0 ->
+ ok
+ end
+ end,
+ case Res of
+ ok ->
+ Mod = St#st.protomod,
+ case Mod:recv(St#st.sock, 0, St#st.timeout) of
+ {ok, _Msg} ->
+ {error, toomuch};
+ {error, _} ->
+ ok
+ end;
+ _ ->
+ Res
+ end;
+await_close(St) ->
+ Sock = St#st.sock,
+ Timeout = St#st.timeout,
+ case St#st.protomod of
+ ssl ->
+ receive
+ {ssl, Sock, _Msg} ->
+ {error, toomuch};
+ {ssl_closed, Sock} ->
+ ok;
+ {ssl_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end;
+ gen_tcp ->
+ receive
+ {tcp, Sock, _Msg} ->
+ {error, toomuch};
+ {tcp_closed, Sock} ->
+ ok;
+ {tcp_error, Sock, Reason} ->
+ {error, Reason}
+ after Timeout ->
+ {error, timeout}
+ end
+ end.
+
+
+%%
+%% HELP FUNCTIONS
+%%
+
+wait_ack(_, [], _) ->
+ ok;
+wait_ack(AccPids0, Pids, Timeout) ->
+ ?debug("#### CONTROLLER: waiting for ~w~n", [Pids]),
+ receive
+ {one_accept_done, Pid} ->
+ case lists:delete(Pid, AccPids0) of
+ [] ->
+ wait_ack([], Pids, Timeout);
+ [AccPid| AccPids1] ->
+ AccPid ! {continue_accept, self()},
+ wait_ack(AccPids1, Pids, Timeout)
+ end;
+ {'EXIT', Pid, normal} ->
+ wait_ack(AccPids0, lists:delete(Pid, Pids), Timeout);
+ {'EXIT', Pid, Reason} ->
+ ?error("#### CONTROLLER got abnormal exit: ~w, ~w~n",
+ [Pid, Reason]),
+ {error, Reason}
+ after Timeout ->
+ ?error("#### CONTROLLER exiting because of timeout = ~w~n",
+ [Timeout]),
+ {error, Timeout}
+ end.
+
+
+%%
+%% ack_lsock(Pid, LSock)
+%%
+ack_lsock(Pid, LSock) ->
+ Pid ! {lsock, self(), LSock}.
+
+wait_lsock(Pid, Timeout) ->
+ receive
+ {lsock, Pid, LSock} ->
+ {ok, LSock}
+ after Timeout ->
+ exit(timeout)
+ end.
+
+%%
+%% sync(Pids)
+%%
+sync(Pids) ->
+ lists:foreach(fun (Pid) -> Pid ! {self(), sync} end, Pids).
+
+%%
+%% wait_sync(St)
+%%
+wait_sync(St) ->
+ Pid = St#st.parent,
+ receive
+ {Pid, sync} ->
+ ok
+ end.
+
+%%
+%% wait(Time)
+%%
+wait(Time) ->
+ receive
+ after Time ->
+ ok
+ end.
+
+%%
+%% mk_msg(Size)
+%%
+mk_msg(Size) ->
+ mk_msg(0, Size, []).
+
+mk_msg(_, 0, Acc) ->
+ Acc;
+mk_msg(Pos, Size, Acc) ->
+ C = (((Pos + Size) rem 256) - 1) band 255,
+ mk_msg(Pos, Size - 1, [C| Acc]).
+
+%%
+%% get_protomod(Config)
+%%
+get_protomod(Config) ->
+ case lists:keysearch(protomod, 1, Config) of
+ {value, {_, ProtoMod}} ->
+ ProtoMod;
+ false ->
+ ssl
+ end.
+
+%%
+%% get_serialize_accept(Config)
+%%
+get_serialize_accept(Config) ->
+ case lists:keysearch(serialize_accept, 1, Config) of
+ {value, {_, Val}} ->
+ Val;
+ false ->
+ false
+ end.
+
diff --git a/lib/ssl/test/ssl_test_MACHINE.hrl b/lib/ssl/test/ssl_test_MACHINE.hrl
new file mode 100644
index 0000000000..e78b33f505
--- /dev/null
+++ b/lib/ssl/test/ssl_test_MACHINE.hrl
@@ -0,0 +1,39 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-record(st, {protomod = ssl,
+ serialize_accept = false,
+ parent = nil,
+ type = nil,
+ active = nil,
+ port = 0,
+ peer = nil,
+ lsock = nil,
+ sock = nil,
+ timeout = infinity,
+ sockopts = [],
+ sslopts = [],
+ protocols = []}).
+
+%%-define(debug(X, Y), io:format(X, Y)).
+-define(debug(X, Y), ok).
+-define(error(X, Y), io:format(X, Y)).
+
+-define(DEFAULT_TIMEOUT, 240000).
+
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
new file mode 100644
index 0000000000..7ed19b3a05
--- /dev/null
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -0,0 +1,408 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ssl_test_lib).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+
+timetrap(Time) ->
+ Mul = try
+ test_server:timetrap_scale_factor()
+ catch _:_ -> 1 end,
+ test_server:timetrap(1000+Time*Mul).
+
+%% For now always run locally
+run_where(_) ->
+ ClientNode = node(),
+ ServerNode = node(),
+ {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ {ClientNode, ServerNode, Host}.
+
+run_where(_, ipv6) ->
+ ClientNode = node(),
+ ServerNode = node(),
+ {ok, Host} = rpc:call(ServerNode, inet, gethostname, []),
+ {ClientNode, ServerNode, Host}.
+
+node_to_hostip(Node) ->
+ [_ , Host] = string:tokens(atom_to_list(Node), "@"),
+ {ok, Address} = inet:getaddr(Host, inet),
+ Address.
+
+start_server(Args) ->
+ spawn_link(?MODULE, run_server, [Args]).
+
+run_server(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:listen(~p, ~p)~n", [Port, Options]),
+ {ok, ListenSocket} = rpc:call(Node, ssl, listen, [Port, Options]),
+ case Port of
+ 0 ->
+ {ok, {_, NewPort}} = ssl:sockname(ListenSocket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+ run_server(ListenSocket, Opts).
+
+run_server(ListenSocket, Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, ssl, transport_accept,
+ [ListenSocket]),
+ test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
+ ok = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("Server: apply(~p,~p,~p)~n",
+ [Module, Function, [AcceptSocket | Args]]),
+ case rpc:call(Node, Module, Function, [AcceptSocket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ Pid ! {self(), Msg}
+ end,
+ receive
+ listen ->
+ run_server(ListenSocket, Opts);
+ close ->
+ ok = rpc:call(Node, ssl, close, [AcceptSocket])
+ end.
+
+start_client(Args) ->
+ spawn_link(?MODULE, run_client, [Args]).
+
+run_client(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Options = proplists:get_value(options, Opts),
+ test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]),
+ case rpc:call(Node, ssl, connect, [Host, Port, Options]) of
+ {ok, Socket} ->
+ test_server:format("Client: connected~n", []),
+ case proplists:get_value(port, Options) of
+ 0 ->
+ {ok, {_, NewPort}} = ssl:sockname(Socket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("Client: apply(~p,~p,~p)~n",
+ [Module, Function, [Socket | Args]]),
+ case rpc:call(Node, Module, Function, [Socket | Args]) of
+ no_result_msg ->
+ ok;
+ Msg ->
+ Pid ! {self(), Msg}
+ end,
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [Socket])
+ end;
+ {error, Reason} ->
+ test_server:format("Client: connection failed: ~p ~n", [Reason]),
+ Pid ! {self(), {error, Reason}}
+ end.
+
+close(Pid) ->
+ Pid ! close.
+
+check_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Reason = {{expected, {Server, ClientMsg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Server, ServerMsg, Client, ClientMsg);
+
+ Unexpected ->
+ Reason = {{expected, {Client, ClientMsg}},
+ {expected, {Server, ServerMsg}}, {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+check_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ check_result(Pid,Msg);
+ Unexpected ->
+ Reason = {{expected, {Pid, Msg}},
+ {got, Unexpected}},
+ test_server:fail(Reason)
+ end.
+
+wait_for_result(Server, ServerMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ Unexpected ->
+ Unexpected
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ Unexpected
+ end;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ wait_for_result(Server, ServerMsg, Client, ClientMsg);
+ Unexpected ->
+ Unexpected
+ end.
+
+
+wait_for_result(Pid, Msg) ->
+ receive
+ {Pid, Msg} ->
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ wait_for_result(Pid,Msg);
+ Unexpected ->
+ Unexpected
+ end.
+
+cert_options(Config) ->
+ ClientCaCertFile = filename:join([?config(priv_dir, Config),
+ "client", "cacerts.pem"]),
+ ClientCertFile = filename:join([?config(priv_dir, Config),
+ "client", "cert.pem"]),
+ ServerCaCertFile = filename:join([?config(priv_dir, Config),
+ "server", "cacerts.pem"]),
+ ServerCertFile = filename:join([?config(priv_dir, Config),
+ "server", "cert.pem"]),
+ ServerKeyFile = filename:join([?config(priv_dir, Config),
+ "server", "key.pem"]),
+ ClientKeyFile = filename:join([?config(priv_dir, Config),
+ "client", "key.pem"]),
+ ServerKeyCertFile = filename:join([?config(priv_dir, Config),
+ "server", "keycert.pem"]),
+ ClientKeyCertFile = filename:join([?config(priv_dir, Config),
+ "client", "keycert.pem"]),
+
+ BadCaCertFile = filename:join([?config(priv_dir, Config),
+ "badcacert.pem"]),
+ BadCertFile = filename:join([?config(priv_dir, Config),
+ "badcert.pem"]),
+ BadKeyFile = filename:join([?config(priv_dir, Config),
+ "badkey.pem"]),
+ [{client_opts, [{ssl_imp, new}]},
+ {client_verification_opts, [{cacertfile, ClientCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {server_opts, [{ssl_imp, new},{reuseaddr, true},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {server_verification_opts, [{ssl_imp, new},{reuseaddr, true},
+ {cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
+ {client_kc_opts, [{certfile, ClientKeyCertFile}, {ssl_imp, new}]},
+ {server_kc_opts, [{ssl_imp, new},{reuseaddr, true},
+ {certfile, ServerKeyCertFile}]},
+ {client_bad_ca, [{cacertfile, BadCaCertFile},
+ {certfile, ClientCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {client_bad_cert, [{cacertfile, ClientCaCertFile},
+ {certfile, BadCertFile},
+ {keyfile, ClientKeyFile},
+ {ssl_imp, new}]},
+ {server_bad_ca, [{ssl_imp, new},{cacertfile, BadCaCertFile},
+ {certfile, ServerCertFile},
+ {keyfile, ServerKeyFile}]},
+ {server_bad_cert, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
+ {certfile, BadCertFile}, {keyfile, ServerKeyFile}]},
+ {server_bad_key, [{ssl_imp, new},{cacertfile, ServerCaCertFile},
+ {certfile, ServerCertFile}, {keyfile, BadKeyFile}]}
+ | Config].
+
+
+start_upgrade_server(Args) ->
+ spawn_link(?MODULE, run_upgrade_server, [Args]).
+
+run_upgrade_server(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ TimeOut = proplists:get_value(timeout, Opts, infinity),
+ TcpOptions = proplists:get_value(tcp_options, Opts),
+ SslOptions = proplists:get_value(ssl_options, Opts),
+ Pid = proplists:get_value(from, Opts),
+
+ test_server:format("gen_tcp:listen(~p, ~p)~n", [Port, TcpOptions]),
+ {ok, ListenSocket} = rpc:call(Node, gen_tcp, listen, [Port, TcpOptions]),
+
+ case Port of
+ 0 ->
+ {ok, {_, NewPort}} = inet:sockname(ListenSocket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+
+ test_server:format("gen_tcp:accept(~p)~n", [ListenSocket]),
+ {ok, AcceptSocket} = rpc:call(Node, gen_tcp, accept, [ListenSocket]),
+
+ {ok, SslAcceptSocket} = case TimeOut of
+ infinity ->
+ test_server:format("ssl:ssl_accept(~p, ~p)~n",
+ [AcceptSocket, SslOptions]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions]);
+ _ ->
+ test_server:format("ssl:ssl_accept(~p, ~p, ~p)~n",
+ [AcceptSocket, SslOptions, TimeOut]),
+ rpc:call(Node, ssl, ssl_accept,
+ [AcceptSocket, SslOptions, TimeOut])
+ end,
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ Msg = rpc:call(Node, Module, Function, [SslAcceptSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslAcceptSocket])
+ end.
+
+start_upgrade_client(Args) ->
+ spawn_link(?MODULE, run_upgrade_client, [Args]).
+
+run_upgrade_client(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ TcpOptions = proplists:get_value(tcp_options, Opts),
+ SslOptions = proplists:get_value(ssl_options, Opts),
+
+ test_server:format("gen_tcp:connect(~p, ~p, ~p)~n",
+ [Host, Port, TcpOptions]),
+ {ok, Socket} = rpc:call(Node, gen_tcp, connect, [Host, Port, TcpOptions]),
+
+ case proplists:get_value(port, Opts) of
+ 0 ->
+ {ok, {_, NewPort}} = inet:sockname(Socket),
+ Pid ! {self(), {port, NewPort}};
+ _ ->
+ ok
+ end,
+
+ test_server:format("ssl:connect(~p, ~p)~n", [Socket, SslOptions]),
+ {ok, SslSocket} = rpc:call(Node, ssl, connect, [Socket, SslOptions]),
+
+ {Module, Function, Args} = proplists:get_value(mfa, Opts),
+ test_server:format("apply(~p, ~p, ~p)~n",
+ [Module, Function, [SslSocket | Args]]),
+ Msg = rpc:call(Node, Module, Function, [SslSocket | Args]),
+ Pid ! {self(), Msg},
+ receive
+ close ->
+ ok = rpc:call(Node, ssl, close, [SslSocket])
+ end.
+
+start_server_error(Args) ->
+ spawn_link(?MODULE, run_server_error, [Args]).
+
+run_server_error(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Port = proplists:get_value(port, Opts),
+ Options = proplists:get_value(options, Opts),
+ Pid = proplists:get_value(from, Opts),
+ test_server:format("ssl:listen(~p, ~p)~n", [Port, Options]),
+ case rpc:call(Node, ssl, listen, [Port, Options]) of
+ {ok, ListenSocket} ->
+ test_server:sleep(2000), %% To make sure error_client will
+ %% get {error, closed} and not {error, connection_refused}
+ test_server:format("ssl:transport_accept(~p)~n", [ListenSocket]),
+ case rpc:call(Node, ssl, transport_accept, [ListenSocket]) of
+ {error, _} = Error ->
+ Pid ! {self(), Error};
+ {ok, AcceptSocket} ->
+ test_server:format("ssl:ssl_accept(~p)~n", [AcceptSocket]),
+ Error = rpc:call(Node, ssl, ssl_accept, [AcceptSocket]),
+ Pid ! {self(), Error}
+ end;
+ Error ->
+ Pid ! {self(), Error}
+ end.
+
+start_client_error(Args) ->
+ spawn_link(?MODULE, run_client_error, [Args]).
+
+run_client_error(Opts) ->
+ Node = proplists:get_value(node, Opts),
+ Host = proplists:get_value(host, Opts),
+ Port = proplists:get_value(port, Opts),
+ Pid = proplists:get_value(from, Opts),
+ Options = proplists:get_value(options, Opts),
+ test_server:format("ssl:connect(~p, ~p, ~p)~n", [Host, Port, Options]),
+ Error = rpc:call(Node, ssl, connect, [Host, Port, Options]),
+ Pid ! {self(), Error}.
+
+inet_port(Pid) when is_pid(Pid)->
+ receive
+ {Pid, {port, Port}} ->
+ Port
+ end;
+
+inet_port(Node) ->
+ {Port, Socket} = do_inet_port(Node),
+ rpc:call(Node, gen_tcp, close, [Socket]),
+ Port.
+
+do_inet_port(Node) ->
+ {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
+ {ok, Port} = rpc:call(Node, inet, port, [Socket]),
+ {Port, Socket}.
+
+no_result(_) ->
+ no_result_msg.
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
new file mode 100644
index 0000000000..c079e12b83
--- /dev/null
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -0,0 +1,772 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+
+-module(ssl_to_openssl_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("ssl_pkix.hrl").
+
+-define(TIMEOUT, 120000).
+-define(SLEEP, 1000).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ case os:find_executable("openssl") of
+ false ->
+ {skip, "Openssl not found"};
+ _ ->
+ crypto:start(),
+ ssl:start(),
+ Result =
+ (catch make_certs:all(?config(data_dir, Config),
+ ?config(priv_dir, Config))),
+ test_server:format("Make certs ~p~n", [Result]),
+ ssl_test_lib:cert_options(Config)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ ssl:stop(),
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = ssl_test_lib:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test erlangs ssl against openssl"];
+
+all(suite) ->
+ [erlang_client_openssl_server,
+ erlang_server_openssl_client,
+ ssl3_erlang_client_openssl_server,
+ ssl3_erlang_server_openssl_client,
+ ssl3_erlang_client_openssl_server_client_cert,
+ ssl3_erlang_server_openssl_client_client_cert,
+ ssl3_erlang_server_erlang_client_client_cert,
+ tls1_erlang_client_openssl_server,
+ tls1_erlang_server_openssl_client,
+ tls1_erlang_client_openssl_server_client_cert,
+ tls1_erlang_server_openssl_client_client_cert,
+ tls1_erlang_server_erlang_client_client_cert,
+ ciphers
+ ].
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+erlang_client_openssl_server(suite) ->
+ [];
+erlang_client_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile,
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down! Server needs to be closed first !!
+ close_port(OpensslPort),
+
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+
+%%--------------------------------------------------------------------
+erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+erlang_server_openssl_client(suite) ->
+ [];
+erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE, erlang_ssl_receive, [Data]}},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+ssl3_erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+ssl3_erlang_client_openssl_server(suite) ->
+ [];
+ssl3_erlang_client_openssl_server(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -key " ++ KeyFile ++ " -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ connection_info, [sslv3]}},
+ {options,
+ [{versions, [sslv3]} | ClientOpts]}]),
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ test_server:sleep(?SLEEP),
+ ok.
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+ssl3_erlang_server_openssl_client(suite) ->
+ [];
+ssl3_erlang_server_openssl_client(Config) when is_list(Config) ->
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, connection_info, [sslv3]}},
+ {options,
+ [{versions, [sslv3]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ close_port(OpenSslPort), %% openssl server first
+ ssl_test_lib:close(Server),
+ test_server:sleep(?SLEEP),
+ ok.
+
+%%--------------------------------------------------------------------
+ssl3_erlang_client_openssl_server_client_cert(doc) ->
+ ["Test erlang client with openssl server when client sends cert"];
+ssl3_erlang_client_openssl_server_client_cert(suite) ->
+ [];
+ssl3_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -Verify 2 -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down!
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_openssl_client_client_cert(doc) ->
+ ["Test erlang server with openssl client when client sends cert"];
+ssl3_erlang_server_openssl_client_client_cert(suite) ->
+ [];
+ssl3_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ CaCertFile = proplists:get_value(cacertfile, ClientOpts),
+ CertFile = proplists:get_value(certfile, ClientOpts),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
+
+ Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl3",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ close_port(OpenSslPort), %% openssl server first
+ ssl_test_lib:close(Server),
+ %% Clean close down!
+ process_flag(trap_exit, false),
+ ok.
+
+
+%%--------------------------------------------------------------------
+
+ssl3_erlang_server_erlang_client_client_cert(doc) ->
+ ["Test erlang server with erlang client when client sends cert"];
+ssl3_erlang_server_erlang_client_client_cert(suite) ->
+ [];
+ssl3_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [sslv3]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_client_openssl_server(doc) ->
+ ["Test erlang client with openssl server"];
+tls1_erlang_client_openssl_server(suite) ->
+ [];
+tls1_erlang_client_openssl_server(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_opts, Config),
+
+
+ test_server:format("Server Opts", [ServerOpts]),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile
+ ++ " -key " ++ KeyFile ++ " -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ connection_info, [tlsv1]}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ ssl_test_lib:close(Client),
+ %% Clean close down!
+ close_port(OpensslPort),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_server_openssl_client(doc) ->
+ ["Test erlang server with openssl client"];
+tls1_erlang_server_openssl_client(suite) ->
+ [];
+tls1_erlang_server_openssl_client(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa,
+ {?MODULE, connection_info, [tlsv1]}},
+ {options,
+ [{versions, [tlsv1]} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down!
+ close_port(OpenSslPort),
+ ssl_test_lib:close(Server),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_client_openssl_server_client_cert(doc) ->
+ ["Test erlang client with openssl server when client sends cert"];
+tls1_erlang_client_openssl_server_client_cert(suite) ->
+ [];
+tls1_erlang_client_openssl_server_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, _, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Port = ssl_test_lib:inet_port(node()),
+ CaCertFile = proplists:get_value(cacertfile, ServerOpts),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -Verify 2 -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpensslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options, ClientOpts}]),
+ port_command(OpensslPort, Data),
+
+ ssl_test_lib:check_result(Client, ok),
+
+ %% Clean close down!
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+
+tls1_erlang_server_openssl_client_client_cert(doc) ->
+ ["Test erlang server with openssl client when client sends cert"];
+tls1_erlang_server_openssl_client_client_cert(suite) ->
+ [];
+tls1_erlang_server_openssl_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {_, ServerNode, _} = ssl_test_lib:run_where(Config),
+
+ Data = "From openssl to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ CaCertFile = proplists:get_value(cacertfile, ClientOpts),
+ CertFile = proplists:get_value(certfile, ClientOpts),
+ KeyFile = proplists:get_value(keyfile, ClientOpts),
+
+ Cmd = "openssl s_client -cert " ++ CertFile ++ " -CAfile " ++ CaCertFile
+ ++ " -key " ++ KeyFile ++ " -port " ++ integer_to_list(Port) ++
+ " -host localhost -tls1",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+ port_command(OpenSslPort, Data),
+
+ ssl_test_lib:check_result(Server, ok),
+
+ %% Clean close down!
+ close_port(OpenSslPort),
+ ssl_test_lib:close(Server),
+ process_flag(trap_exit, false),
+ ok.
+
+%%--------------------------------------------------------------------
+tls1_erlang_server_erlang_client_client_cert(doc) ->
+ ["Test erlang server with erlang client when client sends cert"];
+tls1_erlang_server_erlang_client_client_cert(suite) ->
+ [];
+tls1_erlang_server_erlang_client_client_cert(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ServerOpts = ?config(server_verification_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Data = "From erlang to erlang",
+
+ Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {mfa, {?MODULE,
+ erlang_ssl_receive, [Data]}},
+ {options,
+ [{verify , verify_peer}
+ | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {ssl, send, [Data]}},
+ {options,
+ [{versions, [tlsv1]} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ %% Clean close down!
+ process_flag(trap_exit, false),
+ ok.
+%%--------------------------------------------------------------------
+
+ciphers(doc) ->
+ [""];
+
+ciphers(suite) ->
+ [];
+
+ciphers(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(),
+ Result = lists:map(fun(Cipher) ->
+ cipher(Cipher, Version, Config) end,
+ Ciphers),
+ case lists:flatten(Result) of
+ [] ->
+ ok;
+ Error ->
+ test_server:format("Cipher suite errors: ~p~n", [Error]),
+ test_server:fail(cipher_suite_failed_see_test_case_log)
+ end.
+
+cipher(CipherSuite, Version, Config) ->
+ process_flag(trap_exit, true),
+ test_server:format("Testing CipherSuite ~p~n", [CipherSuite]),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ {ClientNode, _ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Port = ssl_test_lib:inet_port(node()),
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ KeyFile = proplists:get_value(keyfile, ServerOpts),
+
+ Cmd = "openssl s_server -accept " ++ integer_to_list(Port) ++
+ " -cert " ++ CertFile
+ ++ " -key " ++ KeyFile ++ "",
+
+ test_server:format("openssl cmd: ~p~n", [Cmd]),
+
+ OpenSslPort = open_port({spawn, Cmd}, [stderr_to_stdout]),
+
+ test_server:sleep(?SLEEP),
+
+ Client = ssl_test_lib:start_client([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {mfa, {?MODULE, connection_info_result, []}},
+ {options,
+ [{ciphers,[CipherSuite]} |
+ ClientOpts]}]),
+
+ ClientMsg = {ok, {Version, CipherSuite}},
+
+ Result = ssl_test_lib:wait_for_result(Client, ClientMsg),
+
+ close_port(OpenSslPort),
+ %% Clean close down!
+ ssl_test_lib:close(Client),
+ receive
+ {'EXIT', Client, normal} ->
+ ok
+ end,
+
+ Return = case Result of
+ ok ->
+ [];
+ Error ->
+ [{CipherSuite, Error}]
+ end,
+ process_flag(trap_exit, false),
+ Return.
+
+%%--------------------------------------------------------------------
+
+erlang_ssl_receive(Socket, Data) ->
+ test_server:format("Connection info: ~p~n",
+ [ssl:connection_info(Socket)]),
+ receive
+ {ssl, Socket, Data} ->
+ io:format("Received ~p~n",[Data]),
+ %% open_ssl server sometimes hangs waiting in blocking read
+ ssl:send(Socket, "Got it"),
+ ok;
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ erlang_ssl_receive(Socket,Data);
+ Other ->
+ test_server:fail({unexpected_message, Other})
+ after 4000 ->
+ test_server:fail({did_not_get, Data})
+ end.
+
+connection_info(Socket, Version) ->
+ case ssl:connection_info(Socket) of
+ {ok, {Version, _} = Info} ->
+ test_server:format("Connection info: ~p~n", [Info]),
+ ok;
+ {ok, {OtherVersion, _}} ->
+ {wrong_version, OtherVersion}
+ end.
+
+connection_info_result(Socket) ->
+ ssl:connection_info(Socket).
+
+close_port(Port) ->
+ port_command(Port, "Q\n"),
+ %%catch port_command(Port, "quit\n"),
+ close_loop(Port, 500, false).
+
+close_loop(Port, Time, SentClose) ->
+ receive
+ {Port, {data,Debug}} when is_port(Port) ->
+ io:format("openssl ~s~n",[Debug]),
+ close_loop(Port, Time, SentClose);
+ {ssl,_,Msg} ->
+ io:format("ssl Msg ~s~n",[Msg]),
+ close_loop(Port, Time, SentClose);
+ {Port, closed} ->
+ io:format("Port Closed~n",[]),
+ ok;
+ {'EXIT', Port, Reason} ->
+ io:format("Port Closed ~p~n",[Reason]),
+ ok;
+ Msg ->
+ io:format("Port Msg ~p~n",[Msg]),
+ close_loop(Port, Time, SentClose)
+ after Time ->
+ case SentClose of
+ false ->
+ io:format("Closing port ~n",[]),
+ catch erlang:port_close(Port),
+ close_loop(Port, Time, true);
+ true ->
+ io:format("Timeout~n",[])
+ end
+ end.