AnyEvent

 view release on metacpan or  search on metacpan

lib/AnyEvent/TLS.pm  view on Meta::CPAN

The key in the file should look similar this:

   -----BEGIN RSA PRIVATE KEY-----
   ...header data
   ... (key data in base64 encoding) ...
   -----END RSA PRIVATE KEY-----

=item key => $string

The private key string in PEM format (see C<key_file>, only one of
C<key_file> or C<key> can be specified).

The idea behind being able to specify a string is to avoid blocking in
I/O. Unfortunately, Net::SSLeay fails to implement any interface to the
needed OpenSSL functionality, this is currently implemented by writing to
a temporary file.

=item cert_file => $path

The path to the local certificate file in PEM format (might be a combined
certificate/private key file, including chained certificates).

The local certificate (and key) are used to authenticate against the
peer - servers mandatorily need a certificate and key, clients can use
certificate and key optionally to authenticate, e.g. for log-in purposes.

The certificate in the file should look like this:

   -----BEGIN CERTIFICATE-----
   ... (certificate in base64 encoding) ...
   -----END CERTIFICATE-----

If the certificate file or string contain both the certificate and
private key, then there is no need to specify a separate C<key_file> or
C<key>.

Additional signing certifiates to send to the peer (in SSLv3 and newer)
can be specified by appending them to the certificate proper: the order
must be from issuer certificate over any intermediate CA certificates to
the root CA.

So the recommended ordering for a combined key/cert/chain file, specified
via C<cert_file> or C<cert> looks like this:

  certificate private key
  client/server certificate
  ca 1, signing client/server certficate
  ca 2, signing ca 1
  ...

=item cert => $string

The local certificate in PEM format (might be a combined
certificate/private key file). See C<cert_file>.

The idea behind being able to specify a string is to avoid blocking in
I/O. Unfortunately, Net::SSLeay fails to implement any interface to the
needed OpenSSL functionality, this is currently implemented by writing to
a temporary file.

=item cert_password => $string | $callback->($tls)

The certificate password - if the certificate is password-protected, then
you can specify its password here.

Instead of providing a password directly (which is not so recommended),
you can also provide a password-query callback. The callback will be
called whenever a password is required to decode a local certificate, and
is supposed to return the password.

=item dh_file => $path

Path to a file containing Diffie-Hellman parameters in PEM format, for
use in servers. See also C<dh> on how to specify them directly, or use a
pre-generated set.

Diffie-Hellman key exchange generates temporary encryption keys that
are not transferred over the connection, which means that even if the
certificate key(s) are made public at a later time and a full dump of the
connection exists, the key still cannot be deduced.

These ciphers are only available with SSLv3 and later (which is the
default with AnyEvent::TLS), and are only used in server/accept
mode. Anonymous DH protocols are usually disabled by default, and usually
not even compiled into the underlying library, as they provide no direct
protection against man-in-the-middle attacks. The same is true for the
common practise of self-signed certificates that you have to accept first,
of course.

=item dh => $string

Specify the Diffie-Hellman parameters in PEM format directly as a string
(see C<dh_file>), the default is C<ffdhe3072> unless C<dh_file> was
specified.

AnyEvent::TLS supports supports a number of precomputed DH parameters,
since computing them is expensive. They are:

   # from RFC 7919 - recommended
   ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192

   # from "Assigned Number for SKIP Protocols"
   skip512, skip1024, skip2048, skip4096

   # from schmorp
   schmorp1024, schmorp1539, schmorp2048, schmorp4096, schmorp8192

It is said that 2048 bit DH parameters are safe till 2030, and DH
parameters shorter than 900 bits are totally insecure.

To disable DH protocols completely, specify C<undef> as C<dh> parameter.

=item dh_single_use => $enable

Enables or disables "use only once" mode when using Diffie-Hellman key
exchange. When enabled (default), each time a new key is exchanged a new
Diffie-Hellman key is generated, which improves security as each key is
only used once. When disabled, the key will be created as soon as the
AnyEvent::TLS object is created and will be reused.

All the DH parameters supplied with AnyEvent::TLS should be safe with
C<dh_single_use> switched off, but YMMV.

=item cipher_list => $string

The list of ciphers to use, as a string (example:
C<AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH>). The format
of this string and its default value is documented at
L<http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS>.

lib/AnyEvent/TLS.pm  view on Meta::CPAN

      $dh_file = $arg{dh_file};

      $dh_bio = Net::SSLeay::BIO_new_file ($dh_file, "r")
         or croak "$dh_file: failed to open DH parameter file: $!";
   } else {
      $arg{dh} = "ffdhe3072" unless exists $arg{dh};

      if (defined $arg{dh}) {
         $dh_file = "dh string";

         if ($arg{dh} =~ /^\w+$/) {
            $dh_file = "dh params $arg{dh}";
            $arg{dh} = "-----BEGIN DH PARAMETERS-----\n"
                     . (join "\n", unpack "(a74)*", $DH_PARAMS{$arg{dh}}) . "\n"
                     . "-----END DH PARAMETERS-----";
            $arg{dh} =~ s/\|/\n/g;
         }

         $dh_bio = Net::SSLeay::BIO_new (Net::SSLeay::BIO_s_mem ());
         Net::SSLeay::BIO_write ($dh_bio, $arg{dh});
      }
   }

   if ($dh_bio) {
      my $dh = Net::SSLeay::PEM_read_bio_DHparams ($dh_bio);
      Net::SSLeay::BIO_free ($dh_bio);
      $dh or croak "$dh_file: failed to parse DH parameters - not PEM format?";
      my $rv = Net::SSLeay::CTX_set_tmp_dh ($ctx, $dh);
      Net::SSLeay::DH_free ($dh);
      $rv or croak "$dh_file: failed to set DH parameters";
   }

   if ($arg{verify}) {
      $self->{verify_mode} = Net::SSLeay::VERIFY_PEER ();

      $self->{verify_mode} |= Net::SSLeay::VERIFY_FAIL_IF_NO_PEER_CERT ()
         if $arg{verify_require_client_cert};

      $self->{verify_mode} |= Net::SSLeay::VERIFY_CLIENT_ONCE ()
         if $arg{verify_client_once};

   } else {
      $self->{verify_mode} = Net::SSLeay::VERIFY_NONE ();
   }

   $self->{verify_peername} = $arg{verify_peername}
      if exists $arg{verify_peername};

   $self->{verify_cb} = $arg{verify_cb}
      if exists $arg{verify_cb};

   $self->{session_ticket} = $arg{session_ticket}
      if exists $arg{session_ticket};

   $self->{debug} = $ENV{PERL_ANYEVENT_TLS_DEBUG}
      if length $ENV{PERL_ANYEVENT_TLS_DEBUG};

   $self->{debug} = $arg{debug}
      if exists $arg{debug};

   my $pw = $arg{cert_password};
   Net::SSLeay::CTX_set_default_passwd_cb ($ctx, ref $pw ? $pw : sub { $pw });

   if ($self->{verify_mode}) {
      if (exists $arg{ca_file} or exists $arg{ca_path} or exists $arg{ca_cert}) {
         # either specified: use them
         if (exists $arg{ca_cert}) {
            my ($ca_file, $g1) = _tmpfile delete $arg{ca_cert};
            Net::SSLeay::CTX_load_verify_locations ($ctx, $ca_file, undef);
         }
         if (exists $arg{ca_file} or exists $arg{ca_path}) {
            Net::SSLeay::CTX_load_verify_locations ($ctx, $arg{ca_file}, $arg{ca_path});
         }
      } elsif (length $ENV{PERL_ANYEVENT_CA_FILE} or length $ENV{PERL_ANYEVENT_CA_PATH}) {
         Net::SSLeay::CTX_load_verify_locations (
            $ctx,
            $ENV{PERL_ANYEVENT_CA_FILE},
            $ENV{PERL_ANYEVENT_CA_PATH},
         );
      } else {
         # else fall back to defaults
         Net::SSLeay::CTX_set_default_verify_paths ($ctx);
      }
   }

   if (exists $arg{cert} or exists $arg{cert_file}) {
      my ($g1, $g2);

      if (exists $arg{cert}) {
         croak "specifying both cert_file and cert is not allowed"
            if exists $arg{cert_file};

        ($arg{cert_file}, $g1) = _tmpfile delete $arg{cert};
      }

      if (exists $arg{key} or exists $arg{key_file}) {
         if (exists $arg{key}) {
            croak "specifying both key_file and key is not allowed"
               if exists $arg{key_file};
           ($arg{key_file}, $g2) = _tmpfile delete $arg{key};
         }
      } else {
         $arg{key_file} = $arg{cert_file};
      }

      Net::SSLeay::CTX_use_PrivateKey_file
            ($ctx, $arg{key_file}, Net::SSLeay::FILETYPE_PEM ())
         or croak "$arg{key_file}: failed to load local private key (key_file or key)";

      Net::SSLeay::CTX_use_certificate_chain_file ($ctx, $arg{cert_file})
         or croak "$arg{cert_file}: failed to use local certificate chain (cert_file or cert)";
   }

   if ($arg{check_crl}) {
      Net::SSLeay::OPENSSL_VERSION_NUMBER () >= 0x00090702f
         or croak "check_crl requires openssl v0.9.7b or higher";

      Net::SSLeay::X509_STORE_set_flags (
         Net::SSLeay::CTX_get_cert_store ($ctx),
         Net::SSLeay::X509_V_FLAG_CRL_CHECK ());
   }



( run in 0.743 second using v1.01-cache-2.11-cpan-e1769b4cff6 )