diff options
Diffstat (limited to 'lib/ssl')
-rw-r--r-- | lib/ssl/doc/src/ssl.xml | 285 | ||||
-rw-r--r-- | lib/ssl/doc/src/ssl_distribution.xml | 10 | ||||
-rw-r--r-- | lib/ssl/doc/src/ssl_protocol.xml | 12 | ||||
-rw-r--r-- | lib/ssl/doc/src/ssl_session_cache_api.xml | 20 | ||||
-rw-r--r-- | lib/ssl/src/ssl.erl | 6 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 10 | ||||
-rw-r--r-- | lib/ssl/src/ssl_internal.hrl | 1 | ||||
-rw-r--r-- | lib/ssl/test/ssl_basic_SUITE.erl | 14 |
8 files changed, 223 insertions, 135 deletions
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index def61bcf03..0f3054aec3 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -69,10 +69,13 @@ </p> <p> <c>ssloption() = {verify, verify_type()} | + {verify_fun, {fun(), term()}} | {fail_if_no_peer_cert, boolean()} {depth, integer()} | - {certfile, path()} | {keyfile, path()} | {password, string()} | - {cacertfile, path()} | {dhfile, path()} | {ciphers, ciphers()} | + {cert, der_bin()}| {certfile, path()} | + {key, der_bin()} | {keyfile, path()} | {password, string()} | + {cacerts, [der_bin()]} | {cacertfile, path()} | + |{dh, der_bin()} | {dhfile, path()} | {ciphers, ciphers()} | {ssl_imp, ssl_imp()} | {reuse_sessions, boolean()} | {reuse_session, fun()} </c></p> @@ -91,6 +94,8 @@ <p><c>verify_type() = verify_none | verify_peer</c></p> <p><c>path() = string() - representing a file path.</c></p> + + <p><c>der_bin() = binary() -Asn1 DER encoded entity as an erlang binary.</c></p> <p><c>host() = hostname() | ipaddress()</c></p> @@ -121,115 +126,52 @@ <p><c>ssl_imp() = new | old - default is new.</c></p> </section> - -<section> - <title>SSL OPTION DESCRIPTIONS</title> + + <section> + <title>SSL OPTION DESCRIPTIONS - COMMON for SERVER and CLIENT</title> + + <p>Options described here are options that are have the same + meaning in the client and the server. + </p> <taglist> - <tag>{verify, verify_type()}</tag> - <item> If <c>verify_none</c> is specified x509-certificate - path validation errors at the client side - will not automatically cause the connection to fail, as - it will if the verify type is <c>verify_peer</c>. See also - the option verify_fun. - Servers only do the path validation if <c>verify_peer</c> is set to - true, as it then will - send a certificate request to - the client (this message is not sent if the verify option is - <c>verify_none</c>) and you may then also want to specify - the option <c>fail_if_no_peer_cert</c>. - </item> - <tag>{fail_if_no_peer_cert, boolean()}</tag> - <item>Used together with {verify, verify_peer} by a ssl server. - If set to true, - the server will fail if the client does not have a certificate - to send, e.i sends a empty certificate, if set to false it will - only fail if the client sends a invalid certificate (an empty - certificate is considered valid). - </item> + <tag>{cert, der_bin()}</tag> + <item> The DER encoded users certificate. If this option + is supplied it will override the certfile option.</item> - <tag>{verify_fun, fun(ErrorList) -> boolean()}</tag> - <item>Used by the ssl client to determine if - x509-certificate path validations errors are acceptable or - if the connection should fail. Defaults to: - -<code> -fun(ErrorList) -> - case lists:foldl(fun({bad_cert,unknown_ca}, Acc) -> - Acc; - (Other, Acc) -> - [Other | Acc] - end, [], ErrorList) of - [] -> - true; - [_|_] -> - false - end -end -</code> - I.e. by default if the only error found was that the CA-certificate - holder was unknown this will be accepted. - - Possible errors in the error list are: - {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, - {bad_cert, invalid_signature}, {bad_cert, name_not_permitted}, - {bad_cert, unknown_ca}, - {bad_cert, cert_expired}, {bad_cert, invalid_issuer}, - {bad_cert, invalid_signature}, {bad_cert, name_not_permitted}, - {bad_cert, cert_revoked} (not implemented yet), - {bad_cert, unknown_critical_extension} or {bad_cert, term()} - </item> - + <tag>{certfile, path()}</tag> + <item>Path to a file containing the user's certificate.</item> - <tag>{validate_extensions_fun, fun()}</tag> - <item> - This options makes it possible to supply a fun to validate - possible application specific certificate extensions - during the certificat path validation. This option - will be better documented onec the public_key API is more - mature. - </item> + <tag>{key, der_bin()}</tag> + <item> The DER encoded users private key. If this option + is supplied it will override the keyfile option.</item> - <tag>{depth, integer()}</tag> - <item>Specifies the maximum - verification depth, i.e. how far in a chain of certificates the - verification process can proceed before the verification is - considered to fail. Peer certificate = 0, CA certificate = 1, - higher level CA certificate = 2, etc. The value 2 thus means - that a chain can at most contain peer cert, CA cert, next CA - cert, and an additional CA cert. The default value is 1. - </item> - - <tag>{certfile, path()}</tag> - <item>Path to a file containing the - user's certificate. Optional for clients but note - that some servers requires that the client can certify - itself. </item> <tag>{keyfile, path()}</tag> <item>Path to file containing user's private PEM encoded key. As PEM-files may contain several entries this option defaults to the same file as given by certfile option.</item> + <tag>{password, string()}</tag> <item>String containing the user's password. Only used if the private keyfile is password protected. </item> + + <tag>{cacerts, [der_bin()]}</tag> + <item> The DER encoded trusted certificates. If this option + is supplied it will override the cacertfile option.</item> + <tag>{cacertfile, path()}</tag> <item>Path to file containing PEM encoded CA certificates (trusted certificates used for verifying a peer certificate). May be omitted if you do not want to verify the peer.</item> - <tag>{dhfile, path()}</tag> - <item>Path to file containing PEM encoded Diffie Hellman parameters, - for the server to use if a cipher suite using Diffie Hellman key exchange - is negotiated. If not specified hardcode parameters will be used. - </item> - <tag>{ciphers, ciphers()}</tag> - <item>The function <c>ciphers_suites/0</c> can - be used to find all available ciphers. + <item>The cipher suites that should be supported. The function + <c>ciphers_suites/0</c> can be used to find all available + ciphers. </item> <tag>{ssl_imp, ssl_imp()}</tag> @@ -237,13 +179,152 @@ end new. </item> + <tag>{secure_renegotiate, boolean()}</tag> + <item>Specifies if to reject renegotiation attempt that does + not live up to RFC 5746. By default secure_renegotiate is + set to false i.e. secure renegotiation will be used if possible + but it will fallback to unsecure renegotiation if the peer + does not support RFC 5746. + </item> + + <tag>{depth, integer()}</tag> + <item>Specifies the maximum + verification depth, i.e. how far in a chain of certificates the + verification process can proceed before the verification is + considered to fail. Peer certificate = 0, CA certificate = 1, + higher level CA certificate = 2, etc. The value 2 thus means + that a chain can at most contain peer cert, CA cert, next CA + cert, and an additional CA cert. The default value is 1. + </item> + + <tag>{verify_fun, {Verifyfun :: fun(), InitialUserState :: term()}}</tag> + <item> + <p>The verification fun should be defined as:</p> + + <code> + fun(OtpCert :: #'OtpCertificate'{}, + Event :: {bad_cert, Reason :: atom()} | + {extension, #'Extension'{}}, InitialUserState :: term()) -> + {valid, UserState :: term()} | {fail, Reason :: term()} | + {unknown, UserState :: term()}. + </code> + + <p>The verify fun will be called during the X509-path + validation when an error or an extension unknown to the ssl + application is encountered. See + <seealso marker="public_key:application">public_key(3)</seealso> + for definition of #'OtpCertificate'{} and #'Extension'{}.</p> + + <p>If the verify callback fun returns {fail, Reason}, the + verification process is immediately stopped and an alert is + sent to the peer and the TLS/SSL handshake is terminated. If + the verify callback fun returns {valid, UserState}, the + verification process is continued. If the verify callback fun + always returns {valid, UserState}, the TLS/SSL handshake will + not be terminated with respect to verification failures and + the connection will be established. If called with an + extension unknown to the user application the return value + {unknown, UserState} should be used.</p> + + <p>The default verify_fun option in verify_peer mode:</p> + + <code> + {fun(_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []} + </code> + + <p>The default verify_fun option in verify_none mode:</p> + + <code> + {fun(_,{bad_cert, unknown_ca}, UserState) -> + {valid, UserState}; + (_,{bad_cert, _} = Reason, _) -> + {fail, Reason}; + (_,{extension, _}, UserState) -> + {unknown, UserState} + end, []} + </code> + + <p> Possible path validation errors: + {bad_cert, cert_expired}, + {bad_cert, invalid_issuer}, + {bad_cert, invalid_signature}, + {bad_cert, unknown_ca}, + {bad_cert, name_not_permitted}, + {bad_cert, missing_basic_constraint}, + {bad_cert, invalid_key_usage}, + {bad_cert, invalid_subject_altname}</p> + </item> + + </taglist> + + </section> + + <section> + <title>SSL OPTION DESCRIPTIONS - CLIENT SIDE</title> + + <p>Option described here are client specific or has a slightly different + meaning in the client than in the server.</p> + + <taglist> + <tag>{verify, verify_type()}</tag> + <item> In verify_none mode the x509-path validation error {bad_cert, unknown_ca} + will automatically be accepted. See also the verify_fun option. + </item> + <tag>{reuse_sessions, boolean()}</tag> + <item>Specifies if client should try to reuse sessions + when possible. + </item> + + </taglist> + </section> + + <section> + <title>SSL OPTION DESCRIPTIONS - SERVER SIDE</title> + + <p>Option described here are server specific or has a slightly different + meaning in the server than in the client.</p> + + <taglist> + + <tag>{dh, der_bin()}</tag> + <item>The DER encoded Diffie Hellman parameters. If this option + is supplied it will override the dhfile option. + </item> + + <tag>{dhfile, path()}</tag> + <item>Path to file containing PEM encoded Diffie Hellman parameters, + for the server to use if a cipher suite using Diffie Hellman key exchange + is negotiated. If not specified default parameters will be used. + </item> + + <tag>{verify, verify_type()}</tag> + <item>Servers only do the x509-path validation in verify_peer + mode, as it then will send a certificate request to the client + (this message is not sent if the verify option is verify_none) + and you may then also want to specify the option + fail_if_no_peer_cert. + </item> + + <tag>{fail_if_no_peer_cert, boolean()}</tag> + <item>Used together with {verify, verify_peer} by a ssl server. + If set to true, the server will fail if the client does not have + a certificate to send, i.e. sends a empty certificate, if set to + false it will only fail if the client sends a invalid + certificate (an empty certificate is considered valid). + </item> + <tag>{reuse_sessions, boolean()}</tag> - <item>Specifies if ssl sessions should be reused - when possible. + <item>Specifies if the server should agree to reuse sessions + when the clients request to do so. See also the reuse_session + option. </item> - <tag>{reuse_session, fun(SuggestedSessionId, - PeerCert, Compression, CipherSuite) -> boolean()}</tag> + <tag>{reuse_session, fun(SuggestedSessionId, + PeerCert, Compression, CipherSuite) -> boolean()}</tag> <item>Enables the ssl server to have a local policy for deciding if a session should be reused or not, only meaning full if <c>reuse_sessions</c> is set to true. @@ -252,14 +333,6 @@ end and CipherSuite of type ciphersuite(). </item> - <tag>{secure_renegotiate, boolean()}</tag> - <item>Specifies if to reject renegotiation attempt that does - not live up to RFC 5746. By default secure_renegotiate is - set to false e.i. secure renegotiation will be used if possible - but it will fallback to unsecure renegotiation if the peer - does not support RFC 5746. - </item> - </taglist> </section> @@ -316,7 +389,7 @@ end <v>Reason = term()</v> </type> <desc> <p>Upgrades a gen_tcp, or equivalent, - connected socket to a ssl socket e.i performs the + connected socket to a ssl socket i.e. performs the client-side ssl handshake.</p> </desc> </func> @@ -559,12 +632,12 @@ end </type> <desc> <p> Upgrades a gen_tcp, or - equivalent, socket to a ssl socket e.i performs the + equivalent, socket to a ssl socket i.e. performs the ssl server-side handshake.</p> - <p><note>Note that the listen socket should be in {active, false} mode + <p><warning>Note that the listen socket should be in {active, false} mode before telling the client that the server is ready to upgrade and calling this function, otherwise the upgrade may - or may not succeed depending on timing.</note></p> + or may not succeed depending on timing.</warning></p> </desc> </func> diff --git a/lib/ssl/doc/src/ssl_distribution.xml b/lib/ssl/doc/src/ssl_distribution.xml index 4067fb8a22..7bcc12eb5f 100644 --- a/lib/ssl/doc/src/ssl_distribution.xml +++ b/lib/ssl/doc/src/ssl_distribution.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -36,7 +36,7 @@ <note><p>Note this documentation is written for the old ssl implementation and - will be updated for the new one once this functionallity is + will be updated for the new one once this functionality is supported by the new implementation.</p></note> </p> @@ -55,7 +55,7 @@ all participating Erlang nodes in a distributed system must use this distribution module.</p> <p>The security depends on how the connections are set up, one can - use key files or certificates to just get a crypted + use key files or certificates to just get a encrypted connection. One can also make the SSL package verify the certificates of other nodes to get additional security. Cookies are however always used as they can be used to @@ -179,7 +179,7 @@ Eshell V5.0 (abort with ^G) <c>certfile</c> can (and usually needs to) be specified as <c>client_certfile</c> and <c>server_certfile</c>. The <c>client_certfile</c> is used when the distribution initiates a - connection to another node and the <c>server_cerfile</c> is used + connection to another node and the <c>server_certfile</c> is used when accepting a connection from a remote node. </p> <p>The command line argument for specifying the SSL options is named <c>-ssl_dist_opt</c> and should be followed by an even number of diff --git a/lib/ssl/doc/src/ssl_protocol.xml b/lib/ssl/doc/src/ssl_protocol.xml index 726b9a4eeb..6936408881 100644 --- a/lib/ssl/doc/src/ssl_protocol.xml +++ b/lib/ssl/doc/src/ssl_protocol.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -44,7 +44,7 @@ <section> <title>Security overview</title> - <p>To achive authentication and privacy the client and server will + <p>To achieve authentication and privacy the client and server will perform a TLS Handshake procedure before transmitting or receiving any data. During the handshake they agree on a protocol version and cryptographic algorithms, they generate shared secrets using public @@ -56,7 +56,7 @@ <title>Data Privacy and Integrity</title> <p>A <em>symmetric key</em> algorithm has one key only. The key is - used for both encryption and decryption. These algoritms are fast + used for both encryption and decryption. These algorithms are fast compared to public key algorithms (using two keys, a public and a private one) and are therefore typically used for encrypting bulk data. @@ -66,7 +66,7 @@ for each connection and are based on a secret negotiated in the TLS handshake. </p> - <p>The TLS handsake protocol and data transfer is run on top of + <p>The TLS handshake protocol and data transfer is run on top of the TLS Record Protocol that uses a keyed-hash MAC (Message Authenticity Code), or HMAC, to protect the message's data integrity. From the TLS RFC "A Message Authentication Code is a @@ -85,7 +85,7 @@ with the private key of the issuer of the certificate. A chain of trust is build by having the issuer in its turn being certified by an other certificate and so on until you reach the - so called root certificate that is self signed e.i. issued + so called root certificate that is self signed i.e. issued by itself.</p> <p>Certificates are issued by <em>certification diff --git a/lib/ssl/doc/src/ssl_session_cache_api.xml b/lib/ssl/doc/src/ssl_session_cache_api.xml index 7b70c6cf34..e0b07961fb 100644 --- a/lib/ssl/doc/src/ssl_session_cache_api.xml +++ b/lib/ssl/doc/src/ssl_session_cache_api.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -25,7 +25,7 @@ </header> <module>ssl_session_cache_api</module> <modulesummary>Defines the API for the TLS session cache so - that the datastorge scheme can be replaced by + that the data storage scheme can be replaced by defining a new callback module implementing this API.</modulesummary> <section> @@ -56,7 +56,7 @@ <v> Key = key()</v> </type> <desc> - <p> Delets a cache entry. Will only be called from the cache + <p> Deletes a cache entry. Will only be called from the cache handling process. </p> </desc> @@ -85,10 +85,10 @@ <v></v> </type> <desc> - <p>Performes possible initializations of the cache and returns + <p>Performs possible initializations of the cache and returns a reference to it that will be used as parameter to the other api functions. Will be called by the cache handling processes - init function, hence puting the same requierments on it as + init function, hence putting the same requirements on it as a normal process init function. </p> </desc> @@ -96,16 +96,16 @@ <func> <name>lookup(Cache, Key) -> Entry</name> - <fsummary> Looks up a cach entry.</fsummary> + <fsummary> Looks up a cache entry.</fsummary> <type> <v> Cache = cache_ref()</v> <v> Key = key()</v> <v> Entry = session() | undefined </v> </type> <desc> - <p>Looks up a cach entry. Should be callable from any - process. - </p> + <p>Looks up a cache entry. Should be callable from any + process. + </p> </desc> </func> @@ -127,7 +127,7 @@ <func> <name>terminate(Cache) -> _</name> <fsummary>Called by the process that handles the cache when it - is aboute to terminat.</fsummary> + is about to terminate.</fsummary> <type> <v>Cache = term() - as returned by init/0</v> </type> diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index dbc5faff14..cc01b35b64 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -580,6 +580,7 @@ handle_options(Opts0, _Role) -> password = handle_option(password, Opts, ""), cacerts = CaCerts, cacertfile = handle_option(cacertfile, Opts, CaCertDefault), + dh = handle_option(dh, Opts, undefined), dhfile = handle_option(dhfile, Opts, undefined), ciphers = handle_option(ciphers, Opts, []), %% Server side option @@ -594,7 +595,7 @@ handle_options(Opts0, _Role) -> SslOptions = [versions, verify, verify_fun, fail_if_no_peer_cert, verify_client_once, depth, cert, certfile, key, keyfile, - password, cacerts, cacertfile, dhfile, ciphers, + password, cacerts, cacertfile, dh, dhfile, ciphers, debug, reuse_session, reuse_sessions, ssl_imp, cb_info, renegotiate_at, secure_renegotiate], @@ -669,6 +670,9 @@ validate_option(cacertfile, undefined) -> ""; validate_option(cacertfile, Value) when is_list(Value), Value =/= "" -> Value; +validate_option(dh, Value) when Value == undefined; + is_binary(Value) -> + Value; validate_option(dhfile, undefined = Value) -> Value; validate_option(dhfile, Value) when is_list(Value), Value =/= "" -> diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index 7689976ff6..c94199c336 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -1034,7 +1034,7 @@ ssl_init(SslOpts, Role) -> PrivateKey = init_private_key(SslOpts#ssl_options.key, SslOpts#ssl_options.keyfile, SslOpts#ssl_options.password, Role), - DHParams = init_diffie_hellman(SslOpts#ssl_options.dhfile, Role), + DHParams = init_diffie_hellman(SslOpts#ssl_options.dh, SslOpts#ssl_options.dhfile, Role), {ok, CertDbRef, CacheRef, OwnCert, PrivateKey, DHParams}. @@ -1111,11 +1111,13 @@ file_error(Line, Error, Reason, File, Throw, Stack) -> error_logger:error_report(Report), throw(Throw). -init_diffie_hellman(_, client) -> +init_diffie_hellman(Params, _,_) when is_binary(Params)-> + public_key:der_decode('DHParameter', Params); +init_diffie_hellman(_,_, client) -> undefined; -init_diffie_hellman(undefined, _) -> +init_diffie_hellman(_,undefined, _) -> ?DEFAULT_DIFFIE_HELLMAN_PARAMS; -init_diffie_hellman(DHParamFile, server) -> +init_diffie_hellman(_, DHParamFile, server) -> try {ok, List} = ssl_manager:cache_pem_file(DHParamFile), case [Entry || Entry = {'DHParameter', _ , _} <- List] of diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl index 3862dc75de..ddb05e70f6 100644 --- a/lib/ssl/src/ssl_internal.hrl +++ b/lib/ssl/src/ssl_internal.hrl @@ -69,6 +69,7 @@ password, % cacerts, % [der_encoded()] cacertfile, % file() + dh, % der_encoded() dhfile, % file() ciphers, % %% Local policy for the server if it want's to reuse the session diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl index 47c7407a2e..1e96880801 100644 --- a/lib/ssl/test/ssl_basic_SUITE.erl +++ b/lib/ssl/test/ssl_basic_SUITE.erl @@ -2990,14 +2990,20 @@ der_input(suite) -> []; der_input(Config) when is_list(Config) -> + DataDir = ?config(data_dir, Config), + DHParamFile = filename:join(DataDir, "dHParam.pem"), SeverVerifyOpts = ?config(server_verification_opts, Config), - {ServerCert, ServerKey, ServerCaCerts} = der_input_opts(SeverVerifyOpts), + {ServerCert, ServerKey, ServerCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} | + SeverVerifyOpts]), ClientVerifyOpts = ?config(client_verification_opts, Config), - {ClientCert, ClientKey, ClientCaCerts} = der_input_opts(ClientVerifyOpts), + {ClientCert, ClientKey, ClientCaCerts, DHParams} = der_input_opts([{dhfile, DHParamFile} | + ClientVerifyOpts]), ServerOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}, + {dh, DHParams}, {cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCaCerts}], ClientOpts = [{verify, verify_peer}, {fail_if_no_peer_cert, true}, + {dh, DHParams}, {cert, ClientCert}, {key, ClientKey}, {cacerts, ClientCaCerts}], {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config), Server = ssl_test_lib:start_server([{node, ServerNode}, {port, 0}, @@ -3019,14 +3025,16 @@ der_input_opts(Opts) -> Certfile = proplists:get_value(certfile, Opts), CaCertsfile = proplists:get_value(cacertfile, Opts), Keyfile = proplists:get_value(keyfile, Opts), + Dhfile = proplists:get_value(dhfile, Opts), [{_, Cert, _}] = ssl_test_lib:pem_to_der(Certfile), [{_, Key, _}] = ssl_test_lib:pem_to_der(Keyfile), + [{_, DHParams, _}] = ssl_test_lib:pem_to_der(Dhfile), CaCerts = lists:map(fun(Entry) -> {_, CaCert, _} = Entry, CaCert end, ssl_test_lib:pem_to_der(CaCertsfile)), - {Cert, {rsa, Key}, CaCerts}. + {Cert, {rsa, Key}, CaCerts, DHParams}. %%-------------------------------------------------------------------- %%% Internal functions |