|
|
7b6549 |
From 24fa6df5e1910269d86cb97bb5cef464fc3111ca Mon Sep 17 00:00:00 2001
|
|
|
7b6549 |
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
|
|
7b6549 |
Date: Wed, 19 Mar 2014 12:54:22 +0100
|
|
|
7b6549 |
Subject: [PATCH] Added support for ECDH key exchange with key SSL_ecdh_curve
|
|
|
7b6549 |
MIME-Version: 1.0
|
|
|
7b6549 |
Content-Type: text/plain; charset=UTF-8
|
|
|
7b6549 |
Content-Transfer-Encoding: 8bit
|
|
|
7b6549 |
|
|
|
7b6549 |
This is port of following upstream commit to 1.94 version:
|
|
|
7b6549 |
|
|
|
7b6549 |
commit e067e09bf0c6b5844693169af75ec93b22bfa660
|
|
|
7b6549 |
Author: Steffen Ullrich <Steffen_Ullrich@genua.de>
|
|
|
7b6549 |
Date: Fri Oct 11 18:50:01 2013 +0200
|
|
|
7b6549 |
|
|
|
7b6549 |
1.955 - added support for ECDH key exchange with key SSL_ecdh_curve
|
|
|
7b6549 |
|
|
|
7b6549 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
7b6549 |
---
|
|
|
7b6549 |
MANIFEST | 1 +
|
|
|
7b6549 |
SSL.pm | 28 +++++++++++++++++++++++
|
|
|
7b6549 |
t/ecdhe.t | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
7b6549 |
3 files changed, 107 insertions(+)
|
|
|
7b6549 |
create mode 100644 t/ecdhe.t
|
|
|
7b6549 |
|
|
|
7b6549 |
diff --git a/MANIFEST b/MANIFEST
|
|
|
7b6549 |
index afed6c6..3d97511 100644
|
|
|
7b6549 |
--- a/MANIFEST
|
|
|
7b6549 |
+++ b/MANIFEST
|
|
|
7b6549 |
@@ -50,6 +50,7 @@ t/auto_verify_hostname.t
|
|
|
7b6549 |
t/verify_hostname.t
|
|
|
7b6549 |
t/sni.t
|
|
|
7b6549 |
t/mitm.t
|
|
|
7b6549 |
+t/ecdhe.t
|
|
|
7b6549 |
util/export_certs.pl
|
|
|
7b6549 |
META.yml Module YAML meta-data (added by MakeMaker)
|
|
|
7b6549 |
META.json Module JSON meta-data (added by MakeMaker)
|
|
|
7b6549 |
diff --git a/SSL.pm b/SSL.pm
|
|
|
7b6549 |
index bcf098f..ad18f7a 100644
|
|
|
7b6549 |
--- a/lib/IO/Socket/SSL.pm
|
|
|
7b6549 |
+++ b/lib/IO/Socket/SSL.pm
|
|
|
7b6549 |
@@ -1756,6 +1756,25 @@ sub new {
|
|
|
7b6549 |
Net::SSLeay::DH_free( $dh );
|
|
|
7b6549 |
$rv || return IO::Socket::SSL->error( "Failed to set DH from $f" );
|
|
|
7b6549 |
}
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+ if ( my $curve = $arg_hash->{SSL_ecdh_curve} ) {
|
|
|
7b6549 |
+ return IO::Socket::SSL->error(
|
|
|
7b6549 |
+ "ECDH curve needs Net::SSLeay>=1.56 and OpenSSL>=1.0")
|
|
|
7b6549 |
+ if ! defined( &Net::SSLeay::CTX_set_tmp_ecdh );
|
|
|
7b6549 |
+ if ( $curve !~ /^\d+$/ ) {
|
|
|
7b6549 |
+ # name of curve, find NID
|
|
|
7b6549 |
+ $curve = Net::SSLeay::OBJ_txt2nid($curve)
|
|
|
7b6549 |
+ || return IO::Socket::SSL->error(
|
|
|
7b6549 |
+ "cannot find NID for curve name '$curve'");
|
|
|
7b6549 |
+ }
|
|
|
7b6549 |
+ my $ecdh = Net::SSLeay::EC_KEY_new_by_curve_name($curve) or
|
|
|
7b6549 |
+ return IO::Socket::SSL->error(
|
|
|
7b6549 |
+ "cannot create curve for NID $curve");
|
|
|
7b6549 |
+ Net::SSLeay::CTX_set_tmp_ecdh($ctx,$ecdh) or
|
|
|
7b6549 |
+ return IO::Socket::SSL->error(
|
|
|
7b6549 |
+ "failed to set ECDH curve context");
|
|
|
7b6549 |
+ Net::SSLeay::EC_KEY_free($ecdh);
|
|
|
7b6549 |
+ }
|
|
|
7b6549 |
}
|
|
|
7b6549 |
|
|
|
7b6549 |
my $verify_cb = $arg_hash->{SSL_verify_callback};
|
|
|
7b6549 |
@@ -2158,11 +2177,20 @@ C<SSL_key> option.
|
|
|
7b6549 |
|
|
|
7b6549 |
If you want Diffie-Hellman key exchange you need to supply a suitable file here
|
|
|
7b6549 |
or use the SSL_dh parameter. See dhparam command in openssl for more information.
|
|
|
7b6549 |
+To create a server which provides perfect forward secrecy you need to either
|
|
|
7b6549 |
+give the DH parameters or (better, because faster) the ECDH curve.
|
|
|
7b6549 |
|
|
|
7b6549 |
=item SSL_dh
|
|
|
7b6549 |
|
|
|
7b6549 |
Like SSL_dh_file, but instead of giving a file you use a preloaded or generated DH*.
|
|
|
7b6549 |
|
|
|
7b6549 |
+=item SSL_ecdh_curve
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+If you want Elliptic Curve Diffie-Hellmann key exchange you need to supply the
|
|
|
7b6549 |
+OID or NID of a suitable curve (like 'prime256v1') here.
|
|
|
7b6549 |
+To create a server which provides perfect forward secrecy you need to either
|
|
|
7b6549 |
+give the DH parameters or (better, because faster) the ECDH curve.
|
|
|
7b6549 |
+
|
|
|
7b6549 |
=item SSL_passwd_cb
|
|
|
7b6549 |
|
|
|
7b6549 |
If your private key is encrypted, you might not want the default password prompt from
|
|
|
7b6549 |
diff --git a/t/ecdhe.t b/t/ecdhe.t
|
|
|
7b6549 |
new file mode 100644
|
|
|
7b6549 |
index 0000000..40aed59
|
|
|
7b6549 |
--- /dev/null
|
|
|
7b6549 |
+++ b/t/ecdhe.t
|
|
|
7b6549 |
@@ -0,0 +1,78 @@
|
|
|
7b6549 |
+#!perl
|
|
|
7b6549 |
+# Before `make install' is performed this script should be runnable with
|
|
|
7b6549 |
+# `make test'. After `make install' it should work as `perl t/ecdhe.t'
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+use strict;
|
|
|
7b6549 |
+use warnings;
|
|
|
7b6549 |
+use Net::SSLeay;
|
|
|
7b6549 |
+use Socket;
|
|
|
7b6549 |
+use IO::Socket::SSL;
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+if ( grep { $^O =~m{$_} } qw( MacOS VOS vmesa riscos amigaos ) ) {
|
|
|
7b6549 |
+ print "1..0 # Skipped: fork not implemented on this platform\n";
|
|
|
7b6549 |
+ exit
|
|
|
7b6549 |
+}
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+if ( ! defined &Net::SSLeay::CTX_set_tmp_ecdh ) {
|
|
|
7b6549 |
+ print "1..0 # Skipped: no support for ecdh with this openssl/Net::SSLeay\n";
|
|
|
7b6549 |
+ exit
|
|
|
7b6549 |
+}
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+$|=1;
|
|
|
7b6549 |
+print "1..4\n";
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+# first create simple ssl-server
|
|
|
7b6549 |
+my $ID = 'server';
|
|
|
7b6549 |
+my $addr = '127.0.0.1';
|
|
|
7b6549 |
+my $server = IO::Socket::SSL->new(
|
|
|
7b6549 |
+ LocalAddr => $addr,
|
|
|
7b6549 |
+ Listen => 2,
|
|
|
7b6549 |
+ ReuseAddr => 1,
|
|
|
7b6549 |
+ SSL_cert_file => "certs/server-cert.pem",
|
|
|
7b6549 |
+ SSL_key_file => "certs/server-key.pem",
|
|
|
7b6549 |
+ SSL_ecdh_curve => 'prime256v1',
|
|
|
7b6549 |
+) || do {
|
|
|
7b6549 |
+ notok($!);
|
|
|
7b6549 |
+ exit
|
|
|
7b6549 |
+};
|
|
|
7b6549 |
+ok("Server Initialization");
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+# add server port to addr
|
|
|
7b6549 |
+$addr.= ':'.(sockaddr_in( getsockname( $server )))[0];
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+my $pid = fork();
|
|
|
7b6549 |
+if ( !defined $pid ) {
|
|
|
7b6549 |
+ die $!; # fork failed
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+} elsif ( !$pid ) { ###### Client
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+ $ID = 'client';
|
|
|
7b6549 |
+ close($server);
|
|
|
7b6549 |
+ my $to_server = IO::Socket::SSL->new(
|
|
|
7b6549 |
+ PeerAddr => $addr,
|
|
|
7b6549 |
+ SSL_verify_mode => 0 ) || do {
|
|
|
7b6549 |
+ notok( "connect failed: $SSL_ERROR" );
|
|
|
7b6549 |
+ exit
|
|
|
7b6549 |
+ };
|
|
|
7b6549 |
+ ok( "client connected" );
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+ my $cipher = $to_server->get_cipher();
|
|
|
7b6549 |
+ if ( $cipher !~m/^ECDHE-/ ) {
|
|
|
7b6549 |
+ notok("bad key exchange: $cipher");
|
|
|
7b6549 |
+ exit;
|
|
|
7b6549 |
+ }
|
|
|
7b6549 |
+ ok("ecdh key exchange: $cipher");
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+} else { ###### Server
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+ my $to_client = $server->accept || do {
|
|
|
7b6549 |
+ notok( "accept failed: $SSL_ERROR" );
|
|
|
7b6549 |
+ kill(9,$pid);
|
|
|
7b6549 |
+ exit;
|
|
|
7b6549 |
+ };
|
|
|
7b6549 |
+ ok( "Server accepted" );
|
|
|
7b6549 |
+ wait;
|
|
|
7b6549 |
+}
|
|
|
7b6549 |
+
|
|
|
7b6549 |
+sub ok { print "ok # [$ID] @_\n"; }
|
|
|
7b6549 |
+sub notok { print "not ok # [$ID] @_\n"; }
|
|
|
7b6549 |
--
|
|
|
7b6549 |
1.8.5.3
|
|
|
7b6549 |
|