aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/configure.in7
-rw-r--r--erts/emulator/beam/sys.h16
-rw-r--r--erts/emulator/drivers/common/efile_drv.c57
-rw-r--r--erts/emulator/drivers/common/erl_efile.h13
-rw-r--r--erts/emulator/drivers/common/ram_file_drv.c17
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c22
-rw-r--r--erts/emulator/drivers/win32/win_efile.c28
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50816 -> 50708 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23808 -> 23788 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44500 -> 44352 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1448 -> 1420 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin29496 -> 30472 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57320 -> 57288 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22600 -> 22432 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10620 -> 10596 bytes
-rw-r--r--erts/preloaded/src/prim_file.erl52
-rw-r--r--lib/ic/doc/src/notes.xml22
-rw-r--r--lib/ic/vsn.mk6
-rw-r--r--lib/kernel/doc/src/file.xml46
-rw-r--r--lib/kernel/src/file.erl28
-rw-r--r--lib/kernel/src/file_io_server.erl16
-rw-r--r--lib/kernel/src/ram_file.erl48
-rw-r--r--lib/kernel/test/file_SUITE.erl103
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl95
-rw-r--r--lib/ssl/doc/src/new_ssl.xml19
-rw-r--r--lib/ssl/src/ssl.erl5
-rw-r--r--lib/ssl/src/ssl_cipher.erl373
-rw-r--r--lib/ssl/src/ssl_cipher.hrl59
-rw-r--r--lib/ssl/src/ssl_connection.erl148
-rw-r--r--lib/ssl/src/ssl_handshake.erl64
-rw-r--r--lib/ssl/src/ssl_manager.erl18
-rw-r--r--lib/ssl/src/ssl_record.erl11
-rw-r--r--lib/ssl/src/ssl_ssl3.erl71
-rw-r--r--lib/ssl/src/ssl_tls1.erl75
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl310
-rw-r--r--lib/wx/src/wx_object.erl10
36 files changed, 1031 insertions, 708 deletions
diff --git a/erts/configure.in b/erts/configure.in
index a14b10adbf..63bf548c89 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1054,6 +1054,7 @@ fi
AC_SUBST(ERTS_BUILD_SMP_EMU)
+AC_CHECK_FUNCS([posix_fadvise])
#
@@ -1757,6 +1758,12 @@ fi
dnl Need by run_erl.
AC_CHECK_FUNCS([openpty])
+dnl fdatasync syscall (Unix only)
+AC_CHECK_FUNCS([fdatasync])
+
+dnl Find which C libraries are required to use fdatasync
+AC_SEARCH_LIBS(fdatasync, [rt])
+
dnl ----------------------------------------------------------------------
dnl Checks for features/quirks in the system that affects Erlang.
dnl ----------------------------------------------------------------------
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index a1955235b7..0f20d36167 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -1173,14 +1173,14 @@ EXTERN_FUNCTION(void*, sys_calloc2, (Uint, Uint));
/* Standard set of integer macros .. */
-#define get_int64(s) ((((unsigned char*) (s))[0] << 56) | \
- (((unsigned char*) (s))[1] << 48) | \
- (((unsigned char*) (s))[2] << 40) | \
- (((unsigned char*) (s))[3] << 32) | \
- (((unsigned char*) (s))[4] << 24) | \
- (((unsigned char*) (s))[5] << 16) | \
- (((unsigned char*) (s))[6] << 8) | \
- (((unsigned char*) (s))[7]))
+#define get_int64(s) (((Uint64)(((unsigned char*) (s))[0]) << 56) | \
+ (((Uint64)((unsigned char*) (s))[1]) << 48) | \
+ (((Uint64)((unsigned char*) (s))[2]) << 40) | \
+ (((Uint64)((unsigned char*) (s))[3]) << 32) | \
+ (((Uint64)((unsigned char*) (s))[4]) << 24) | \
+ (((Uint64)((unsigned char*) (s))[5]) << 16) | \
+ (((Uint64)((unsigned char*) (s))[6]) << 8) | \
+ (((Uint64)((unsigned char*) (s))[7])))
#define put_int64(i, s) do {((char*)(s))[0] = (char)((Sint64)(i) >> 56) & 0xff;\
((char*)(s))[1] = (char)((Sint64)(i) >> 48) & 0xff;\
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index d2b916000e..60ae4cb108 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -53,6 +53,8 @@
#define FILE_IPREAD 27
#define FILE_ALTNAME 28
#define FILE_READ_LINE 29
+#define FILE_FDATASYNC 30
+#define FILE_FADVISE 31
/* Return codes */
@@ -357,6 +359,11 @@ struct t_data
struct t_readdir_buf *first_buf;
struct t_readdir_buf *last_buf;
} read_dir;
+ struct {
+ Sint64 offset;
+ Sint64 length;
+ int advise;
+ } fadvise;
} c;
char b[1];
};
@@ -883,6 +890,15 @@ static void invoke_chdir(void *data)
invoke_name(data, efile_chdir);
}
+static void invoke_fdatasync(void *data)
+{
+ struct t_data *d = (struct t_data *) data;
+ int fd = (int) d->fd;
+
+ d->again = 0;
+ d->result_ok = efile_fdatasync(&d->errInfo, fd);
+}
+
static void invoke_fsync(void *data)
{
struct t_data *d = (struct t_data *) data;
@@ -1637,6 +1653,18 @@ static void invoke_open(void *data)
d->result_ok = status;
}
+static void invoke_fadvise(void *data)
+{
+ struct t_data *d = (struct t_data *) data;
+ int fd = (int) d->fd;
+ off_t offset = (off_t) d->c.fadvise.offset;
+ off_t length = (off_t) d->c.fadvise.length;
+ int advise = (int) d->c.fadvise.advise;
+
+ d->again = 0;
+ d->result_ok = efile_fadvise(&d->errInfo, fd, offset, length, advise);
+}
+
static void free_readdir(void *data)
{
struct t_data *d = (struct t_data *) data;
@@ -1919,12 +1947,14 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
case FILE_RMDIR:
case FILE_CHDIR:
case FILE_DELETE:
+ case FILE_FDATASYNC:
case FILE_FSYNC:
case FILE_TRUNCATE:
case FILE_LINK:
case FILE_SYMLINK:
case FILE_RENAME:
case FILE_WRITE_INFO:
+ case FILE_FADVISE:
reply(desc, d->result_ok, &d->errInfo);
free_data(data);
break;
@@ -2209,6 +2239,18 @@ file_output(ErlDrvData e, char* buf, int count)
goto done;
}
+ case FILE_FDATASYNC:
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data));
+
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_fdatasync;
+ d->free = free_data;
+ d->level = 2;
+ goto done;
+ }
+
case FILE_FSYNC:
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
@@ -2332,6 +2374,21 @@ file_output(ErlDrvData e, char* buf, int count)
goto done;
}
+ case FILE_FADVISE:
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data));
+
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_fadvise;
+ d->free = free_data;
+ d->level = 2;
+ d->c.fadvise.offset = get_int64((uchar*) buf);
+ d->c.fadvise.length = get_int64(((uchar*) buf) + sizeof(Sint64));
+ d->c.fadvise.advise = get_int32(((uchar*) buf) + 2 * sizeof(Sint64));
+ goto done;
+ }
+
}
/*
diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index 9aa941e550..bbc973d58b 100644
--- a/erts/emulator/drivers/common/erl_efile.h
+++ b/erts/emulator/drivers/common/erl_efile.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1997-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%
*/
/*
@@ -126,6 +126,7 @@ int efile_readdir(Efile_error* errInfo, char* name,
int efile_openfile(Efile_error* errInfo, char* name, int flags,
int* pfd, Sint64* pSize);
void efile_closefile(int fd);
+int efile_fdatasync(Efile_error* errInfo, int fd);
int efile_fsync(Efile_error* errInfo, int fd);
int efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
char *name, int info_for_link);
@@ -150,3 +151,5 @@ int efile_altname(Efile_error* errInfo, char *name,
int efile_link(Efile_error* errInfo, char* old, char* new);
int efile_symlink(Efile_error* errInfo, char* old, char* new);
int efile_may_openfile(Efile_error* errInfo, char *name);
+int efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset, Sint64 length,
+ int advise);
diff --git a/erts/emulator/drivers/common/ram_file_drv.c b/erts/emulator/drivers/common/ram_file_drv.c
index 4a39a156e6..abedcc933a 100644
--- a/erts/emulator/drivers/common/ram_file_drv.c
+++ b/erts/emulator/drivers/common/ram_file_drv.c
@@ -35,6 +35,7 @@
#define RAM_FILE_TRUNCATE 14
#define RAM_FILE_PREAD 17
#define RAM_FILE_PWRITE 18
+#define RAM_FILE_FDATASYNC 19
/* other operations */
#define RAM_FILE_GET 30
@@ -45,6 +46,8 @@
#define RAM_FILE_UUENCODE 35 /* uuencode file */
#define RAM_FILE_UUDECODE 36 /* uudecode file */
#define RAM_FILE_SIZE 37 /* get file size */
+#define RAM_FILE_ADVISE 38 /* predeclare the access
+ * pattern for file data */
/* possible new operations include:
DES_ENCRYPT
DES_DECRYPT
@@ -558,6 +561,13 @@ static void rfile_command(ErlDrvData e, char* buf, int count)
numeric_reply(f, 0); /* 0 is not used */
break;
+ case RAM_FILE_FDATASYNC:
+ if (f->flags == 0)
+ error_reply(f, EBADF);
+ else
+ reply(f, 1, 0);
+ break;
+
case RAM_FILE_FSYNC:
if (f->flags == 0)
error_reply(f, EBADF);
@@ -685,6 +695,13 @@ static void rfile_command(ErlDrvData e, char* buf, int count)
case RAM_FILE_UUDECODE: /* uudecode file */
ram_file_uudecode(f);
break;
+
+ case RAM_FILE_ADVISE:
+ if (f->flags == 0)
+ error_reply(f, EBADF);
+ else
+ reply(f, 1, 0);
+ break;
}
/*
* Ignore anything else -- let the caller hang.
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 1d094ee613..ea016526ef 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -774,6 +774,17 @@ efile_closefile(int fd)
}
int
+efile_fdatasync(Efile_error *errInfo, /* Where to return error codes. */
+ int fd) /* File descriptor for file to sync data. */
+{
+#ifdef HAVE_FDATASYNC
+ return check_error(fdatasync(fd), errInfo);
+#else
+ return efile_fsync(errInfo, fd);
+#endif
+}
+
+int
efile_fsync(Efile_error *errInfo, /* Where to return error codes. */
int fd) /* File descriptor for file to sync. */
{
@@ -1437,3 +1448,14 @@ efile_symlink(Efile_error* errInfo, char* old, char* new)
return check_error(symlink(old, new), errInfo);
#endif
}
+
+int
+efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,
+ Sint64 length, int advise)
+{
+#ifdef HAVE_POSIX_FADVISE
+ return check_error(posix_fadvise(fd, offset, length, advise), errInfo);
+#else
+ return check_error(0, errInfo);
+#endif
+}
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index 89aaad31da..d5f2b79706 100644
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1997-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1997-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%
*/
/*
@@ -764,6 +764,15 @@ int fd; /* File descriptor for file to close. */
}
int
+efile_fdatasync(errInfo, fd)
+Efile_error* errInfo; /* Where to return error codes. */
+int fd; /* File descriptor for file to sync. */
+{
+ /* Not available in Windows, just call regular fsync */
+ return efile_fsync(errInfo, fd);
+}
+
+int
efile_fsync(errInfo, fd)
Efile_error* errInfo; /* Where to return error codes. */
int fd; /* File descriptor for file to sync. */
@@ -1424,3 +1433,12 @@ efile_symlink(Efile_error* errInfo, char* old, char* new)
errno = ENOTSUP;
return check_error(-1, errInfo);
}
+
+int
+efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,
+ Sint64 length, int advise)
+{
+ /* posix_fadvise is not available on Windows, do nothing */
+ errno = ERROR_SUCCESS;
+ return check_error(0, errInfo);
+}
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index afd8a90b3f..fe3cee1c56 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 4ec84948d8..5a4c5e9d1e 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index c3e746f3ee..cfe2c36cee 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 4b2d8bb2de..74587de26b 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 2916baaa77..c6610b71e6 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 46912e2bea..8d19923281 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index ccf8aff6f6..cd41f36413 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index ccd597ba68..ce1163d260 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 43e6f6cd88..2d177bf80e 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2000-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%
%%
-module(prim_file).
@@ -25,7 +25,7 @@
%%% Interface towards a single file's contents. Uses ?FD_DRV.
%% Generic file contents operations
--export([open/2, close/1, sync/1, position/2, truncate/1,
+-export([open/2, close/1, datasync/1, sync/1, advise/4, position/2, truncate/1,
write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3, copy/3]).
%% Specialized file operations
@@ -96,6 +96,8 @@
-define(FILE_IPREAD, 27).
-define(FILE_ALTNAME, 28).
-define(FILE_READ_LINE, 29).
+-define(FILE_FDATASYNC, 30).
+-define(FILE_ADVISE, 31).
%% Driver responses
-define(FILE_RESP_OK, 0).
@@ -130,6 +132,13 @@
%% IPREAD variants
-define(IPREAD_S32BU_P32BU, 0).
+%% POSIX file advises
+-define(POSIX_FADV_NORMAL, 0).
+-define(POSIX_FADV_RANDOM, 1).
+-define(POSIX_FADV_SEQUENTIAL, 2).
+-define(POSIX_FADV_WILLNEED, 3).
+-define(POSIX_FADV_DONTNEED, 4).
+-define(POSIX_FADV_NOREUSE, 5).
%%%-----------------------------------------------------------------
@@ -220,7 +229,35 @@ close(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
close(Port) when is_port(Port) ->
drv_close(Port).
+-define(ADVISE(Offs, Len, Adv),
+ <<?FILE_ADVISE, Offs:64/signed, Len:64/signed,
+ Adv:32/signed>>).
+%% Returns {error, Reason} | ok.
+advise(#file_descriptor{module = ?MODULE, data = {Port, _}},
+ Offset, Length, Advise) ->
+ case Advise of
+ normal ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NORMAL),
+ drv_command(Port, Cmd);
+ random ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_RANDOM),
+ drv_command(Port, Cmd);
+ sequential ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_SEQUENTIAL),
+ drv_command(Port, Cmd);
+ will_need ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_WILLNEED),
+ drv_command(Port, Cmd);
+ dont_need ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_DONTNEED),
+ drv_command(Port, Cmd);
+ no_reuse ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NOREUSE),
+ drv_command(Port, Cmd);
+ _ ->
+ {error, einval}
+ end.
%% Returns {error, Reason} | ok.
write(#file_descriptor{module = ?MODULE, data = {Port, _}}, Bytes) ->
@@ -292,6 +329,9 @@ pwrite(#file_descriptor{module = ?MODULE}, _, _) ->
{error, badarg}.
+%% Returns {error, Reason} | ok.
+datasync(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ drv_command(Port, [?FILE_FDATASYNC]).
%% Returns {error, Reason} | ok.
sync(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index dbafde7b4b..6684547572 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
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.
-
+
</legalnotice>
<title>IDL Compiler Release Notes</title>
@@ -31,6 +31,22 @@
</header>
<section>
+ <title>IC 4.2.25</title>
+
+ <section>
+ <title>Improvements and New Features</title>
+ <list type="bulleted">
+ <item>
+ <p>
+ The documentation can now be built and installed without Java.</p>
+ <p>
+ Own Id: OTP-8639 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>IC 4.2.24</title>
<section>
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index e0fccf4889..4aa2a04b60 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1,6 +1,8 @@
-IC_VSN = 4.2.24
+IC_VSN = 4.2.25
-TICKETS = OTP-8307 \
+TICKETS = OTP-8639
+
+TICKETS_4.2.24 = OTP-8307 \
OTP-8353 \
OTP-8354 \
OTP-8355
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 50f9722a1c..382262d1ee 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -62,6 +62,25 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}}
</section>
<funcs>
<func>
+ <name>advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}</name>
+ <fsummary>Predeclare an access pattern for file data</fsummary>
+ <type>
+ <v>IoDevice = io_device()</v>
+ <v>Offset = int()</v>
+ <v>Length = int()</v>
+ <v>Advise = posix_file_advise()</v>
+ <v>posix_file_advise() = normal | sequential | random | no_reuse
+ | will_need | dont_need</v>
+ <v>Reason = ext_posix()</v>
+ </type>
+ <desc>
+ <p><c>advise/4</c> can be used to announce an intention to access file
+ data in a specific pattern in the future, thus allowing the
+ operating system to perform appropriate optimizations.</p>
+ <p>On some platforms, this function might have no effect.</p>
+ </desc>
+ </func>
+ <func>
<name>change_group(Filename, Gid) -> ok | {error, Reason}</name>
<fsummary>Change group of a file</fsummary>
<type>
@@ -1641,6 +1660,33 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
+ <name>datasync(IoDevice) -> ok | {error, Reason}</name>
+ <fsummary>Synchronizes the in-memory data of a file, ignoring most of its metadata, with that on the physical medium</fsummary>
+ <type>
+ <v>IoDevice = io_device()</v>
+ <v>Reason = ext_posix() | terminated</v>
+ </type>
+ <desc>
+ <p>Makes sure that any buffers kept by the operating system
+ (not by the Erlang runtime system) are written to disk. In
+ many ways it's resembles fsync but it not requires to update
+ some of file's metadata such as the access time. On
+ some platforms, this function might have no effect.</p>
+ <p>Applications that access databases or log files often write
+ a tiny data fragment (e.g., one line in a log file) and then
+ call fsync() immediately in order to ensure that the written
+ data is physically stored on the harddisk. Unfortunately, fsync()
+ will always initiate two write operations: one for the newly
+ written data and another one in order to update the modification
+ time stored in the inode. If the modification time is not a part
+ of the transaction concept fdatasync() can be used to avoid
+ unnecessary inode disk write operations.</p>
+ <p>Available only in some POSIX systems. This call results in a
+ call to fsync(), or has no effect, in systems not implementing
+ the fdatasync syscall.</p>
+ </desc>
+ </func>
+ <func>
<name>truncate(IoDevice) -> ok | {error, Reason}</name>
<fsummary>Truncate a file</fsummary>
<type>
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 46ffa9d708..a694ed0708 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -36,11 +36,11 @@
%% Specialized
-export([ipread_s32bu_p32bu/3]).
%% Generic file contents.
--export([open/2, close/1,
+-export([open/2, close/1, advise/4,
read/2, write/2,
pread/2, pread/3, pwrite/2, pwrite/3,
read_line/1,
- position/2, truncate/1, sync/1,
+ position/2, truncate/1, datasync/1, sync/1,
copy/2, copy/3]).
%% High level operations
-export([consult/1, path_consult/2]).
@@ -89,6 +89,8 @@
-type date() :: {pos_integer(), pos_integer(), pos_integer()}.
-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
-type date_time() :: {date(), time()}.
+-type posix_file_advise() :: 'normal' | 'sequential' | 'random' | 'no_reuse' |
+ 'will_need' | 'dont_need'.
%%%-----------------------------------------------------------------
%%% General functions
@@ -352,6 +354,18 @@ close(#file_descriptor{module = Module} = Handle) ->
close(_) ->
{error, badarg}.
+-spec advise(File :: io_device(), Offset :: integer(),
+ Length :: integer(), Advise :: posix_file_advise()) ->
+ 'ok' | {'error', posix()}.
+
+advise(File, Offset, Length, Advise) when is_pid(File) ->
+ R = file_request(File, {advise, Offset, Length, Advise}),
+ wait_file_reply(File, R);
+advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) ->
+ Module:advise(Handle, Offset, Length, Advise);
+advise(_, _, _, _) ->
+ {error, badarg}.
+
-spec read(File :: io_device(), Size :: non_neg_integer()) ->
'eof' | {'ok', [char()] | binary()} | {'error', posix()}.
@@ -472,6 +486,16 @@ pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) ->
pwrite(_, _, _) ->
{error, badarg}.
+-spec datasync(File :: io_device()) -> 'ok' | {'error', posix()}.
+
+datasync(File) when is_pid(File) ->
+ R = file_request(File, datasync),
+ wait_file_reply(File, R);
+datasync(#file_descriptor{module = Module} = Handle) ->
+ Module:datasync(Handle);
+datasync(_) ->
+ {error, badarg}.
+
-spec sync(File :: io_device()) -> 'ok' | {'error', posix()}.
sync(File) when is_pid(File) ->
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index 3ac35a209d..39dc32bb79 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -198,6 +198,14 @@ io_reply(From, ReplyAs, Reply) ->
%%%-----------------------------------------------------------------
%%% file requests
+file_request({advise,Offset,Length,Advise},
+ #state{handle=Handle}=State) ->
+ case ?PRIM_FILE:advise(Handle, Offset, Length, Advise) of
+ {error,_}=Reply ->
+ {stop,normal,Reply,State};
+ Reply ->
+ {reply,Reply,State}
+ end;
file_request({pread,At,Sz},
#state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
case position(Handle, At, Buf) of
@@ -219,6 +227,14 @@ file_request({pwrite,At,Data},
Reply ->
std_reply(Reply, State)
end;
+file_request(datasync,
+ #state{handle=Handle}=State) ->
+ case ?PRIM_FILE:datasync(Handle) of
+ {error,_}=Reply ->
+ {stop,normal,Reply,State};
+ Reply ->
+ {reply,Reply,State}
+ end;
file_request(sync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:sync(Handle) of
diff --git a/lib/kernel/src/ram_file.erl b/lib/kernel/src/ram_file.erl
index d996650948..48ea871433 100644
--- a/lib/kernel/src/ram_file.erl
+++ b/lib/kernel/src/ram_file.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-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%
%%
-module(ram_file).
@@ -24,11 +24,11 @@
-export([open/2, close/1]).
-export([write/2, read/2, copy/3,
pread/2, pread/3, pwrite/2, pwrite/3,
- position/2, truncate/1, sync/1]).
+ position/2, truncate/1, datasync/1, sync/1]).
%% Specialized file operations
-export([get_size/1, get_file/1, set_file/2, get_file_close/1]).
--export([compress/1, uncompress/1, uuencode/1, uudecode/1]).
+-export([compress/1, uncompress/1, uuencode/1, uudecode/1, advise/4]).
-export([open_mode/1]). %% used by ftp-file
@@ -60,6 +60,7 @@
-define(RAM_FILE_TRUNCATE, 14).
-define(RAM_FILE_PREAD, 17).
-define(RAM_FILE_PWRITE, 18).
+-define(RAM_FILE_FDATASYNC, 19).
%% Other operations
-define(RAM_FILE_GET, 30).
@@ -70,6 +71,7 @@
-define(RAM_FILE_UUENCODE, 35).
-define(RAM_FILE_UUDECODE, 36).
-define(RAM_FILE_SIZE, 37).
+-define(RAM_FILE_ADVISE, 38).
%% Open modes for RAM_FILE_OPEN
-define(RAM_FILE_MODE_READ, 1).
@@ -90,6 +92,14 @@
-define(RAM_FILE_RESP_NUMBER, 3).
-define(RAM_FILE_RESP_INFO, 4).
+%% POSIX file advises
+-define(POSIX_FADV_NORMAL, 0).
+-define(POSIX_FADV_RANDOM, 1).
+-define(POSIX_FADV_SEQUENTIAL, 2).
+-define(POSIX_FADV_WILLNEED, 3).
+-define(POSIX_FADV_DONTNEED, 4).
+-define(POSIX_FADV_NOREUSE, 5).
+
%% --------------------------------------------------------------------------
%% Generic file contents operations.
%%
@@ -167,6 +177,8 @@ copy(#file_descriptor{module = ?MODULE} = Source,
%% XXX Should be moved down to the driver for optimization.
file:copy_opened(Source, Dest, Length).
+datasync(#file_descriptor{module = ?MODULE, data = Port}) ->
+ call_port(Port, <<?RAM_FILE_FDATASYNC>>).
sync(#file_descriptor{module = ?MODULE, data = Port}) ->
call_port(Port, <<?RAM_FILE_FSYNC>>).
@@ -349,6 +361,28 @@ uudecode(#file_descriptor{module = ?MODULE, data = Port}) ->
uudecode(#file_descriptor{}) ->
{error, enotsup}.
+advise(#file_descriptor{module = ?MODULE, data = Port}, Offset,
+ Length, Advise) ->
+ Cmd0 = <<?RAM_FILE_ADVISE, Offset:64/signed, Length:64/signed>>,
+ case Advise of
+ normal ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_NORMAL:32/signed>>);
+ random ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_RANDOM:32/signed>>);
+ sequential ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_SEQUENTIAL:32/signed>>);
+ will_need ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_WILLNEED:32/signed>>);
+ dont_need ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_DONTNEED:32/signed>>);
+ no_reuse ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_NOREUSE:32/signed>>);
+ _ ->
+ {error, einval}
+ end;
+advise(#file_descriptor{}, _Offset, _Length, _Advise) ->
+ {error, enotsup}.
+
%%%-----------------------------------------------------------------
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 1d170790a3..1d652679b0 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -52,7 +52,7 @@
old_modes/1, new_modes/1, path_open/1, open_errors/1]).
-export([file_info/1, file_info_basic_file/1, file_info_basic_directory/1,
file_info_bad/1, file_info_times/1, file_write_file_info/1]).
--export([rename/1, access/1, truncate/1, sync/1,
+-export([rename/1, access/1, truncate/1, datasync/1, sync/1,
read_write/1, pread_write/1, append/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
-export([otp_5814/1]).
@@ -82,6 +82,8 @@
-export([read_line_1/1, read_line_2/1, read_line_3/1,read_line_4/1]).
+-export([advise/1]).
+
%% Debug exports
-export([create_file_slow/2, create_file/2, create_bin/2]).
-export([verify_file/2, verify_bin/3]).
@@ -377,7 +379,9 @@ win_cur_dir_1(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-files(suite) -> [open,pos,file_info,consult,eval,script,truncate,sync].
+files(suite) ->
+ [open,pos,file_info,consult,eval,script,truncate,
+ sync,datasync,advise].
open(suite) -> [open1,old_modes,new_modes,path_open,close,access,read_write,
pread_write,append,open_errors].
@@ -1355,6 +1359,30 @@ truncate(Config) when is_list(Config) ->
ok.
+datasync(suite) -> [];
+datasync(doc) -> "Tests that ?FILE_MODULE:datasync/1 at least doesn't crash.";
+datasync(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Sync = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_sync.fil"),
+
+ %% Raw open.
+ ?line {ok, Fd} = ?FILE_MODULE:open(Sync, [write, raw]),
+ ?line ok = ?FILE_MODULE:datasync(Fd),
+ ?line ok = ?FILE_MODULE:close(Fd),
+
+ %% Ordinary open.
+ ?line {ok, Fd2} = ?FILE_MODULE:open(Sync, [write]),
+ ?line ok = ?FILE_MODULE:datasync(Fd2),
+ ?line ok = ?FILE_MODULE:close(Fd2),
+
+ ?line [] = flush(),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+
sync(suite) -> [];
sync(doc) -> "Tests that ?FILE_MODULE:sync/1 at least doesn't crash.";
sync(Config) when is_list(Config) ->
@@ -1378,6 +1406,77 @@ sync(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+advise(suite) -> [];
+advise(doc) -> "Tests that ?FILE_MODULE:advise/4 at least doesn't crash.";
+advise(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Advise = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_advise.fil"),
+
+ Line1 = "Hello\n",
+ Line2 = "World!\n",
+
+ ?line {ok, Fd} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd, 0, 0, normal),
+ ?line ok = io:format(Fd, "~s", [Line1]),
+ ?line ok = io:format(Fd, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd),
+
+ ?line {ok, Fd2} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd2, 0, 0, random),
+ ?line ok = io:format(Fd2, "~s", [Line1]),
+ ?line ok = io:format(Fd2, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd2),
+
+ ?line {ok, Fd3} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd3, 0, 0, sequential),
+ ?line ok = io:format(Fd3, "~s", [Line1]),
+ ?line ok = io:format(Fd3, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd3),
+
+ ?line {ok, Fd4} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd4, 0, 0, will_need),
+ ?line ok = io:format(Fd4, "~s", [Line1]),
+ ?line ok = io:format(Fd4, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd4),
+
+ ?line {ok, Fd5} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd5, 0, 0, dont_need),
+ ?line ok = io:format(Fd5, "~s", [Line1]),
+ ?line ok = io:format(Fd5, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd5),
+
+ ?line {ok, Fd6} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd6, 0, 0, no_reuse),
+ ?line ok = io:format(Fd6, "~s", [Line1]),
+ ?line ok = io:format(Fd6, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd6),
+
+ ?line {ok, Fd7} = ?FILE_MODULE:open(Advise, [write]),
+ ?line {error, einval} = ?FILE_MODULE:advise(Fd7, 0, 0, bad_advise),
+ ?line ok = ?FILE_MODULE:close(Fd7),
+
+ %% test write without advise, then a read after an advise
+ ?line {ok, Fd8} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = io:format(Fd8, "~s", [Line1]),
+ ?line ok = io:format(Fd8, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd8),
+ ?line {ok, Fd9} = ?FILE_MODULE:open(Advise, [read]),
+ Offset = 0,
+ %% same as a 0 length in some implementations
+ Length = length(Line1) + length(Line2),
+ ?line ok = ?FILE_MODULE:advise(Fd9, Offset, Length, sequential),
+ ?line {ok, Line1} = ?FILE_MODULE:read_line(Fd9),
+ ?line {ok, Line2} = ?FILE_MODULE:read_line(Fd9),
+ ?line eof = ?FILE_MODULE:read_line(Fd9),
+ ?line ok = ?FILE_MODULE:close(Fd9),
+
+ ?line [] = flush(),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 6badbb5090..21bdc06fdc 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -34,7 +34,7 @@
file_info_times_a/1, file_info_times_b/1,
file_write_file_info_a/1, file_write_file_info_b/1]).
-export([rename_a/1, rename_b/1,
- access/1, truncate/1, sync/1,
+ access/1, truncate/1, datasync/1, sync/1,
read_write/1, pread_write/1, append/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
@@ -48,6 +48,8 @@
symlinks_a/1, symlinks_b/1,
list_dir_limit/1]).
+-export([advise/1]).
+
-include("test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -380,7 +382,7 @@ win_cur_dir_1(_Config, Handle) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-files(suite) -> [open,pos,file_info,truncate,sync].
+files(suite) -> [open,pos,file_info,truncate,sync,datasync,advise].
open(suite) -> [open1,modes,close,access,read_write,
pread_write,append].
@@ -1064,6 +1066,24 @@ truncate(Config) when is_list(Config) ->
ok.
+datasync(suite) -> [];
+datasync(doc) -> "Tests that ?PRIM_FILE:datasync/1 at least doesn't crash.";
+datasync(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Sync = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_sync.fil"),
+
+ %% Raw open.
+ ?line {ok, Fd} = ?PRIM_FILE:open(Sync, [write]),
+ ?line ok = ?PRIM_FILE:datasync(Fd),
+ ?line ok = ?PRIM_FILE:close(Fd),
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+
sync(suite) -> [];
sync(doc) -> "Tests that ?PRIM_FILE:sync/1 at least doesn't crash.";
sync(Config) when is_list(Config) ->
@@ -1082,6 +1102,77 @@ sync(Config) when is_list(Config) ->
ok.
+advise(suite) -> [];
+advise(doc) -> "Tests that ?PRIM_FILE:advise/4 at least doesn't crash.";
+advise(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Advise = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_advise.fil"),
+
+ Line1 = "Hello\n",
+ Line2 = "World!\n",
+
+ ?line {ok, Fd} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd, 0, 0, normal),
+ ?line ok = ?PRIM_FILE:write(Fd, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd),
+
+ ?line {ok, Fd2} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd2, 0, 0, random),
+ ?line ok = ?PRIM_FILE:write(Fd2, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd2, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd2),
+
+ ?line {ok, Fd3} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd3, 0, 0, sequential),
+ ?line ok = ?PRIM_FILE:write(Fd3, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd3, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd3),
+
+ ?line {ok, Fd4} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd4, 0, 0, will_need),
+ ?line ok = ?PRIM_FILE:write(Fd4, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd4, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd4),
+
+ ?line {ok, Fd5} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd5, 0, 0, dont_need),
+ ?line ok = ?PRIM_FILE:write(Fd5, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd5, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd5),
+
+ ?line {ok, Fd6} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd6, 0, 0, no_reuse),
+ ?line ok = ?PRIM_FILE:write(Fd6, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd6, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd6),
+
+ ?line {ok, Fd7} = ?PRIM_FILE:open(Advise, [write]),
+ ?line {error, einval} = ?PRIM_FILE:advise(Fd7, 0, 0, bad_advise),
+ ?line ok = ?PRIM_FILE:close(Fd7),
+
+ %% test write without advise, then a read after an advise
+ ?line {ok, Fd8} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:write(Fd8, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd8, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd8),
+ ?line {ok, Fd9} = ?PRIM_FILE:open(Advise, [read]),
+ Offset = 0,
+ %% same as a 0 length in some implementations
+ Length = length(Line1) + length(Line2),
+ ?line ok = ?PRIM_FILE:advise(Fd9, Offset, Length, sequential),
+ ?line {ok, Line1} = ?PRIM_FILE:read_line(Fd9),
+ ?line {ok, Line2} = ?PRIM_FILE:read_line(Fd9),
+ ?line eof = ?PRIM_FILE:read_line(Fd9),
+ ?line ok = ?PRIM_FILE:close(Fd9),
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
delete_a(suite) -> [];
diff --git a/lib/ssl/doc/src/new_ssl.xml b/lib/ssl/doc/src/new_ssl.xml
index ab6e112a35..4ffaa9d96a 100644
--- a/lib/ssl/doc/src/new_ssl.xml
+++ b/lib/ssl/doc/src/new_ssl.xml
@@ -88,6 +88,10 @@
extensions are not supported yet. </item>
<item>Supported SSL/TLS-versions are SSL-3.0 and TLS-1.0 </item>
<item>For security reasons sslv2 is not supported.</item>
+ <item>Ephemeral Diffie-Hellman cipher suites are supported
+ but not Diffie Hellman Certificates cipher suites.</item>
+ <item>Export cipher suites are not supported as the
+ U.S. lifted its export restrictions in early 2000.</item>
</list>
</section>
@@ -148,25 +152,20 @@
<p><c>protocol() = sslv3 | tlsv1 </c></p>
- <p><c>ciphers() = [ciphersuite()] | sting() (according to old API)</c></p>
+ <p><c>ciphers() = [ciphersuite()] | string() (according to old API)</c></p>
<p><c>ciphersuite() =
- {key_exchange(), cipher(), hash(), exportable()}</c></p>
+ {key_exchange(), cipher(), hash()}</c></p>
- <p><c>key_exchange() = rsa | dh_dss | dh_rsa | dh_anon | dhe_dss
- | dhe_rsa | krb5 | KeyExchange_export
+ <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa
</c></p>
- <p><c>cipher() = rc4_128 | idea_cbc | des_cbc | '3des_ede_cbc'
- des40_cbc | dh_dss | aes_128_cbc | aes_256_cbc |
- rc2_cbc_40 | rc4_40 </c></p>
+ <p><c>cipher() = rc4_128 | des_cbc | '3des_ede_cbc'
+ | aes_128_cbc | aes_256_cbc </c></p>
<p> <c>hash() = md5 | sha
</c></p>
- <p> <c>exportable() = export | no_export | ignore
- </c></p>
-
<p><c>ssl_imp() = new | old - default is old.</c></p>
</section>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 95cd92ee60..185a1f755a 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -718,7 +718,10 @@ emulated_options([], Inet,Emulated) ->
cipher_suites(Version, []) ->
ssl_cipher:suites(Version);
-cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) ->
+cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> %% Backwards compatibility
+ Ciphers = [{KeyExchange, Cipher, Hash} || {KeyExchange, Cipher, Hash, _} <- Ciphers0],
+ cipher_suites(Version, Ciphers);
+cipher_suites(Version, [{_,_,_}| _] = Ciphers0) ->
Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
cipher_suites(Version, Ciphers);
cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index ef4b450d68..daf4ef48b7 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.erl
@@ -48,7 +48,7 @@
%% cipher values has been updated according to <CipherSuite>
%%-------------------------------------------------------------------
security_parameters(CipherSuite, SecParams) ->
- { _, Cipher, Hash, Exportable} = suite_definition(CipherSuite),
+ { _, Cipher, Hash} = suite_definition(CipherSuite),
SecParams#security_parameters{
cipher_suite = CipherSuite,
bulk_cipher_algorithm = bulk_cipher_algorithm(Cipher),
@@ -58,8 +58,7 @@ security_parameters(CipherSuite, SecParams) ->
key_material_length = key_material(Cipher),
iv_size = iv_size(Cipher),
mac_algorithm = mac_algorithm(Hash),
- hash_size = hash_size(Hash),
- exportable = Exportable}.
+ hash_size = hash_size(Hash)}.
%%--------------------------------------------------------------------
%% Function: cipher(Method, CipherState, Mac, Data) ->
@@ -109,10 +108,6 @@ cipher(?AES, CipherState, Mac, Fragment) ->
%% block_cipher(fun(Key, IV, T) ->
%% crypto:idea_cbc_encrypt(Key, IV, T)
%% end, block_size(idea_cbc), CipherState, Mac, Fragment);
-%% cipher(?RC2, CipherState, Mac, Fragment) ->
-%% block_cipher(fun(Key, IV, T) ->
-%% crypto:rc2_40_cbc_encrypt(Key, IV, T)
-%% end, block_size(rc2_cbc_40), CipherState, Mac, Fragment).
block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
Mac, Fragment) ->
@@ -175,10 +170,6 @@ decipher(?AES, HashSz, CipherState, Fragment) ->
%% block_decipher(fun(Key, IV, T) ->
%% crypto:idea_cbc_decrypt(Key, IV, T)
%% end, CipherState, HashSz, Fragment);
-%% decipher(?RC2, HashSz, CipherState, Fragment) ->
-%% block_decipher(fun(Key, IV, T) ->
-%% crypto:rc2_40_cbc_decrypt(Key, IV, T)
-%% end, CipherState, HashSz, Fragment).
block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
HashSz, Fragment) ->
@@ -209,289 +200,147 @@ suites({3, N}) when N == 1; N == 2 ->
%%--------------------------------------------------------------------
%% Function: suite_definition(CipherSuite) ->
-%% {KeyExchange, Cipher, Hash, Exportable}
+%% {KeyExchange, Cipher, Hash}
%%
%%
%% CipherSuite - as defined in ssl_cipher.hrl
-%% KeyExchange - rsa | dh_dss | dh_rsa | dh_anon | dhe_dss | dhe_rsa
-%% krb5 | *_export (old ssl)
+%% KeyExchange - rsa | dh_anon | dhe_dss | dhe_rsa | kerb5
+%%
%% Cipher - null | rc4_128 | idea_cbc | des_cbc | '3des_ede_cbc'
-%% des40_cbc | dh_dss | aes_128_cbc | aes_256_cbc |
-%% rc2_cbc_40 | rc4_40
+%% des40_cbc | aes_128_cbc | aes_256_cbc
%% Hash - null | md5 | sha
-%% Exportable - export | no_export | ignore(?)
%%
-%% Description: Returns a security parameters record where the
+%% Description: Returns a security parameters tuple where the
%% cipher values has been updated according to <CipherSuite>
%% Note: Currently not supported suites are commented away.
%% They should be supported or removed in the future.
%%-------------------------------------------------------------------
%% TLS v1.1 suites
suite_definition(?TLS_NULL_WITH_NULL_NULL) ->
- {null, null, null, ignore};
+ {null, null, null};
%% suite_definition(?TLS_RSA_WITH_NULL_MD5) ->
-%% {rsa, null, md5, ignore};
+%% {rsa, null, md5};
%% suite_definition(?TLS_RSA_WITH_NULL_SHA) ->
-%% {rsa, null, sha, ignore};
+%% {rsa, null, sha};
suite_definition(?TLS_RSA_WITH_RC4_128_MD5) ->
- {rsa, rc4_128, md5, no_export};
+ {rsa, rc4_128, md5};
suite_definition(?TLS_RSA_WITH_RC4_128_SHA) ->
- {rsa, rc4_128, sha, no_export};
+ {rsa, rc4_128, sha};
%% suite_definition(?TLS_RSA_WITH_IDEA_CBC_SHA) ->
-%% {rsa, idea_cbc, sha, no_export};
+%% {rsa, idea_cbc, sha};
suite_definition(?TLS_RSA_WITH_DES_CBC_SHA) ->
- {rsa, des_cbc, sha, no_export};
+ {rsa, des_cbc, sha};
suite_definition(?TLS_RSA_WITH_3DES_EDE_CBC_SHA) ->
- {rsa, '3des_ede_cbc', sha, no_export};
-%% suite_definition(?TLS_DH_DSS_WITH_DES_CBC_SHA) ->
-%% {dh_dss, des_cbc, sha, no_export};
-%% suite_definition(?TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA) ->
-%% {dh_dss, '3des_ede_cbc', sha, no_export};
-%% suite_definition(?TLS_DH_RSA_WITH_DES_CBC_SHA) ->
-%% {dh_rsa, des_cbc, sha, no_export};
-%% suite_definition(?TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA) ->
-%% {dh_rsa, '3des_ede_cbc', sha, no_export};
+ {rsa, '3des_ede_cbc', sha};
suite_definition(?TLS_DHE_DSS_WITH_DES_CBC_SHA) ->
- {dhe_dss, des_cbc, sha, no_export};
+ {dhe_dss, des_cbc, sha};
suite_definition(?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) ->
- {dhe_dss, '3des_ede_cbc', sha, no_export};
+ {dhe_dss, '3des_ede_cbc'};
suite_definition(?TLS_DHE_RSA_WITH_DES_CBC_SHA) ->
- {dhe_rsa, des_cbc, sha, no_export};
+ {dhe_rsa, des_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) ->
- {dhe_rsa, '3des_ede_cbc', sha, no_export};
-%% suite_definition(?TLS_DH_anon_WITH_RC4_128_MD5) ->
-%% {dh_anon, rc4_128, md5, no_export};
-%% suite_definition(?TLS_DH_anon_WITH_DES_CBC_SHA) ->
-%% {dh_anon, des40_cbc, sha, no_export};
-%% suite_definition(?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA) ->
-%% {dh_anon, '3des_ede_cbc', sha, no_export};
+ {dhe_rsa, '3des_ede_cbc', sha};
%%% TSL V1.1 AES suites
suite_definition(?TLS_RSA_WITH_AES_128_CBC_SHA) ->
- {rsa, aes_128_cbc, sha, ignore};
-%% suite_definition(?TLS_DH_DSS_WITH_AES_128_CBC_SHA) ->
-%% {dh_dss, aes_128_cbc, sha, ignore};
-%% suite_definition(?TLS_DH_RSA_WITH_AES_128_CBC_SHA) ->
-%% {dh_rsa, aes_128_cbc, sha, ignore};
+ {rsa, aes_128_cbc, sha};
suite_definition(?TLS_DHE_DSS_WITH_AES_128_CBC_SHA) ->
- {dhe_dss, aes_128_cbc, sha, ignore};
+ {dhe_dss, aes_128_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_AES_128_CBC_SHA) ->
- {dhe_rsa, aes_128_cbc, sha, ignore};
-%% suite_definition(?TLS_DH_anon_WITH_AES_128_CBC_SHA) ->
-%% {dh_anon, aes_128_cbc, sha, ignore};
+ {dhe_rsa, aes_128_cbc, sha};
suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) ->
- {rsa, aes_256_cbc, sha, ignore};
-%% suite_definition(?TLS_DH_DSS_WITH_AES_256_CBC_SHA) ->
-%% {dh_dss, aes_256_cbc, sha, ignore};
-%% suite_definition(?TLS_DH_RSA_WITH_AES_256_CBC_SHA) ->
-%% {dh_rsa, aes_256_cbc, sha, ignore};
+ {rsa, aes_256_cbc, sha};
suite_definition(?TLS_DHE_DSS_WITH_AES_256_CBC_SHA) ->
- {dhe_dss, aes_256_cbc, sha, ignore};
+ {dhe_dss, aes_256_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) ->
- {dhe_rsa, aes_256_cbc, sha, ignore}.
-%% suite_definition(?TLS_DH_anon_WITH_AES_256_CBC_SHA) ->
-%% {dh_anon, aes_256_cbc, sha, ignore};
+ {dhe_rsa, aes_256_cbc, sha}.
-%% TSL V1.1 KRB SUITES
+%% TODO: support kerbos key exchange?
+%% TSL V1.1 KRB SUITES
%% suite_definition(?TLS_KRB5_WITH_DES_CBC_SHA) ->
-%% {krb5, des_cbc, sha, ignore};
+%% {krb5, des_cbc, sha};
%% suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_SHA) ->
-%% {krb5, '3des_ede_cbc', sha, ignore};
+%% {krb5, '3des_ede_cbc', sha};
%% suite_definition(?TLS_KRB5_WITH_RC4_128_SHA) ->
-%% {krb5, rc4_128, sha, ignore};
+%% {krb5, rc4_128, sha};
%% suite_definition(?TLS_KRB5_WITH_IDEA_CBC_SHA) ->
-%% {krb5, idea_cbc, sha, ignore};
+%% {krb5, idea_cbc, sha};
%% suite_definition(?TLS_KRB5_WITH_DES_CBC_MD5) ->
-%% {krb5, des_cbc, md5, ignore};
+%% {krb5, des_cbc, md5};
%% suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_MD5) ->
-%% {krb5, '3des_ede_cbc', md5, ignore};
+%% {krb5, '3des_ede_cbc', md5};
%% suite_definition(?TLS_KRB5_WITH_RC4_128_MD5) ->
-%% {krb5, rc4_128, md5, ignore};
+%% {krb5, rc4_128, md5};
%% suite_definition(?TLS_KRB5_WITH_IDEA_CBC_MD5) ->
-%% {krb5, idea_cbc, md5, ignore};
-
-%% suite_definition(?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5) ->
-%% {rsa, rc4_56, md5, export};
-%% suite_definition(?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5) ->
-%% {rsa, rc2_cbc_56, md5, export};
-%% suite_definition(?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA) ->
-%% {rsa, des_cbc, sha, export};
-%% suite_definition(?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA) ->
-%% {dhe_dss, des_cbc, sha, export};
-%% suite_definition(?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA) ->
-%% {rsa, rc4_56, sha, export};
-%% suite_definition(?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA) ->
-%% {dhe_dss, rc4_56, sha, export};
-%% suite_definition(?TLS_DHE_DSS_WITH_RC4_128_SHA) ->
-%% {dhe_dss, rc4_128, sha, export};
-
-%% Export suites TLS 1.0 OR SSLv3-only servers.
-%% suite_definition(?TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA) ->
-%% {krb5_export, des40_cbc, sha, export};
-%% suite_definition(?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA) ->
-%% {krb5_export, rc2_cbc_40, sha, export};
-%% suite_definition(?TLS_KRB5_EXPORT_WITH_RC4_40_SHA) ->
-%% {krb5_export, des40_cbc, sha, export};
-%% suite_definition(?TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5) ->
-%% {krb5_export, des40_cbc, md5, export};
-%% suite_definition(?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5) ->
-%% {krb5_export, rc2_cbc_40, md5, export};
-%% suite_definition(?TLS_KRB5_EXPORT_WITH_RC4_40_MD5) ->
-%% {krb5_export, rc2_cbc_40, md5, export};
-%% suite_definition(?TLS_RSA_EXPORT_WITH_RC4_40_MD5) ->
-%% {rsa, rc4_40, md5, export};
-%% suite_definition(?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5) ->
-%% {rsa, rc2_cbc_40, md5, export};
-%% suite_definition(?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
-%% {rsa, des40_cbc, sha, export};
-%% suite_definition(?TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA) ->
-%% {dh_dss, des40_cbc, sha, export};
-%% suite_definition(?TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
-%% {dh_rsa, des40_cbc, sha, export};
-%% suite_definition(?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA) ->
-%% {dhe_dss, des40_cbc, sha, export};
-%% suite_definition(?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
-%% {dhe_rsa, des40_cbc, sha, export};
-%% suite_definition(?TLS_DH_anon_EXPORT_WITH_RC4_40_MD5) ->
-%% {dh_anon, rc4_40, md5, export};
-%% suite_definition(?TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA) ->
-%% {dh_anon, des40_cbc, sha, export}.
+%% {krb5, idea_cbc, md5};
%% TLS v1.1 suites
-suite({rsa, null, md5, ignore}) ->
- ?TLS_RSA_WITH_NULL_MD5;
-suite({rsa, null, sha, ignore}) ->
- ?TLS_RSA_WITH_NULL_SHA;
-suite({rsa, rc4_128, md5, no_export}) ->
+%%suite({rsa, null, md5}) ->
+%% ?TLS_RSA_WITH_NULL_MD5;
+%%suite({rsa, null, sha}) ->
+%% ?TLS_RSA_WITH_NULL_SHA;
+suite({rsa, rc4_128, md5}) ->
?TLS_RSA_WITH_RC4_128_MD5;
-suite({rsa, rc4_128, sha, no_export}) ->
+suite({rsa, rc4_128, sha}) ->
?TLS_RSA_WITH_RC4_128_SHA;
-%% suite({rsa, idea_cbc, sha, no_export}) ->
+%% suite({rsa, idea_cbc, sha}) ->
%% ?TLS_RSA_WITH_IDEA_CBC_SHA;
-suite({rsa, des_cbc, sha, no_export}) ->
+suite({rsa, des_cbc, sha}) ->
?TLS_RSA_WITH_DES_CBC_SHA;
-suite({rsa, '3des_ede_cbc', sha, no_export}) ->
+suite({rsa, '3des_ede_cbc', sha}) ->
?TLS_RSA_WITH_3DES_EDE_CBC_SHA;
-%% suite({dh_dss, des_cbc, sha, no_export}) ->
-%% ?TLS_DH_DSS_WITH_DES_CBC_SHA;
-%% suite({dh_dss, '3des_ede_cbc', sha, no_export}) ->
-%% ?TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA;
-%% suite({dh_rsa, des_cbc, sha, no_export}) ->
-%% ?TLS_DH_RSA_WITH_DES_CBC_SHA;
-%% suite({dh_rsa, '3des_ede_cbc', sha, no_export}) ->
-%% ?TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA;
-suite({dhe_dss, des_cbc, sha, no_export}) ->
+suite({dhe_dss, des_cbc, sha}) ->
?TLS_DHE_DSS_WITH_DES_CBC_SHA;
-suite({dhe_dss, '3des_ede_cbc', sha, no_export}) ->
+suite({dhe_dss, '3des_ede_cbc', sha}) ->
?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
-suite({dhe_rsa, des_cbc, sha, no_export}) ->
+suite({dhe_rsa, des_cbc, sha}) ->
?TLS_DHE_RSA_WITH_DES_CBC_SHA;
-suite({dhe_rsa, '3des_ede_cbc', sha, no_export}) ->
+suite({dhe_rsa, '3des_ede_cbc', sha}) ->
?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
-%% suite({dh_anon, rc4_128, md5, no_export}) ->
+%% suite({dh_anon, rc4_128, md5}) ->
%% ?TLS_DH_anon_WITH_RC4_128_MD5;
-%% suite({dh_anon, des40_cbc, sha, no_export}) ->
+%% suite({dh_anon, des40_cbc, sha}) ->
%% ?TLS_DH_anon_WITH_DES_CBC_SHA;
-%% suite({dh_anon, '3des_ede_cbc', sha, no_export}) ->
+%% suite({dh_anon, '3des_ede_cbc', sha}) ->
%% ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
%%% TSL V1.1 AES suites
-suite({rsa, aes_128_cbc, sha, ignore}) ->
+suite({rsa, aes_128_cbc, sha}) ->
?TLS_RSA_WITH_AES_128_CBC_SHA;
-%% suite({dh_dss, aes_128_cbc, sha, ignore}) ->
-%% ?TLS_DH_DSS_WITH_AES_128_CBC_SHA;
-%% suite({dh_rsa, aes_128_cbc, sha, ignore}) ->
-%% ?TLS_DH_RSA_WITH_AES_128_CBC_SHA;
-%% suite({dhe_dss, aes_128_cbc, sha, ignore}) ->
+%% suite({dhe_dss, aes_128_cbc, sha}) ->
%% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
-suite({dhe_rsa, aes_128_cbc, sha, ignore}) ->
+suite({dhe_rsa, aes_128_cbc, sha}) ->
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
-%% suite({dh_anon, aes_128_cbc, sha, ignore}) ->
+%% suite({dh_anon, aes_128_cbc, sha}) ->
%% ?TLS_DH_anon_WITH_AES_128_CBC_SHA;
-suite({rsa, aes_256_cbc, sha, ignore}) ->
+suite({rsa, aes_256_cbc, sha}) ->
?TLS_RSA_WITH_AES_256_CBC_SHA;
-%% suite({dh_dss, aes_256_cbc, sha, ignore}) ->
-%% ?TLS_DH_DSS_WITH_AES_256_CBC_SHA;
-%% suite({dh_rsa, aes_256_cbc, sha, ignore}) ->
-%% ?TLS_DH_RSA_WITH_AES_256_CBC_SHA;
-suite({dhe_dss, aes_256_cbc, sha, ignore}) ->
+suite({dhe_dss, aes_256_cbc, sha}) ->
?TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
-suite({dhe_rsa, aes_256_cbc, sha, ignore}) ->
+suite({dhe_rsa, aes_256_cbc, sha}) ->
?TLS_DHE_RSA_WITH_AES_256_CBC_SHA.
-%% suite({dh_anon, aes_256_cbc, sha, ignore}) ->
+%% suite({dh_anon, aes_256_cbc, sha}) ->
%% ?TLS_DH_anon_WITH_AES_256_CBC_SHA.
+%% TODO: support kerbos key exchange?
%% TSL V1.1 KRB SUITES
-%% suite({krb5, des_cbc, sha, ignore}) ->
+%% suite({krb5, des_cbc, sha}) ->
%% ?TLS_KRB5_WITH_DES_CBC_SHA;
-%% suite({krb5_cbc, '3des_ede_cbc', sha, ignore}) ->
+%% suite({krb5_cbc, '3des_ede_cbc', sha}) ->
%% ?TLS_KRB5_WITH_3DES_EDE_CBC_SHA;
-%% suite({krb5, rc4_128, sha, ignore}) ->
+%% suite({krb5, rc4_128, sha}) ->
%% ?TLS_KRB5_WITH_RC4_128_SHA;
-%% suite({krb5_cbc, idea_cbc, sha, ignore}) ->
+%% suite({krb5_cbc, idea_cbc, sha}) ->
%% ?TLS_KRB5_WITH_IDEA_CBC_SHA;
-%% suite({krb5_cbc, md5, ignore}) ->
+%% suite({krb5_cbc, md5}) ->
%% ?TLS_KRB5_WITH_DES_CBC_MD5;
-%% suite({krb5_ede_cbc, des_cbc, md5, ignore}) ->
+%% suite({krb5_ede_cbc, des_cbc, md5}) ->
%% ?TLS_KRB5_WITH_3DES_EDE_CBC_MD5;
-%% suite({krb5_128, rc4_128, md5, ignore}) ->
+%% suite({krb5_128, rc4_128, md5}) ->
%% ?TLS_KRB5_WITH_RC4_128_MD5;
-%% suite({krb5, idea_cbc, md5, ignore}) ->
+%% suite({krb5, idea_cbc, md5}) ->
%% ?TLS_KRB5_WITH_IDEA_CBC_MD5;
-%% Export suites TLS 1.0 OR SSLv3-only servers.
-%% suite({rsa, rc4_40, md5, export}) ->
-%% ?TLS_RSA_EXPORT_WITH_RC4_40_MD5;
-%% suite({rsa, rc2_cbc_40, md5, export}) ->
-%% ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
-%% suite({rsa, des40_cbc, sha, export}) ->
-%% ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
-%% suite({rsa, rc4_56, md5, export}) ->
-%% ?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5;
-%% suite({rsa, rc2_cbc_56, md5, export}) ->
-%% ?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5;
-%% suite({rsa, des_cbc, sha, export}) ->
-%% ?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA;
-%% suite({dhe_dss, des_cbc, sha, export}) ->
-%% ?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA;
-%% suite({rsa, rc4_56, sha, export}) ->
-%% ?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA;
-%% suite({dhe_dss, rc4_56, sha, export}) ->
-%% ?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA;
-%% suite({dhe_dss, rc4_128, sha, export}) ->
-%% ?TLS_DHE_DSS_WITH_RC4_128_SHA;
-%% suite({krb5_export, des40_cbc, sha, export}) ->
-%% ?TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA;
-%% suite({krb5_export, rc2_cbc_40, sha, export}) ->
-%% ?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA;
-%% suite({krb5_export, rc4_cbc_40, sha, export}) ->
-%% ?TLS_KRB5_EXPORT_WITH_RC4_40_SHA;
-%% suite({krb5_export, des40_cbc, md5, export}) ->
-%% ?TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5;
-%% suite({krb5_export, rc2_cbc_40, md5, export}) ->
-%% ?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5;
-%% suite({krb5_export, rc4_cbc_40, md5, export}) ->
-%% ?TLS_KRB5_EXPORT_WITH_RC4_40_MD5;
-%% suite({rsa_export, rc4_cbc_40, md5, export}) ->
-%% ?TLS_RSA_EXPORT_WITH_RC4_40_MD5;
-%% suite({rsa_export, rc2_cbc_40, md5, export}) ->
-%% ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
-%% suite({rsa_export, des40_cbc, sha, export}) ->
-%% ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
-%% suite({dh_dss_export, des40_cbc, sha, export}) ->
-%% ?TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
-%% suite({dh_rsa_export, des40_cbc, sha, export}) ->
-%% ?TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
-%% suite({dhe_dss_export, des40_cbc, sha, export}) ->
-%% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
-%% suite({dhe_rsa_export, des40_cbc, sha, export}) ->
-%% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
-%% suite({dh_anon_export, rc4_40, md5, export}) ->
-%% ?TLS_DH_anon_EXPORT_WITH_RC4_40_MD5;
-%% suite({dh_anon_export, des40_cbc, sha, export}) ->
-%% ?TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA.
-
-
%% translate constants <-> openssl-strings
%% TODO: Is there a pattern in the nameing
%% that is useable to make a nicer function defention?
@@ -523,36 +372,12 @@ openssl_suite("RC4-SHA") ->
?TLS_RSA_WITH_RC4_128_SHA;
openssl_suite("RC4-MD5") ->
?TLS_RSA_WITH_RC4_128_MD5;
-%% TODO: Do we want to support this?
-%% openssl_suite("EXP1024-RC4-MD5") ->
-%% ?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5;
-%% openssl_suite("EXP1024-RC2-CBC-MD5") ->
-%% ?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5;
-%% openssl_suite("EXP1024-DES-CBC-SHA") ->
-%% ?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA;
-%% openssl_suite("EXP1024-DHE-DSS-DES-CBC-SHA") ->
-%% ?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA;
-%% openssl_suite("EXP1024-RC4-SHA") ->
-%% ?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA;
-%% openssl_suite("EXP1024-DHE-DSS-RC4-SHA") ->
-%% ?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA;
%% openssl_suite("DHE-DSS-RC4-SHA") ->
%% ?TLS_DHE_DSS_WITH_RC4_128_SHA;
-
openssl_suite("EDH-RSA-DES-CBC-SHA") ->
?TLS_DHE_RSA_WITH_DES_CBC_SHA;
openssl_suite("DES-CBC-SHA") ->
?TLS_RSA_WITH_DES_CBC_SHA.
-%% openssl_suite("EXP-EDH-RSA-DES-CBC-SHA") ->
-%% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
-%% openssl_suite("EXP-EDH-DSS-DES-CBC-SHA") ->
-%% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
-%% openssl_suite("EXP-DES-CBC-SHA") ->
-%% ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
-%% openssl_suite("EXP-RC2-CBC-MD5") ->
-%% ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
-%% openssl_suite("EXP-RC4-MD5") ->
-%% ?TLS_RSA_EXPORT_WITH_RC4_40_MD5.
openssl_suite_name(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) ->
"DHE-RSA-AES256-SHA";
@@ -582,29 +407,7 @@ openssl_suite_name(?TLS_DHE_RSA_WITH_DES_CBC_SHA) ->
"EDH-RSA-DES-CBC-SHA";
openssl_suite_name(?TLS_RSA_WITH_DES_CBC_SHA) ->
"DES-CBC-SHA";
-%% openssl_suite_name(?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
-%% "EXP-EDH-RSA-DES-CBC-SHA";
-%% openssl_suite_name(?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA) ->
-%% "EXP-EDH-DSS-DES-CBC-SHA";
-%% openssl_suite_name(?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
-%% "EXP-DES-CBC-SHA";
-%% openssl_suite_name(?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5) ->
-%% "EXP-RC2-CBC-MD5";
-%% openssl_suite_name(?TLS_RSA_EXPORT_WITH_RC4_40_MD5) ->
-%% "EXP-RC4-MD5";
-
-%% openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5) ->
-%% "EXP1024-RC4-MD5";
-%% openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5) ->
-%% "EXP1024-RC2-CBC-MD5";
-%% openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA) ->
-%% "EXP1024-DES-CBC-SHA";
-%% openssl_suite_name(?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA) ->
-%% "EXP1024-DHE-DSS-DES-CBC-SHA";
-%% openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA) ->
-%% "EXP1024-RC4-SHA";
-%% openssl_suite_name(?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA) ->
-%% "EXP1024-DHE-DSS-RC4-SHA";
+
%% openssl_suite_name(?TLS_DHE_DSS_WITH_RC4_128_SHA) ->
%% "DHE-DSS-RC4-SHA";
@@ -621,12 +424,7 @@ bulk_cipher_algorithm(null) ->
%% Not supported yet
%% bulk_cipher_algorithm(idea_cbc) ->
%% ?IDEA;
-%% bulk_cipher_algorithm(Cipher) when Cipher == rc2_cbc_40;
-%% Cipher == rc2_cbc_56 ->
-%% ?RC2;
-bulk_cipher_algorithm(Cipher) when Cipher == rc4_40;
- Cipher == rc4_56;
- Cipher == rc4_128 ->
+bulk_cipher_algorithm(rc4_128) ->
?RC4;
%% bulk_cipher_algorithm(des40_cbc) ->
%% ?DES40;
@@ -639,14 +437,10 @@ bulk_cipher_algorithm(Cipher) when Cipher == aes_128_cbc;
?AES.
type(Cipher) when Cipher == null;
- Cipher == rc4_40;
- Cipher == rc4_56;
Cipher == rc4_128 ->
?STREAM;
type(Cipher) when Cipher == idea_cbc;
- Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56;
Cipher == des40_cbc;
Cipher == des_cbc;
Cipher == '3des_ede_cbc';
@@ -659,13 +453,8 @@ key_material(null) ->
key_material(Cipher) when Cipher == idea_cbc;
Cipher == rc4_128 ->
16;
-key_material(Cipher) when Cipher == rc2_cbc_56;
- Cipher == rc4_56 ->
- 7;
-key_material(Cipher) when Cipher == rc2_cbc_40;
- Cipher == rc4_40;
- Cipher == des40_cbc ->
- 5;
+%%key_material(des40_cbc) ->
+%% 5;
key_material(des_cbc) ->
8;
key_material('3des_ede_cbc') ->
@@ -678,10 +467,6 @@ key_material(aes_256_cbc) ->
expanded_key_material(null) ->
0;
expanded_key_material(Cipher) when Cipher == idea_cbc;
- Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56;
- Cipher == rc4_40;
- Cipher == rc4_56;
Cipher == rc4_128 ->
16;
expanded_key_material(Cipher) when Cipher == des_cbc;
@@ -696,13 +481,9 @@ expanded_key_material(Cipher) when Cipher == aes_128_cbc;
effective_key_bits(null) ->
0;
-effective_key_bits(Cipher) when Cipher == rc2_cbc_40;
- Cipher == rc4_40;
- Cipher == des40_cbc ->
- 40;
-effective_key_bits(Cipher) when Cipher == rc2_cbc_56;
- Cipher == rc4_56;
- Cipher == des_cbc ->
+%%effective_key_bits(des40_cbc) ->
+%% 40;
+effective_key_bits(des_cbc) ->
56;
effective_key_bits(Cipher) when Cipher == idea_cbc;
Cipher == rc4_128;
@@ -714,16 +495,12 @@ effective_key_bits(aes_256_cbc) ->
256.
iv_size(Cipher) when Cipher == null;
- Cipher == rc4_40;
- Cipher == rc4_56;
Cipher == rc4_128 ->
0;
iv_size(Cipher) ->
block_size(Cipher).
block_size(Cipher) when Cipher == idea_cbc;
- Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56;
Cipher == des40_cbc;
Cipher == des_cbc;
Cipher == '3des_ede_cbc' ->
diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl
index d282cbd780..80fe527f45 100644
--- a/lib/ssl/src/ssl_cipher.hrl
+++ b/lib/ssl/src/ssl_cipher.hrl
@@ -57,7 +57,7 @@
%% TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 };
-define(TLS_NULL_WITH_NULL_NULL, <<?BYTE(16#00), ?BYTE(16#00)>>).
-%%% The following CipherSuite definitions require that the server
+%%% The following cipher suite definitions require that the server
%%% provide an RSA certificate that can be used for key exchange. The
%%% server may request either an RSA or a DSS signature-capable
%%% certificate in the certificate request message.
@@ -68,24 +68,15 @@
%% TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 };
-define(TLS_RSA_WITH_NULL_SHA, <<?BYTE(16#00), ?BYTE(16#02)>>).
-%% TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x03 };
--define(TLS_RSA_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#03)>>).
-
%% TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 };
-define(TLS_RSA_WITH_RC4_128_MD5, <<?BYTE(16#00), ?BYTE(16#04)>>).
%% TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 };
-define(TLS_RSA_WITH_RC4_128_SHA, <<?BYTE(16#00), ?BYTE(16#05)>>).
-%% TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x06 };
--define(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#06)>>).
-
%% TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00,0x07 };
-define(TLS_RSA_WITH_IDEA_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#07)>>).
-%% TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x08 };
--define(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#08)>>).
-
%% TLS_RSA_WITH_DES_CBC_SHA = { 0x00,0x09 };
-define(TLS_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#09)>>).
@@ -106,51 +97,33 @@
%%% provided by the client must use the parameters (group and
%%% generator) described by the server.
-%% TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0B };
--define(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0B)>>).
-
%% TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00,0x0C };
-define(TLS_DH_DSS_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0C)>>).
%% TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D };
-define(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0D)>>).
-%% TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0E };
--define(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0E)>>).
-
%% TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00,0x0F };
-define(TLS_DH_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0F)>>).
%% TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 };
-define(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#10)>>).
-%% TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 };
--define(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#11)>>).
-
%% TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00,0x12 };
-define(TLS_DHE_DSS_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#12)>>).
%% TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 };
-define(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#13)>>).
-%% TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 };
--define(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#14)>>).
-
%% TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00,0x15 };
-define(TLS_DHE_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#15)>>).
%% TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 };
-define(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#16)>>).
-%% TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x17 };
--define(TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#17)>>).
-
%% TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 };
-define(TLS_DH_anon_WITH_RC4_128_MD5, <<?BYTE(16#00),?BYTE(16#18)>>).
-%% TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 };
--define(TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#19)>>).
-
%% TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A };
-define(TLS_DH_anon_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#1A)>>).
@@ -222,35 +195,7 @@
%% TLS_KRB5_WITH_IDEA_CBC_MD5 = { 0x00,0x25 };
-define(TLS_KRB5_WITH_IDEA_CBC_MD5, <<?BYTE(16#00), ?BYTE(16#25)>>).
-%% TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = { 0x00,0x26 };
--define(TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, <<?BYTE(16#00), ?BYTE(16#26)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = { 0x00,0x27 };
--define(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, <<?BYTE(16#00), ?BYTE(16#27)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC4_40_SHA = { 0x00,0x28 };
--define(TLS_KRB5_EXPORT_WITH_RC4_40_SHA, <<?BYTE(16#00), ?BYTE(16#28)>>).
-
-%% TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = { 0x00,0x29 };
--define(TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#29)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x2A };
--define(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#2A)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x2B };
--define(TLS_KRB5_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#2B)>>).
-
-%% Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
-
--define(TLS_RSA_EXPORT1024_WITH_RC4_56_MD5, <<?BYTE(16#00), ?BYTE(16#60)>>).
--define(TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, <<?BYTE(16#00), ?BYTE(16#61)>>).
--define(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#62)>>).
--define(TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#63)>>).
--define(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, <<?BYTE(16#00), ?BYTE(16#64)>>).
--define(TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, <<?BYTE(16#00), ?BYTE(16#65)>>).
--define(TLS_DHE_DSS_WITH_RC4_128_SHA, <<?BYTE(16#00), ?BYTE(16#66)>>).
-
-%% RFC 5746 - Not a real ciphersuite used to signal empty "renegotiation_info" extension
+%% RFC 5746 - Not a real cipher suite used to signal empty "renegotiation_info" extension
%% to avoid handshake failure from old servers that do not ignore
%% hello extension data as they should.
-define(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, <<?BYTE(16#00), ?BYTE(16#FF)>>).
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index a4eaf03086..75faac9a95 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -39,7 +39,7 @@
-include_lib("public_key/include/public_key.hrl").
%% Internal application API
--export([send/2, send/3, recv/3, connect/7, ssl_accept/6, handshake/2,
+-export([send/2, recv/3, connect/7, ssl_accept/6, handshake/2,
socket_control/3, close/1, shutdown/2,
new_user/2, get_opts/2, set_opts/2, info/1, session_info/1,
peer_certificate/1, sockname/1, peername/1, renegotiation/1]).
@@ -109,8 +109,7 @@
%%--------------------------------------------------------------------
send(Pid, Data) ->
sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, infinity).
-send(Pid, Data, Timeout) ->
- sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, Timeout).
+
%%--------------------------------------------------------------------
%% Function: recv(Socket, Length Timeout) -> {ok, Data} | {error, reason}
%%
@@ -211,8 +210,6 @@ peername(ConnectionPid) ->
%%
%% Description: Same as inet:getopts/2
%%--------------------------------------------------------------------
-get_opts({ListenSocket, {_SslOpts, SockOpts}, _}, OptTags) ->
- get_socket_opts(ListenSocket, OptTags, SockOpts, []);
get_opts(ConnectionPid, OptTags) ->
sync_send_all_state_event(ConnectionPid, {get_opts, OptTags}).
%%--------------------------------------------------------------------
@@ -361,7 +358,7 @@ hello(#server_hello{cipher_suite = CipherSuite,
case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
{Version, NewId, ConnectionStates1} ->
- {KeyAlgorithm, _, _, _} =
+ {KeyAlgorithm, _, _} =
ssl_cipher:suite_definition(CipherSuite),
PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm),
@@ -520,8 +517,7 @@ certify(#server_key_exchange{} = KeyExchangeMsg,
certify(#server_key_exchange{},
State = #state{role = client, negotiated_version = Version,
- key_algorithm = Alg})
- when Alg == rsa; Alg == dh_dss; Alg == dh_rsa ->
+ key_algorithm = rsa}) ->
Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE),
handle_own_alert(Alert, Version, certify_server_key_exchange, State),
{stop, normal, State};
@@ -1056,16 +1052,9 @@ init_certificates(#ssl_options{cacertfile = CACertFile,
case ssl_manager:connection_init(CACertFile, Role) of
{ok, CertDbRef, CacheRef} ->
init_certificates(CertDbRef, CacheRef, CertFile, Role);
- {error, {badmatch, _Error}} ->
- Report = io_lib:format("SSL: Error ~p Initializing: ~p ~n",
- [_Error, CACertFile]),
- error_logger:error_report(Report),
- throw(ecacertfile);
- {error, _Error} ->
- Report = io_lib:format("SSL: Error ~p Initializing: ~p ~n",
- [_Error, CACertFile]),
- error_logger:error_report(Report),
- throw(ecacertfile)
+ {error, Reason} ->
+ handle_file_error(?LINE, error, Reason, CACertFile, ecacertfile,
+ erlang:get_stacktrace())
end.
init_certificates(CertDbRef, CacheRef, CertFile, client) ->
@@ -1081,59 +1070,56 @@ init_certificates(CertDbRef, CacheRef, CertFile, server) ->
[OwnCert] = ssl_certificate:file_to_certificats(CertFile),
{ok, CertDbRef, CacheRef, OwnCert}
catch
- _E:{badmatch, _R={error,_}} ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
- [?LINE, _E,_R, CertFile,
- erlang:get_stacktrace()]),
- error_logger:error_report(Report),
- throw(ecertfile);
- _E:_R ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
- [?LINE, _E,_R, CertFile,
- erlang:get_stacktrace()]),
- error_logger:error_report(Report),
- throw(ecertfile)
+ Error:Reason ->
+ handle_file_error(?LINE, Error, Reason, CertFile, ecertfile,
+ erlang:get_stacktrace())
end.
init_private_key(undefined, "", _Password, client) ->
undefined;
init_private_key(undefined, KeyFile, Password, _) ->
- try
- {ok, List} = ssl_manager:cache_pem_file(KeyFile),
- [Der] = [Der || Der = {PKey, _ , _} <- List,
- PKey =:= rsa_private_key orelse
- PKey =:= dsa_private_key],
- {ok, Decoded} = public_key:decode_private_key(Der,Password),
- Decoded
- catch
- _E:{badmatch, _R={error,_}} ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
- [?LINE, _E,_R, KeyFile,
- erlang:get_stacktrace()]),
- error_logger:error_report(Report),
- throw(ekeyfile);
- _E:_R ->
- Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
- [?LINE, _E,_R, KeyFile,
- erlang:get_stacktrace()]),
- error_logger:error_report(Report),
- throw(ekeyfile)
+ case ssl_manager:cache_pem_file(KeyFile) of
+ {ok, List} ->
+ [Der] = [Der || Der = {PKey, _ , _} <- List,
+ PKey =:= rsa_private_key orelse
+ PKey =:= dsa_private_key],
+ {ok, Decoded} = public_key:decode_private_key(Der,Password),
+ Decoded;
+ {error, Reason} ->
+ handle_file_error(?LINE, error, Reason, KeyFile, ekeyfile,
+ erlang:get_stacktrace())
end;
+
init_private_key(PrivateKey, _, _,_) ->
PrivateKey.
+handle_file_error(Line, Error, {badmatch, Reason}, File, Throw, Stack) ->
+ file_error(Line, Error, Reason, File, Throw, Stack);
+handle_file_error(Line, Error, Reason, File, Throw, Stack) ->
+ file_error(Line, Error, Reason, File, Throw, Stack).
+
+file_error(Line, Error, Reason, File, Throw, Stack) ->
+ Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
+ [Line, Error, Reason, File, Stack]),
+ error_logger:error_report(Report),
+ throw(Throw).
+
init_diffie_hellman(_, client) ->
undefined;
init_diffie_hellman(undefined, _) ->
?DEFAULT_DIFFIE_HELLMAN_PARAMS;
init_diffie_hellman(DHParamFile, server) ->
- {ok, List} = ssl_manager:cache_pem_file(DHParamFile),
- case [Der || Der = {dh_params, _ , _} <- List] of
- [Der] ->
- {ok, Decoded} = public_key:decode_dhparams(Der),
- Decoded;
- [] ->
- ?DEFAULT_DIFFIE_HELLMAN_PARAMS
+ case ssl_manager:cache_pem_file(DHParamFile) of
+ {ok, List} ->
+ case [Der || Der = {dh_params, _ , _} <- List] of
+ [Der] ->
+ {ok, Decoded} = public_key:decode_dhparams(Der),
+ Decoded;
+ [] ->
+ ?DEFAULT_DIFFIE_HELLMAN_PARAMS
+ end;
+ {error, Reason} ->
+ handle_file_error(?LINE, error, Reason, DHParamFile, edhfile, erlang:get_stacktrace())
end.
sync_send_all_state_event(FsmPid, Event) ->
@@ -1191,15 +1177,18 @@ verify_client_cert(#state{client_certificate_requested = true, role = client,
case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret,
Version, KeyAlg,
PrivateKey, Hashes0) of
- ignore -> %% No key or cert or fixed_diffie_hellman
- State;
- Verified ->
+ #certificate_verify{} = Verified ->
{BinVerified, ConnectionStates1, Hashes1} =
encode_handshake(Verified, KeyAlg, Version,
ConnectionStates0, Hashes0),
Transport:send(Socket, BinVerified),
State#state{connection_states = ConnectionStates1,
- tls_handshake_hashes = Hashes1}
+ tls_handshake_hashes = Hashes1};
+ ignore ->
+ State;
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version, certify, State)
+
end;
verify_client_cert(#state{client_certificate_requested = false} = State) ->
State.
@@ -1290,7 +1279,7 @@ server_hello(ServerHello, #state{transport_cb = Transport,
connection_states = ConnectionStates0,
tls_handshake_hashes = Hashes0} = State) ->
CipherSuite = ServerHello#server_hello.cipher_suite,
- {KeyAlgorithm, _, _, _} = ssl_cipher:suite_definition(CipherSuite),
+ {KeyAlgorithm, _, _} = ssl_cipher:suite_definition(CipherSuite),
%% Version = ServerHello#server_hello.server_version, TODO ska kontrolleras
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(ServerHello, Version, ConnectionStates0, Hashes0),
@@ -1333,19 +1322,8 @@ certify_server(#state{transport_cb = Transport,
throw(Alert)
end.
-key_exchange(#state{role = server, key_algorithm = Algo} = State)
- when Algo == rsa;
- Algo == dh_dss;
- Algo == dh_rsa ->
+key_exchange(#state{role = server, key_algorithm = rsa} = State) ->
State;
-
-%% Remove or uncomment when we decide if to support export cipher suites
-%%key_exchange(#state{role = server, key_algorithm = rsa_export} = State) ->
- %% TODO when the public key in the server certificate is
- %% less than or equal to 512 bits in length dont send key_exchange
- %% but do it otherwise
-%% State;
-
key_exchange(#state{role = server, key_algorithm = Algo,
diffie_hellman_params = Params,
private_key = PrivateKey,
@@ -1396,7 +1374,6 @@ key_exchange(#state{role = client,
Transport:send(Socket, BinMsg),
State#state{connection_states = ConnectionStates1,
tls_handshake_hashes = Hashes1};
-
key_exchange(#state{role = client,
connection_states = ConnectionStates0,
key_algorithm = Algorithm,
@@ -1415,9 +1392,6 @@ key_exchange(#state{role = client,
State#state{connection_states = ConnectionStates1,
tls_handshake_hashes = Hashes1}.
-%% key_algorithm = dh_rsa | dh_dss are not supported. If we want to
-%% support it we need a key_exchange clause for it here.
-
rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
when Algorithm == ?rsaEncryption;
Algorithm == ?md2WithRSAEncryption;
@@ -1429,20 +1403,6 @@ rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
rsa_key_exchange(_, _) ->
throw (?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)).
-%% Uncomment if we decide to support cipher suites with key_algorithm
-%% dh_rsa and dh_dss. Could also be removed if we decide support for
-%% this will not be needed. Not supported by openssl!
-%% dh_key_exchange(OwnCert, DhKeys, true) ->
-%% case public_key:pkix_is_fixed_dh_cert(OwnCert) of
-%% true ->
-%% ssl_handshake:key_exchange(client, fixed_diffie_hellman);
-%% false ->
-%% {DhPubKey, _} = DhKeys,
-%% ssl_handshake:key_exchange(client, {dh, DhPubKey})
-%% end;
-%% dh_key_exchange(_, {DhPubKey, _}, false) ->
-%% ssl_handshake:key_exchange(client, {dh, DhPubKey}).
-
request_client_cert(#state{ssl_options = #ssl_options{verify = verify_peer},
connection_states = ConnectionStates0,
cert_db_ref = CertDbRef,
@@ -2117,9 +2077,7 @@ handle_unexpected_message(_Msg, StateName, #state{negotiated_version = Version}
handle_own_alert(Alert, Version, StateName, State),
{stop, normal, State}.
-make_premaster_secret({MajVer, MinVer}, Alg) when Alg == rsa;
- Alg == dh_dss;
- Alg == dh_rsa ->
+make_premaster_secret({MajVer, MinVer}, rsa) ->
Rand = crypto:rand_bytes(?NUM_OF_PREMASTERSECRET_BYTES-2),
<<?BYTE(MajVer), ?BYTE(MinVer), Rand/binary>>;
make_premaster_secret(_, _) ->
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 3772e540b3..5f3dff8894 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -282,7 +282,7 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
PrivateKey, {Hashes0, _}) ->
case public_key:pkix_is_fixed_dh_cert(OwnCert) of
true ->
- ignore;
+ ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE);
false ->
Hashes =
calc_certificate_verify(Version, MasterSecret,
@@ -302,7 +302,6 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
certificate_verify(Signature, {_, PublicKey, _}, Version,
MasterSecret, Algorithm, {_, Hashes0})
when Algorithm == rsa;
- Algorithm == dh_rsa;
Algorithm == dhe_rsa ->
Hashes = calc_certificate_verify(Version, MasterSecret,
Algorithm, Hashes0),
@@ -346,13 +345,6 @@ key_exchange(client, {premaster_secret, Secret, {_, PublicKey, _}}) ->
encrypted_premaster_secret(Secret, PublicKey),
#client_key_exchange{exchange_keys = EncPremasterSecret};
-%% Uncomment if dh_rsa and dh_dss cipher suites should
-%% be supported.
-%% key_exchange(client, fixed_diffie_hellman) ->
-%% #client_key_exchange{exchange_keys =
-%% #client_diffie_hellman_public{
-%% dh_public = <<>>
-%% }};
key_exchange(client, {dh, <<?UINT32(Len), PublicKey:Len/binary>>}) ->
#client_key_exchange{
exchange_keys = #client_diffie_hellman_public{
@@ -725,12 +717,11 @@ master_secret(Version, MasterSecret, #security_parameters{
hash_size = HashSize,
key_material_length = KML,
expanded_key_material_length = EKML,
- iv_size = IVS,
- exportable = Exportable},
+ iv_size = IVS},
ConnectionStates, Role) ->
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
ServerWriteKey, ClientIV, ServerIV} =
- setup_keys(Version, Exportable, MasterSecret, ServerRandom,
+ setup_keys(Version, MasterSecret, ServerRandom,
ClientRandom, HashSize, KML, EKML, IVS),
?DBG_HEX(ClientWriteKey),
?DBG_HEX(ClientIV),
@@ -812,14 +803,7 @@ dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
renegotiation_info = RenegotiationInfo};
dec_hs(?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>, _, _) ->
#certificate{asn1_certificates = certs_to_list(ASN1Certs)};
-%% Uncomment if support for export ciphers is added.
-%% dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen), Mod:ModLen/binary,
-%% ?UINT16(ExpLen), Exp:ExpLen/binary,
-%% ?UINT16(_), Sig/binary>>,
-%% ?KEY_EXCHANGE_RSA, _) ->
-%% #server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod,
-%% rsa_exponent = Exp},
-%% signed_params = Sig};
+
dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
?UINT16(GLen), G:GLen/binary,
?UINT16(YLen), Y:YLen/binary,
@@ -846,8 +830,7 @@ dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(_), PKEPMS/binary>>,
PreSecret = #encrypted_premaster_secret{premaster_secret = PKEPMS},
#client_key_exchange{exchange_keys = PreSecret};
dec_hs(?CLIENT_KEY_EXCHANGE, <<>>, ?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
- %% TODO: Should check whether the cert already contains a suitable DH-key (7.4.7.2)
- throw(?ALERT_REC(?FATAL, implicit_public_value_encoding));
+ throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE));
dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>,
?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
#client_key_exchange{exchange_keys =
@@ -953,17 +936,6 @@ enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version, _) ->
ASN1Certs = certs_from_list(ASN1CertList),
ACLen = erlang:iolist_size(ASN1Certs),
{?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>};
-%% Uncomment if support for export ciphers is added.
-%% enc_hs(#server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod,
-%% rsa_exponent = Exp},
-%% signed_params = SignedParams}, _Version, _) ->
-%% ModLen = byte_size(Mod),
-%% ExpLen = byte_size(Exp),
-%% SignedLen = byte_size(SignedParams),
-%% {?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen),Mod/binary,
-%% ?UINT16(ExpLen), Exp/binary,
-%% ?UINT16(SignedLen), SignedParams/binary>>
-%% };
enc_hs(#server_key_exchange{params = #server_dh_params{
dh_p = P, dh_g = G, dh_y = Y},
signed_params = SignedParams}, _Version, _) ->
@@ -1073,16 +1045,11 @@ from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) ->
certificate_types({KeyExchange, _, _, _})
when KeyExchange == rsa;
- KeyExchange == dh_dss;
- KeyExchange == dh_rsa;
KeyExchange == dhe_dss;
KeyExchange == dhe_rsa ->
<<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>;
certificate_types(_) ->
- %%TODO: Is this a good default,
- %% is there a case where we like to request
- %% a RSA_FIXED_DH or DSS_FIXED_DH
<<?BYTE(?RSA_SIGN)>>.
certificate_authorities(CertDbRef) ->
@@ -1125,22 +1092,16 @@ calc_master_secret({3,N},PremasterSecret, ClientRandom, ServerRandom)
when N == 1; N == 2 ->
ssl_tls1:master_secret(PremasterSecret, ClientRandom, ServerRandom).
-setup_keys({3,0}, Exportable, MasterSecret,
+setup_keys({3,0}, MasterSecret,
ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) ->
- ssl_ssl3:setup_keys(Exportable, MasterSecret, ServerRandom,
+ ssl_ssl3:setup_keys(MasterSecret, ServerRandom,
ClientRandom, HashSize, KML, EKML, IVS);
-setup_keys({3,1}, _Exportable, MasterSecret,
+setup_keys({3,1}, MasterSecret,
ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) ->
ssl_tls1:setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
KML, IVS).
-%% Uncomment when supported
-%% setup_keys({3,2}, _Exportable, MasterSecret,
-%% ServerRandom, ClientRandom, HashSize, KML, _EKML, _IVS) ->
-%% ssl_tls1:setup_keys(MasterSecret, ServerRandom,
-%% ClientRandom, HashSize, KML).
-
calc_finished({3, 0}, Role, MasterSecret, Hashes) ->
ssl_ssl3:finished(Role, MasterSecret, Hashes);
calc_finished({3, N}, Role, MasterSecret, Hashes)
@@ -1154,7 +1115,6 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes)
ssl_tls1:certificate_verify(Algorithm, Hashes).
server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa;
- Algorithm == dh_rsa;
Algorithm == dhe_rsa ->
MD5Context = crypto:md5_init(),
NewMD5Context = crypto:md5_update(MD5Context, Value),
@@ -1166,9 +1126,7 @@ server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa;
<<MD5/binary, SHA/binary>>;
-server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss;
- Algorithm == dhe_dss ->
-
+server_key_exchange_hash(dhe_dss, Value) ->
SHAContext = crypto:sha_init(),
NewSHAContext = crypto:sha_update(SHAContext, Value),
crypto:sha_final(NewSHAContext).
@@ -1176,9 +1134,9 @@ server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss;
sig_alg(dh_anon) ->
?SIGNATURE_ANONYMOUS;
-sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa; Alg == dh_rsa ->
+sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa ->
?SIGNATURE_RSA;
-sig_alg(Alg) when Alg == dh_dss; Alg == dhe_dss ->
+sig_alg(dhe_dss) ->
?SIGNATURE_DSA;
sig_alg(_) ->
?NULL.
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 539ddd936a..7a0192a80f 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -179,10 +179,8 @@ handle_call({{connection_init, TrustedcertsFile, _Role}, Pid}, _From,
{ok, Ref} = ssl_certificate_db:add_trusted_certs(Pid, TrustedcertsFile, Db),
{ok, Ref, Cache}
catch
- _:{badmatch, Error} ->
- {error, Error};
- _E:_R ->
- {error, {_R,erlang:get_stacktrace()}}
+ _:Reason ->
+ {error, Reason}
end,
{reply, Result, State};
@@ -204,14 +202,10 @@ handle_call({{cache_pem, File},Pid}, _, State = #state{certificate_db = Db}) ->
try ssl_certificate_db:cache_pem_file(Pid,File,Db) of
Result ->
{reply, Result, State}
- catch _:{badmatch, Reason} ->
- {reply, Reason, State};
- _:Reason ->
+ catch
+ _:Reason ->
{reply, {error, Reason}, State}
- end;
-
-handle_call(_,_, State) ->
- {reply, ok, State}.
+ end.
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
@@ -339,7 +333,7 @@ init_session_validator([Cache, CacheCb, LifeTime]) ->
CacheCb:foldl(fun session_validation/2,
LifeTime, Cache).
-session_validation({{Host, Port, _}, Session}, LifeTime) ->
+session_validation({{{Host, Port}, _}, Session}, LifeTime) ->
validate_session(Host, Port, Session, LifeTime),
LifeTime;
session_validation({{Port, _}, Session}, LifeTime) ->
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index f9f915f13d..c867848c31 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -29,6 +29,7 @@
-include("ssl_internal.hrl").
-include("ssl_alert.hrl").
-include("ssl_handshake.hrl").
+-include("ssl_cipher.hrl").
-include("ssl_debug.hrl").
%% Connection state handling
@@ -532,12 +533,10 @@ initial_connection_state(ConnectionEnd) ->
}.
initial_security_params(ConnectionEnd) ->
- #security_parameters{connection_end = ConnectionEnd,
- bulk_cipher_algorithm = ?NULL,
- mac_algorithm = ?NULL,
- compression_algorithm = ?NULL,
- cipher_type = ?NULL
- }.
+ SecParams = #security_parameters{connection_end = ConnectionEnd,
+ compression_algorithm = ?NULL},
+ ssl_cipher:security_parameters(?TLS_NULL_WITH_NULL_NULL,
+ SecParams).
empty_connection_state(ConnectionEnd) ->
SecParams = empty_security_params(ConnectionEnd),
diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl
index df809ce275..1bf8c2b458 100644
--- a/lib/ssl/src/ssl_ssl3.erl
+++ b/lib/ssl/src/ssl_ssl3.erl
@@ -30,7 +30,7 @@
-include("ssl_record.hrl"). % MD5 and SHA
-export([master_secret/3, finished/3, certificate_verify/3,
- mac_hash/6, setup_keys/8,
+ mac_hash/6, setup_keys/7,
suites/0]).
-compile(inline).
@@ -76,7 +76,7 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) ->
<<MD5/binary, SHA/binary>>.
certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash})
- when Algorithm == rsa; Algorithm == dh_rsa; Algorithm == dhe_rsa ->
+ when Algorithm == rsa; Algorithm == dhe_rsa ->
%% md5_hash
%% MD5(master_secret + pad_2 +
%% MD5(handshake_messages + master_secret + pad_1));
@@ -88,8 +88,7 @@ certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash})
SHA = handshake_hash(?SHA, MasterSecret, undefined, SHAHash),
<<MD5/binary, SHA/binary>>;
-certificate_verify(Algorithm, MasterSecret, {_, SHAHash})
- when Algorithm == dh_dss; Algorithm == dhe_dss ->
+certificate_verify(dhe_dss, MasterSecret, {_, SHAHash}) ->
%% sha_hash
%% SHA(master_secret + pad_2 +
%% SHA(handshake_messages + master_secret + pad_1));
@@ -114,9 +113,7 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) ->
?DBG_HEX(Mac),
Mac.
-setup_keys(Exportable, MasterSecret, ServerRandom, ClientRandom,
- HS, KML, _EKML, IVS)
- when Exportable == no_export; Exportable == ignore ->
+setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) ->
KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom,
2*(HS+KML+IVS)),
%% draft-ietf-tls-ssl-version3-00 - 6.2.2
@@ -137,47 +134,7 @@ setup_keys(Exportable, MasterSecret, ServerRandom, ClientRandom,
?DBG_HEX(ClientIV),
?DBG_HEX(ServerIV),
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
- ServerWriteKey, ClientIV, ServerIV};
-
-setup_keys(export, MasterSecret, ServerRandom, ClientRandom,
- HS, KML, EKML, IVS) ->
- KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom,
- 2*(HS+KML)),
- %% draft-ietf-tls-ssl-version3-00 - 6.2.2
- %% Exportable encryption algorithms (for which
- %% CipherSpec.is_exportable is true) require additional processing as
- %% follows to derive their final write keys:
-
- %% final_client_write_key = MD5(client_write_key +
- %% ClientHello.random +
- %% ServerHello.random);
- %% final_server_write_key = MD5(server_write_key +
- %% ServerHello.random +
- %% ClientHello.random);
-
- %% Exportable encryption algorithms derive their IVs from the random
- %% messages:
- %% client_write_IV = MD5(ClientHello.random + ServerHello.random);
- %% server_write_IV = MD5(ServerHello.random + ClientHello.random);
-
- <<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary,
- ClientWriteKey:KML/binary, ServerWriteKey:KML/binary>> = KeyBlock,
- <<ClientIV:IVS/binary, _/binary>> =
- hash(?MD5, [ClientRandom, ServerRandom]),
- <<ServerIV:IVS/binary, _/binary>> =
- hash(?MD5, [ServerRandom, ClientRandom]),
- <<FinalClientWriteKey:EKML/binary, _/binary>> =
- hash(?MD5, [ClientWriteKey, ClientRandom, ServerRandom]),
- <<FinalServerWriteKey:EKML/binary, _/binary>> =
- hash(?MD5, [ServerWriteKey, ServerRandom, ClientRandom]),
- ?DBG_HEX(ClientWriteMacSecret),
- ?DBG_HEX(ServerWriteMacSecret),
- ?DBG_HEX(FinalClientWriteKey),
- ?DBG_HEX(FinalServerWriteKey),
- ?DBG_HEX(ClientIV),
- ?DBG_HEX(ServerIV),
- {ClientWriteMacSecret, ServerWriteMacSecret, FinalClientWriteKey,
- FinalServerWriteKey, ClientIV, ServerIV}.
+ ServerWriteKey, ClientIV, ServerIV}.
suites() ->
[
@@ -191,25 +148,12 @@ suites() ->
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
%% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
- %%?TLS_DHE_DSS_WITH_RC4_128_SHA, TODO: Support this?
+ %%?TLS_DHE_DSS_WITH_RC4_128_SHA,
%% ?TLS_RSA_WITH_IDEA_CBC_SHA, Not supported: in later openssl version than OTP requires
-
?TLS_RSA_WITH_RC4_128_SHA,
?TLS_RSA_WITH_RC4_128_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
%%?TLS_DHE_DSS_WITH_RC4_128_SHA,
-
?TLS_RSA_WITH_DES_CBC_SHA
- %% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- %% ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %%?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- %%?TLS_RSA_EXPORT_WITH_RC4_40_MD5
].
%%--------------------------------------------------------------------
@@ -269,8 +213,7 @@ handshake_hash(Method, MasterSecret, Sender, HandshakeHash) ->
hash(Method, [MasterSecret, pad_2(Method), InnerHash]).
get_sender(client) -> "CLNT";
-get_sender(server) -> "SRVR";
-get_sender(none) -> "".
+get_sender(server) -> "SRVR".
generate_keyblock(MasterSecret, ServerRandom, ClientRandom, WantedLength) ->
gen(MasterSecret, [MasterSecret, ServerRandom, ClientRandom],
diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl
index ce9a135168..900b8e166d 100644
--- a/lib/ssl/src/ssl_tls1.erl
+++ b/lib/ssl/src/ssl_tls1.erl
@@ -30,7 +30,7 @@
-include("ssl_debug.hrl").
-export([master_secret/3, finished/3, certificate_verify/2, mac_hash/7,
- setup_keys/5, setup_keys/6, suites/0]).
+ setup_keys/6, suites/0]).
%%====================================================================
%% Internal application API
@@ -58,14 +58,12 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) ->
certificate_verify(Algorithm, {MD5Hash, SHAHash}) when Algorithm == rsa;
- Algorithm == dh_rsa;
Algorithm == dhe_rsa ->
MD5 = hash_final(?MD5, MD5Hash),
SHA = hash_final(?SHA, SHAHash),
<<MD5/binary, SHA/binary>>;
-certificate_verify(Algorithm, {_, SHAHash}) when Algorithm == dh_dss;
- Algorithm == dhe_dss ->
+certificate_verify(dhe_dss, {_, SHAHash}) ->
hash_final(?SHA, SHAHash).
setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
@@ -92,26 +90,27 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
ServerWriteKey, ClientIV, ServerIV}.
-setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen) ->
- %% RFC 4346 - 6.3. Key calculation
- %% key_block = PRF(SecurityParameters.master_secret,
- %% "key expansion",
- %% SecurityParameters.server_random +
- %% SecurityParameters.client_random);
- %% Then the key_block is partitioned as follows:
- %% client_write_MAC_secret[SecurityParameters.hash_size]
- %% server_write_MAC_secret[SecurityParameters.hash_size]
- %% client_write_key[SecurityParameters.key_material_length]
- %% server_write_key[SecurityParameters.key_material_length]
- WantedLength = 2 * (HashSize + KeyMatLen),
- KeyBlock = prf(MasterSecret, "key expansion",
- [ServerRandom, ClientRandom], WantedLength),
- <<ClientWriteMacSecret:HashSize/binary,
- ServerWriteMacSecret:HashSize/binary,
- ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary>>
- = KeyBlock,
- {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
- ServerWriteKey, undefined, undefined}.
+%% TLS v1.1 uncomment when supported.
+%% setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen) ->
+%% %% RFC 4346 - 6.3. Key calculation
+%% %% key_block = PRF(SecurityParameters.master_secret,
+%% %% "key expansion",
+%% %% SecurityParameters.server_random +
+%% %% SecurityParameters.client_random);
+%% %% Then the key_block is partitioned as follows:
+%% %% client_write_MAC_secret[SecurityParameters.hash_size]
+%% %% server_write_MAC_secret[SecurityParameters.hash_size]
+%% %% client_write_key[SecurityParameters.key_material_length]
+%% %% server_write_key[SecurityParameters.key_material_length]
+%% WantedLength = 2 * (HashSize + KeyMatLen),
+%% KeyBlock = prf(MasterSecret, "key expansion",
+%% [ServerRandom, ClientRandom], WantedLength),
+%% <<ClientWriteMacSecret:HashSize/binary,
+%% ServerWriteMacSecret:HashSize/binary,
+%% ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary>>
+%% = KeyBlock,
+%% {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
+%% ServerWriteKey, undefined, undefined}.
mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor},
Length, Fragment) ->
@@ -140,30 +139,18 @@ suites() ->
%%?TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
?TLS_RSA_WITH_AES_256_CBC_SHA,
?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- %% ?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ %%?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
?TLS_RSA_WITH_3DES_EDE_CBC_SHA,
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- %% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ %%?TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
?TLS_RSA_WITH_AES_128_CBC_SHA,
- %%?TLS_DHE_DSS_WITH_RC4_128_SHA, TODO: Support this?
- %% ?TLS_RSA_WITH_IDEA_CBC_SHA,
+ %%?TLS_DHE_DSS_WITH_RC4_128_SHA,
+ %%?TLS_RSA_WITH_IDEA_CBC_SHA,
?TLS_RSA_WITH_RC4_128_SHA,
?TLS_RSA_WITH_RC4_128_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
- %%?TLS_DHE_DSS_WITH_RC4_128_SHA,
- %%?TLS_DHE_RSA_WITH_DES_CBC_SHA,
- %% EDH-DSS-DES-CBC-SHA TODO: ??
+ ?TLS_DHE_RSA_WITH_DES_CBC_SHA,
+ %%TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
?TLS_RSA_WITH_DES_CBC_SHA
- %% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- %%?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %%?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- %%?TLS_RSA_EXPORT_WITH_RC4_40_MD5
].
%%--------------------------------------------------------------------
@@ -245,7 +232,3 @@ hash_final(?MD5, Conntext) ->
crypto:md5_final(Conntext);
hash_final(?SHA, Conntext) ->
crypto:sha_final(Conntext).
-
-
-
-
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 7ca906363f..4cea55cca0 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -27,6 +27,7 @@
-include("test_server.hrl").
-include("test_server_line.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include("ssl_alert.hrl").
-define('24H_in_sec', 86400).
-define(TIMEOUT, 60000).
@@ -98,6 +99,21 @@ init_per_testcase(reuse_session_expired, Config0) ->
ssl:start(),
[{watchdog, Dog} | Config];
+init_per_testcase(no_authority_key_identifier, Config) ->
+ %% Clear cach so that root cert will not
+ %% be found.
+ ssl:stop(),
+ ssl:start(),
+ Config;
+
+init_per_testcase(TestCase, Config) when TestCase == ciphers_ssl3;
+ TestCase == ciphers_ssl3_openssl_names ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, protocol_version, sslv3),
+ ssl:start(),
+ Config;
+
init_per_testcase(_TestCase, Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = test_server:timetrap(?TIMEOUT),
@@ -130,6 +146,10 @@ end_per_testcase(session_cache_process_mnesia, 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) when TestCase == ciphers_ssl3;
+ TestCase == ciphers_ssl3_openssl_names ->
+ application:unset_env(ssl, protocol_version),
+ end_per_testcase(default_action, Config);
end_per_testcase(_TestCase, Config) ->
Dog = ?config(watchdog, Config),
case Dog of
@@ -151,13 +171,14 @@ all(doc) ->
["Test the basic ssl functionality"];
all(suite) ->
- [app, connection_info, controlling_process, controller_dies,
+ [app, alerts, connection_info, controlling_process, controller_dies,
client_closes_socket,
peercert, connect_dist,
peername, sockname, socket_options, misc_ssl_options, versions, cipher_suites,
upgrade, upgrade_with_timeout, tcp_connect,
ipv6, ekeyfile, ecertfile, ecacertfile, eoptions, shutdown,
- shutdown_write, shutdown_both, shutdown_error, ciphers,
+ shutdown_write, shutdown_both, shutdown_error, ciphers, ciphers_ssl3,
+ ciphers_openssl_names, ciphers_ssl3_openssl_names,
send_close, close_transport_accept, dh_params,
server_verify_peer_passive,
server_verify_peer_active, server_verify_peer_active_once,
@@ -168,13 +189,14 @@ all(suite) ->
server_verify_client_once_active,
server_verify_client_once_active_once,
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,
+ 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,
client_renegotiate, server_renegotiate, client_renegotiate_reused_session,
server_renegotiate_reused_session,
client_no_wrap_sequence_number, server_no_wrap_sequence_number,
- extended_key_usage, validate_extensions_fun
+ extended_key_usage, validate_extensions_fun, no_authority_key_identifier,
+ invalid_signature_client, invalid_signature_server
].
%% Test cases starts here.
@@ -185,7 +207,31 @@ app(suite) ->
[];
app(Config) when is_list(Config) ->
ok = test_server:app_test(ssl).
-
+%%--------------------------------------------------------------------
+alerts(doc) ->
+ "Test ssl_alert:alert_txt/1";
+alerts(suite) ->
+ [];
+alerts(Config) when is_list(Config) ->
+ Descriptions = [?CLOSE_NOTIFY, ?UNEXPECTED_MESSAGE, ?BAD_RECORD_MAC,
+ ?DECRYPTION_FAILED, ?RECORD_OVERFLOW, ?DECOMPRESSION_FAILURE,
+ ?HANDSHAKE_FAILURE, ?BAD_CERTIFICATE, ?UNSUPPORTED_CERTIFICATE,
+ ?CERTIFICATE_REVOKED,?CERTIFICATE_EXPIRED, ?CERTIFICATE_UNKNOWN,
+ ?ILLEGAL_PARAMETER, ?UNKNOWN_CA, ?ACCESS_DENIED, ?DECODE_ERROR,
+ ?DECRYPT_ERROR, ?EXPORT_RESTRICTION, ?PROTOCOL_VERSION,
+ ?INSUFFICIENT_SECURITY, ?INTERNAL_ERROR, ?USER_CANCELED,
+ ?NO_RENEGOTIATION],
+ Alerts = [?ALERT_REC(?WARNING, ?CLOSE_NOTIFY) |
+ [?ALERT_REC(?FATAL, Desc) || Desc <- Descriptions]],
+ lists:foreach(fun(Alert) ->
+ case ssl_alert:alert_txt(Alert) of
+ Txt when is_list(Txt) ->
+ ok;
+ Other ->
+ test_server:fail({unexpected, Other})
+ end
+ end, Alerts).
+%%--------------------------------------------------------------------
connection_info(doc) ->
["Test the API function ssl:connection_info/1"];
connection_info(suite) ->
@@ -214,7 +260,7 @@ connection_info(Config) when is_list(Config) ->
Version =
ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
- ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha,no_export}}},
+ ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha}}},
ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
@@ -283,7 +329,7 @@ controlling_process_result(Socket, Pid, Msg) ->
ssl:send(Socket, Msg),
no_result_msg.
-
+%%--------------------------------------------------------------------
controller_dies(doc) ->
["Test that the socket is closed after controlling process dies"];
controller_dies(suite) -> [];
@@ -598,9 +644,12 @@ cipher_suites(suite) ->
[];
cipher_suites(Config) when is_list(Config) ->
- MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha,no_export},
+ MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha},
[_|_] = Suites = ssl:cipher_suites(),
- true = lists:member(MandatoryCipherSuite, Suites).
+ true = lists:member(MandatoryCipherSuite, Suites),
+ Suites = ssl:cipher_suites(erlang),
+ [_|_] =ssl:cipher_suites(openssl).
+
%%--------------------------------------------------------------------
socket_options(doc) ->
["Test API function getopts/2 and setopts/2"];
@@ -637,7 +686,13 @@ socket_options(Config) when is_list(Config) ->
ssl_test_lib:check_result(Server, ok, Client, ok),
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
+ ssl_test_lib:close(Client),
+
+ {ok, Listen} = ssl:listen(0, ServerOpts),
+ {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
+ ok = ssl:setopts(Listen, [{mode, binary}]),
+ {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
+ ssl:close(Listen).
socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
%% Test get/set emulated opts
@@ -1272,9 +1327,9 @@ shutdown_error(Config) when is_list(Config) ->
ok = ssl:close(Listen),
{error, closed} = ssl:shutdown(Listen, read_write).
-%%--------------------------------------------------------------------
+%%-------------------------------------------------------------------
ciphers(doc) ->
- [""];
+ ["Test all ssl cipher suites in highest support ssl/tls version"];
ciphers(suite) ->
[];
@@ -1284,6 +1339,7 @@ ciphers(Config) when is_list(Config) ->
ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
Ciphers = ssl:cipher_suites(),
+ test_server:format("tls1 erlang cipher suites ~p~n", [Ciphers]),
Result = lists:map(fun(Cipher) ->
cipher(Cipher, Version, Config) end,
Ciphers),
@@ -1294,7 +1350,74 @@ ciphers(Config) when is_list(Config) ->
test_server:format("Cipher suite errors: ~p~n", [Error]),
test_server:fail(cipher_suite_failed_see_test_case_log)
end.
-
+
+ciphers_ssl3(doc) ->
+ ["Test all ssl cipher suites in ssl3"];
+
+ciphers_ssl3(suite) ->
+ [];
+
+ciphers_ssl3(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version({3,0}),
+
+ Ciphers = ssl:cipher_suites(),
+ test_server:format("ssl3 erlang cipher suites ~p~n", [Ciphers]),
+ 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.
+
+ciphers_openssl_names(doc) ->
+ ["Test all ssl cipher suites in highest support ssl/tls version"];
+
+ciphers_openssl_names(suite) ->
+ [];
+
+ciphers_openssl_names(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(openssl),
+ test_server:format("tls1 openssl cipher suites ~p~n", [Ciphers]),
+ 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.
+
+
+ciphers_ssl3_openssl_names(doc) ->
+ ["Test all ssl cipher suites in ssl3"];
+
+ciphers_ssl3_openssl_names(suite) ->
+ [];
+
+ciphers_ssl3_openssl_names(Config) when is_list(Config) ->
+ Version = ssl_record:protocol_version({3,0}),
+ Ciphers = ssl:cipher_suites(openssl),
+ 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]),
@@ -1314,7 +1437,9 @@ cipher(CipherSuite, Version, Config) ->
[{ciphers,[CipherSuite]} |
ClientOpts]}]),
- ServerMsg = ClientMsg = {ok, {Version, CipherSuite}},
+ ErlangCipherSuite = erlang_cipher_suite(CipherSuite),
+
+ ServerMsg = ClientMsg = {ok, {Version, ErlangCipherSuite}},
Result = ssl_test_lib:wait_for_result(Server, ServerMsg,
Client, ClientMsg),
@@ -1333,9 +1458,14 @@ cipher(CipherSuite, Version, Config) ->
ok ->
[];
Error ->
- [{CipherSuite, Error}]
+ [{ErlangCipherSuite, Error}]
end.
+erlang_cipher_suite(Suite) when is_list(Suite)->
+ ssl_cipher:suite_definition(ssl_cipher:openssl_suite(Suite));
+erlang_cipher_suite(Suite) ->
+ Suite.
+
%%--------------------------------------------------------------------
reuse_session(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -2273,7 +2403,7 @@ extended_key_usage(Config) when is_list(Config) ->
ServerOpts = ?config(server_verification_opts, Config),
PrivDir = ?config(priv_dir, Config),
- KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
{ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
{ok, Key} = public_key:decode_private_key(KeyInfo),
@@ -2316,7 +2446,7 @@ extended_key_usage(Config) when is_list(Config) ->
{host, Hostname},
{from, self()},
{mfa, {?MODULE, send_recv_result_active, []}},
- {options, NewClientOpts}]),
+ {options, [{verify, verify_peer} | NewClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
@@ -2359,6 +2489,148 @@ validate_extensions_fun(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+no_authority_key_identifier(doc) ->
+ ["Test cert that does not have authorityKeyIdentifier extension"];
+
+no_authority_key_identifier(suite) ->
+ [];
+no_authority_key_identifier(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ NewCertFile = filename:join(PrivDir, "server/new_cert.pem"),
+ {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(CertFile),
+ {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp),
+ OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
+ Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions,
+ NewExtensions = delete_authority_key_extension(Extensions, []),
+ NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = NewExtensions},
+
+ test_server:format("Extensions ~p~n, NewExtensions: ~p~n", [Extensions, NewExtensions]),
+
+ NewDerCert = public_key:sign(NewOTPTbsCert, Key),
+ public_key:der_to_pem(NewCertFile, [{cert, NewDerCert}]),
+ NewServerOpts = [{certfile, NewCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ {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, NewServerOpts}]),
+ 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, [{verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+delete_authority_key_extension([], Acc) ->
+ lists:reverse(Acc);
+delete_authority_key_extension([#'Extension'{extnID = ?'id-ce-authorityKeyIdentifier'} | Rest],
+ Acc) ->
+ delete_authority_key_extension(Rest, Acc);
+delete_authority_key_extension([Head | Rest], Acc) ->
+ delete_authority_key_extension(Rest, [Head | Acc]).
+
+%%--------------------------------------------------------------------
+
+invalid_signature_server(doc) ->
+ ["Test server with invalid signature"];
+
+invalid_signature_server(suite) ->
+ [];
+
+invalid_signature_server(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "server/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join(PrivDir, "server/invalid_cert.pem"),
+ {ok, [{cert, ServerDerCert, _}]} = public_key:pem_to_der(ServerCertFile),
+ {ok, ServerOTPCert} = public_key:pkix_decode_cert(ServerDerCert, otp),
+ ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
+ NewServerDerCert = public_key:sign(ServerOTPTbsCert, Key),
+ public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert}]),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, NewServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, "bad certificate"},
+ Client, {error,"bad certificate"}),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
+invalid_signature_client(doc) ->
+ ["Test server with invalid signature"];
+
+invalid_signature_client(suite) ->
+ [];
+
+invalid_signature_client(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "client/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ NewClientCertFile = filename:join(PrivDir, "client/invalid_cert.pem"),
+ {ok, [{cert, ClientDerCert, _}]} = public_key:pem_to_der(ClientCertFile),
+ {ok, ClientOTPCert} = public_key:pkix_decode_cert(ClientDerCert, otp),
+ ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
+ NewClientDerCert = public_key:sign(ClientOTPTbsCert, Key),
+ public_key:der_to_pem(NewClientCertFile, [{cert, NewClientDerCert}]),
+ NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, NewClientOpts}]),
+
+ ssl_test_lib:check_result(Server, {error, "bad certificate"},
+ Client, {error,"bad certificate"}),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
send_recv_result(Socket) ->
diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl
index 83f9219484..71041ff558 100644
--- a/lib/wx/src/wx_object.erl
+++ b/lib/wx/src/wx_object.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-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%
%%%-------------------------------------------------------------------
%%% File : wx_object.erl