aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asn1/doc/src/notes.xml38
-rw-r--r--lib/asn1/vsn.mk2
-rw-r--r--lib/common_test/doc/src/notes.xml38
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/notes.xml39
-rw-r--r--lib/compiler/vsn.mk2
-rw-r--r--lib/crypto/doc/src/notes.xml15
-rw-r--r--lib/crypto/vsn.mk2
-rw-r--r--lib/debugger/doc/src/notes.xml15
-rw-r--r--lib/debugger/vsn.mk2
-rwxr-xr-xlib/dialyzer/doc/src/notes.xml86
-rw-r--r--lib/edoc/doc/src/notes.xml55
-rw-r--r--lib/edoc/vsn.mk2
-rw-r--r--lib/erl_interface/doc/src/notes.xml43
-rw-r--r--lib/erl_interface/vsn.mk2
-rw-r--r--lib/hipe/doc/src/notes.xml94
-rw-r--r--lib/hipe/vsn.mk2
-rw-r--r--lib/jinterface/doc/src/notes.xml16
-rw-r--r--lib/jinterface/vsn.mk2
-rw-r--r--lib/kernel/doc/src/notes.xml59
-rw-r--r--lib/kernel/vsn.mk2
-rw-r--r--lib/mnesia/doc/src/notes.xml38
-rw-r--r--lib/observer/doc/src/notes.xml40
-rw-r--r--lib/observer/vsn.mk2
-rw-r--r--lib/odbc/doc/src/notes.xml17
-rw-r--r--lib/percept/doc/src/notes.xml15
-rw-r--r--lib/percept/vsn.mk2
-rw-r--r--lib/public_key/doc/src/notes.xml19
-rw-r--r--lib/public_key/doc/src/public_key.xml98
-rw-r--r--lib/public_key/include/public_key.hrl12
-rw-r--r--lib/public_key/src/Makefile1
-rw-r--r--lib/public_key/src/pubkey_cert.erl6
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl2
-rw-r--r--lib/public_key/src/pubkey_pem.erl38
-rw-r--r--lib/public_key/src/pubkey_ssh.erl431
-rw-r--r--lib/public_key/src/public_key.app.src6
-rw-r--r--lib/public_key/src/public_key.erl86
-rw-r--r--lib/public_key/test/public_key_SUITE.erl416
-rw-r--r--lib/public_key/test/public_key_SUITE_data/auth_keys3
-rw-r--r--lib/public_key/test/public_key_SUITE_data/known_hosts3
-rw-r--r--lib/public_key/test/public_key_SUITE_data/openssh_dsa_pub1
-rw-r--r--lib/public_key/test/public_key_SUITE_data/openssh_dsa_with_comment_pub3
-rw-r--r--lib/public_key/test/public_key_SUITE_data/openssh_rsa_pub1
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh1_auth_keys3
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh1_known_hosts2
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_dsa_comment_pub13
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_dsa_pub12
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_rsa_comment_pub7
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_rsa_pub13
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh2_subject_pub8
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_comment_pub9
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_header_pub9
-rw-r--r--lib/reltool/doc/src/notes.xml24
-rw-r--r--lib/reltool/src/reltool_server.erl2
-rw-r--r--lib/reltool/test/reltool_server_SUITE.erl34
-rw-r--r--lib/reltool/vsn.mk2
-rw-r--r--lib/runtime_tools/doc/src/notes.xml17
-rw-r--r--lib/runtime_tools/vsn.mk2
-rw-r--r--lib/sasl/doc/src/notes.xml33
-rw-r--r--lib/sasl/vsn.mk2
-rw-r--r--lib/ssl/doc/src/notes.xml29
-rw-r--r--lib/ssl/src/ssl.erl7
-rw-r--r--lib/ssl/src/ssl_handshake.hrl5
-rw-r--r--lib/stdlib/doc/src/notes.xml91
-rw-r--r--lib/stdlib/src/erl_parse.yrl10
-rw-r--r--lib/stdlib/src/erl_pp.erl10
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl24
-rw-r--r--lib/stdlib/vsn.mk2
-rw-r--r--lib/test_server/doc/src/notes.xml37
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/doc/src/notes.xml49
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/wx/doc/src/notes.xml25
-rw-r--r--lib/wx/vsn.mk2
-rw-r--r--lib/xmerl/doc/src/notes.xml29
-rw-r--r--lib/xmerl/vsn.mk2
76 files changed, 2066 insertions, 210 deletions
diff --git a/lib/asn1/doc/src/notes.xml b/lib/asn1/doc/src/notes.xml
index c93adeffe2..77769afcd4 100644
--- a/lib/asn1/doc/src/notes.xml
+++ b/lib/asn1/doc/src/notes.xml
@@ -31,6 +31,44 @@
<p>This document describes the changes made to the asn1 application.</p>
+<section><title>Asn1 1.6.16</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ asn1ct: Make formatting of errors and warnings consistent</p>
+ <p>
+ Consistently format warning and error reports. Warning
+ and error options from erlc now also work in asnc1ct.
+ (thanks to Tuncer Ayaz)</p>
+ <p>
+ Own Id: OTP-9062</p>
+ </item>
+ <item>
+ <p>
+ Shut off some dialyzer warnings</p>
+ <p>
+ Own Id: OTP-9063</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Crash in asn1ct_check, componentrelation_leadingattr
+ fixed. (Thanks to Stephane Pamelard for finding the bug)</p>
+ <p>
+ Own Id: OTP-9092</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Asn1 1.6.15</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/asn1/vsn.mk b/lib/asn1/vsn.mk
index e900a52286..7b52e18805 100644
--- a/lib/asn1/vsn.mk
+++ b/lib/asn1/vsn.mk
@@ -1,2 +1,2 @@
#next version number to use is 1.6.15 | 1.7 | 2.0
-ASN1_VSN = 1.6.15
+ASN1_VSN = 1.6.16
diff --git a/lib/common_test/doc/src/notes.xml b/lib/common_test/doc/src/notes.xml
index 2fd5dcf4f1..fef1222fcb 100644
--- a/lib/common_test/doc/src/notes.xml
+++ b/lib/common_test/doc/src/notes.xml
@@ -32,6 +32,44 @@
<file>notes.xml</file>
</header>
+<section><title>Common_Test 1.5.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Added an option to test specs which allow the execution
+ of tests as is, instead of doing merging of tests on the
+ same "level". See the merge_tests directive the test
+ specification documentation.</p>
+ <p>
+ Own Id: OTP-9026 Aux Id: seq11768 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Alpha release of Common Test Hooks (CTH). CTHs allow the
+ users of common test to abtract out common behaviours
+ from test suites in a much more elegant and flexible way
+ than was possible before. Note that the addition of this
+ feature may introduce minor changes in the undocumented
+ behaviour of the interface inbetween common_test and
+ test_server.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8851</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Common_Test 1.5.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index 1a820848b5..8a4853e070 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1,3 +1,3 @@
-COMMON_TEST_VSN = 1.5.2
+COMMON_TEST_VSN = 1.5.3
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index 9d89b17afb..25a6db4ce0 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -31,6 +31,45 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 4.7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The <c>-export_type()</c> directive is no longer included
+ among the attributes.</p>
+ <p>
+ Own Id: OTP-8998</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The maximum number of allowed arguments for an Erlang
+ function has been lowered from 256 to 255, so that the
+ number of arguments can now fit in a byte.</p>
+ <p>
+ Own Id: OTP-9049</p>
+ </item>
+ <item>
+ <p>
+ Dependency generation for Makefiles has been added to the
+ compiler and erlc. See the manual pages for
+ <c>compile</c> and <c>erlc</c>. (Thanks to Jean-Sebastien
+ Pedron.)</p>
+ <p>
+ Own Id: OTP-9065</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 4.7.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index d180ecd4e2..e46096a6df 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 4.7.2
+COMPILER_VSN = 4.7.3
diff --git a/lib/crypto/doc/src/notes.xml b/lib/crypto/doc/src/notes.xml
index 54dd0cb01f..5e9bda3920 100644
--- a/lib/crypto/doc/src/notes.xml
+++ b/lib/crypto/doc/src/notes.xml
@@ -30,6 +30,21 @@
</header>
<p>This document describes the changes made to the Crypto application.</p>
+<section><title>Crypto 2.0.2.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Misc. Updates.</p>
+ <p>
+ Own Id: OTP-9132</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Crypto 2.0.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/crypto/vsn.mk b/lib/crypto/vsn.mk
index 4b35c7c0b4..e2d6fd0b37 100644
--- a/lib/crypto/vsn.mk
+++ b/lib/crypto/vsn.mk
@@ -1 +1 @@
-CRYPTO_VSN = 2.0.2
+CRYPTO_VSN = 2.0.2.1
diff --git a/lib/debugger/doc/src/notes.xml b/lib/debugger/doc/src/notes.xml
index 2f8bdc36a1..3aa169a135 100644
--- a/lib/debugger/doc/src/notes.xml
+++ b/lib/debugger/doc/src/notes.xml
@@ -32,6 +32,21 @@
<p>This document describes the changes made to the Debugger
application.</p>
+<section><title>Debugger 3.2.6</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix issues reported by dialyzer.</p>
+ <p>
+ Own Id: OTP-9107</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Debugger 3.2.5</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/debugger/vsn.mk b/lib/debugger/vsn.mk
index b9786b4a75..0f70dafc19 100644
--- a/lib/debugger/vsn.mk
+++ b/lib/debugger/vsn.mk
@@ -1 +1 @@
-DEBUGGER_VSN = 3.2.5
+DEBUGGER_VSN = 3.2.6
diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml
index 3678291be7..f132a50e0d 100755
--- a/lib/dialyzer/doc/src/notes.xml
+++ b/lib/dialyzer/doc/src/notes.xml
@@ -31,6 +31,92 @@
<p>This document describes the changes made to the Dialyzer
application.</p>
+<section><title>Dialyzer 2.4.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add a --fullpath option to Dialyzer</p>
+ <p>
+ This change adds a --fullpath option to Dialyzer, which
+ makes the warning messages contain the full path of the
+ corresponding file.</p>
+ <p>
+ Original patch submitted by Magnus Henoch (legoscia) on
+ 15/9/2010 and cooked to death in the 'pu' branch all this
+ time.</p>
+ <p>
+ The patch was essentially correct and most of it has been
+ used as is, but there have been some changes to make the
+ code slightly prettier, avoid some code duplication, and
+ add documentation to dialyzer's doc files and to its help
+ message.</p>
+ <p>
+ Own Id: OTP-9098</p>
+ </item>
+ <item>
+ <p>
+ Fix warnings about guards containing not</p>
+ <p>
+ The wording of warnings about unsatisfiable guards that
+ used 'not' was incorrect (the 'not' was not mentioned and
+ it appeared as "Guard test is_atom(atom()) can never
+ succeed") (thanks to Stavros Aronis).</p>
+ <p>
+ Own Id: OTP-9099</p>
+ </item>
+ <item>
+ <p>
+ Version 2.4.2 (in Erlang/OTP R14B02)
+ ------------------------------------ - Added --fullpath
+ option to display files with warnings with their full
+ file names (thanks to Magnus Henoch for the original
+ patch). - Better handling of 'and'/'or'/'not' guards that
+ generate warnings (thanks to Stavros Aronis). - Better
+ blame assignment for cases when a function's spec is
+ erroneous (thanks to Stavros Aronis). - More descriptive
+ warnings when a tuple/record pattern contains subterms
+ that violate the declared types of record fields (thanks
+ to Matthias Lang for the test case and for Stavros Aronis
+ for the actual fix).</p>
+ <p>
+ Own Id: OTP-9126</p>
+ </item>
+ <item>
+ <p>
+ Add spec to dialyzer_cl_parse:get_lib_dir/1</p>
+ <p>
+ Own Id: OTP-9129</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Test suites for Dialyzer</p>
+ <p>
+ This is a transcription of most of the
+ cvs.srv.it.uu.se:/hipe repository dialyzer_tests into
+ test suites that use the test server framework.</p>
+ <p>
+ See README for information on how to use the included
+ scripts for modifications and updates.</p>
+ <p>
+ When testing Dialyzer it's important that several OTP
+ modules are included in the plt. The suites takes care of
+ that too.</p>
+ <p>
+ Own Id: OTP-9116</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Dialyzer 2.4.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/edoc/doc/src/notes.xml b/lib/edoc/doc/src/notes.xml
index afcccf22b5..c18a126264 100644
--- a/lib/edoc/doc/src/notes.xml
+++ b/lib/edoc/doc/src/notes.xml
@@ -31,6 +31,61 @@
<p>This document describes the changes made to the EDoc
application.</p>
+<section><title>Edoc 0.7.7</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Add encoding when parsing Wiki text. EDoc used to
+ fail on strings such as "���". (Thanks to Richard
+ Carlsson.) </p>
+ <p>
+ Own Id: OTP-9109</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> It is now possible to use Erlang specifications and
+ types in EDoc documentation. Erlang specifications and
+ types will be used unless there is also a function
+ specification (<c>@spec</c>) or a type alias
+ (<c>@type</c>) with the same name. In the current
+ implementation the placement of <c>-spec</c> matters: it
+ should be placed where the <c>@spec</c> would otherwise
+ have been placed. </p>
+ <p>Not all Erlang types are included in the
+ documentation, but only those exported by some
+ <c>export_type</c> declaration or used by some documented
+ Erlang specification (<c>-spec</c>). </p>
+ <p> There is currently no support for overloaded Erlang
+ specifications. </p>
+ <p> The syntax definitions of EDoc have been augmented to
+ cope with most of the Erlang types. (But we recommend
+ that Erlang types should be used instead.) </p>
+ <p> <c>edoc:read_source()</c> takes one new option,
+ <c>report_missing_types</c>. <c>edoc_layout:module()</c>
+ takes one new option, <c>pretty_printer</c>. </p>
+ <p>
+ Own Id: OTP-8525</p>
+ </item>
+ <item>
+ <p> The <c>edoc_lib</c> module is meant to be private,
+ but since it is referred to from other man pages it has
+ been included in the OTP documentation. The modifications
+ introduced in this ticket make all functions private
+ except those referred to from other pages. </p>
+ <p>
+ Own Id: OTP-9110</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Edoc 0.7.6.8</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/edoc/vsn.mk b/lib/edoc/vsn.mk
index e030174862..febac9cc42 100644
--- a/lib/edoc/vsn.mk
+++ b/lib/edoc/vsn.mk
@@ -1 +1 @@
-EDOC_VSN = 0.7.6.8
+EDOC_VSN = 0.7.7
diff --git a/lib/erl_interface/doc/src/notes.xml b/lib/erl_interface/doc/src/notes.xml
index de5ba61938..784ba78d3e 100644
--- a/lib/erl_interface/doc/src/notes.xml
+++ b/lib/erl_interface/doc/src/notes.xml
@@ -30,6 +30,49 @@
</header>
<p>This document describes the changes made to the Erl_interface application.</p>
+<section><title>Erl_Interface 3.7.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Some malformed distribution messages could cause VM to
+ crash, this is now corrected.</p>
+ <p>
+ Own Id: OTP-8993</p>
+ </item>
+ <item>
+ <p>
+ Strengthen string copy check (Thanks to Michael Santos).</p>
+ <p>
+ Own Id: OTP-9071</p>
+ </item>
+ <item>
+ <p>
+ Strengthen atom length check when decoding atoms (Thanks
+ to Michael Santos).</p>
+ <p>
+ Own Id: OTP-9072</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Fix global registration. C node needed
+ DFLAG_DIST_MONITOR_FLAT set when connecting. Fix list
+ compare in erl_compare_ext to return correct result.
+ (Thanks to Vitaliy Batichko and Evgeny Khirin)</p>
+ <p>
+ Own Id: OTP-9015</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erl_Interface 3.7.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/erl_interface/vsn.mk b/lib/erl_interface/vsn.mk
index ffda886553..0317462106 100644
--- a/lib/erl_interface/vsn.mk
+++ b/lib/erl_interface/vsn.mk
@@ -1 +1 @@
-EI_VSN = 3.7.2
+EI_VSN = 3.7.3
diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml
index 8c9dbc0c18..434bfac64c 100644
--- a/lib/hipe/doc/src/notes.xml
+++ b/lib/hipe/doc/src/notes.xml
@@ -30,6 +30,100 @@
</header>
<p>This document describes the changes made to HiPE.</p>
+<section><title>Hipe 3.7.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fix erroneous fail info of a hipe_bs_primop</p>
+ <p>
+ Own Id: OTP-9036</p>
+ </item>
+ <item>
+ <p>
+ The change fixes a bug in the translation of 'bs_add'
+ BEAM instruction to HiPE's Icode representation. When
+ these instructions appeared in a guard context the
+ previous translation was obviously buggy.</p>
+ <p>
+ Own Id: OTP-9044</p>
+ </item>
+ <item>
+ <p>
+ Sanitize the specs of the code module</p>
+ <p>
+ After the addition of unicode_binary() to the
+ file:filename() type, dialyzer started complaining about
+ erroneous or incomplete specs in some functions of the
+ 'code' module. The culprit was hard-coded information in
+ erl_bif_types for functions of this module, which were
+ not updated. Since these functions have proper specs
+ these days and code duplication (pun intended) is never a
+ good idea, their type information was removed from
+ erl_bif_types.</p>
+ <p>
+ While doing this, some erroneous comments were fixed in
+ the code module and also made sure that the code now runs
+ without dialyzer warnings even when the
+ -Wunmatched_returns option is used.</p>
+ <p>
+ Some cleanups were applied to erl_bif_types too.</p>
+ <p>
+ Own Id: OTP-9100</p>
+ </item>
+ <item>
+ <p>
+ Fix bug in the simplification of inexact comparisons</p>
+ <p>
+ On 31/1/2011 Paul Guyot reported a bug in the native code
+ compilation of inexact equality/inequality tests between
+ floats and integers. The relevant test was:</p>
+ <p>
+ f(X) -&gt; Y = X / 2, Y == 0.</p>
+ <p>
+ and hipe erroneously evaluated the calls f(0) and f(0.0)
+ to 'false'.</p>
+ <p>
+ The culprit was in the simplification code of the Icode
+ range analysis which used an erroneous test (lists:any/1
+ instead of lists:all/1).</p>
+ <p>
+ Own Id: OTP-9101</p>
+ </item>
+ <item>
+ <p>
+ Document exiting and garbage_collecting process statuses</p>
+ <p>
+ Own Id: OTP-9102</p>
+ </item>
+ <item>
+ <p>
+ Remove hipe constants pool</p>
+ <p>
+ Hipe constants used to be allocated within a single,
+ fixed-size pool for interaction with the garbage
+ collector. However, the garbage collector no longer
+ depends on constants being allocated within a single
+ pool, and the fixed size of the pool both meant
+ unnecessary allocations on most deployments and crashes
+ on deployments requiring more constants.</p>
+ <p>
+ The code was simplified to directly invoke erts_alloc.
+ Debugging and undocumented function
+ hipe_bifs:show_literals/0 was removed (it returned true
+ and output text to the console), and debugging and
+ undocumented function hipe_bifs:constants_size/0 was
+ rewritten with a global to count the size of allocated
+ constants.</p>
+ <p>
+ Own Id: OTP-9128</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Hipe 3.7.8.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk
index 513b1f4943..6ba9009a24 100644
--- a/lib/hipe/vsn.mk
+++ b/lib/hipe/vsn.mk
@@ -1 +1 @@
-HIPE_VSN = 3.7.8.1
+HIPE_VSN = 3.7.9
diff --git a/lib/jinterface/doc/src/notes.xml b/lib/jinterface/doc/src/notes.xml
index 879634561b..962be63968 100644
--- a/lib/jinterface/doc/src/notes.xml
+++ b/lib/jinterface/doc/src/notes.xml
@@ -30,6 +30,22 @@
</header>
<p>This document describes the changes made to the Jinterface application.</p>
+<section><title>Jinterface 1.5.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Some malformed distribution messages could cause VM to
+ crash, this is now corrected.</p>
+ <p>
+ Own Id: OTP-8993</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Jinterface 1.5.3.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/jinterface/vsn.mk b/lib/jinterface/vsn.mk
index 24ffe7c5e6..9d75a653e3 100644
--- a/lib/jinterface/vsn.mk
+++ b/lib/jinterface/vsn.mk
@@ -1 +1 @@
-JINTERFACE_VSN = 1.5.3.2
+JINTERFACE_VSN = 1.5.4
diff --git a/lib/kernel/doc/src/notes.xml b/lib/kernel/doc/src/notes.xml
index 29580a4cd1..065b24c53d 100644
--- a/lib/kernel/doc/src/notes.xml
+++ b/lib/kernel/doc/src/notes.xml
@@ -30,6 +30,65 @@
</header>
<p>This document describes the changes made to the Kernel application.</p>
+<section><title>Kernel 2.14.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ <c>os:find_executable/{1,2}</c> will no longer return the
+ path of a directory that happens to be in the PATH.</p>
+ <p>
+ Own Id: OTP-8983 Aux Id: seq11749 </p>
+ </item>
+ <item>
+ <p>
+ Fix -spec for file:write_file/3</p>
+ <p>
+ Change type for second parameter from binary() to
+ iodata(), since the function explicitly takes steps to
+ accept lists as well as binaries. (thanks to Magnus
+ Henoch).</p>
+ <p>
+ Own Id: OTP-9067</p>
+ </item>
+ <item>
+ <p>
+ Sanitize the specs of the code module</p>
+ <p>
+ After the addition of unicode_binary() to the
+ file:filename() type, dialyzer started complaining about
+ erroneous or incomplete specs in some functions of the
+ 'code' module. The culprit was hard-coded information in
+ erl_bif_types for functions of this module, which were
+ not updated. Since these functions have proper specs
+ these days and code duplication (pun intended) is never a
+ good idea, their type information was removed from
+ erl_bif_types.</p>
+ <p>
+ While doing this, some erroneous comments were fixed in
+ the code module and also made sure that the code now runs
+ without dialyzer warnings even when the
+ -Wunmatched_returns option is used.</p>
+ <p>
+ Some cleanups were applied to erl_bif_types too.</p>
+ <p>
+ Own Id: OTP-9100</p>
+ </item>
+ <item>
+ <p>
+ - Add spec for function that does not return - Strenghen
+ spec - Introduce types to avoid duplication in specs -
+ Add specs for functions that do not return - Add specs
+ for behaviour callbacks - Simplify two specs</p>
+ <p>
+ Own Id: OTP-9127</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Kernel 2.14.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/kernel/vsn.mk b/lib/kernel/vsn.mk
index e33b90a274..e7b71cc168 100644
--- a/lib/kernel/vsn.mk
+++ b/lib/kernel/vsn.mk
@@ -1 +1 @@
-KERNEL_VSN = 2.14.3
+KERNEL_VSN = 2.14.4
diff --git a/lib/mnesia/doc/src/notes.xml b/lib/mnesia/doc/src/notes.xml
index 5a6de05c8b..ccf70b8373 100644
--- a/lib/mnesia/doc/src/notes.xml
+++ b/lib/mnesia/doc/src/notes.xml
@@ -38,7 +38,43 @@
thus constitutes one section in this document. The title of each
section is the version number of Mnesia.</p>
- <section><title>Mnesia 4.4.16</title>
+ <section><title>Mnesia 4.4.17</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Calling mnesia:first/1 on empty fragmented table works.
+ Thanks Magnus Henoch.</p>
+ <p>
+ Own Id: OTP-9108</p>
+ </item>
+ <item>
+ <p>
+ If Mnesia detects that the network is not fully connected
+ during start, Mnesia will not start until all nodes are
+ reachable.</p>
+ <p>
+ Own Id: OTP-9115 Aux Id: seq-11728 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Fix issues reported by dialyzer.</p>
+ <p>
+ Own Id: OTP-9107</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Mnesia 4.4.16</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/observer/doc/src/notes.xml b/lib/observer/doc/src/notes.xml
index 76c13fb3ff..b3b9937f1c 100644
--- a/lib/observer/doc/src/notes.xml
+++ b/lib/observer/doc/src/notes.xml
@@ -31,6 +31,46 @@
<p>This document describes the changes made to the Observer
application.</p>
+<section><title>Observer 0.9.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ The time needed for loading a crashump into the crashdump
+ viewer would earlier grow exponentially with the size of
+ the crashdump file. Reading a file of 20M would take a
+ couple of minutes, and for a dump of 250M it would take
+ between 1 and 2 hours. This has been solved.</p>
+ <p>
+ Earlier, all processes, timers, funs or ets-tables would
+ be loaded into the memory of the crashdump viewer node
+ before sending it on to the web server. This has been
+ changed and the pages are now sent to the web server in
+ chunks.</p>
+ <p>
+ A security function in newer web browsers prevents a full
+ file path to be sent from an HTML file input field, i.e.
+ the field needed to implement the "Browse" button when
+ loading a file into the crashdump viewer. To overcome
+ this, the file input field is no longer used. Instead a
+ normal text input field is used, and the user needs to
+ manually insert the complete file path. For convenience,
+ a shell script and a batch file are added to the observer
+ application. These can be used to start the
+ crashdump_viewer and a browser and load a file - with the
+ file name given from the command line. The shell script
+ and batch file are called cdv and cdv.bat respectively,
+ and can be found in the priv dir of the observer
+ application.</p>
+ <p>
+ Own Id: OTP-9051 Aux Id: seq11789 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Observer 0.9.8.4</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/observer/vsn.mk b/lib/observer/vsn.mk
index 1b72d30eab..14c8f54ba3 100644
--- a/lib/observer/vsn.mk
+++ b/lib/observer/vsn.mk
@@ -1 +1 @@
-OBSERVER_VSN = 0.9.8.4
+OBSERVER_VSN = 0.9.9
diff --git a/lib/odbc/doc/src/notes.xml b/lib/odbc/doc/src/notes.xml
index 7dece7c584..b88c7cf1cd 100644
--- a/lib/odbc/doc/src/notes.xml
+++ b/lib/odbc/doc/src/notes.xml
@@ -31,7 +31,22 @@
<p>This document describes the changes made to the odbc application.
</p>
- <section><title>ODBC 2.10.9</title>
+ <section><title>ODBC 2.10.10</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Better error messages for connection issues.</p>
+ <p>
+ Own Id: OTP-9111</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>ODBC 2.10.9</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/percept/doc/src/notes.xml b/lib/percept/doc/src/notes.xml
index af6ed7b048..33bfa7baab 100644
--- a/lib/percept/doc/src/notes.xml
+++ b/lib/percept/doc/src/notes.xml
@@ -32,6 +32,21 @@
</header>
<p>This document describes the changes made to the Percept application.</p>
+<section><title>Percept 0.8.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> Fixes a race condition found in percept_db start/1
+ function. (Thanks to Ahmed Omar) </p>
+ <p>
+ Own Id: OTP-9012</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Percept 0.8.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/percept/vsn.mk b/lib/percept/vsn.mk
index 443d25c78f..2a302991aa 100644
--- a/lib/percept/vsn.mk
+++ b/lib/percept/vsn.mk
@@ -1 +1 @@
-PERCEPT_VSN = 0.8.4
+PERCEPT_VSN = 0.8.5
diff --git a/lib/public_key/doc/src/notes.xml b/lib/public_key/doc/src/notes.xml
index befbd3e586..14b43041ce 100644
--- a/lib/public_key/doc/src/notes.xml
+++ b/lib/public_key/doc/src/notes.xml
@@ -34,6 +34,25 @@
<file>notes.xml</file>
</header>
+<section><title>Public_Key 0.11</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Allows the public_key module to decode and encode RSA and
+ DSA keys encoded using the SubjectPublicKeyInfo format.
+ When pem_entry_encode is called on an RSA or DSA public
+ key type, the key is wrapped in the SubjectPublicKeyInfo
+ format.</p>
+ <p>
+ Own Id: OTP-9061</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Public_Key 0.10</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 81aedaea56..c5f57214b1 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -56,44 +56,43 @@
<p><em>Data Types </em></p>
- <p><c>boolean() = true | false</c></p>
+ <p><code>boolean() = true | false</code></p>
- <p><c>string = [bytes()]</c></p>
+ <p><code>string = [bytes()]</code></p>
- <p><c>der_encoded() = binary() </c></p>
-
- <p><c>decrypt_der() = binary() </c></p>
+ <p><code>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey'
+ 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo'</code></p>
- <p><c>pki_asn1_type() = 'Certificate' | 'RSAPrivateKey'| 'RSAPublicKey'
- 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter' | 'SubjectPublicKeyInfo'</c></p>
-
- <p><c>pem_entry () = {pki_asn1_type(), der_encoded() | decrypt_der(), not_encrypted |
- {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}}.</c></p>
-
- <p><c>rsa_public_key() = #'RSAPublicKey'{}</c></p>
+ <p><code>pem_entry () = {pki_asn1_type(), binary() %% DER or encrypted DER
+ not_encrypted | {"DES-CBC" | "DES-EDE3-CBC", crypto:rand_bytes(8)}}.</code></p>
- <p><c>rsa_private_key() = #'RSAPrivateKey'{} </c></p>
+ <p><code>rsa_public_key() = #'RSAPublicKey'{}</code></p>
+
+ <p><code>rsa_private_key() = #'RSAPrivateKey'{} </code></p>
- <p><c>dsa_public_key() = {integer(), #'Dss-Parms'{}} </c></p>
+ <p><code>dsa_public_key() = {integer(), #'Dss-Parms'{}} </code></p>
- <p><c>rsa_private_key() = #'RSAPrivateKey'{} </c></p>
+ <p><code>rsa_private_key() = #'RSAPrivateKey'{} </code></p>
- <p><c>dsa_private_key() = #'DSAPrivateKey'{}</c></p>
+ <p><code>dsa_private_key() = #'DSAPrivateKey'{}</code></p>
- <p><c> public_crypt_options() = [{rsa_pad, rsa_padding()}]. </c></p>
+ <p><code> public_crypt_options() = [{rsa_pad, rsa_padding()}]. </code></p>
- <p><c> rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding'
- | 'rsa_no_padding'</c></p>
+ <p><code> rsa_padding() = 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding'
+ | 'rsa_no_padding'</code></p>
- <p><c> rsa_digest_type() = 'md5' | 'sha' </c></p>
-
- <p><c> dss_digest_type() = 'none' | 'sha' </c></p>
+ <p><code> rsa_digest_type() = 'md5' | 'sha' </code></p>
+
+ <p><code> dss_digest_type() = 'none' | 'sha' </code></p>
+
+ <p><code> ssh_file() = openssh_public_key | rfc4716_public_key |
+ known_hosts | auth_keys </code></p>
-<!-- <p><c>policy_tree() = [Root, Children]</c></p> -->
+<!-- <p><code>policy_tree() = [Root, Children]</code></p> -->
-<!-- <p><c>Root = #policy_tree_node{}</c></p> -->
+<!-- <p><code>Root = #policy_tree_node{}</code></p> -->
-<!-- <p><c>Children = [] | policy_tree()</c></p> -->
+<!-- <p><code>Children = [] | policy_tree()</code></p> -->
<!-- <p> The policy_tree_node record has the following fields:</p> -->
@@ -403,6 +402,55 @@
</func>
<func>
+ <name>ssh_decode(SshBin, Type) -> [{public_key(), Attributes::list()}]</name>
+ <fsummary>Decodes a ssh file-binary. </fsummary>
+ <type>
+ <v>SshBin = binary()</v>
+ <d>Example {ok, SshBin} = file:read_file("known_hosts").</d>
+ <v> Type = public_key | ssh_file()</v>
+ <d>If <c>Type</c> is <c>public_key</c> the binary may be either
+ a rfc4716 public key or a openssh public key.</d>
+ </type>
+ <desc>
+ <p> Decodes a ssh file-binary. In the case of know_hosts or
+ auth_keys the binary may include one or more lines of the
+ file. Returns a list of public keys and their attributes, possible
+ attribute values depends on the file type represented by the
+ binary.
+ </p>
+
+ <taglist>
+ <tag>rfc4716 attributes - see RFC 4716</tag>
+ <item>{headers, [{string(), utf8_string()}]}</item>
+ <tag>auth_key attributes - see man sshd </tag>
+ <item>{comment, string()}</item>
+ <item>{options, [string()]}</item>
+ <item>{bits, integer()} - In ssh version 1 files</item>
+ <tag>known_host attributes - see man sshd</tag>
+ <item>{hostnames, [string()]}</item>
+ <item>{comment, string()}</item>
+ <item>{bits, integer()} - In ssh version 1 files</item>
+ </taglist>
+
+ </desc>
+ </func>
+
+ <func>
+ <name>ssh_encode([{Key, Attributes}], Type) -> binary()</name>
+ <fsummary> Encodes a list of ssh file entries to a binary.</fsummary>
+ <type>
+ <v>Key = public_key()</v>
+ <v>Attributes = list()</v>
+ <v>Type = ssh_file()</v>
+ </type>
+ <desc>
+ <p>Encodes a list of ssh file entries (public keys and attributes) to a binary. Possible
+ attributes depends on the file type, see <seealso
+ marker="ssh_decode"> ssh_decode/2 </seealso></p>
+ </desc>
+ </func>
+
+ <func>
<name>verify(Msg, DigestType, Signature, Key) -> boolean()</name>
<fsummary>Verifies a digital signature.</fsummary>
<type>
diff --git a/lib/public_key/include/public_key.hrl b/lib/public_key/include/public_key.hrl
index 3498a2a433..5f97d80f7e 100644
--- a/lib/public_key/include/public_key.hrl
+++ b/lib/public_key/include/public_key.hrl
@@ -70,14 +70,18 @@
interim_reasons_mask
}).
-
--type der_encoded() :: binary().
--type decrypt_der() :: binary().
+-type public_key() :: rsa_public_key() | dsa_public_key().
+-type rsa_public_key() :: #'RSAPublicKey'{}.
+-type rsa_private_key() :: #'RSAPrivateKey'{}.
+-type dsa_private_key() :: #'DSAPrivateKey'{}.
+-type dsa_public_key() :: {integer(), #'Dss-Parms'{}}.
-type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' | 'RSAPublicKey'
| 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter'
| 'SubjectPublicKeyInfo'.
--type pem_entry() :: {pki_asn1_type(), der_encoded() | decrypt_der(),
+-type pem_entry() :: {pki_asn1_type(), binary(), %% DER or Encrypted DER
not_encrypted | {Cipher :: string(), Salt :: binary()}}.
-type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl
+-type ssh_file() :: openssh_public_key | rfc4716_public_key | known_hosts |
+ auth_keys.
-endif. % -ifdef(public_key).
diff --git a/lib/public_key/src/Makefile b/lib/public_key/src/Makefile
index b042b0c30a..5a24b02d2a 100644
--- a/lib/public_key/src/Makefile
+++ b/lib/public_key/src/Makefile
@@ -41,6 +41,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/public_key-$(VSN)
MODULES = \
public_key \
pubkey_pem \
+ pubkey_ssh \
pubkey_cert \
pubkey_cert_records
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index fadb993ed9..5ab9642279 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2008-2011. 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
@@ -38,7 +38,7 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec verify_data(der_encoded()) -> {md5 | sha, binary(), binary()}.
+-spec verify_data(DER::binary()) -> {md5 | sha, binary(), binary()}.
%%
%% Description: Extracts data from DerCert needed to call public_key:verify/4.
%%--------------------------------------------------------------------
@@ -146,7 +146,7 @@ validate_issuer(OtpCert, Issuer, UserState, VerifyFun) ->
verify_fun(OtpCert, {bad_cert, invalid_issuer}, UserState, VerifyFun)
end.
%%--------------------------------------------------------------------
--spec validate_signature(#'OTPCertificate'{}, der_encoded(),
+-spec validate_signature(#'OTPCertificate'{}, DER::binary(),
term(),term(), term(), fun()) -> term().
%%
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index 2441cfc0e0..b86d7a1f0c 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -30,7 +30,7 @@
%%====================================================================
%%--------------------------------------------------------------------
--spec decode_cert(der_encoded()) -> {ok, #'OTPCertificate'{}}.
+-spec decode_cert(DerCert::binary()) -> {ok, #'OTPCertificate'{}}.
%%
%% Description: Recursively decodes a Certificate.
%%--------------------------------------------------------------------
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index c8c69bcdd0..c26815bc04 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.erl
@@ -69,8 +69,9 @@ encode(PemEntries) ->
encode_pem_entries(PemEntries).
%%--------------------------------------------------------------------
--spec decipher({pki_asn1_type(), decrypt_der(),{Cipher :: string(), Salt :: binary()}}, string()) ->
- der_encoded().
+-spec decipher({pki_asn1_type(), DerEncrypted::binary(),{Cipher :: string(),
+ Salt :: binary()}},
+ string()) -> Der::binary().
%%
%% Description: Deciphers a decrypted pem entry.
%%--------------------------------------------------------------------
@@ -78,7 +79,8 @@ decipher({_, DecryptDer, {Cipher,Salt}}, Password) ->
decode_key(DecryptDer, Password, Cipher, Salt).
%%--------------------------------------------------------------------
--spec cipher(der_encoded(),{Cipher :: string(), Salt :: binary()} , string()) -> binary().
+-spec cipher(Der::binary(),{Cipher :: string(), Salt :: binary()} ,
+ string()) -> binary().
%%
%% Description: Ciphers a PEM entry
%%--------------------------------------------------------------------
@@ -91,11 +93,11 @@ cipher(Der, {Cipher,Salt}, Password)->
encode_pem_entries(Entries) ->
[encode_pem_entry(Entry) || Entry <- Entries].
-encode_pem_entry({Asn1Type, Der, not_encrypted}) ->
- StartStr = pem_start(Asn1Type),
+encode_pem_entry({Type, Der, not_encrypted}) ->
+ StartStr = pem_start(Type),
[StartStr, "\n", b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"];
-encode_pem_entry({Asn1Type, Der, {Cipher, Salt}}) ->
- StartStr = pem_start(Asn1Type),
+encode_pem_entry({Type, Der, {Cipher, Salt}}) ->
+ StartStr = pem_start(Type),
[StartStr,"\n", pem_decrypt(),"\n", pem_decrypt_info(Cipher, Salt),"\n",
b64encode_and_split(Der), "\n", pem_end(StartStr) ,"\n\n"].
@@ -115,17 +117,17 @@ decode_pem_entries([Start| Lines], Entries) ->
end.
decode_pem_entry(Start, [<<"Proc-Type: 4,ENCRYPTED", _/binary>>, Line | Lines]) ->
- Asn1Type = asn1_type(Start),
+ Type = asn1_type(Start),
Cs = erlang:iolist_to_binary(Lines),
Decoded = base64:mime_decode(Cs),
[_, DekInfo0] = string:tokens(binary_to_list(Line), ": "),
[Cipher, Salt] = string:tokens(DekInfo0, ","),
- {Asn1Type, Decoded, {Cipher, unhex(Salt)}};
+ {Type, Decoded, {Cipher, unhex(Salt)}};
decode_pem_entry(Start, Lines) ->
- Asn1Type = asn1_type(Start),
+ Type = asn1_type(Start),
Cs = erlang:iolist_to_binary(Lines),
- Der = base64:mime_decode(Cs),
- {Asn1Type, Der, not_encrypted}.
+ Decoded = base64:mime_decode(Cs),
+ {Type, Decoded, not_encrypted}.
split_bin(Bin) ->
split_bin(0, Bin).
@@ -153,17 +155,7 @@ split_lines(Bin) ->
[Bin].
%% Ignore white space at end of line
-join_entry([<<"-----END CERTIFICATE-----", _/binary>>| Lines], Entry) ->
- {lists:reverse(Entry), Lines};
-join_entry([<<"-----END RSA PRIVATE KEY-----", _/binary>>| Lines], Entry) ->
- {lists:reverse(Entry), Lines};
-join_entry([<<"-----END PUBLIC KEY-----", _/binary>>| Lines], Entry) ->
- {lists:reverse(Entry), Lines};
-join_entry([<<"-----END RSA PUBLIC KEY-----", _/binary>>| Lines], Entry) ->
- {lists:reverse(Entry), Lines};
-join_entry([<<"-----END DSA PRIVATE KEY-----", _/binary>>| Lines], Entry) ->
- {lists:reverse(Entry), Lines};
-join_entry([<<"-----END DH PARAMETERS-----", _/binary>>| Lines], Entry) ->
+join_entry([<<"-----END ", _/binary>>| Lines], Entry) ->
{lists:reverse(Entry), Lines};
join_entry([Line | Lines], Entry) ->
join_entry(Lines, [Line | Entry]).
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
new file mode 100644
index 0000000000..f342eab159
--- /dev/null
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -0,0 +1,431 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2011-2011. 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(pubkey_ssh).
+
+-include("public_key.hrl").
+
+-export([decode/2, encode/2]).
+
+-define(UINT32(X), X:32/unsigned-big-integer).
+%% Max encoded line length is 72, but conformance examples use 68
+%% Comment from rfc 4716: "The following are some examples of public
+%% key files that are compliant (note that the examples all wrap
+%% before 72 bytes to meet IETF document requirements; however, they
+%% are still compliant.)" So we choose to use 68 also.
+-define(ENCODED_LINE_LENGTH, 68).
+
+%%====================================================================
+%% Internal application API
+%%====================================================================
+
+%%--------------------------------------------------------------------
+-spec decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}].
+%%
+%% Description: Decodes a ssh file-binary.
+%%--------------------------------------------------------------------
+decode(Bin, public_key)->
+ case binary:match(Bin, begin_marker()) of
+ nomatch ->
+ openssh_decode(Bin, openssh_public_key);
+ _ ->
+ rfc4716_decode(Bin)
+ end;
+decode(Bin, rfc4716_public_key) ->
+ rfc4716_decode(Bin);
+decode(Bin, Type) ->
+ openssh_decode(Bin, Type).
+
+%%--------------------------------------------------------------------
+-spec encode([{public_key(), Attributes::list()}], ssh_file()) ->
+ binary().
+%%
+%% Description: Encodes a list of ssh file entries.
+%%--------------------------------------------------------------------
+encode(Entries, Type) ->
+ erlang:iolist_to_binary(lists:map(fun({Key, Attributes}) ->
+ do_encode(Type, Key, Attributes)
+ end, Entries)).
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+begin_marker() ->
+ <<"---- BEGIN SSH2 PUBLIC KEY ----">>.
+end_marker() ->
+ <<"---- END SSH2 PUBLIC KEY ----">>.
+
+rfc4716_decode(Bin) ->
+ Lines = binary:split(Bin, <<"\n">>, [global]),
+ do_rfc4716_decode(Lines, []).
+
+do_rfc4716_decode([<<"---- BEGIN SSH2 PUBLIC KEY ----", _/binary>> | Lines], Acc) ->
+ do_rfc4716_decode(Lines, Acc);
+%% Ignore empty lines before or after begin/end - markers.
+do_rfc4716_decode([<<>> | Lines], Acc) ->
+ do_rfc4716_decode(Lines, Acc);
+do_rfc4716_decode([], Acc) ->
+ lists:reverse(Acc);
+do_rfc4716_decode(Lines, Acc) ->
+ {Headers, PubKey, Rest} = rfc4716_decode_lines(Lines, []),
+ case Headers of
+ [_|_] ->
+ do_rfc4716_decode(Rest, [{PubKey, [{headers, Headers}]} | Acc]);
+ _ ->
+ do_rfc4716_decode(Rest, [{PubKey, []} | Acc])
+ end.
+
+rfc4716_decode_lines([Line | Lines], Acc) ->
+ case binary:last(Line) of
+ $\\ ->
+ NewLine = binary:replace(Line,<<"\\">>, hd(Lines), []),
+ rfc4716_decode_lines([NewLine | tl(Lines)], Acc);
+ _ ->
+ rfc4716_decode_line(Line, Lines, Acc)
+ end.
+
+rfc4716_decode_line(Line, Lines, Acc) ->
+ case binary:split(Line, <<":">>) of
+ [Tag, Value] ->
+ rfc4716_decode_lines(Lines, [{string_decode(Tag), unicode_decode(Value)} | Acc]);
+ _ ->
+ {Body, Rest} = join_entry([Line | Lines], []),
+ {lists:reverse(Acc), rfc4716_pubkey_decode(base64:mime_decode(Body)), Rest}
+ end.
+
+join_entry([<<"---- END SSH2 PUBLIC KEY ----", _/binary>>| Lines], Entry) ->
+ {lists:reverse(Entry), Lines};
+join_entry([Line | Lines], Entry) ->
+ join_entry(Lines, [Line | Entry]).
+
+
+rfc4716_pubkey_decode(<<?UINT32(Len), Type:Len/binary,
+ ?UINT32(SizeE), E:SizeE/binary,
+ ?UINT32(SizeN), N:SizeN/binary>>) when Type == <<"ssh-rsa">> ->
+ #'RSAPublicKey'{modulus = erlint(SizeN, N),
+ publicExponent = erlint(SizeE, E)};
+
+rfc4716_pubkey_decode(<<?UINT32(Len), Type:Len/binary,
+ ?UINT32(SizeP), P:SizeP/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary,
+ ?UINT32(SizeG), G:SizeG/binary,
+ ?UINT32(SizeY), Y:SizeY/binary>>) when Type == <<"ssh-dss">> ->
+ {erlint(SizeY, Y),
+ #'Dss-Parms'{p = erlint(SizeP, P),
+ q = erlint(SizeQ, Q),
+ g = erlint(SizeG, G)}}.
+
+openssh_decode(Bin, FileType) ->
+ Lines = binary:split(Bin, <<"\n">>, [global]),
+ do_openssh_decode(FileType, Lines, []).
+
+do_openssh_decode(_, [], Acc) ->
+ lists:reverse(Acc);
+%% Ignore empty lines
+do_openssh_decode(FileType, [<<>> | Lines], Acc) ->
+ do_openssh_decode(FileType, Lines, Acc);
+%% Ignore lines that start with #
+do_openssh_decode(FileType,[<<"#", _/binary>> | Lines], Acc) ->
+ do_openssh_decode(FileType, Lines, Acc);
+do_openssh_decode(auth_keys = FileType, [Line | Lines], Acc) ->
+ Split = binary:split(Line, <<" ">>, [global]),
+ case mend_split(Split, []) of
+ %% ssh2
+ [Options, KeyType, Base64Enc, Comment] when KeyType == <<"ssh-rsa">>;
+ KeyType == <<"ssh-dss">> ->
+ do_openssh_decode(FileType, Lines,
+ [{openssh_pubkey_decode(KeyType, Base64Enc),
+ [{comment, string_decode(Comment)},
+ {options, comma_list_decode(Options)}]}
+ | Acc]);
+
+ [KeyType, Base64Enc, Comment] when KeyType == <<"ssh-rsa">>;
+ KeyType == <<"ssh-dss">> ->
+ do_openssh_decode(FileType, Lines,
+ [{openssh_pubkey_decode(KeyType, Base64Enc),
+ [{comment, string_decode(Comment)}]} | Acc]);
+ %% ssh1
+ [Options, Bits, Exponent, Modulus, Comment] ->
+ do_openssh_decode(FileType, Lines,
+ [{ssh1_rsa_pubkey_decode(Modulus, Exponent),
+ [{comment, string_decode(Comment)},
+ {options, comma_list_decode(Options)},
+ {bits, integer_decode(Bits)}]} | Acc]);
+ [Bits, Exponent, Modulus, Comment] ->
+ do_openssh_decode(FileType, Lines,
+ [{ssh1_rsa_pubkey_decode(Modulus, Exponent),
+ [{comment, string_decode(Comment)},
+ {bits, integer_decode(Bits)}]} | Acc])
+ end;
+
+do_openssh_decode(known_hosts = FileType, [Line | Lines], Acc) ->
+ case binary:split(Line, <<" ">>, [global]) of
+ %% ssh 2
+ [HostNames, KeyType, Base64Enc] when KeyType == <<"ssh-rsa">>;
+ KeyType == <<"ssh-dss">> ->
+ do_openssh_decode(FileType, Lines,
+ [{openssh_pubkey_decode(KeyType, Base64Enc),
+ [{hostnames, comma_list_decode(HostNames)}]}| Acc]);
+ [HostNames, KeyType, Base64Enc, Comment] when KeyType == <<"ssh-rsa">>;
+ KeyType == <<"ssh-dss">> ->
+ do_openssh_decode(FileType, Lines,
+ [{openssh_pubkey_decode(KeyType, Base64Enc),
+ [{comment, string_decode(Comment)},
+ {hostnames, comma_list_decode(HostNames)}]} | Acc]);
+ %% ssh 1
+ [HostNames, Bits, Exponent, Modulus, Comment] ->
+ do_openssh_decode(FileType, Lines,
+ [{ssh1_rsa_pubkey_decode(Modulus, Exponent),
+ [{comment, string_decode(Comment)},
+ {hostnames, comma_list_decode(HostNames)},
+ {bits, integer_decode(Bits)}]} | Acc]);
+ [HostNames, Bits, Exponent, Modulus] ->
+ do_openssh_decode(FileType, Lines,
+ [{ssh1_rsa_pubkey_decode(Modulus, Exponent),
+ [{comment, []},
+ {hostnames, comma_list_decode(HostNames)},
+ {bits, integer_decode(Bits)}]} | Acc])
+ end;
+
+do_openssh_decode(openssh_public_key = FileType, [Line | Lines], Acc) ->
+ case binary:split(Line, <<" ">>, [global]) of
+ [KeyType, Base64Enc, Comment0] when KeyType == <<"ssh-rsa">>;
+ KeyType == <<"ssh-dss">> ->
+ Comment = string:strip(binary_to_list(Comment0), right, $\n),
+ do_openssh_decode(FileType, Lines,
+ [{openssh_pubkey_decode(KeyType, Base64Enc),
+ [{comment, Comment}]} | Acc])
+ end.
+
+
+openssh_pubkey_decode(<<"ssh-rsa">>, Base64Enc) ->
+ <<?UINT32(StrLen), _:StrLen/binary,
+ ?UINT32(SizeE), E:SizeE/binary,
+ ?UINT32(SizeN), N:SizeN/binary>>
+ = base64:mime_decode(Base64Enc),
+ #'RSAPublicKey'{modulus = erlint(SizeN, N),
+ publicExponent = erlint(SizeE, E)};
+
+openssh_pubkey_decode(<<"ssh-dss">>, Base64Enc) ->
+ <<?UINT32(StrLen), _:StrLen/binary,
+ ?UINT32(SizeP), P:SizeP/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary,
+ ?UINT32(SizeG), G:SizeG/binary,
+ ?UINT32(SizeY), Y:SizeY/binary>>
+ = base64:mime_decode(Base64Enc),
+ {erlint(SizeY, Y),
+ #'Dss-Parms'{p = erlint(SizeP, P),
+ q = erlint(SizeQ, Q),
+ g = erlint(SizeG, G)}}.
+
+erlint(MPIntSize, MPIntValue) ->
+ Bits= MPIntSize * 8,
+ <<Integer:Bits/integer>> = MPIntValue,
+ Integer.
+
+ssh1_rsa_pubkey_decode(MBin, EBin) ->
+ #'RSAPublicKey'{modulus = integer_decode(MBin),
+ publicExponent = integer_decode(EBin)}.
+
+integer_decode(BinStr) ->
+ list_to_integer(binary_to_list(BinStr)).
+
+string_decode(BinStr) ->
+ binary_to_list(BinStr).
+
+unicode_decode(BinStr) ->
+ unicode:characters_to_list(BinStr).
+
+comma_list_decode(BinOpts) ->
+ CommaList = binary:split(BinOpts, <<",">>, [global]),
+ lists:map(fun(Item) ->
+ binary_to_list(Item)
+ end, CommaList).
+
+do_encode(rfc4716_public_key, Key, Attributes) ->
+ rfc4716_encode(Key, proplists:get_value(headers, Attributes, []), []);
+
+do_encode(Type, Key, Attributes) ->
+ openssh_encode(Type, Key, Attributes).
+
+rfc4716_encode(Key, [],[]) ->
+ erlang:iolist_to_binary([begin_marker(),"\n",
+ split_lines(base64:encode(ssh2_pubkey_encode(Key))),
+ "\n", end_marker(), "\n"]);
+rfc4716_encode(Key, [], [_|_] = Acc) ->
+ erlang:iolist_to_binary([begin_marker(), "\n",
+ lists:reverse(Acc),
+ split_lines(base64:encode(ssh2_pubkey_encode(Key))),
+ "\n", end_marker(), "\n"]);
+rfc4716_encode(Key, [ Header | Headers], Acc) ->
+ LinesStr = rfc4716_encode_header(Header),
+ rfc4716_encode(Key, Headers, [LinesStr | Acc]).
+
+rfc4716_encode_header({Tag, Value}) ->
+ TagLen = length(Tag),
+ ValueLen = length(Value),
+ case TagLen + 1 + ValueLen of
+ N when N > ?ENCODED_LINE_LENGTH ->
+ NumOfChars = ?ENCODED_LINE_LENGTH - (TagLen + 1),
+ {First, Rest} = lists:split(NumOfChars, Value),
+ [Tag,":" , First, [$\\], "\n", rfc4716_encode_value(Rest) , "\n"];
+ _ ->
+ [Tag, ":", Value, "\n"]
+ end.
+
+rfc4716_encode_value(Value) ->
+ case length(Value) of
+ N when N > ?ENCODED_LINE_LENGTH ->
+ {First, Rest} = lists:split(?ENCODED_LINE_LENGTH, Value),
+ [First, [$\\], "\n", rfc4716_encode_value(Rest)];
+ _ ->
+ Value
+ end.
+
+openssh_encode(openssh_public_key, Key, Attributes) ->
+ Comment = proplists:get_value(comment, Attributes),
+ Enc = base64:encode(ssh2_pubkey_encode(Key)),
+ erlang:iolist_to_binary([key_type(Key), " ", Enc, " ", Comment, "\n"]);
+
+openssh_encode(auth_keys, Key, Attributes) ->
+ Comment = proplists:get_value(comment, Attributes, ""),
+ Options = proplists:get_value(options, Attributes, undefined),
+ Bits = proplists:get_value(bits, Attributes, undefined),
+ case Bits of
+ undefined ->
+ openssh_ssh2_auth_keys_encode(Options, Key, Comment);
+ _ ->
+ openssh_ssh1_auth_keys_encode(Options, Bits, Key, Comment)
+ end;
+openssh_encode(known_hosts, Key, Attributes) ->
+ Comment = proplists:get_value(comment, Attributes, ""),
+ Hostnames = proplists:get_value(hostnames, Attributes),
+ Bits = proplists:get_value(bits, Attributes, undefined),
+ case Bits of
+ undefined ->
+ openssh_ssh2_know_hosts_encode(Hostnames, Key, Comment);
+ _ ->
+ openssh_ssh1_known_hosts_encode(Hostnames, Bits, Key, Comment)
+ end.
+
+openssh_ssh2_auth_keys_encode(undefined, Key, Comment) ->
+ erlang:iolist_to_binary([key_type(Key)," ", base64:encode(ssh2_pubkey_encode(Key)), line_end(Comment)]);
+openssh_ssh2_auth_keys_encode(Options, Key, Comment) ->
+ erlang:iolist_to_binary([comma_list_encode(Options, []), " ",
+ key_type(Key)," ", base64:encode(ssh2_pubkey_encode(Key)), line_end(Comment)]).
+
+openssh_ssh1_auth_keys_encode(undefined, Bits,
+ #'RSAPublicKey'{modulus = N, publicExponent = E},
+ Comment) ->
+ erlang:iolist_to_binary([integer_to_list(Bits), " ", integer_to_list(E), " ", integer_to_list(N),
+ line_end(Comment)]);
+openssh_ssh1_auth_keys_encode(Options, Bits,
+ #'RSAPublicKey'{modulus = N, publicExponent = E},
+ Comment) ->
+ erlang:iolist_to_binary([comma_list_encode(Options, []), " ", integer_to_list(Bits),
+ " ", integer_to_list(E), " ", integer_to_list(N), line_end(Comment)]).
+
+openssh_ssh2_know_hosts_encode(Hostnames, Key, Comment) ->
+ erlang:iolist_to_binary([comma_list_encode(Hostnames, []), " ",
+ key_type(Key)," ", base64:encode(ssh2_pubkey_encode(Key)), line_end(Comment)]).
+
+openssh_ssh1_known_hosts_encode(Hostnames, Bits,
+ #'RSAPublicKey'{modulus = N, publicExponent = E},
+ Comment) ->
+ erlang:iolist_to_binary([comma_list_encode(Hostnames, [])," ", integer_to_list(Bits)," ",
+ integer_to_list(E)," ", integer_to_list(N), line_end(Comment)]).
+
+line_end("") ->
+ "\n";
+line_end(Comment) ->
+ [" ", Comment, "\n"].
+
+key_type(#'RSAPublicKey'{}) ->
+ <<"ssh-rsa">>;
+key_type({_, #'Dss-Parms'{}}) ->
+ <<"ssh-dss">>.
+
+comma_list_encode([Option], []) ->
+ Option;
+comma_list_encode([Option], Acc) ->
+ Acc ++ "," ++ Option;
+comma_list_encode([Option | Rest], []) ->
+ comma_list_encode(Rest, Option);
+comma_list_encode([Option | Rest], Acc) ->
+ comma_list_encode(Rest, Acc ++ "," ++ Option).
+
+ssh2_pubkey_encode(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
+ TypeStr = <<"ssh-rsa">>,
+ StrLen = size(TypeStr),
+ EBin = crypto:mpint(E),
+ NBin = crypto:mpint(N),
+ <<?UINT32(StrLen), TypeStr:StrLen/binary,
+ EBin/binary,
+ NBin/binary>>;
+ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
+ TypeStr = <<"ssh-dss">>,
+ StrLen = size(TypeStr),
+ PBin = crypto:mpint(P),
+ QBin = crypto:mpint(Q),
+ GBin = crypto:mpint(G),
+ YBin = crypto:mpint(Y),
+ <<?UINT32(StrLen), TypeStr:StrLen/binary,
+ PBin/binary,
+ QBin/binary,
+ GBin/binary,
+ YBin/binary>>.
+
+mend_split([Part1, Part2 | Rest] = List, Acc) ->
+ case option_end(Part1, Part2) of
+ true ->
+ lists:reverse(Acc) ++ List;
+ false ->
+ case length(binary:matches(Part1, <<"\"">>)) of
+ N when N rem 2 == 0 ->
+ mend_split(Rest, [Part1 | Acc]);
+ _ ->
+ mend_split([<<Part1/binary, Part2/binary>> | Rest], Acc)
+ end
+ end.
+
+option_end(Part1, Part2) ->
+ (is_key_field(Part1) orelse is_bits_field(Part1))
+ orelse
+ (is_key_field(Part2) orelse is_bits_field(Part2)).
+
+is_key_field(<<"ssh-dss">>) ->
+ true;
+is_key_field(<<"ssh-rsa">>) ->
+ true;
+is_key_field(_) ->
+ false.
+
+is_bits_field(Part) ->
+ try list_to_integer(binary_to_list(Part)) of
+ _ ->
+ true
+ catch _:_ ->
+ false
+ end.
+
+split_lines(<<Text:?ENCODED_LINE_LENGTH/binary>>) ->
+ [Text];
+split_lines(<<Text:?ENCODED_LINE_LENGTH/binary, Rest/binary>>) ->
+ [Text, $\n | split_lines(Rest)];
+split_lines(Bin) ->
+ [Bin].
diff --git a/lib/public_key/src/public_key.app.src b/lib/public_key/src/public_key.app.src
index 60487946fa..1963bd05d4 100644
--- a/lib/public_key/src/public_key.app.src
+++ b/lib/public_key/src/public_key.app.src
@@ -1,9 +1,9 @@
{application, public_key,
[{description, "Public key infrastructure"},
{vsn, "%VSN%"},
- {modules, [
- public_key,
- pubkey_pem,
+ {modules, [ public_key,
+ pubkey_pem,
+ pubkey_ssh,
pubkey_cert,
pubkey_cert_records,
'OTP-PUB-KEY'
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 7e022da7e5..2901020e83 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -41,7 +41,8 @@
pkix_is_issuer/2,
pkix_issuer_id/2,
pkix_normalize_name/1,
- pkix_path_validation/3
+ pkix_path_validation/3,
+ ssh_decode/2, ssh_encode/2
]).
%% Deprecated
@@ -51,10 +52,6 @@
-deprecated({decode_private_key, 1, next_major_release}).
-deprecated({decode_private_key, 2, next_major_release}).
--type rsa_public_key() :: #'RSAPublicKey'{}.
--type rsa_private_key() :: #'RSAPrivateKey'{}.
--type dsa_private_key() :: #'DSAPrivateKey'{}.
--type dsa_public_key() :: {integer(), #'Dss-Parms'{}}.
-type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding'
| 'rsa_no_padding'.
-type public_crypt_options() :: [{rsa_pad, rsa_padding()}].
@@ -67,7 +64,6 @@
%%====================================================================
%% API
%%====================================================================
-
%%--------------------------------------------------------------------
-spec pem_decode(binary()) -> [pem_entry()].
%%
@@ -152,7 +148,7 @@ pem_entry_encode(Asn1Type, Entity,
{Asn1Type, DecryptDer, CipherInfo}.
%%--------------------------------------------------------------------
--spec der_decode(asn1_type(), der_encoded()) -> term().
+-spec der_decode(asn1_type(), Der::binary()) -> term().
%%
%% Description: Decodes a public key asn1 der encoded entity.
%%--------------------------------------------------------------------
@@ -166,7 +162,7 @@ der_decode(Asn1Type, Der) when is_atom(Asn1Type), is_binary(Der) ->
end.
%%--------------------------------------------------------------------
--spec der_encode(asn1_type(), term()) -> der_encoded().
+-spec der_encode(asn1_type(), term()) -> Der::binary().
%%
%% Description: Encodes a public key entity with asn1 DER encoding.
%%--------------------------------------------------------------------
@@ -180,7 +176,7 @@ der_encode(Asn1Type, Entity) when is_atom(Asn1Type) ->
end.
%%--------------------------------------------------------------------
--spec pkix_decode_cert(der_encoded(), plain | otp) ->
+-spec pkix_decode_cert(Cert::binary(), plain | otp) ->
#'Certificate'{} | #'OTPCertificate'{}.
%%
%% Description: Decodes an asn1 der encoded pkix certificate. The otp
@@ -201,7 +197,7 @@ pkix_decode_cert(DerCert, otp) when is_binary(DerCert) ->
end.
%%--------------------------------------------------------------------
--spec pkix_encode(asn1_type(), term(), otp | plain) -> der_encoded().
+-spec pkix_encode(asn1_type(), term(), otp | plain) -> Der::binary().
%%
%% Description: Der encodes a certificate or part of a certificate.
%% This function must be used for encoding certificates or parts of certificates
@@ -361,7 +357,7 @@ verify(PlainText, sha, Signature, {Key, #'Dss-Parms'{p = P, q = Q, g = G}})
crypto:mpint(G), crypto:mpint(Key)]).
%%--------------------------------------------------------------------
-spec pkix_sign(#'OTPTBSCertificate'{},
- rsa_private_key() | dsa_private_key()) -> der_encoded().
+ rsa_private_key() | dsa_private_key()) -> Der::binary().
%%
%% Description: Sign a pkix x.509 certificate. Returns the corresponding
%% der encoded 'Certificate'{}
@@ -370,7 +366,7 @@ pkix_sign(#'OTPTBSCertificate'{signature =
#'SignatureAlgorithm'{algorithm = Alg}
= SigAlg} = TBSCert, Key) ->
- Msg = pkix_encode('OTPTBSCertificate', TBSCert, otp),
+ Msg = pkix_encode('OTPTBSCertificate', TBSCert, otp),
DigestType = pubkey_cert:digest_type(Alg),
Signature = sign(Msg, DigestType, Key),
Cert = #'OTPCertificate'{tbsCertificate= TBSCert,
@@ -380,7 +376,7 @@ pkix_sign(#'OTPTBSCertificate'{signature =
pkix_encode('OTPCertificate', Cert, otp).
%%--------------------------------------------------------------------
--spec pkix_verify(der_encoded(), rsa_public_key()|
+-spec pkix_verify(Cert::binary(), rsa_public_key()|
dsa_public_key()) -> boolean().
%%
%% Description: Verify pkix x.509 certificate signature.
@@ -396,9 +392,9 @@ pkix_verify(DerCert, #'RSAPublicKey'{} = RSAKey)
verify(PlainText, DigestType, Signature, RSAKey).
%%--------------------------------------------------------------------
--spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{},
- IssuerCert :: der_encoded()|
- #'OTPCertificate'{}) -> boolean().
+-spec pkix_is_issuer(Cert::binary()| #'OTPCertificate'{},
+ IssuerCert::binary()|
+ #'OTPCertificate'{}) -> boolean().
%%
%% Description: Checks if <IssuerCert> issued <Cert>.
%%--------------------------------------------------------------------
@@ -414,7 +410,7 @@ pkix_is_issuer(#'OTPCertificate'{tbsCertificate = TBSCert},
Candidate#'OTPTBSCertificate'.subject).
%%--------------------------------------------------------------------
--spec pkix_is_self_signed(der_encoded()| #'OTPCertificate'{}) -> boolean().
+-spec pkix_is_self_signed(Cert::binary()| #'OTPCertificate'{}) -> boolean().
%%
%% Description: Checks if a Certificate is self signed.
%%--------------------------------------------------------------------
@@ -425,7 +421,7 @@ pkix_is_self_signed(Cert) when is_binary(Cert) ->
pkix_is_self_signed(OtpCert).
%%--------------------------------------------------------------------
--spec pkix_is_fixed_dh_cert(der_encoded()| #'OTPCertificate'{}) -> boolean().
+-spec pkix_is_fixed_dh_cert(Cert::binary()| #'OTPCertificate'{}) -> boolean().
%%
%% Description: Checks if a Certificate is a fixed Diffie-Hellman Cert.
%%--------------------------------------------------------------------
@@ -436,14 +432,14 @@ pkix_is_fixed_dh_cert(Cert) when is_binary(Cert) ->
pkix_is_fixed_dh_cert(OtpCert).
%%--------------------------------------------------------------------
--spec pkix_issuer_id(der_encoded()| #'OTPCertificate'{},
- IssuedBy :: self | other) ->
- {ok, {SerialNr :: integer(),
- Issuer :: {rdnSequence,
- [#'AttributeTypeAndValue'{}]}}}
+-spec pkix_issuer_id(Cert::binary()| #'OTPCertificate'{},
+ IssuedBy :: self | other) ->
+ {ok, {SerialNr :: integer(),
+ Issuer :: {rdnSequence,
+ [#'AttributeTypeAndValue'{}]}}}
| {error, Reason :: term()}.
%
-%% Description: Returns the issuer id.
+%% Description: Returns the issuer id.
%%--------------------------------------------------------------------
pkix_issuer_id(#'OTPCertificate'{} = OtpCert, self) ->
pubkey_cert:issuer_id(OtpCert, self);
@@ -456,8 +452,8 @@ pkix_issuer_id(Cert, Signed) when is_binary(Cert) ->
pkix_issuer_id(OtpCert, Signed).
%%--------------------------------------------------------------------
--spec pkix_normalize_name({rdnSequence,
- [#'AttributeTypeAndValue'{}]}) ->
+-spec pkix_normalize_name({rdnSequence,
+ [#'AttributeTypeAndValue'{}]}) ->
{rdnSequence,
[#'AttributeTypeAndValue'{}]}.
%%
@@ -468,8 +464,8 @@ pkix_normalize_name(Issuer) ->
pubkey_cert:normalize_general_name(Issuer).
%%--------------------------------------------------------------------
--spec pkix_path_validation(der_encoded()| #'OTPCertificate'{} | atom(),
- CertChain :: [der_encoded()] ,
+-spec pkix_path_validation(Cert::binary()| #'OTPCertificate'{} | atom(),
+ CertChain :: [binary()] ,
Options :: list()) ->
{ok, {PublicKeyInfo :: term(),
PolicyTree :: term()}} |
@@ -496,7 +492,7 @@ pkix_path_validation(TrustedCert, CertChain, Options) when
is_binary(TrustedCert) -> OtpCert = pkix_decode_cert(TrustedCert,
otp), pkix_path_validation(OtpCert, CertChain, Options);
-pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
+pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
when is_list(CertChain), is_list(Options) ->
MaxPathDefault = length(CertChain),
ValidationState = pubkey_cert:init_validation_state(TrustedCert,
@@ -505,6 +501,37 @@ pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options)
path_validation(CertChain, ValidationState).
%%--------------------------------------------------------------------
+-spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}].
+%%
+%% Description: Decodes a ssh file-binary. In the case of know_hosts
+%% or auth_keys the binary may include one or more lines of the
+%% file. Returns a list of public keys and their attributes, possible
+%% attribute values depends on the file type represented by the
+%% binary.
+%%--------------------------------------------------------------------
+ssh_decode(SshBin, Type) when is_binary(SshBin),
+ Type == public_key;
+ Type == rfc4716_public_key;
+ Type == openssh_public_key;
+ Type == auth_keys;
+ Type == known_hosts ->
+ pubkey_ssh:decode(SshBin, Type).
+
+%%--------------------------------------------------------------------
+-spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) ->
+ binary().
+%% Description: Encodes a list of ssh file entries (public keys and
+%% attributes) to a binary. Possible attributes depends on the file
+%% type.
+%%--------------------------------------------------------------------
+ssh_encode(Entries, Type) when is_list(Entries),
+ Type == rfc4716_public_key;
+ Type == openssh_public_key;
+ Type == auth_keys;
+ Type == known_hosts ->
+ pubkey_ssh:encode(Entries, Type).
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -518,7 +545,6 @@ decrypt_public(CipherText, N,E, Options) ->
crypto:rsa_public_decrypt(CipherText,[crypto:mpint(E), crypto:mpint(N)],
Padding).
-
path_validation([], #path_validation_state{working_public_key_algorithm
= Algorithm,
working_public_key =
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 6c482f9c30..b11e4d092a 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -102,11 +102,23 @@ end_per_testcase(_TestCase, Config) ->
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [app, pk_decode_encode, encrypt_decrypt, sign_verify,
+ [app,
+ {group, pem_decode_encode},
+ {group, ssh_public_key_decode_encode},
+ encrypt_decrypt,
+ {group, sign_verify},
pkix, pkix_path_validation, deprecated].
groups() ->
- [].
+ [{pem_decode_encode, [], [dsa_pem, rsa_pem, encrypted_pem,
+ dh_pem, cert_pem]},
+ {ssh_public_key_decode_encode, [],
+ [ssh_rsa_public_key, ssh_dsa_public_key, ssh_rfc4716_rsa_comment,
+ ssh_rfc4716_dsa_comment, ssh_rfc4716_rsa_subject, ssh_known_hosts,
+ ssh_auth_keys, ssh1_known_hosts, ssh1_auth_keys, ssh_openssh_public_key_with_comment,
+ ssh_openssh_public_key_long_header]},
+ {sign_verify, [], [rsa_sign_verify, dsa_sign_verify]}
+ ].
init_per_group(_GroupName, Config) ->
Config.
@@ -125,22 +137,20 @@ app(suite) ->
app(Config) when is_list(Config) ->
ok = test_server:app_test(public_key).
-pk_decode_encode(doc) ->
- ["Tests pem_decode/1, pem_encode/1, "
- "der_decode/2, der_encode/2, "
- "pem_entry_decode/1, pem_entry_decode/2,"
- "pem_entry_encode/2, pem_entry_encode/3."];
+%%--------------------------------------------------------------------
-pk_decode_encode(suite) ->
+dsa_pem(doc) ->
+ [""];
+dsa_pem(suite) ->
[];
-pk_decode_encode(Config) when is_list(Config) ->
+dsa_pem(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
- [{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] =
- erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
-
+ [{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] =
+ erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
+
DSAKey = public_key:der_decode('DSAPrivateKey', DerDSAKey),
-
+
DSAKey = public_key:pem_entry_decode(Entry0),
{ok, DSAPubPem} = file:read_file(filename:join(Datadir, "dsa_pub.pem")),
@@ -150,74 +160,107 @@ pk_decode_encode(Config) when is_list(Config) ->
true = check_entry_type(DSAPubKey, 'DSAPublicKey'),
PubEntry0 = public_key:pem_entry_encode('SubjectPublicKeyInfo', DSAPubKey),
DSAPubPemNoEndNewLines = strip_ending_newlines(DSAPubPem),
- DSAPubPemEndNoNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry0])),
-
- [{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry1 ] =
+ DSAPubPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry0])).
+
+%%--------------------------------------------------------------------
+
+rsa_pem(doc) ->
+ [""];
+rsa_pem(suite) ->
+ [];
+rsa_pem(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+ [{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry0 ] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
-
+
RSAKey0 = public_key:der_decode('RSAPrivateKey', DerRSAKey),
+
+ RSAKey0 = public_key:pem_entry_decode(Entry0),
- RSAKey0 = public_key:pem_entry_decode(Entry1),
-
- [{'RSAPrivateKey', _, {_,_}} = Entry2] =
+ [{'RSAPrivateKey', _, {_,_}} = Entry1] =
erl_make_certs:pem_to_der(filename:join(Datadir, "rsa.pem")),
-
- true = check_entry_type(public_key:pem_entry_decode(Entry2, "abcd1234"),
+
+ true = check_entry_type(public_key:pem_entry_decode(Entry1, "abcd1234"),
'RSAPrivateKey'),
{ok, RSAPubPem} = file:read_file(filename:join(Datadir, "rsa_pub.pem")),
- [{'SubjectPublicKeyInfo', _, _} = PubEntry1] =
+ [{'SubjectPublicKeyInfo', _, _} = PubEntry0] =
public_key:pem_decode(RSAPubPem),
- RSAPubKey = public_key:pem_entry_decode(PubEntry1),
+ RSAPubKey = public_key:pem_entry_decode(PubEntry0),
true = check_entry_type(RSAPubKey, 'RSAPublicKey'),
- PubEntry1 = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey),
+ PubEntry0 = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey),
RSAPubPemNoEndNewLines = strip_ending_newlines(RSAPubPem),
- RSAPubPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry1])),
+ RSAPubPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry0])),
{ok, RSARawPem} = file:read_file(filename:join(Datadir, "rsa_pub_key.pem")),
- [{'RSAPublicKey', _, _} = PubEntry2] =
+ [{'RSAPublicKey', _, _} = PubEntry1] =
public_key:pem_decode(RSARawPem),
- RSAPubKey = public_key:pem_entry_decode(PubEntry2),
+ RSAPubKey = public_key:pem_entry_decode(PubEntry1),
RSARawPemNoEndNewLines = strip_ending_newlines(RSARawPem),
- RSARawPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry2])),
+ RSARawPemNoEndNewLines = strip_ending_newlines(public_key:pem_encode([PubEntry1])).
+
+%%--------------------------------------------------------------------
+
+encrypted_pem(doc) ->
+ [""];
+encrypted_pem(suite) ->
+ [];
+encrypted_pem(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ [{'RSAPrivateKey', DerRSAKey, not_encrypted}] =
+ erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
+
+ RSAKey = public_key:der_decode('RSAPrivateKey', DerRSAKey),
Salt0 = crypto:rand_bytes(8),
- Entry3 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey0,
+ Entry0 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey,
{{"DES-EDE3-CBC", Salt0}, "1234abcd"}),
-
- RSAKey0 = public_key:pem_entry_decode(Entry3,"1234abcd"),
-
+ RSAKey = public_key:pem_entry_decode(Entry0,"1234abcd"),
Des3KeyFile = filename:join(Datadir, "des3_client_key.pem"),
+ erl_make_certs:der_to_pem(Des3KeyFile, [Entry0]),
+ [{'RSAPrivateKey', _, {"DES-EDE3-CBC", Salt0}}] =
+ erl_make_certs:pem_to_der(Des3KeyFile),
- erl_make_certs:der_to_pem(Des3KeyFile, [Entry3]),
-
- [{'RSAPrivateKey', _, {"DES-EDE3-CBC", Salt0}}] = erl_make_certs:pem_to_der(Des3KeyFile),
-
Salt1 = crypto:rand_bytes(8),
- Entry4 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey0,
+ Entry1 = public_key:pem_entry_encode('RSAPrivateKey', RSAKey,
{{"DES-CBC", Salt1}, "4567efgh"}),
-
-
DesKeyFile = filename:join(Datadir, "des_client_key.pem"),
+ erl_make_certs:der_to_pem(DesKeyFile, [Entry1]),
+ [{'RSAPrivateKey', _, {"DES-CBC", Salt1}} =Entry2] =
+ erl_make_certs:pem_to_der(DesKeyFile),
+ true = check_entry_type(public_key:pem_entry_decode(Entry2, "4567efgh"),
+ 'RSAPrivateKey').
- erl_make_certs:der_to_pem(DesKeyFile, [Entry4]),
-
- [{'RSAPrivateKey', _, {"DES-CBC", Salt1}} =Entry5] = erl_make_certs:pem_to_der(DesKeyFile),
-
-
- true = check_entry_type(public_key:pem_entry_decode(Entry5, "4567efgh"),
- 'RSAPrivateKey'),
+%%--------------------------------------------------------------------
- [{'DHParameter', DerDH, not_encrypted} = Entry6] =
+dh_pem(doc) ->
+ [""];
+dh_pem(suite) ->
+ [];
+dh_pem(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+ [{'DHParameter', DerDH, not_encrypted} = Entry] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dh.pem")),
-
- erl_make_certs:der_to_pem(filename:join(Datadir, "new_dh.pem"), [Entry6]),
+
+ erl_make_certs:der_to_pem(filename:join(Datadir, "new_dh.pem"), [Entry]),
DHParameter = public_key:der_decode('DHParameter', DerDH),
- DHParameter = public_key:pem_entry_decode(Entry6),
+ DHParameter = public_key:pem_entry_decode(Entry),
- Entry6 = public_key:pem_entry_encode('DHParameter', DHParameter),
+ Entry = public_key:pem_entry_encode('DHParameter', DHParameter).
+%%--------------------------------------------------------------------
+cert_pem(doc) ->
+ [""];
+cert_pem(suite) ->
+ [];
+cert_pem(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ [Entry0] =
+ erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
+
[{'Certificate', DerCert, not_encrypted} = Entry7] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")),
@@ -227,15 +270,232 @@ pk_decode_encode(Config) when is_list(Config) ->
CertEntries = [{'Certificate', _, not_encrypted} = CertEntry0,
{'Certificate', _, not_encrypted} = CertEntry1] =
erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")),
-
+
ok = erl_make_certs:der_to_pem(filename:join(Datadir, "wcacerts.pem"), CertEntries),
ok = erl_make_certs:der_to_pem(filename:join(Datadir, "wdsa.pem"), [Entry0]),
NewCertEntries = erl_make_certs:pem_to_der(filename:join(Datadir, "wcacerts.pem")),
true = lists:member(CertEntry0, NewCertEntries),
true = lists:member(CertEntry1, NewCertEntries),
- [Entry0] = erl_make_certs:pem_to_der(filename:join(Datadir, "wdsa.pem")),
- ok.
+ [Entry0] = erl_make_certs:pem_to_der(filename:join(Datadir, "wdsa.pem")).
+
+%%--------------------------------------------------------------------
+ssh_rsa_public_key(doc) ->
+ "";
+ssh_rsa_public_key(suite) ->
+ [];
+ssh_rsa_public_key(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_rsa_pub")),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(RSARawSsh2, public_key),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(RSARawSsh2, rfc4716_public_key),
+
+ {ok, RSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_rsa_pub")),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(RSARawOpenSsh, public_key),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(RSARawOpenSsh, openssh_public_key),
+
+ %% Can not check EncodedSSh == RSARawSsh2 and EncodedOpenSsh
+ %% = RSARawOpenSsh as line breakpoints may differ
+
+ EncodedSSh = public_key:ssh_encode([{PubKey, Attributes1}], rfc4716_public_key),
+ EncodedOpenSsh = public_key:ssh_encode([{PubKey, Attributes2}], openssh_public_key),
+
+ [{PubKey, Attributes1}] =
+ public_key:ssh_decode(EncodedSSh, public_key),
+ [{PubKey, Attributes2}] =
+ public_key:ssh_decode(EncodedOpenSsh, public_key).
+
+%%--------------------------------------------------------------------
+
+ssh_dsa_public_key(doc) ->
+ "";
+ssh_dsa_public_key(suite) ->
+ [];
+ssh_dsa_public_key(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, DSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_dsa_pub")),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(DSARawSsh2, public_key),
+ [{PubKey, Attributes1}] = public_key:ssh_decode(DSARawSsh2, rfc4716_public_key),
+
+ {ok, DSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_dsa_pub")),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(DSARawOpenSsh, public_key),
+ [{PubKey, Attributes2}] = public_key:ssh_decode(DSARawOpenSsh, openssh_public_key),
+
+ %% Can not check EncodedSSh == DSARawSsh2 and EncodedOpenSsh
+ %% = DSARawOpenSsh as line breakpoints may differ
+
+ EncodedSSh = public_key:ssh_encode([{PubKey, Attributes1}], rfc4716_public_key),
+ EncodedOpenSsh = public_key:ssh_encode([{PubKey, Attributes2}], openssh_public_key),
+
+ [{PubKey, Attributes1}] =
+ public_key:ssh_decode(EncodedSSh, public_key),
+ [{PubKey, Attributes2}] =
+ public_key:ssh_decode(EncodedOpenSsh, public_key).
+
+%%--------------------------------------------------------------------
+ssh_rfc4716_rsa_comment(doc) ->
+ "Test comment header and rsa key";
+ssh_rfc4716_rsa_comment(suite) ->
+ [];
+ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_rsa_comment_pub")),
+ [{#'RSAPublicKey'{} = PubKey, Attributes}] =
+ public_key:ssh_decode(RSARawSsh2, public_key),
+
+ Headers = proplists:get_value(headers, Attributes),
+
+ Value = proplists:get_value("Comment", Headers, undefined),
+ true = Value =/= undefined,
+ RSARawSsh2 = public_key:ssh_encode([{PubKey, Attributes}], rfc4716_public_key).
+
+%%--------------------------------------------------------------------
+ssh_rfc4716_dsa_comment(doc) ->
+ "Test comment header and dsa key";
+ssh_rfc4716_dsa_comment(suite) ->
+ [];
+ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, DSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_dsa_comment_pub")),
+ [{{_, #'Dss-Parms'{}} = PubKey, Attributes}] =
+ public_key:ssh_decode(DSARawSsh2, public_key),
+
+ Headers = proplists:get_value(headers, Attributes),
+
+ Value = proplists:get_value("Comment", Headers, undefined),
+ true = Value =/= undefined,
+
+ %% Can not check Encoded == DSARawSsh2 as line continuation breakpoints may differ
+ Encoded = public_key:ssh_encode([{PubKey, Attributes}], rfc4716_public_key),
+ [{PubKey, Attributes}] =
+ public_key:ssh_decode(Encoded, public_key).
+
+%%--------------------------------------------------------------------
+ssh_rfc4716_rsa_subject(doc) ->
+ "Test another header value than comment";
+ssh_rfc4716_rsa_subject(suite) ->
+ [];
+ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_subject_pub")),
+ [{#'RSAPublicKey'{} = PubKey, Attributes}] =
+ public_key:ssh_decode(RSARawSsh2, public_key),
+
+ Headers = proplists:get_value(headers, Attributes),
+
+ Value = proplists:get_value("Subject", Headers, undefined),
+ true = Value =/= undefined,
+
+ %% Can not check Encoded == RSARawSsh2 as line continuation breakpoints may differ
+ Encoded = public_key:ssh_encode([{PubKey, Attributes}], rfc4716_public_key),
+ [{PubKey, Attributes}] =
+ public_key:ssh_decode(Encoded, public_key).
+
+%%--------------------------------------------------------------------
+ssh_known_hosts(doc) ->
+ "";
+ssh_known_hosts(suite) ->
+ [];
+ssh_known_hosts(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, SshKnownHosts} = file:read_file(filename:join(Datadir, "known_hosts")),
+ [{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2}] = Decoded =
+ public_key:ssh_decode(SshKnownHosts, known_hosts),
+
+ Value1 = proplists:get_value(hostnames, Attributes1, undefined),
+ Value2 = proplists:get_value(hostnames, Attributes2, undefined),
+ true = (Value1 =/= undefined) and (Value2 =/= undefined),
+
+ Encoded = public_key:ssh_encode(Decoded, known_hosts),
+ Decoded = public_key:ssh_decode(Encoded, known_hosts).
+
+%%--------------------------------------------------------------------
+
+ssh1_known_hosts(doc) ->
+ "";
+ssh1_known_hosts(suite) ->
+ [];
+ssh1_known_hosts(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, SshKnownHosts} = file:read_file(filename:join(Datadir, "ssh1_known_hosts")),
+ [{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2}] = Decoded =
+ public_key:ssh_decode(SshKnownHosts, known_hosts),
+
+ Value1 = proplists:get_value(hostnames, Attributes1, undefined),
+ Value2 = proplists:get_value(hostnames, Attributes2, undefined),
+ true = (Value1 =/= undefined) and (Value2 =/= undefined),
+
+ Encoded = public_key:ssh_encode(Decoded, known_hosts),
+ Decoded = public_key:ssh_decode(Encoded, known_hosts).
+
+%%--------------------------------------------------------------------
+ssh_auth_keys(doc) ->
+ "";
+ssh_auth_keys(suite) ->
+ [];
+ssh_auth_keys(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, SshAuthKeys} = file:read_file(filename:join(Datadir, "auth_keys")),
+ [{#'RSAPublicKey'{}, Attributes1}, {{_, #'Dss-Parms'{}}, _Attributes2}] = Decoded =
+ public_key:ssh_decode(SshAuthKeys, auth_keys),
+
+ Value1 = proplists:get_value(options, Attributes1, undefined),
+ true = Value1 =/= undefined,
+
+ Encoded = public_key:ssh_encode(Decoded, auth_keys),
+ Decoded = public_key:ssh_decode(Encoded, auth_keys).
+
+%%--------------------------------------------------------------------
+ssh1_auth_keys(doc) ->
+ "";
+ssh1_auth_keys(suite) ->
+ [];
+ssh1_auth_keys(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, SshAuthKeys} = file:read_file(filename:join(Datadir, "ssh1_auth_keys")),
+ [{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2}] = Decoded =
+ public_key:ssh_decode(SshAuthKeys, auth_keys),
+
+ Value1 = proplists:get_value(bits, Attributes1, undefined),
+ Value2 = proplists:get_value(bits, Attributes2, undefined),
+ true = (Value1 =/= undefined) and (Value2 =/= undefined),
+
+ Encoded = public_key:ssh_encode(Decoded, auth_keys),
+ Decoded = public_key:ssh_decode(Encoded, auth_keys).
+
+%%--------------------------------------------------------------------
+ssh_openssh_public_key_with_comment(doc) ->
+ "Test that emty lines and lines starting with # are ignored";
+ssh_openssh_public_key_with_comment(suite) ->
+ [];
+ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok, DSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_dsa_with_comment_pub")),
+ [{{_, #'Dss-Parms'{}}, _}] = public_key:ssh_decode(DSARawOpenSsh, openssh_public_key).
+
+%%--------------------------------------------------------------------
+ssh_openssh_public_key_long_header(doc) ->
+ "Test that long headers are handled";
+ssh_openssh_public_key_long_header(suite) ->
+ [];
+ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+
+ {ok,RSARawOpenSsh} = file:read_file(filename:join(Datadir, "ssh_rsa_long_header_pub")),
+ [{#'RSAPublicKey'{}, _}] = Decoded = public_key:ssh_decode(RSARawOpenSsh, public_key),
+
+ Encoded = public_key:ssh_encode(Decoded, rfc4716_public_key),
+ Decoded = public_key:ssh_decode(Encoded, rfc4716_public_key).
%%--------------------------------------------------------------------
encrypt_decrypt(doc) ->
@@ -258,44 +518,49 @@ encrypt_decrypt(Config) when is_list(Config) ->
ok.
%%--------------------------------------------------------------------
-sign_verify(doc) ->
- ["Checks that we can sign and verify signatures."];
-sign_verify(suite) ->
+rsa_sign_verify(doc) ->
+ ["Checks that we can sign and verify rsa signatures."];
+rsa_sign_verify(suite) ->
[];
-sign_verify(Config) when is_list(Config) ->
- %% Make cert signs and validates the signature using RSA and DSA
+rsa_sign_verify(Config) when is_list(Config) ->
Ca = {_, CaKey} = erl_make_certs:make_cert([]),
+ {Cert1, _} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]),
PrivateRSA = #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} =
public_key:pem_entry_decode(CaKey),
-
- CertInfo = {Cert1,CertKey1} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]),
-
PublicRSA = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp},
true = public_key:pkix_verify(Cert1, PublicRSA),
- {Cert2,_CertKey} = erl_make_certs:make_cert([{issuer, CertInfo}]),
-
- #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y, x=_X} =
- public_key:pem_entry_decode(CertKey1),
- true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}),
-
- %% RSA sign
Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")),
-
RSASign = public_key:sign(Msg, sha, PrivateRSA),
true = public_key:verify(Msg, sha, RSASign, PublicRSA),
false = public_key:verify(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA),
false = public_key:verify(Msg, sha, <<1:8, RSASign/binary>>, PublicRSA),
RSASign1 = public_key:sign(Msg, md5, PrivateRSA),
- true = public_key:verify(Msg, md5, RSASign1, PublicRSA),
+ true = public_key:verify(Msg, md5, RSASign1, PublicRSA).
- %% DSA sign
+%%--------------------------------------------------------------------
+
+dsa_sign_verify(doc) ->
+ ["Checks that we can sign and verify dsa signatures."];
+dsa_sign_verify(suite) ->
+ [];
+dsa_sign_verify(Config) when is_list(Config) ->
+ Ca = erl_make_certs:make_cert([]),
+ CertInfo = {_,CertKey1} = erl_make_certs:make_cert([{key, dsa}, {issuer, Ca}]),
+ {Cert2,_CertKey} = erl_make_certs:make_cert([{issuer, CertInfo}]),
+
+ #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y, x=_X} =
+ public_key:pem_entry_decode(CertKey1),
+ true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}),
+
Datadir = ?config(data_dir, Config),
[DsaKey = {'DSAPrivateKey', _, _}] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
DSAPrivateKey = public_key:pem_entry_decode(DsaKey),
#'DSAPrivateKey'{p=P1, q=Q1, g=G1, y=Y1, x=_X1} = DSAPrivateKey,
+
+ Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")),
DSASign = public_key:sign(Msg, sha, DSAPrivateKey),
DSAPublicKey = Y1,
DSAParams = #'Dss-Parms'{p=P1, q=Q1, g=G1},
@@ -312,9 +577,8 @@ sign_verify(Config) when is_list(Config) ->
false = public_key:verify(<<1:8, RestDigest/binary>>, none, DigestSign,
{DSAPublicKey, DSAParams}),
false = public_key:verify(Digest, none, <<1:8, DigestSign/binary>>,
- {DSAPublicKey, DSAParams}),
-
- ok.
+ {DSAPublicKey, DSAParams}).
+
%%--------------------------------------------------------------------
pkix(doc) ->
"Misc pkix tests not covered elsewhere";
diff --git a/lib/public_key/test/public_key_SUITE_data/auth_keys b/lib/public_key/test/public_key_SUITE_data/auth_keys
new file mode 100644
index 0000000000..0c4b47edde
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/auth_keys
@@ -0,0 +1,3 @@
+command="dump /home",no-pty,no-port-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o39jSkHNiMMER/GETBbzP83LOcekm02aRjo55ArO7gPPVvCXbrirJu9pkm4AC4BBre5xSLS7soyzwbigFruM8G63jSXqpHqJ/ooi168sKMC2b0Ncsi+JlTfNYlDXJVLKEeZgZOInQyMmtisaDTUQWTIv1snAizf4iIYENuAkGYGNCL77u5Y5VOu5eQipvFajTnps9QvUx/zdSFYn9e2sulWM3Bxc/S4IJ67JWHVRpfJxGi3hinRBH8WQdXuUwdJJTiJHKPyYrrM7Q6Xq4TOMFtcRuLDC6u3BXM1L0gBvHPNOnD5l2Lp5EjUkQ9CBf2j4A4gfH+iWQZyk08esAG/iwArAVxkl368+dkbMWOXL8BN4x5zYgdzoeypQZZ2RKH780MCTSo4WQ19DP8pw+9q3bSFC9H3xYAxrKAJNWjeTUJOTrTe+mWXXU770gYyQTxa2ycnYrlZucn1S3vsvn6eq7NZZ8NRbyv1n15Ocg+nHK4fuKOrwPhU3NbKQwtjb0Wsxx1gAmQqIOLTpAdsrAauPxC7TPYA5qQVCphvimKuhQM/1gMV225JrnjspVlthCzuFYUjXOKC3wxz6FFEtwnXu3uC5bVVkmkNadJmD21gD23yk4BraGXVYpRMIB+X+OTUUI8= dhopson@VMUbuntu-DSH
+
+ssh-dss AAAAB3NzaC1kc3MAAACBAPY8ZOHY2yFSJA6XYC9HRwNHxaehvx5wOJ0rzZdzoSOXxbETW6ToHv8D1UJ/z+zHo9Fiko5XybZnDIaBDHtblQ+Yp7StxyltHnXF1YLfKD1G4T6JYrdHYI14Om1eg9e4NnCRleaqoZPF3UGfZia6bXrGTQf3gJq2e7Yisk/gF+1VAAAAFQDb8D5cvwHWTZDPfX0D2s9Rd7NBvQAAAIEAlN92+Bb7D4KLYk3IwRbXblwXdkPggA4pfdtW9vGfJ0/RHd+NjB4eo1D+0dix6tXwYGN7PKS5R/FXPNwxHPapcj9uL1Jn2AWQ2dsknf+i/FAAvioUPkmdMc0zuWoSOEsSNhVDtX3WdvVcGcBq9cetzrtOKWOocJmJ80qadxTRHtUAAACBAN7CY+KKv1gHpRzFwdQm7HK9bb1LAo2KwaoXnadFgeptNBQeSXG1vO+JsvphVMBJc9HSn24VYtYtsMu74qXviYjziVucWKjjKEb11juqnF0GDlB3VVmxHLmxnAz643WK42Z7dLM5sY29ouezv4Xz2PuMch5VGPP+CDqzCM4loWgV dhopson@VMUbuntu-DSH
diff --git a/lib/public_key/test/public_key_SUITE_data/known_hosts b/lib/public_key/test/public_key_SUITE_data/known_hosts
new file mode 100644
index 0000000000..30fc3b1fe8
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/known_hosts
@@ -0,0 +1,3 @@
+hostname.domain.com,192.168.0.1 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA1XY18+zA8VNK2YkzygOkMqUxHSTfxT1Xxx8CgDZgcQH8HUhPssW5ttvG8nKetlPQZAVk1C4WkWS1y5b3ekBhZTIxocp9Joc6V1+f2EOfO2mSLRwB16RGrdw6q7msrBXTC/dl+hF45kMMzVNzqxnSMVOa0sEPK2zK6Sg3Vi9fCSM=
+
+|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA1XY18+zA8VNK2YkzygOkMqUxHSTfxT1Xxx8CgDZgcQH8HUhPssW5ttvG8nKetlPQZAVk1C4WkWS1y5b3ekBhZTIxocp9Joc6V1+f2EOfO2mSLRwB16RGrdw6q7msrBXTC/dl+hF45kMMzVNzqxnSMVOa0sEPK2zK6Sg3Vi9fCSM= [email protected]
diff --git a/lib/public_key/test/public_key_SUITE_data/openssh_dsa_pub b/lib/public_key/test/public_key_SUITE_data/openssh_dsa_pub
new file mode 100644
index 0000000000..a765ba8189
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/openssh_dsa_pub
@@ -0,0 +1 @@
+ssh-dss AAAAB3NzaC1kc3MAAACBAPY8ZOHY2yFSJA6XYC9HRwNHxaehvx5wOJ0rzZdzoSOXxbETW6ToHv8D1UJ/z+zHo9Fiko5XybZnDIaBDHtblQ+Yp7StxyltHnXF1YLfKD1G4T6JYrdHYI14Om1eg9e4NnCRleaqoZPF3UGfZia6bXrGTQf3gJq2e7Yisk/gF+1VAAAAFQDb8D5cvwHWTZDPfX0D2s9Rd7NBvQAAAIEAlN92+Bb7D4KLYk3IwRbXblwXdkPggA4pfdtW9vGfJ0/RHd+NjB4eo1D+0dix6tXwYGN7PKS5R/FXPNwxHPapcj9uL1Jn2AWQ2dsknf+i/FAAvioUPkmdMc0zuWoSOEsSNhVDtX3WdvVcGcBq9cetzrtOKWOocJmJ80qadxTRHtUAAACBAN7CY+KKv1gHpRzFwdQm7HK9bb1LAo2KwaoXnadFgeptNBQeSXG1vO+JsvphVMBJc9HSn24VYtYtsMu74qXviYjziVucWKjjKEb11juqnF0GDlB3VVmxHLmxnAz643WK42Z7dLM5sY29ouezv4Xz2PuMch5VGPP+CDqzCM4loWgV dhopson@VMUbuntu-DSH
diff --git a/lib/public_key/test/public_key_SUITE_data/openssh_dsa_with_comment_pub b/lib/public_key/test/public_key_SUITE_data/openssh_dsa_with_comment_pub
new file mode 100644
index 0000000000..d5a34a3f78
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/openssh_dsa_with_comment_pub
@@ -0,0 +1,3 @@
+#This should be ignored!!
+
+ssh-dss AAAAB3NzaC1kc3MAAACBAPY8ZOHY2yFSJA6XYC9HRwNHxaehvx5wOJ0rzZdzoSOXxbETW6ToHv8D1UJ/z+zHo9Fiko5XybZnDIaBDHtblQ+Yp7StxyltHnXF1YLfKD1G4T6JYrdHYI14Om1eg9e4NnCRleaqoZPF3UGfZia6bXrGTQf3gJq2e7Yisk/gF+1VAAAAFQDb8D5cvwHWTZDPfX0D2s9Rd7NBvQAAAIEAlN92+Bb7D4KLYk3IwRbXblwXdkPggA4pfdtW9vGfJ0/RHd+NjB4eo1D+0dix6tXwYGN7PKS5R/FXPNwxHPapcj9uL1Jn2AWQ2dsknf+i/FAAvioUPkmdMc0zuWoSOEsSNhVDtX3WdvVcGcBq9cetzrtOKWOocJmJ80qadxTRHtUAAACBAN7CY+KKv1gHpRzFwdQm7HK9bb1LAo2KwaoXnadFgeptNBQeSXG1vO+JsvphVMBJc9HSn24VYtYtsMu74qXviYjziVucWKjjKEb11juqnF0GDlB3VVmxHLmxnAz643WK42Z7dLM5sY29ouezv4Xz2PuMch5VGPP+CDqzCM4loWgV dhopson@VMUbuntu-DSH
diff --git a/lib/public_key/test/public_key_SUITE_data/openssh_rsa_pub b/lib/public_key/test/public_key_SUITE_data/openssh_rsa_pub
new file mode 100644
index 0000000000..0a0838db40
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/openssh_rsa_pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o39jSkHNiMMER/GETBbzP83LOcekm02aRjo55ArO7gPPVvCXbrirJu9pkm4AC4BBre5xSLS7soyzwbigFruM8G63jSXqpHqJ/ooi168sKMC2b0Ncsi+JlTfNYlDXJVLKEeZgZOInQyMmtisaDTUQWTIv1snAizf4iIYENuAkGYGNCL77u5Y5VOu5eQipvFajTnps9QvUx/zdSFYn9e2sulWM3Bxc/S4IJ67JWHVRpfJxGi3hinRBH8WQdXuUwdJJTiJHKPyYrrM7Q6Xq4TOMFtcRuLDC6u3BXM1L0gBvHPNOnD5l2Lp5EjUkQ9CBf2j4A4gfH+iWQZyk08esAG/iwArAVxkl368+dkbMWOXL8BN4x5zYgdzoeypQZZ2RKH780MCTSo4WQ19DP8pw+9q3bSFC9H3xYAxrKAJNWjeTUJOTrTe+mWXXU770gYyQTxa2ycnYrlZucn1S3vsvn6eq7NZZ8NRbyv1n15Ocg+nHK4fuKOrwPhU3NbKQwtjb0Wsxx1gAmQqIOLTpAdsrAauPxC7TPYA5qQVCphvimKuhQM/1gMV225JrnjspVlthCzuFYUjXOKC3wxz6FFEtwnXu3uC5bVVkmkNadJmD21gD23yk4BraGXVYpRMIB+X+OTUUI8= dhopson@VMUbuntu-DSH
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh1_auth_keys b/lib/public_key/test/public_key_SUITE_data/ssh1_auth_keys
new file mode 100644
index 0000000000..c91f4e4679
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh1_auth_keys
@@ -0,0 +1,3 @@
+1024 35 794430685278501116412873221867658581245241426828503388129294124540165981586596106773643485704743298698207838825035605868404742682423919455523383721081589378970796492944950066480951790660582889972423189943567111507801410254720228911513553205592856585541922662924268445466959576882300405064708497308004255650466014242855505233634626075778108365396568863197935915425650388910408127232583533503834009244199384570662092164277923946411149853110048365318587554141774139652307149492021035538341281427025252592933784473453522113124752189378715431529801894015739903371171585194505182320772654217490509848165365152457990491089951560694728469571221819385402117009544812199223715540348068497710535492913376699508575875577554607325905000745578091554027803374110357015655416894607641289462159580964951182385869168785183135763253784745647466464331174922663455073627501620274348748413309761116542324505123795743603781806636788810617169341018091186028310551725315297135354426735951943325476221811539822892501042385411792050504283745898099390893596941969752683246939665141002098430129617772928840718016009187577151479855846883928332010147501182201528575840364152774917950524127063432334646746291719251739989499132767590205934821590545762802261107691663 dhopson@VMUbuntu-DSH
+
+command="dump /home",no-pty,no-port-forwarding 1024 35 794430685278501116412873221867658581245241426828503388129294124540165981586596106773643485704743298698207838825035605868404742682423919455523383721081589378970796492944950066480951790660582889972423189943567111507801410254720228911513553205592856585541922662924268445466959576882300405064708497308004255650466014242855505233634626075778108365396568863197935915425650388910408127232583533503834009244199384570662092164277923946411149853110048365318587554141774139652307149492021035538341281427025252592933784473453522113124752189378715431529801894015739903371171585194505182320772654217490509848165365152457990491089951560694728469571221819385402117009544812199223715540348068497710535492913376699508575875577554607325905000745578091554027803374110357015655416894607641289462159580964951182385869168785183135763253784745647466464331174922663455073627501620274348748413309761116542324505123795743603781806636788810617169341018091186028310551725315297135354426735951943325476221811539822892501042385411792050504283745898099390893596941969752683246939665141002098430129617772928840718016009187577151479855846883928332010147501182201528575840364152774917950524127063432334646746291719251739989499132767590205934821590545762802261107691663 dhopson@VMUbuntu-DSH
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh1_known_hosts b/lib/public_key/test/public_key_SUITE_data/ssh1_known_hosts
new file mode 100644
index 0000000000..ec668fe05b
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh1_known_hosts
@@ -0,0 +1,2 @@
+hostname.domain.com,192.168.0.1 1024 35 794430685278501116412873221867658581245241426828503388129294124540165981586596106773643485704743298698207838825035605868404742682423919455523383721081589378970796492944950066480951790660582889972423189943567111507801410254720228911513553205592856585541922662924268445466959576882300405064708497308004255650466014242855505233634626075778108365396568863197935915425650388910408127232583533503834009244199384570662092164277923946411149853110048365318587554141774139652307149492021035538341281427025252592933784473453522113124752189378715431529801894015739903371171585194505182320772654217490509848165365152457990491089951560694728469571221819385402117009544812199223715540348068497710535492913376699508575875577554607325905000745578091554027803374110357015655416894607641289462159580964951182385869168785183135763253784745647466464331174922663455073627501620274348748413309761116542324505123795743603781806636788810617169341018091186028310551725315297135354426735951943325476221811539822892501042385411792050504283745898099390893596941969752683246939665141002098430129617772928840718016009187577151479855846883928332010147501182201528575840364152774917950524127063432334646746291719251739989499132767590205934821590545762802261107691663 dhopson@VMUbuntu-DSH
+hostname2.domain.com,192.168.0.2 1024 35 794430685278501116412873221867658581245241426828503388129294124540165981586596106773643485704743298698207838825035605868404742682423919455523383721081589378970796492944950066480951790660582889972423189943567111507801410254720228911513553205592856585541922662924268445466959576882300405064708497308004255650466014242855505233634626075778108365396568863197935915425650388910408127232583533503834009244199384570662092164277923946411149853110048365318587554141774139652307149492021035538341281427025252592933784473453522113124752189378715431529801894015739903371171585194505182320772654217490509848165365152457990491089951560694728469571221819385402117009544812199223715540348068497710535492913376699508575875577554607325905000745578091554027803374110357015655416894607641289462159580964951182385869168785183135763253784745647466464331174922663455073627501620274348748413309761116542324505123795743603781806636788810617169341018091186028310551725315297135354426735951943325476221811539822892501042385411792050504283745898099390893596941969752683246939665141002098430129617772928840718016009187577151479855846883928332010147501182201528575840364152774917950524127063432334646746291719251739989499132767590205934821590545762802261107691663
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_dsa_comment_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_dsa_comment_pub
new file mode 100644
index 0000000000..ca5089dbd7
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_dsa_comment_pub
@@ -0,0 +1,13 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: This is my public key for use on \
+servers which I don't like.
+AAAAB3NzaC1kc3MAAACBAPY8ZOHY2yFSJA6XYC9HRwNHxaehvx5wOJ0rzZdzoSOXxbET
+W6ToHv8D1UJ/z+zHo9Fiko5XybZnDIaBDHtblQ+Yp7StxyltHnXF1YLfKD1G4T6JYrdH
+YI14Om1eg9e4NnCRleaqoZPF3UGfZia6bXrGTQf3gJq2e7Yisk/gF+1VAAAAFQDb8D5c
+vwHWTZDPfX0D2s9Rd7NBvQAAAIEAlN92+Bb7D4KLYk3IwRbXblwXdkPggA4pfdtW9vGf
+J0/RHd+NjB4eo1D+0dix6tXwYGN7PKS5R/FXPNwxHPapcj9uL1Jn2AWQ2dsknf+i/FAA
+vioUPkmdMc0zuWoSOEsSNhVDtX3WdvVcGcBq9cetzrtOKWOocJmJ80qadxTRHtUAAACB
+AN7CY+KKv1gHpRzFwdQm7HK9bb1LAo2KwaoXnadFgeptNBQeSXG1vO+JsvphVMBJc9HS
+n24VYtYtsMu74qXviYjziVucWKjjKEb11juqnF0GDlB3VVmxHLmxnAz643WK42Z7dLM5
+sY29ouezv4Xz2PuMch5VGPP+CDqzCM4loWgV
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_dsa_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_dsa_pub
new file mode 100644
index 0000000000..a5e38be81a
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_dsa_pub
@@ -0,0 +1,12 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: DSA Public Key for use with MyIsp
+AAAAB3NzaC1kc3MAAACBAPY8ZOHY2yFSJA6XYC9HRwNHxaehvx5wOJ0rzZdzoSOXxbET
+W6ToHv8D1UJ/z+zHo9Fiko5XybZnDIaBDHtblQ+Yp7StxyltHnXF1YLfKD1G4T6JYrdH
+YI14Om1eg9e4NnCRleaqoZPF3UGfZia6bXrGTQf3gJq2e7Yisk/gF+1VAAAAFQDb8D5c
+vwHWTZDPfX0D2s9Rd7NBvQAAAIEAlN92+Bb7D4KLYk3IwRbXblwXdkPggA4pfdtW9vGf
+J0/RHd+NjB4eo1D+0dix6tXwYGN7PKS5R/FXPNwxHPapcj9uL1Jn2AWQ2dsknf+i/FAA
+vioUPkmdMc0zuWoSOEsSNhVDtX3WdvVcGcBq9cetzrtOKWOocJmJ80qadxTRHtUAAACB
+AN7CY+KKv1gHpRzFwdQm7HK9bb1LAo2KwaoXnadFgeptNBQeSXG1vO+JsvphVMBJc9HS
+n24VYtYtsMu74qXviYjziVucWKjjKEb11juqnF0GDlB3VVmxHLmxnAz643WK42Z7dLM5
+sY29ouezv4Xz2PuMch5VGPP+CDqzCM4loWgV
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_rsa_comment_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_rsa_comment_pub
new file mode 100644
index 0000000000..e4d446147c
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_rsa_comment_pub
@@ -0,0 +1,7 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: "1024-bit RSA, converted from OpenSSH by [email protected]"
+x-command: /home/me/bin/lock-in-guest.sh
+AAAAB3NzaC1yc2EAAAABIwAAAIEA1on8gxCGJJWSRT4uOrR13mUaUk0hRf4RzxSZ1zRb
+YYFw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ
+5TT4SfsUu/iKy9lUcCfXzwre4WWZSXXcPff+EHtWshahu3WzBdnGxm5Xoi89zcE=
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_rsa_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_rsa_pub
new file mode 100644
index 0000000000..761088b517
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_rsa_pub
@@ -0,0 +1,13 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o
+39jSkHNiMMER/GETBbzP83LOcekm02aRjo55ArO7gPPVvCXbrirJu9pkm4AC4BBre5xSLS
+7soyzwbigFruM8G63jSXqpHqJ/ooi168sKMC2b0Ncsi+JlTfNYlDXJVLKEeZgZOInQyMmt
+isaDTUQWTIv1snAizf4iIYENuAkGYGNCL77u5Y5VOu5eQipvFajTnps9QvUx/zdSFYn9e2
+sulWM3Bxc/S4IJ67JWHVRpfJxGi3hinRBH8WQdXuUwdJJTiJHKPyYrrM7Q6Xq4TOMFtcRu
+LDC6u3BXM1L0gBvHPNOnD5l2Lp5EjUkQ9CBf2j4A4gfH+iWQZyk08esAG/iwArAVxkl368
++dkbMWOXL8BN4x5zYgdzoeypQZZ2RKH780MCTSo4WQ19DP8pw+9q3bSFC9H3xYAxrKAJNW
+jeTUJOTrTe+mWXXU770gYyQTxa2ycnYrlZucn1S3vsvn6eq7NZZ8NRbyv1n15Ocg+nHK4f
+uKOrwPhU3NbKQwtjb0Wsxx1gAmQqIOLTpAdsrAauPxC7TPYA5qQVCphvimKuhQM/1gMV22
+5JrnjspVlthCzuFYUjXOKC3wxz6FFEtwnXu3uC5bVVkmkNadJmD21gD23yk4BraGXVYpRM
+IB+X+OTUUI8=
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh2_subject_pub b/lib/public_key/test/public_key_SUITE_data/ssh2_subject_pub
new file mode 100644
index 0000000000..8b8ccda8ba
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh2_subject_pub
@@ -0,0 +1,8 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Subject: me
+Comment: 1024-bit rsa, created by [email protected] Mon Jan 15 \
+08:31:24 2001
+AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4
+596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4
+soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_comment_pub b/lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_comment_pub
new file mode 100644
index 0000000000..7b42ced93e
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_comment_pub
@@ -0,0 +1,9 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: This is an example of a very very very very looooooooooooo\
+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\
+commment
+x-command: /home/me/bin/lock-in-guest.sh
+AAAAB3NzaC1yc2EAAAABIwAAAIEA1on8gxCGJJWSRT4uOrR13mUaUk0hRf4RzxSZ1zRb
+YYFw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ
+5TT4SfsUu/iKy9lUcCfXzwre4WWZSXXcPff+EHtWshahu3WzBdnGxm5Xoi89zcE=
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_header_pub b/lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_header_pub
new file mode 100644
index 0000000000..7b42ced93e
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ssh_rsa_long_header_pub
@@ -0,0 +1,9 @@
+---- BEGIN SSH2 PUBLIC KEY ----
+Comment: This is an example of a very very very very looooooooooooo\
+ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong\
+commment
+x-command: /home/me/bin/lock-in-guest.sh
+AAAAB3NzaC1yc2EAAAABIwAAAIEA1on8gxCGJJWSRT4uOrR13mUaUk0hRf4RzxSZ1zRb
+YYFw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ
+5TT4SfsUu/iKy9lUcCfXzwre4WWZSXXcPff+EHtWshahu3WzBdnGxm5Xoi89zcE=
+---- END SSH2 PUBLIC KEY ----
diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml
index 11c6cd4c02..a791f2ce03 100644
--- a/lib/reltool/doc/src/notes.xml
+++ b/lib/reltool/doc/src/notes.xml
@@ -37,7 +37,29 @@
thus constitutes one section in this document. The title of each
section is the version number of Reltool.</p>
- <section><title>Reltool 0.5.4</title>
+ <section><title>Reltool 0.5.5</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The reltool module contained two seriously erroneous
+ specs which caused bogus warnings when dialyzing reltool
+ and some correct code of users. These were fixed (specs
+ for start_link/1 and eval_server/3)</p>
+ <p>
+ - Code cleanups and simplifications - Fix a bug in the
+ calculation of circular dependencies - Eliminate two
+ dialyzer warnings - Put files alphabetically</p>
+ <p>
+ Own Id: OTP-9120</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>Reltool 0.5.4</title>
<section><title>Improvements and New Features</title>
<list>
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index d7cad8b29e..9743289ca6 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -1318,7 +1318,7 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
Val =:= none;
Val =:= undefined ->
{Sys#sys{embedded_app_type = Val}, Status};
- app_file when Val =:= keep; Val =:= strip, Val =:= all ->
+ app_file when Val =:= keep; Val =:= strip; Val =:= all ->
{Sys#sys{app_file = Val}, Status};
debug_info when Val =:= keep; Val =:= strip ->
{Sys#sys{debug_info = Val}, Status};
diff --git a/lib/reltool/test/reltool_server_SUITE.erl b/lib/reltool/test/reltool_server_SUITE.erl
index ef3076f305..b77560db94 100644
--- a/lib/reltool/test/reltool_server_SUITE.erl
+++ b/lib/reltool/test/reltool_server_SUITE.erl
@@ -52,7 +52,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[start_server, set_config, create_release,
create_script, create_target, create_embedded,
- create_standalone, create_old_target].
+ create_standalone, create_old_target,
+ otp_9135].
groups() ->
[].
@@ -110,6 +111,37 @@ set_config(_Config) ->
ok.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% OTP-9135, test that app_file option can be set to all | keep | strip
+
+otp_9135(TestInfo) when is_atom(TestInfo) ->
+ reltool_test_lib:tc_info(TestInfo);
+otp_9135(_Config) ->
+ Libs = lists:sort(erl_libs()),
+ StrippedDefaultSys =
+ case Libs of
+ [] -> [];
+ _ -> {lib_dirs, Libs}
+ end,
+
+ Config1 = {sys,[{app_file, keep}]}, % this is the default
+ {ok, Pid1} = ?msym({ok, _}, reltool:start_server([{config, Config1}])),
+ ?m({ok, {sys,StrippedDefaultSys}}, reltool:get_config(Pid1)),
+ ?m(ok, reltool:stop(Pid1)),
+
+ Config2 = {sys,[{app_file, strip}]},
+ {ok, Pid2} = ?msym({ok, _}, reltool:start_server([{config, Config2}])),
+ ExpectedConfig2 = StrippedDefaultSys++[{app_file,strip}],
+ ?m({ok, {sys,ExpectedConfig2}}, reltool:get_config(Pid2)),
+ ?m(ok, reltool:stop(Pid2)),
+
+ Config3 = {sys,[{app_file, all}]},
+ {ok, Pid3} = ?msym({ok, _}, reltool:start_server([{config, Config3}])),
+ ExpectedConfig3 = StrippedDefaultSys++[{app_file,all}],
+ ?m({ok, {sys,ExpectedConfig3}}, reltool:get_config(Pid3)),
+ ?m(ok, reltool:stop(Pid3)),
+ ok.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generate releases
create_release(TestInfo) when is_atom(TestInfo) ->
diff --git a/lib/reltool/vsn.mk b/lib/reltool/vsn.mk
index 9e0bce1d01..484f84788d 100644
--- a/lib/reltool/vsn.mk
+++ b/lib/reltool/vsn.mk
@@ -1 +1 @@
-RELTOOL_VSN = 0.5.4
+RELTOOL_VSN = 0.5.5
diff --git a/lib/runtime_tools/doc/src/notes.xml b/lib/runtime_tools/doc/src/notes.xml
index 92629c18e5..b27a3a0996 100644
--- a/lib/runtime_tools/doc/src/notes.xml
+++ b/lib/runtime_tools/doc/src/notes.xml
@@ -31,6 +31,23 @@
<p>This document describes the changes made to the Runtime_Tools
application.</p>
+<section><title>Runtime_Tools 1.8.5</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ When a big number of trace patterns are set by inviso the
+ Erlang VM could get unresponsive for several seconds.
+ This is now corrected.</p>
+ <p>
+ Own Id: OTP-9048 Aux Id: seq11480 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Runtime_Tools 1.8.4.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/runtime_tools/vsn.mk b/lib/runtime_tools/vsn.mk
index 8be4ae613b..6ed98f697e 100644
--- a/lib/runtime_tools/vsn.mk
+++ b/lib/runtime_tools/vsn.mk
@@ -1 +1 @@
-RUNTIME_TOOLS_VSN = 1.8.4.1
+RUNTIME_TOOLS_VSN = 1.8.5
diff --git a/lib/sasl/doc/src/notes.xml b/lib/sasl/doc/src/notes.xml
index e528af2522..7941e371a0 100644
--- a/lib/sasl/doc/src/notes.xml
+++ b/lib/sasl/doc/src/notes.xml
@@ -30,6 +30,39 @@
</header>
<p>This document describes the changes made to the SASL application.</p>
+<section><title>SASL 2.1.9.3</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Honor start type in .rel files when building relup files</p>
+ <p>
+ Previously, relup file always included an
+ application:start(Application, permanent) apply
+ instruction for every application that appear in the
+ UpTo/DowFrom release file, whatever their start type in
+ the release file.</p>
+ <p>
+ The new implementation fixes this bug by honoring the
+ start type according to the rel(5) format. If the start
+ type is none, no apply line is included in the relup. If
+ the start type is load, the relup includes instruction to
+ only load the application. Otherwise, the relup includes
+ an instruction to start the application to the according
+ type.</p>
+ <p>
+ The fix is implemented by adding a new parameter to the
+ add_application high level appup instruction. This new
+ parameter is documented in appup(5).</p>
+ <p>
+ Own Id: OTP-9097</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SASL 2.1.9.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/sasl/vsn.mk b/lib/sasl/vsn.mk
index d01a9bc4f1..8112d145dd 100644
--- a/lib/sasl/vsn.mk
+++ b/lib/sasl/vsn.mk
@@ -1 +1 @@
-SASL_VSN = 2.1.9.2
+SASL_VSN = 2.1.9.3
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 1d8380e881..52ee9c086a 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -31,7 +31,34 @@
<p>This document describes the changes made to the SSL application.
</p>
- <section><title>SSL 4.1.3</title>
+ <section><title>SSL 4.1.4</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Reduced memory footprint of an ssl connection.</p>
+ <p>
+ Handshake hashes, premaster secret and "public_key_info"
+ does not need to be saved when the connection has been
+ established. The own certificate is no longer duplicated
+ in the state.</p>
+ <p>
+ Own Id: OTP-9021</p>
+ </item>
+ <item>
+ <p>
+ Add the option {hibernate_after, int()} to ssl:connect
+ and ssl:listen</p>
+ <p>
+ Own Id: OTP-9106</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
+<section><title>SSL 4.1.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
<list>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 3512e194bc..7b1fda4cf9 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -52,13 +52,12 @@
-type option() :: socketoption() | ssloption() | transportoption().
-type socketoption() :: [{property(), term()}]. %% See gen_tcp and inet
-type property() :: atom().
-
-type ssloption() :: {verify, verify_type()} |
{verify_fun, {fun(), InitialUserState::term()}} |
{fail_if_no_peer_cert, boolean()} | {depth, integer()} |
- {cert, der_encoded()} | {certfile, path()} | {key, der_encoded()} |
- {keyfile, path()} | {password, string()} | {cacerts, [der_encoded()]} |
- {cacertfile, path()} | {dh, der_encoded()} | {dhfile, path()} |
+ {cert, Der::binary()} | {certfile, path()} | {key, Der::binary()} |
+ {keyfile, path()} | {password, string()} | {cacerts, [Der::binary()]} |
+ {cacertfile, path()} | {dh, Der::binary()} | {dhfile, path()} |
{ciphers, ciphers()} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} |
{reuse_session, fun()} | {hibernate_after, integer()|undefined}.
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index 8ae4d2332e..fb0ebac7d1 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2007-2011. 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
@@ -29,9 +29,8 @@
-include_lib("public_key/include/public_key.hrl").
-type algo_oid() :: ?'rsaEncryption' | ?'id-dsa'.
--type public_key() :: #'RSAPublicKey'{} | integer().
-type public_key_params() :: #'Dss-Parms'{} | term().
--type public_key_info() :: {algo_oid(), public_key(), public_key_params()}.
+-type public_key_info() :: {algo_oid(), #'RSAPublicKey'{} | integer() , public_key_params()}.
-record(session, {
session_id,
diff --git a/lib/stdlib/doc/src/notes.xml b/lib/stdlib/doc/src/notes.xml
index a8fe41f000..8cd499f960 100644
--- a/lib/stdlib/doc/src/notes.xml
+++ b/lib/stdlib/doc/src/notes.xml
@@ -30,6 +30,97 @@
</header>
<p>This document describes the changes made to the STDLIB application.</p>
+<section><title>STDLIB 1.17.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Two bugs in io:format for ~F.~Ps has been corrected. When
+ length(S) >= abs(F) > P, the precision P was incorrectly
+ ignored. When F == P > lenght(S) the result was
+ incorrectly left adjusted. Bug found by Ali Yakout who
+ also provided a fix.</p>
+ <p>
+ Own Id: OTP-8989 Aux Id: seq11741 </p>
+ </item>
+ <item>
+ <p>Fix exception generation in the io module
+ <p>
+ Some functions did not generate correct badarg exception
+ on a badarg exception.</p></p>
+ <p>
+ Own Id: OTP-9045</p>
+ </item>
+ <item>
+ <p>
+ Fixes to the dict and orddict module documentation</p>
+ <p>
+ Fixed grammar and one inconsistency (Key - Value instead
+ of key/value, since everywhere else the former is used).
+ (thanks to Filipe David Manana)</p>
+ <p>
+ Own Id: OTP-9083</p>
+ </item>
+ <item>
+ <p>
+ Add ISO week number calculation functions to the calendar
+ module in stdlib</p>
+ <p>
+ This new feature adds the missing week number function to
+ the calendar module of the stdlib application. The
+ implementation conforms to the ISO 8601 standard. The new
+ feature has been implemented tested and documented
+ (thanks to Imre Horvath).</p>
+ <p>
+ Own Id: OTP-9087</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Implement the 'MAY' clauses from RFC4648 regarding the
+ pad character to make mime_decode() and
+ mime_decode_to_string() functions more tolerant of badly
+ padded base64. The RFC is quoted below for easy
+ reference.</p>
+ <p>
+ "RFC4648 Section 3.3 with reference to MIME decoding:
+ Furthermore, such specifications MAY ignore the pad
+ character, "=", treating it as non-alphabet data, if it
+ is present before the end of the encoded data. If more
+ than the allowed number of pad characters is found at the
+ end of the string (e.g., a base 64 string terminated with
+ "==="), the excess pad characters MAY also be ignored."</p>
+ <p>
+ Own Id: OTP-9020</p>
+ </item>
+ <item>
+ <p>
+ Supervisors will no longer save start parameters for
+ temporary processes as they will not be restarted. In the
+ case of simple_one_for_one workers such as ssl-connection
+ processes this will substantial reduce the memory
+ footprint of the supervisor.</p>
+ <p>
+ Own Id: OTP-9064</p>
+ </item>
+ <item>
+ <p>
+ When running escript it is now possible to add the -n
+ flag and the escript will be compiled using +native.</p>
+ <p>
+ Own Id: OTP-9076</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>STDLIB 1.17.2.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index bb4b18cf9b..15b45d72f4 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -2,7 +2,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -757,7 +757,8 @@ record_fields([{typed,Expr,TypeInfo}|Fields]) ->
{atom, La, _} ->
case has_undefined(TypeInfo) of
false ->
- lift_unions(abstract(undefined, La), TypeInfo);
+ TypeInfo2 = maybe_add_paren(TypeInfo),
+ lift_unions(abstract(undefined, La), TypeInfo2);
true ->
TypeInfo
end
@@ -778,6 +779,11 @@ has_undefined({type,_,union,Ts}) ->
has_undefined(_) ->
false.
+maybe_add_paren({ann_type,L,T}) ->
+ {paren_type,L,[{ann_type,L,T}]};
+maybe_add_paren(T) ->
+ T.
+
term(Expr) ->
try normalise(Expr)
catch _:_R -> ret_err(?line(Expr), "bad attribute")
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index df4a20b833..66c80a45cb 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -558,17 +558,11 @@ record_field({typed_record_field,{record_field,_,F,Val},Type}, Hook) ->
Fl = lexpr(F, L, Hook),
Vl = typed(lexpr(Val, R, Hook), Type),
{list,[{cstep,[Fl,' ='],Vl}]};
-record_field({typed_record_field,Field,Type0}, Hook) ->
- Type = remove_undefined(Type0),
+record_field({typed_record_field,Field,Type}, Hook) ->
typed(record_field(Field, Hook), Type);
record_field({record_field,_,F}, Hook) ->
lexpr(F, 0, Hook).
-remove_undefined({type,L,union,[{atom,_,undefined}|T]}) ->
- {type,L,union,T};
-remove_undefined(T) -> % cannot happen
- T.
-
list({cons,_,H,T}, Es, Hook) ->
list(T, [H|Es], Hook);
list({nil,_}, Es, Hook) ->
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index 822886cb8a..bc811355ab 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -48,7 +48,7 @@
neg_indent/1,
otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1,
- otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1]).
+ otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1, otp_9147/1]).
%% Internal export.
-export([ehook/6]).
@@ -79,7 +79,7 @@ groups() ->
{attributes, [], [misc_attrs, import_export]},
{tickets, [],
[otp_6321, otp_6911, otp_6914, otp_8150, otp_8238,
- otp_8473, otp_8522, otp_8567, otp_8664]}].
+ otp_8473, otp_8522, otp_8567, otp_8664, otp_9147]}].
init_per_suite(Config) ->
Config.
@@ -1047,6 +1047,26 @@ otp_8664(Config) when is_list(Config) ->
ok.
+otp_9147(doc) ->
+ "OTP_9147. Create well-formed types when adding 'undefined'.";
+otp_9147(suite) -> [];
+otp_9147(Config) when is_list(Config) ->
+ FileName = filename('otp_9147.erl', Config),
+ C1 = <<"-module(otp_9147).\n"
+ "-export_type([undef/0]).\n"
+ "-record(undef, {f1 :: F1 :: a | b}).\n"
+ "-type undef() :: #undef{}.\n">>,
+ ?line ok = file:write_file(FileName, C1),
+ ?line {ok, _, []} =
+ compile:file(FileName, [return,'P',{outdir,?privdir}]),
+ PFileName = filename('otp_9147.P', Config),
+ ?line {ok, Bin} = file:read_file(PFileName),
+ %% The parentheses around "F1 :: a | b" are new (bugfix).
+ ?line true =
+ lists:member("-record(undef,{f1 :: undefined | (F1 :: a | b)}).",
+ string:tokens(binary_to_list(Bin), "\n")),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
compile(Config, Tests) ->
diff --git a/lib/stdlib/vsn.mk b/lib/stdlib/vsn.mk
index ac02e1f359..c0956030cf 100644
--- a/lib/stdlib/vsn.mk
+++ b/lib/stdlib/vsn.mk
@@ -1 +1 @@
-STDLIB_VSN = 1.17.3
+STDLIB_VSN = 1.17.4
diff --git a/lib/test_server/doc/src/notes.xml b/lib/test_server/doc/src/notes.xml
index ab329c399b..9c62b0fcf6 100644
--- a/lib/test_server/doc/src/notes.xml
+++ b/lib/test_server/doc/src/notes.xml
@@ -32,6 +32,43 @@
<file>notes.xml</file>
</header>
+<section><title>Test_Server 3.4.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Updated the ts*.config files to contain information
+ relevant to testing Erlang/OTP in an open source
+ environment.</p>
+ <p>
+ Own Id: OTP-9017</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Alpha release of Common Test Hooks (CTH). CTHs allow the
+ users of common test to abtract out common behaviours
+ from test suites in a much more elegant and flexible way
+ than was possible before. Note that the addition of this
+ feature may introduce minor changes in the undocumented
+ behaviour of the interface inbetween common_test and
+ test_server.</p>
+ <p>
+ *** POTENTIAL INCOMPATIBILITY ***</p>
+ <p>
+ Own Id: OTP-8851</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Test_Server 3.4.2</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index 4e293b76a7..b7c0987845 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1,2 +1,2 @@
-TEST_SERVER_VSN = 3.4.2
+TEST_SERVER_VSN = 3.4.3
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 5f9cecd6e4..118800e44a 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -30,6 +30,55 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.6.6.3</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Declare indentation options as "safe" in erlang-mode for
+ Emacs</p>
+ <p>
+ Emacs has a facility for setting options on a per-file
+ basis based on comments in the source file. By default,
+ all options are considered "unsafe", and the user is
+ queried before the variable is set. This patch declares
+ the variables erlang-indent-level, erlang-indent-guard
+ and erlang-argument-indent to be safe, if the value
+ specified in the source file is valid.</p>
+ <p>
+ Such declarations usually look like this:</p>
+ <p>
+ %% -*- erlang-indent-level: 2 -*-</p>
+ <p>
+ and appear on the first line of the file. (thanks to
+ Magnus Henoch)</p>
+ <p>
+ Own Id: OTP-9122</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>
+ Cover has been improved to take less memory and allow
+ parallel analysis of cover data. Data collection from
+ nodes is now done in parallel and it is now possible to
+ issue multiple analyse and analyse_to_file requests at
+ the same time. A new function call async_analyse_to_file
+ has also been introduced, see the documentation for more
+ details.</p>
+ <p>
+ Own Id: OTP-9043 Aux Id: seq11771 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.6.6.2</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 0c89b18065..83027cfaa6 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -1 +1 @@
-TOOLS_VSN = 2.6.6.2
+TOOLS_VSN = 2.6.6.3
diff --git a/lib/wx/doc/src/notes.xml b/lib/wx/doc/src/notes.xml
index 1493501ea4..3d27cf671b 100644
--- a/lib/wx/doc/src/notes.xml
+++ b/lib/wx/doc/src/notes.xml
@@ -31,6 +31,31 @@
<p>This document describes the changes made to the wxErlang
application.</p>
+<section><title>Wx 0.98.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Wx crashed if graphics could not be initiated, for
+ instance if DISPLAY was not available.</p> <p>Wx could
+ crash during startup, thanks Boris Muhmer for extra
+ ordinary testing.</p>
+ <p>
+ Own Id: OTP-9080</p>
+ </item>
+ <item>
+ <p>
+ Wx on MacOS X generated complains on stderr about certain
+ cocoa functions not beeing called from the "Main thread".
+ This is now corrected.</p>
+ <p>
+ Own Id: OTP-9081</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Wx 0.98.8</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/wx/vsn.mk b/lib/wx/vsn.mk
index dea0678063..7c440a7f5b 100644
--- a/lib/wx/vsn.mk
+++ b/lib/wx/vsn.mk
@@ -1 +1 @@
-WX_VSN = 0.98.8
+WX_VSN = 0.98.9
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index aa66cbec77..8542435456 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -31,6 +31,35 @@
<p>This document describes the changes made to the Xmerl application.</p>
+<section><title>Xmerl 1.2.8</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p> The function xmerl_lib:expand_content/1 is mainly for
+ expanding Simple XML, but can also handle xmerl records.
+ This patch fixes an omission that caused expand_content/1
+ to not maintain the parents list when expanding
+ #xmlElement{} records. (Thanks to Ulf Wiger) </p>
+ <p>
+ Own Id: OTP-9034</p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p> Removed some dialyzer warnings. </p>
+ <p>
+ Own Id: OTP-9074</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Xmerl 1.2.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/xmerl/vsn.mk b/lib/xmerl/vsn.mk
index a4d7efaee3..280ff10efa 100644
--- a/lib/xmerl/vsn.mk
+++ b/lib/xmerl/vsn.mk
@@ -1 +1 @@
-XMERL_VSN = 1.2.7
+XMERL_VSN = 1.2.8