diff options
-rw-r--r-- | erts/configure.in | 60 | ||||
-rw-r--r-- | lib/crypto/c_src/Makefile.in | 8 | ||||
-rw-r--r-- | lib/crypto/doc/src/licenses.xml | 2 | ||||
-rw-r--r-- | lib/edoc/src/edoc.hrl | 2 | ||||
-rw-r--r-- | lib/edoc/src/edoc_specs.erl | 6 | ||||
-rw-r--r-- | lib/edoc/src/edoc_tags.erl | 116 | ||||
-rw-r--r-- | lib/public_key/doc/src/Makefile | 3 | ||||
-rw-r--r-- | lib/public_key/doc/src/part.xml | 3 | ||||
-rw-r--r-- | lib/public_key/doc/src/public_key.xml | 24 | ||||
-rw-r--r-- | lib/public_key/doc/src/using_public_key.xml | 504 | ||||
-rw-r--r-- | lib/ssl/c_src/Makefile.in | 8 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 18 | ||||
-rwxr-xr-x | otp_build | 15 |
13 files changed, 670 insertions, 99 deletions
diff --git a/erts/configure.in b/erts/configure.in index e4c6a7852f..fac07f8b6a 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -3524,6 +3524,8 @@ dnl use "PATH/include" and "PATH/lib". AC_SUBST(SSL_INCLUDE) AC_SUBST(SSL_ROOT) AC_SUBST(SSL_LIBDIR) +AC_SUBST(SSL_CRYPTO_LIBNAME) +AC_SUBST(SSL_SSL_LIBNAME) AC_SUBST(SSL_CC_RUNTIME_LIBRARY_PATH) AC_SUBST(SSL_LD_RUNTIME_LIBRARY_PATH) AC_SUBST(SSL_DED_LD_RUNTIME_LIBRARY_PATH) @@ -3687,19 +3689,41 @@ case "$erl_xcomp_without_sysroot-$with_ssl" in CRYPTO_APP=crypto SSH_APP=ssh - AC_MSG_CHECKING(for OpenSSL >= 0.9.7 in standard locations) + SSL_CRYPTO_LIBNAME=crypto + SSL_SSL_LIBNAME=ssl + + AC_MSG_CHECKING(for OpenSSL >= 0.9.7 in standard locations) for rdir in $extra_dir /cygdrive/c/OpenSSL $std_ssl_locations; do dir="$erl_xcomp_sysroot$rdir" if test -f "$erl_xcomp_isysroot$rdir/include/openssl/opensslv.h"; then is_real_ssl=yes SSL_ROOT="$dir" if test "x$MIXED_CYGWIN" = "xyes" ; then - if test -f "$dir/lib/VC/ssleay32.lib" || \ - test -f "$dir/lib/VC/openssl.lib"; then + if test -f "$dir/lib/VC/libeay32.lib"; then + SSL_RUNTIME_LIBDIR="$rdir/lib/VC" + SSL_LIBDIR="$dir/lib/VC" + SSL_CRYPTO_LIBNAME=libeay32 + SSL_SSL_LIBNAME=ssleay32 + elif test -f "$dir/lib/VC/openssl.lib"; then SSL_RUNTIME_LIBDIR="$rdir/lib/VC" SSL_LIBDIR="$dir/lib/VC" - elif test -f "$dir/lib/ssleay32.lib" || \ - test -f "$dir/lib/openssl.lib"; then + elif test -f $dir/lib/VC/libeay32MD.lib; then + SSL_CRYPTO_LIBNAME=libeay32MD + SSL_SSL_LIBNAME=ssleay32MD + if test "x$enable_dynamic_ssl" = "xno" && \ + test -f $dir/lib/VC/static/libeay32MD.lib; then + SSL_RUNTIME_LIBDIR="$rdir/lib/VC/static" + SSL_LIBDIR="$dir/lib/VC/static" + else + SSL_RUNTIME_LIBDIR="$rdir/lib/VC" + SSL_LIBDIR="$dir/lib/VC" + fi + elif test -f "$dir/lib/libeay32.lib"; then + SSL_RUNTIME_LIBDIR="$rdir/lib" + SSL_LIBDIR="$dir/lib" + SSL_CRYPTO_LIBNAME=libeay32 + SSL_CRYPTO_LIBNAME=ssleay32 + elif test -f "$dir/lib/openssl.lib"; then SSL_RUNTIME_LIBDIR="$rdir/lib" SSL_LIBDIR="$dir/lib" else @@ -3859,8 +3883,32 @@ dnl so it is - be adoptable AC_MSG_ERROR(Invalid path to option --with-ssl=PATH) fi SSL_ROOT="$with_ssl" + SSL_CRYPTO_LIBNAME=crypto + SSL_SSL_LIBNAME=ssl if test "x$MIXED_CYGWIN" = "xyes" && test -d "$with_ssl/lib/VC"; then - SSL_LIBDIR="$with_ssl/lib/VC" + if test -f "$with_ssl/lib/VC/libeay32.lib"; then + SSL_LIBDIR="$with_ssl/lib/VC" + SSL_CRYPTO_LIBNAME=libeay32 + SSL_SSL_LIBNAME=ssleay32 + elif test -f "$with_ssl/lib/VC/openssl.lib"; then + SSL_LIBDIR="$with_ssl/lib/VC" + elif test -f $with_ssl/lib/VC/libeay32MD.lib; then + SSL_CRYPTO_LIBNAME=libeay32MD + SSL_SSL_LIBNAME=ssleay32MD + if test "x$enable_dynamic_ssl" = "xno" && \ + test -f $with_ssl/lib/VC/static/libeay32MD.lib; then + SSL_LIBDIR="$with_ssl/lib/VC/static" + else + SSL_LIBDIR="$with_ssl/lib/VC" + fi + elif test -f "$with_ssl/lib/libeay32.lib"; then + SSL_LIBDIR="$with_ssl/lib" + SSL_CRYPTO_LIBNAME=libeay32 + SSL_CRYPTO_LIBNAME=ssleay32 + else + # This probably wont work, but that's what the user said, so... + SSL_LIBDIR="$with_ssl/lib" + fi elif test "x$ac_cv_sizeof_void_p" = "x8"; then if test -f "$with_ssl/lib64/libcrypto.a"; then SSL_LIBDIR="$with_ssl/lib64" diff --git a/lib/crypto/c_src/Makefile.in b/lib/crypto/c_src/Makefile.in index 040adcfd09..3ace10403e 100644 --- a/lib/crypto/c_src/Makefile.in +++ b/lib/crypto/c_src/Makefile.in @@ -40,7 +40,7 @@ CFLAGS = $(DED_CFLAGS) # From erts/configure SSL_LIBDIR = @SSL_LIBDIR@ SSL_INCLUDE = @SSL_INCLUDE@ - +SSL_CRYPTO_LIBNAME = @SSL_CRYPTO_LIBNAME@ INCLUDES = $(SSL_INCLUDE) $(DED_INCLUDES) @@ -84,10 +84,10 @@ DYNAMIC_CRYPTO_LIB=@SSL_DYNAMIC_ONLY@ ifeq ($(DYNAMIC_CRYPTO_LIB),yes) SSL_DED_LD_RUNTIME_LIBRARY_PATH = @SSL_DED_LD_RUNTIME_LIBRARY_PATH@ -CRYPTO_LINK_LIB=$(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -lcrypto +CRYPTO_LINK_LIB=$(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -l$(SSL_CRYPTO_LIBNAME) else SSL_DED_LD_RUNTIME_LIBRARY_PATH= -CRYPTO_LINK_LIB=$(SSL_LIBDIR)/libcrypto.a +CRYPTO_LINK_LIB=$(SSL_LIBDIR)/lib$(SSL_CRYPTO_LIBNAME).a endif # ---------------------------------------------------- @@ -112,7 +112,7 @@ $(LIBDIR)/crypto$(TYPEMARKER).so: $(OBJS) $(LIBDIR)/crypto$(TYPEMARKER).dll: $(OBJS) $(INSTALL_DIR) $(LIBDIR) - $(LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(OBJS) -llibeay32 + $(LD) $(LDFLAGS) -o $@ $(SSL_DED_LD_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) $(OBJS) -l$(SSL_CRYPTO_LIBNAME) clean: ifeq ($(findstring win32,$(TARGET)), win32) diff --git a/lib/crypto/doc/src/licenses.xml b/lib/crypto/doc/src/licenses.xml index bae87a373e..e851655aa5 100644 --- a/lib/crypto/doc/src/licenses.xml +++ b/lib/crypto/doc/src/licenses.xml @@ -37,7 +37,7 @@ This chapter contains in extenso versions <title>OpenSSL License</title> <code type="none"> /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/lib/edoc/src/edoc.hrl b/lib/edoc/src/edoc.hrl index 43657b3b8f..31cf45ade9 100644 --- a/lib/edoc/src/edoc.hrl +++ b/lib/edoc/src/edoc.hrl @@ -37,7 +37,7 @@ -define(SOURCE_DIR, "src"). -define(EBIN_DIR, "ebin"). -define(EDOC_DIR, "doc"). --define(REPORT_MISSING_TYPE, false). +-define(REPORT_MISSING_TYPES, false). -include("edoc_doclet.hrl"). diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl index 45016ef85a..519ade726f 100644 --- a/lib/edoc/src/edoc_specs.erl +++ b/lib/edoc/src/edoc_specs.erl @@ -1,4 +1,4 @@ -% +%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1996-2011. All Rights Reserved. @@ -428,8 +428,8 @@ get_typevars(Ts) -> expand_records(Entries, TypeDefs, DT, Opts, File, Module) -> TypeList = [{type_name(T), T, not_seen} || T <- TypeDefs], true = ets:insert(DT, TypeList), - Warn = proplists:get_value(report_missing_type, Opts, - ?REPORT_MISSING_TYPE) =:= true, + Warn = proplists:get_value(report_missing_types, Opts, + ?REPORT_MISSING_TYPES) =:= true, P = #parms{tab = DT, warn = Warn, file = File, line = 0}, ExportedTypes = [Name || {export_type,Ts} <- Module#module.attributes, diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl index def39ee34c..8ee8f87b5f 100644 --- a/lib/edoc/src/edoc_tags.erl +++ b/lib/edoc/src/edoc_tags.erl @@ -331,8 +331,8 @@ parse_typedef(Data, Line, _Env, Where) -> NAs = length(As), case edoc_types:is_predefined(T, NAs) of true -> - case - edoc_types:is_new_predefined(T, NAs) + case + edoc_types:is_new_predefined(T, NAs) orelse edoc_types:is_predefined_otp_type(T, NAs) of false -> @@ -406,17 +406,20 @@ throw_error(L, D) -> -record(parms, {tab, warn, file, line}). -check_types(Entries0, Opts, File) -> - Entries = edoc_data:hidden_filter(Entries0, Opts), +check_types(Entries, Opts, File) -> Tags = edoc_data:get_all_tags(Entries), + TypeTags = [Tag || #tag{data = {#t_typedef{},_}}=Tag <- Tags], + Entries2 = edoc_data:hidden_filter(Entries, Opts), + Tags2 = edoc_data:get_all_tags(Entries2), + SpecTags = [Tag || #tag{data = #t_spec{}}=Tag <- Tags2], DT = ets:new(types, [bag]), _ = [add_type(DT, Name, As, File, Line) || #tag{line = Line, - data = {#t_typedef{name = Name, args = As},_}} <- Tags], - Warn = proplists:get_value(report_missing_type, Opts, - ?REPORT_MISSING_TYPE) =:= true, + data = {#t_typedef{name = Name, args = As},_}} <- TypeTags], + Warn = proplists:get_value(report_missing_types, Opts, + ?REPORT_MISSING_TYPES) =:= true, P = #parms{tab = DT, warn = Warn, file = File, line = 0}, - try check_types(Tags, P) + try check_types3(TypeTags++SpecTags, P, []) after true = ets:delete(DT) end. @@ -431,60 +434,64 @@ add_type(DT, Name, Args, File, Line) -> ets:insert(DT, {Name, NArgs}) end. -check_types([], _P)-> +check_types3([], _P, _Ls)-> ok; -check_types([Tag | Tags], P) -> - check_type(Tag, P, Tags). +check_types3([Tag | Tags], P, Ls) -> + check_type(Tag, P, Ls, Tags). -check_type(#tag{line = L, data = Data}, P0, Ts) -> +check_type(#tag{line = L, data = Data}, P0, Ls, Ts) -> P = P0#parms{line = L}, case Data of {#t_typedef{type = Type, defs = Defs},_} -> - check_type(Type, P, Defs++Ts); + check_type(Type, P, Ls, Defs++Ts); #t_spec{type = Type, defs = Defs} -> - check_type(Type, P, Defs++Ts); + LocalTypes = + [{N,length(Args)} || + #t_def{name = #t_type{name = N, args = Args}} <- Defs], + check_type(Type, P, LocalTypes, Defs), + check_types3(Ts, P, Ls); _-> - check_types(Ts, P0) + check_types3(Ts, P0, Ls) end; -check_type(#t_def{type = Type}, P, Ts) -> - check_type(Type, P, Ts); -check_type(#t_type{name = Name, args = Args}, P, Ts) -> - check_used_type(Name, Args, P), - check_types(Args++Ts, P); -check_type(#t_var{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_fun{args = Args, range = Range}, P, Ts) -> - check_type(Range, P, Args++Ts); -check_type(#t_tuple{types = Types}, P, Ts) -> - check_types(Types ++Ts, P); -check_type(#t_list{type = Type}, P, Ts) -> - check_type(Type, P, Ts); -check_type(#t_nil{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_paren{type = Type}, P, Ts) -> - check_type(Type, P, Ts); -check_type(#t_nonempty_list{type = Type}, P, Ts) -> - check_type(Type, P, Ts); -check_type(#t_atom{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_integer{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_integer_range{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_binary{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_float{}, P, Ts) -> - check_types(Ts, P); -check_type(#t_union{types = Types}, P, Ts) -> - check_types(Types++Ts, P); -check_type(#t_record{fields = Fields}, P, Ts) -> - check_types(Fields++Ts, P); -check_type(#t_field{type = Type}, P, Ts) -> - check_type(Type, P, Ts); -check_type(undefined, P, Ts) -> - check_types(Ts, P). - -check_used_type(#t_name{name = N, module = Mod}=Name, Args, P) -> +check_type(#t_def{type = Type}, P, Ls, Ts) -> + check_type(Type, P, Ls, Ts); +check_type(#t_type{name = Name, args = Args}, P, Ls, Ts) -> + check_used_type(Name, Args, P, Ls), + check_types3(Args++Ts, P, Ls); +check_type(#t_var{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_fun{args = Args, range = Range}, P, Ls, Ts) -> + check_type(Range, P, Ls, Args++Ts); +check_type(#t_tuple{types = Types}, P, Ls, Ts) -> + check_types3(Types ++Ts, P, Ls); +check_type(#t_list{type = Type}, P, Ls, Ts) -> + check_type(Type, P, Ls, Ts); +check_type(#t_nil{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_paren{type = Type}, P, Ls, Ts) -> + check_type(Type, P, Ls, Ts); +check_type(#t_nonempty_list{type = Type}, P, Ls, Ts) -> + check_type(Type, P, Ls, Ts); +check_type(#t_atom{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_integer{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_integer_range{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_binary{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_float{}, P, Ls, Ts) -> + check_types3(Ts, P, Ls); +check_type(#t_union{types = Types}, P, Ls, Ts) -> + check_types3(Types++Ts, P, Ls); +check_type(#t_record{fields = Fields}, P, Ls, Ts) -> + check_types3(Fields++Ts, P, Ls); +check_type(#t_field{type = Type}, P, Ls, Ts) -> + check_type(Type, P, Ls, Ts); +check_type(undefined, P, Ls, Ts) -> + check_types3(Ts, P, Ls). + +check_used_type(#t_name{name = N, module = Mod}=Name, Args, P, LocalTypes) -> NArgs = length(Args), TypeName = {Name, NArgs}, DT = P#parms.tab, @@ -493,6 +500,7 @@ check_used_type(#t_name{name = N, module = Mod}=Name, Args, P) -> orelse lists:member(TypeName, ets:lookup(DT, Name)) orelse edoc_types:is_predefined(N, NArgs) orelse edoc_types:is_predefined_otp_type(N, NArgs) + orelse lists:member(TypeName, LocalTypes) of true -> ok; diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile index 298c28a740..afb17399da 100644 --- a/lib/public_key/doc/src/Makefile +++ b/lib/public_key/doc/src/Makefile @@ -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 @@ -52,6 +52,7 @@ XML_CHAPTER_FILES = \ introduction.xml \ public_key_records.xml \ cert_records.xml \ + using_public_key.xml \ notes.xml BOOK_FILES = book.xml diff --git a/lib/public_key/doc/src/part.xml b/lib/public_key/doc/src/part.xml index c338a71613..ea3123b5bd 100644 --- a/lib/public_key/doc/src/part.xml +++ b/lib/public_key/doc/src/part.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE part SYSTEM "part.dtd"> <part xmlns:xi="http://www.w3.org/2001/XInclude"> @@ -38,5 +38,6 @@ <xi:include href="introduction.xml"/> <xi:include href="public_key_records.xml"/> <xi:include href="cert_records.xml"/> + <xi:include href="using_public_key.xml"/> </part> diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index c5f57214b1..d60d91cd83 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -43,7 +43,7 @@ <note><p>All records used in this manual <!-- except #policy_tree_node{} --> - are generated from asn1 specifications + are generated from ASN.1 specifications and are documented in the User's Guide. See <seealso marker="public_key_records">Public key records</seealso> and <seealso marker="cert_records">X.509 Certificate records</seealso>. @@ -150,12 +150,12 @@ <fsummary> Decodes a public key asn1 der encoded entity.</fsummary> <type> <v>Asn1Type = atom() -</v> - <d> Asn1 type present in the public_key applications + <d> ASN.1 type present in the public_key applications asn1 specifications.</d> <v>Der = der_encoded()</v> </type> <desc> - <p> Decodes a public key asn1 der encoded entity.</p> + <p> Decodes a public key ASN.1 der encoded entity.</p> </desc> </func> @@ -165,25 +165,25 @@ <type> <v>Asn1Type = atom()</v> <d> Asn1 type present in the public_key applications - asn1 specifications.</d> + ASN.1 specifications.</d> <v>Entity = term() - The erlang representation of <c> Asn1Type</c></v> </type> <desc> - <p> Encodes a public key entity with asn1 DER encoding.</p> + <p> Encodes a public key entity with ASN.1 DER encoding.</p> </desc> </func> <func> <name>pem_decode(PemBin) -> [pem_entry()]</name> <fsummary>Decode PEM binary data and return - entries as asn1 der encoded entities. </fsummary> + entries as ASN.1 der encoded entities. </fsummary> <type> <v>PemBin = binary()</v> <d>Example {ok, PemBin} = file:read_file("cert.pem").</d> </type> <desc> <p>Decode PEM binary data and return - entries as asn1 der encoded entities.</p> + entries as ASN.1 der encoded entities.</p> </desc> </func> @@ -258,13 +258,13 @@ <func> <name>pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{}</name> - <fsummary> Decodes an asn1 der encoded pkix x509 certificate.</fsummary> + <fsummary> Decodes an ASN.1 der encoded pkix x509 certificate.</fsummary> <type> <v>Cert = der_encoded()</v> </type> <desc> - <p>Decodes an asn1 der encoded pkix certificate. The otp option - will use the customized asn1 specification OTP-PKIX.asn1 for + <p>Decodes an ASN.1 der encoded pkix certificate. The otp option + will use the customized ASN.1 specification OTP-PKIX.asn1 for decoding and also recursively decode most of the standard parts.</p> </desc> @@ -276,7 +276,7 @@ certificate.</fsummary> <type> <v>Asn1Type = atom()</v> - <d>The asn1 type can be 'Certificate', 'OTPCertificate' or a subtype of either .</d> + <d>The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either .</d> </type> <desc> <p>Der encodes a pkix x509 certificate or part of such a @@ -394,7 +394,7 @@ signed or in the case that digest type is <c>none</c> it is the hashed value of "plain text" i.e. the digest.</d> <v>DigestType = rsa_digest_type() | dsa_digest_type()</v> - <v>Key = rsa_public_key() | dsa_public_key()</v> + <v>Key = rsa_private_key() | dsa_private_key()</v> </type> <desc> <p> Creates a digital signature.</p> diff --git a/lib/public_key/doc/src/using_public_key.xml b/lib/public_key/doc/src/using_public_key.xml new file mode 100644 index 0000000000..f0eaeb8654 --- /dev/null +++ b/lib/public_key/doc/src/using_public_key.xml @@ -0,0 +1,504 @@ +<?xml version="1.0" encoding="iso-8859-1" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2011</year><year>2011</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Using the public_key API</title> + <file>using_public_key.xml</file> + </header> + + <section> + <title>General information</title> + + <p> This chapter is dedicated to showing some + examples of how to use the public_key API. Keys and certificates + used in the following sections are generated only for the purpose + of testing the public key application.</p> + + <p>Note that some shell printouts, in the following examples, + have been abbreviated for increased readability.</p> + + </section> + + <section> + <title>PEM files</title> + <p> Pulic key data (keys, certificates etc) may be stored in PEM format. PEM files + comes from the Private Enhanced Mail Internet standard and has a + structure that looks like this:</p> + + <code><text> + -----BEGIN <SOMETHING>----- + <Attribute> : <Value> + <Base64 encoded DER data> + -----END <SOMETHING>----- + <text></code> + + <p>A file can contain several BEGIN/END blocks. Text lines between + blocks are ignored. Attributes, if present, are currently ignored except + for <c>Proc-Type</c> and <c>DEK-Info</c> that are used when the DER data is + encrypted.</p> + + <section> + <title>DSA private key</title> + + <p>Note file handling is not done by the public_key application. </p> + <code>1> {ok, PemBin} = file:read_file("dsa.pem"). +{ok,<<"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...>>}</code> + + <p>This PEM file only has one entry a private DSA key.</p> + <code>2> [DSAEntry] = public_key:pem_decode(PemBin). +[{'DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183, + 179,230,217,37,99,144,157,21,228,204, + 162,207,61,246,...>>, + not_encrypted}]</code> + + <code>3> Key = public_key:pem_entry_decode(DSAEntry). +#'DSAPrivateKey'{version = 0, + p = 12900045185019966618...6593, + q = 1216700114794736143432235288305776850295620488937, + g = 10442040227452349332...47213, + y = 87256807980030509074...403143, + x = 510968529856012146351317363807366575075645839654}</code> + </section> + + <section> + <title>RSA private key encrypted with a password.</title> + + <code>1> {ok, PemBin} = file:read_file("rsa.pem"). +{ok,<<"Bag Attribut"...>>}</code> + + <p>This PEM file only has one entry a private RSA key.</p> + <code>2>[RSAEntry] = public_key:pem_decode(PemBin). +[{'RSAPrivateKey',<<224,108,117,203,152,40,15,77,128,126, + 221,195,154,249,85,208,202,251,109, + 119,120,57,29,89,19,9,...>>, + {"DES-EDE3-CBC",<<"k�e��p�L">>}}] + + </code> + + <p>In this example the password is "abcd1234".</p> + <code>3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234"). + #'RSAPrivateKey'{version = 'two-prime', + modulus = 1112355156729921663373...2737107, + publicExponent = 65537, + privateExponent = 58064406231183...2239766033, + prime1 = 11034766614656598484098...7326883017, + prime2 = 10080459293561036618240...77738643771, + exponent1 = 77928819327425934607...22152984217, + exponent2 = 36287623121853605733...20588523793, + coefficient = 924840412626098444...41820968343, + otherPrimeInfos = asn1_NOVALUE}</code> + </section> + + <section> + <title>X509 Certificates</title> + + <code>1> {ok, PemBin} = file:read_file("cacerts.pem"). +{ok,<<"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...>>}</code> + + <p>This file includes two certificates</p> + <code>2> [CertEntry1, CertEntry2] = public_key:pem_decode(PemBin). +[{'Certificate',<<48,130,2,238,48,130,2,87,160,3,2,1,2,2, + 9,0,230,145,97,214,191,2,120,150,48,13, + ...>>, + not_encrypted}, + {'Certificate',<<48,130,3,200,48,130,3,49,160,3,2,1,2,2,1, + 1,48,13,6,9,42,134,72,134,247,...>>>, + not_encrypted}]</code> + + <p>Certificates may of course be decoded as usual ... </p> + <code>2> Cert = public_key:pem_entry_decode(CertEntry1). +#'Certificate'{ + tbsCertificate = + #'TBSCertificate'{ + version = v3,serialNumber = 16614168075301976214, + signature = + #'AlgorithmIdentifier'{ + algorithm = {1,2,840,113549,1,1,5}, + parameters = <<5,0>>}, + issuer = + {rdnSequence, + [[#'AttributeTypeAndValue'{ + type = {2,5,4,3}, + value = <<19,8,101,114,108,97,110,103,67,65>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,11}, + value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,10}, + value = <<19,11,69,114,105,99,115,115,111,110,32,65,66>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,7}, + value = <<19,9,83,116,111,99,107,104,111,108,109>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,6}, + value = <<19,2,83,69>>}], + [#'AttributeTypeAndValue'{ + type = {1,2,840,113549,1,9,1}, + value = <<22,22,112,101,116,101,114,64,101,114,...>>}]]}, + validity = + #'Validity'{ + notBefore = {utcTime,"080109082929Z"}, + notAfter = {utcTime,"080208082929Z"}}, + subject = + {rdnSequence, + [[#'AttributeTypeAndValue'{ + type = {2,5,4,3}, + value = <<19,8,101,114,108,97,110,103,67,65>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,11}, + value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,10}, + value = <<19,11,69,114,105,99,115,115,111,110,32,...>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,7}, + value = <<19,9,83,116,111,99,107,104,111,108,...>>}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,6}, + value = <<19,2,83,69>>}], + [#'AttributeTypeAndValue'{ + type = {1,2,840,113549,1,9,1}, + value = <<22,22,112,101,116,101,114,64,...>>}]]}, + subjectPublicKeyInfo = + #'SubjectPublicKeyInfo'{ + algorithm = + #'AlgorithmIdentifier'{ + algorithm = {1,2,840,113549,1,1,1}, + parameters = <<5,0>>}, + subjectPublicKey = + {0,<<48,129,137,2,129,129,0,203,209,187,77,73,231,90,...>>}}, + issuerUniqueID = asn1_NOVALUE, + subjectUniqueID = asn1_NOVALUE, + extensions = + [#'Extension'{ + extnID = {2,5,29,19}, + critical = true, + extnValue = [48,3,1,1,255]}, + #'Extension'{ + extnID = {2,5,29,15}, + critical = false, + extnValue = [3,2,1,6]}, + #'Extension'{ + extnID = {2,5,29,14}, + critical = false, + extnValue = [4,20,27,217,65,152,6,30,142|...]}, + #'Extension'{ + extnID = {2,5,29,17}, + critical = false, + extnValue = [48,24,129,22,112,101,116,101|...]}]}, + signatureAlgorithm = + #'AlgorithmIdentifier'{ + algorithm = {1,2,840,113549,1,1,5}, + parameters = <<5,0>>}, + signature = + {0, + <<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120, + 165,2,52,196,195,109,167,192,...>>}} +</code> + + <p> Parts of certificates can be decoded with + public_key:der_decode/2 using that parts ASN.1 type. + Although application specific certificate + extension requires application specific ASN.1 decode/encode-functions. + Example, the first value of the rdnSequence above is of ASN.1 type + 'X520CommonName'. ({2,5,4,3} = ?id-at-commonName)</p> + + <code>public_key:der_decode('X520CommonName', <<19,8,101,114,108,97,110,103,67,65>>). +{printableString,"erlangCA"}</code> + + <p>... but certificates can also be decode using the pkix_decode_cert/2 that + can customize and recursively decode standard parts of a certificate.</p> + <code>3>{_, DerCert, _} = CertEntry1.</code> + <code>4> public_key:pkix_decode_cert(DerCert, otp). +#'OTPCertificate'{ + tbsCertificate = + #'OTPTBSCertificate'{ + version = v3,serialNumber = 16614168075301976214, + signature = + #'SignatureAlgorithm'{ + algorithm = {1,2,840,113549,1,1,5}, + parameters = 'NULL'}, + issuer = + {rdnSequence, + [[#'AttributeTypeAndValue'{ + type = {2,5,4,3}, + value = {printableString,"erlangCA"}}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,11}, + value = {printableString,"Erlang OTP"}}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,10}, + value = {printableString,"Ericsson AB"}}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,7}, + value = {printableString,"Stockholm"}}], + [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}], + [#'AttributeTypeAndValue'{ + type = {1,2,840,113549,1,9,1}, + value = "[email protected]"}]]}, + validity = + #'Validity'{ + notBefore = {utcTime,"080109082929Z"}, + notAfter = {utcTime,"080208082929Z"}}, + subject = + {rdnSequence, + [[#'AttributeTypeAndValue'{ + type = {2,5,4,3}, + value = {printableString,"erlangCA"}}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,11}, + value = {printableString,"Erlang OTP"}}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,10}, + value = {printableString,"Ericsson AB"}}], + [#'AttributeTypeAndValue'{ + type = {2,5,4,7}, + value = {printableString,"Stockholm"}}], + [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}], + [#'AttributeTypeAndValue'{ + type = {1,2,840,113549,1,9,1}, + value = "[email protected]"}]]}, + subjectPublicKeyInfo = + #'OTPSubjectPublicKeyInfo'{ + algorithm = + #'PublicKeyAlgorithm'{ + algorithm = {1,2,840,113549,1,1,1}, + parameters = 'NULL'}, + subjectPublicKey = + #'RSAPublicKey'{ + modulus = + 1431267547247997...37419, + publicExponent = 65537}}, + issuerUniqueID = asn1_NOVALUE, + subjectUniqueID = asn1_NOVALUE, + extensions = + [#'Extension'{ + extnID = {2,5,29,19}, + critical = true, + extnValue = + #'BasicConstraints'{ + cA = true,pathLenConstraint = asn1_NOVALUE}}, + #'Extension'{ + extnID = {2,5,29,15}, + critical = false, + extnValue = [keyCertSign,cRLSign]}, + #'Extension'{ + extnID = {2,5,29,14}, + critical = false, + extnValue = [27,217,65,152,6,30,142,132,245|...]}, + #'Extension'{ + extnID = {2,5,29,17}, + critical = false, + extnValue = [{rfc822Name,"[email protected]"}]}]}, + signatureAlgorithm = + #'SignatureAlgorithm'{ + algorithm = {1,2,840,113549,1,1,5}, + parameters = 'NULL'}, + signature = + {0, + <<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120, + 165,2,52,196,195,109,167,192,...>>}} +</code> + + <p>This call is equivalent to public_key:pem_entry_decode(CertEntry1)</p> + <code>5> public_key:pkix_decode_cert(DerCert, plain). +#'Certificate'{ ...} +</code> + </section> + + <section> + <title>Encoding public key data to PEM format</title> + + <p>If you have public key data and and want to create a PEM file + you can do that by calling the functions + public_key:pem_entry_encode/2 and pem_encode/1 and then saving the + result to a file. For example assume you have PubKey = + 'RSAPublicKey'{} then you can create a PEM-"RSA PUBLIC KEY" file + (ASN.1 type 'RSAPublicKey') or a PEM-"PUBLIC KEY" file + ('SubjectPublicKeyInfo' ASN.1 type).</p> + + <p> The second element of the PEM-entry will be the ASN.1 DER encoded + key data.</p> + + <code>1> PemEntry = public_key:pem_entry_encode('RSAPublicKey', RSAPubKey). +{'RSAPublicKey', <<48,72,...>>, not_encrypted} + +2> PemBin = public_key:pem_encode([PemEntry]). +<<"-----BEGIN RSA PUBLIC KEY-----\nMEgC...>> + +3> file:write_file("rsa_pub_key.pem", PemBin). +ok</code> + + <p> or </p> + + <code>1> PemBin = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey). +{'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted} + +2> PemBin = public_key:pem_encode([PemEntry]). +<<"-----BEGIN PUBLIC KEY-----\nMFw...>> + +3> file:write_file("pub_key.pem", PemBin). +ok</code> + + </section> +</section> + +<section> + <title>RSA public key cryptography </title> + <p> Suppose you have PrivateKey = #'RSAPrivateKey{}' and the + plaintext Msg = binary() and the corresponding public key + PublicKey = #'RSAPublicKey'{} then you can do the following. + Note that you normally will only do one of the encrypt or + decrypt operations and the peer will do the other. + </p> + + <p>Encrypt with the private key </p> + <code>RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey), +Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),</code> + + <p>Encrypt with the public key </p> + <code>RsaEncrypted = public_key:encrypt_public(Msg, PublicKey), +Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey),</code> + </section> + + <section> + <title>Digital signatures</title> + + <p> Suppose you have PrivateKey = #'RSAPrivateKey{}'or + #'DSAPrivateKey'{} and the plaintext Msg = binary() and the + corresponding public key PublicKey = #'RSAPublicKey'{} or + {integer(), #'DssParams'{}} then you can do the following. Note + that you normally will only do one of the sign or verify operations + and the peer will do the other. </p> + + <code>Signature = public_key:sign(Msg, sha, PrivateKey), +true = public_key:verify(Msg, sha, Signature, PublicKey),</code> + + <p>It might be appropriate to calculate the message digest before + calling sign or verify and then you can use the none as second + argument.</p> + + <code>Digest = crypto:sha(Msg), +Signature = public_key:sign(Digest, none, PrivateKey), +true = public_key:verify(Digest, none, Signature, PublicKey), + </code> + + </section> + + <section> + <title>SSH files</title> + + <p>SSH typically uses PEM files for private keys but has its + own file format for storing public keys. The erlang public_key + application can be used to parse the content of SSH public key files.</p> + + <section> + <title> RFC 4716 SSH public key files </title> + + <p>RFC 4716 SSH files looks confusingly like PEM files, + but there are some differences.</p> + <code>1> {ok, SshBin} = file:read_file("ssh2_rsa_pub"). +{ok, <<"---- BEGIN SSH2 PUBLIC KEY ----\nAAAA"...>>}</code> + + <p>This is equivalent to calling public_key:ssh_decode(SshBin, rfc4716_public_key). + </p> + <code>2> public_key:ssh_decode(SshBin, public_key). +[{#'RSAPublicKey'{modulus = 794430685...91663, + publicExponent = 35}, []}] +</code> + + </section> + + <section> + <title> Openssh public key format </title> + <code>1> {ok, SshBin} = file:read_file("openssh_dsa_pub"). +{ok,<<"ssh-dss AAAAB3Nza"...>>}</code> + + <p>This is equivalent to calling public_key:ssh_decode(SshBin, openssh_public_key). + </p> + <code>2> public_key:ssh_decode(SshBin, public_key). +[{{15642692...694280725, + #'Dss-Parms'{p = 17291273936...696123221, + q = 1255626590179665817295475654204371833735706001853, + g = 10454211196...480338645}}, + [{comment,"dhopson@VMUbuntu-DSH"}]}] +</code> + </section> + + <section> + <title> Known hosts - openssh format</title> + + <code>1> {ok, SshBin} = file:read_file("known_hosts"). +{ok,<<"hostname.domain.com,192.168.0.1 ssh-rsa AAAAB...>>}</code> + + <p>Returns a list of public keys and their related attributes + each pair of key and attributes corresponds to one entry in + the known hosts file.</p> + + <code>2> public_key:ssh_decode(SshBin, known_hosts). +[{#'RSAPublicKey'{modulus = 1498979460408...72721699, + publicExponent = 35}, + [{hostnames,["hostname.domain.com","192.168.0.1"]}]}, + {#'RSAPublicKey'{modulus = 14989794604088...2721699, + publicExponent = 35}, + [{comment,"[email protected]"}, + {hostnames,["|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA="]}]}] +</code> + </section> + + <section> + <title> Authorized keys - openssh format</title> + + <code>1> {ok, SshBin} = file:read_file("auth_keys"). +{ok, <<"command=\"dump /home\",no-pty,no-port-forwarding ssh-rsa AAA...>>}</code> + + <p>Returns a list of public keys and their related attributes + each pair of key and attributes corresponds to one entry in + the authorized key file.</p> + + <code>2> public_key:ssh_decode(SshBin, auth_keys). +[{#'RSAPublicKey'{modulus = 794430685...691663, + publicExponent = 35}, + [{comment,"dhopson@VMUbuntu-DSH"}, + {options,["command=\"dump/home\"","no-pty", + "no-port-forwarding"]}]}, + {{1564269258491...607694280725, + #'Dss-Parms'{p = 17291273936185...763696123221, + q = 1255626590179665817295475654204371833735706001853, + g = 10454211195705...60511039590076780999046480338645}}, + [{comment,"dhopson@VMUbuntu-DSH"}]}] +</code> + </section> + + <section> + <title> Creating an SSH file from public key data </title> + + <p>If you got a public key <c>PubKey</c> and a related list of + attributes <c>Attributes</c> as returned + by ssh_decode/2 you can create a new ssh file for example</p> + <code>N> SshBin = public_key:ssh_encode([{PubKey, Attributes}], openssh_public_key), +<<"ssh-rsa "...>> +N+1> file:write_file("id_rsa.pub", SshBin). +ok</code> + </section> + </section> +</chapter> diff --git a/lib/ssl/c_src/Makefile.in b/lib/ssl/c_src/Makefile.in index 49a209f2eb..da716f7c40 100644 --- a/lib/ssl/c_src/Makefile.in +++ b/lib/ssl/c_src/Makefile.in @@ -28,6 +28,8 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # ---------------------------------------------------- SSL_LIBDIR = @SSL_LIBDIR@ SSL_INCLUDE = @SSL_INCLUDE@ +SSL_CRYPTO_LIBNAME = @SSL_CRYPTO_LIBNAME@ +SSL_SSL_LIBNAME = @SSL_SSL_LIBNAME@ # ---------------------------------------------------- # Application version @@ -134,7 +136,7 @@ ifeq ($(findstring @,$(SSL_CC_RUNTIME_LIBRARY_PATH)),@) SSL_CC_RUNTIME_LIBRARY_PATH = $(CC_R_OPT) endif -SSL_LINK_LIB=-L$(SSL_LIBDIR) -lssl -lcrypto +SSL_LINK_LIB=-L$(SSL_LIBDIR) -l$(SSL_SSL_LIBNAME) -l$(SSL_CRYPTO_LIBNAME) else # not dynamic crypto lib (default from R11B-5) NEED_KERBEROS=@SSL_LINK_WITH_KERBEROS@ @@ -142,7 +144,7 @@ NEED_ZLIB=@SSL_LINK_WITH_ZLIB@ SSL_MAKEFILE = CC_R_OPT = SSL_CC_RUNTIME_LIBRARY_PATH= -SSL_LINK_LIB = $(SSL_LIBDIR)/libssl.a $(SSL_LIBDIR)/libcrypto.a +SSL_LINK_LIB = $(SSL_LIBDIR)/lib$(SSL_SSL_LIBNAME).a $(SSL_LIBDIR)/lib$(SSL_CRYPTO_LIBNAME).a ifeq ($(NEED_KERBEROS),yes) SSL_LINK_LIB += @STATIC_KERBEROS_LIBS@ endif @@ -175,7 +177,7 @@ $(BINDIR)/ssl_esock: $(OBJS) # Win32/Cygwin $(BINDIR)/ssl_esock.exe: $(OBJS) - $(LD) $(SSL_CC_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -o $@ $^ -lwsock32 -llibeay32 -lssleay32 + $(LD) $(SSL_CC_RUNTIME_LIBRARY_PATH) -L$(SSL_LIBDIR) -o $@ $^ -lwsock32 -l$(SSL_CRYPTO_LIBNAME) -l$(SSL_SSL_LIBNAME) # Unix only, and only when linking statically $(SSL_MAKEFILE): diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 0a86e9bd29..2c452837f8 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -941,17 +941,23 @@ handle_info({Protocol, _, Data}, StateName, handle_info({CloseTag, Socket}, _StateName, #state{socket = Socket, close_tag = CloseTag, - negotiated_version = Version, host = Host, - port = Port, socket_options = Opts, + negotiated_version = Version, + socket_options = Opts, user_application = {_Mon,Pid}, from = From, - role = Role, session = Session} = State) -> - %% Debug option maybe, the user do NOT want to see these in their logs - %% error_logger:info_report("SSL: Peer did not send close notify alert."), + role = Role} = State) -> + %% Note that as of TLS 1.1, + %% failure to properly close a connection no longer requires that a + %% session not be resumed. This is a change from TLS 1.0 to conform + %% with widespread implementation practice. case Version of {1, N} when N >= 1 -> ok; _ -> - invalidate_session(Role, Host, Port, Session) + %% As invalidate_sessions here causes performance issues, + %% we will conform to the widespread implementation + %% practice and go aginst the spec + %%invalidate_session(Role, Host, Port, Session) + ok end, alert_user(Opts#socket_options.active, Pid, From, ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), Role), @@ -186,15 +186,16 @@ set_config_flags () if target_contains free_source; then CONFIG_FLAGS="$CONFIG_FLAGS --host=$TARGET" fi + # Link SSL static for all binary distributions if not overridden + # Even for win32 starting with R14B03 + XX=`echo $* | grep -v dynamic-ssl-lib` + if [ "$*" = "$XX" ]; then + CONFIG_FLAGS="--disable-dynamic-ssl-lib $CONFIG_FLAGS" + fi if target_contains win32; then - CONFIG_FLAGS="--build=$BUILDSYS build_alias=win32 --host=win32 --target=win32 $CONFIG_FLAGS" - else - # Link SSL static for all binary distributions if not overridden - XX=`echo $* | grep -v dynamic-ssl-lib` - if [ "$*" = "$XX" ]; then - CONFIG_FLAGS="--disable-dynamic-ssl-lib $CONFIG_FLAGS" - fi + CONFIG_FLAGS="--build=$BUILDSYS build_alias=win32 --host=win32 --target=win32 $CONFIG_FLAGS" fi + if [ "x$OVERRIDE_CONFIG_CACHE" = "x" ]; then CONFIG_FLAGS="$CONFIG_FLAGS --cache-file=/dev/null" else |