IO-Socket-SSL-2.085/0000755000175000017500000000000014553536272013606 5ustar steffensteffenIO-Socket-SSL-2.085/META.yml0000664000175000017500000000161514553536272015064 0ustar steffensteffen--- abstract: 'Nearly transparent SSL encapsulation for IO::Socket::INET.' author: - 'Steffen Ullrich , Peter Behroozi, Marko Asplund' build_requires: ExtUtils::MakeMaker: '0' configure_requires: ExtUtils::MakeMaker: '0' Net::SSLeay: '1.46' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: IO-Socket-SSL no_index: directory: - t - inc requires: Mozilla::CA: '0' Net::SSLeay: '1.46' Scalar::Util: '0' resources: bugtracker: https://github.com/noxxi/p5-io-socket-ssl/issues homepage: https://github.com/noxxi/p5-io-socket-ssl license: http://dev.perl.org/licenses/ repository: https://github.com/noxxi/p5-io-socket-ssl version: '2.085' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' IO-Socket-SSL-2.085/README0000644000175000017500000000222214521466373014463 0ustar steffensteffen IO::Socket::SSL is a class implementing an object oriented interface to SSL sockets. The class is a descendent of IO::Socket::INET. In order to use IO::Socket::SSL you need to have Net::SSLeay v1.46 or newer installed. To use ECDH curves (needed for perfect forward secrecy) you need to use Net::SSLeay >= 1.56. To use OCSP to check for certificate revocations you need OpenSSL 1.0.0 or better and Net::SSLeay>=1.59. For those who do not have a built-in random number generator (including most users of Solaris), you should install one before attempting to install IO::Socket::SSL. If you don't already have a favorite, try "egd" (egd.sourceforge.net) or one of the other "Related Projects" listed on its home page. If you want to bypass the test for existence of the RNG, then set the "SKIP_RNG_TEST" environment variable to a true value. In addition to providing a general OO interface to SSL sockets, this package can be used with libwww-perl. installation: perl Makefile.PL make make test make install -- Steffen Ullrich, Steffen_Ullrich at genua.de Peter Behroozi, behrooz at fas.harvard.edu (Originally by Marko Asplund, marko.asplund at kronodoc.fi) IO-Socket-SSL-2.085/META.json0000664000175000017500000000265314553536272015237 0ustar steffensteffen{ "abstract" : "Nearly transparent SSL encapsulation for IO::Socket::INET.", "author" : [ "Steffen Ullrich , Peter Behroozi, Marko Asplund" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "IO-Socket-SSL", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0", "Net::SSLeay" : "1.46" } }, "runtime" : { "requires" : { "Mozilla::CA" : "0", "Net::SSLeay" : "1.46", "Scalar::Util" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/noxxi/p5-io-socket-ssl/issues" }, "homepage" : "https://github.com/noxxi/p5-io-socket-ssl", "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "https://github.com/noxxi/p5-io-socket-ssl" } }, "version" : "2.085", "x_serialization_backend" : "JSON::PP version 4.06" } IO-Socket-SSL-2.085/example/0000755000175000017500000000000014553536272015241 5ustar steffensteffenIO-Socket-SSL-2.085/example/ssl_server.pl0000644000175000017500000001073714521466373017774 0ustar steffensteffen# # a test server for testing IO::Socket::SSL-class's behavior use strict; use warnings; use IO::Socket::SSL; use Getopt::Long qw(:config posix_default bundling); use Digest::MD5 'md5_hex'; my ($cert_file,$key_file,$key_pass,$ca,$http); GetOptions( 'd|debug:i' => \$IO::Socket::SSL::DEBUG, 'h|help' => sub { usage() }, 'C|cert=s' => \$cert_file, 'K|key=s' => \$key_file, 'P|pass=s' => \$key_pass, 'ca=s' => \$ca, 'http' => \$http, ) or usage("bad option"); sub usage { print STDERR "Error: @_\n" if @_; print STDERR <new( Listen => 5, LocalAddr => $addr, ReuseAddr => 1, ) or die "failed to create SSL server at $addr: $!"; my $ctx = IO::Socket::SSL::SSL_Context->new( SSL_server => 1, SSL_cert_file => $cert_file, SSL_key_file => $key_file, defined($key_pass) ? ( SSL_passwd_cb => sub { $key_pass } ):(), $ca ? ( SSL_verify_mode => SSL_VERIFY_PEER, -d $ca ? ( SSL_ca_path => $ca ):( SSL_ca_file => $ca, SSL_client_ca_file => $ca ) ):(), ) or die "cannot create context: $SSL_ERROR"; while (1) { warn "waiting for next connection.\n"; my $cl = $server->accept or do { warn "failed to accept: $!\n"; next; }; IO::Socket::SSL->start_SSL($cl, SSL_server => 1, SSL_reuse_ctx => $ctx, SSL_startHandshake => 0 ) or do { warn "ssl handshake failed: $SSL_ERROR\n"; next; }; my $ja3; $cl->set_msg_callback(\&msgcb, \$ja3); $cl->accept_SSL() or do { warn "failed SSL handshake: $SSL_ERROR\n"; next; }; my $info = "cipher=".$cl->get_cipher . " version=".$cl->get_sslversion . " ja3=".md5_hex($ja3)." $ja3"; if ( $cl->peer_certificate ) { warn "new SSL connection with client certificate\n". "\tsubject=".$cl->peer_certificate('subject')."\n". "\tissuer=".$cl->peer_certificate('issuer')."\n". $info."\n"; } else { warn "new SSL connection without client certificate\n". $info."\n"; } if ($http) { sysread($cl, my $buf, 8192); $buf =~s{\n\r?\n.*}{\n}s; $info =~s{\b\w+=}{\n$&}mg; $info .= "\n\n-------\n\n$buf"; print $cl "HTTP/1.0 200 ok\r\n". "Content-type: text/plain\r\n". "Content-length: ".length($info)."\r\n". "\r\n". $info; } else { print $cl "connect with $info\n"; } } sub msgcb { my ($self, $direction, $ssl_ver, $content_type, $buf, $len, $ssl, $ja3_r) = @_; $content_type == 22 or return; # TLS handshake # 1 byte: msg type # 3 byte: length (my $msg_type, $buf) = unpack('c x3 a*', $buf); if ($msg_type == 1) { # Client Hello $self->set_msg_callback(undef); # no need to look further my %grease = map { $_ =>1 } ( 0x0a0a, 0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a, 0x8a8a, 0x9a9a, 0xaaaa, 0xbaba, 0xcaca, 0xdada, 0xeaea, 0xfafa, ); # 2 byte: protocol version # 32 byte: random # 1/.. : session id # 2/... : cipher suites # 1/... : compression methods # 2/... : extensions my ($ver, $ciphers, $ext) = unpack("n x32 c/x n/a c/x n/a", $buf); my @ciphers = grep { !$grease{$_} } unpack("n*", $ciphers); my (@ext, @elliptic_curve, @elliptic_curve_point_format); while (length($ext)>2) { # 2 byte: extension value # 2|... : extension data (my $ext_val, my $ext_data, $ext) = unpack("n n/a a*", $ext); next if $grease{$ext_val}; push @ext, $ext_val; if ($ext_val == 0x0a) { # Elliptic curve points @elliptic_curve = unpack("x2 n*", $ext_data); } elsif ($ext_val == 0x0b) { # Elliptic curve point formats @elliptic_curve_point_format = unpack("x c*", $ext_data); } } $$ja3_r = join(",", $ver, join("-", @ciphers), join("-", @ext), join("-", @elliptic_curve), join("-", @elliptic_curve_point_format), ); } } IO-Socket-SSL-2.085/example/async_https_server.pl0000644000175000017500000001117014521466373021522 0ustar steffensteffen########################################################## # example HTTPS server using nonblocking sockets # requires Event::Lib # at the moment the response consists only of the HTTP # request, send back as text/plain ########################################################## use strict; use IO::Socket; use IO::Socket::SSL; use Event::Lib; use Errno ':POSIX'; #$Net::SSLeay::trace=3; eval 'use Debug'; *{DEBUG} = sub {} if !defined(&DEBUG); # create server socket my $server = IO::Socket::INET->new( LocalAddr => '0.0.0.0:9000', Listen => 10, Reuse => 1, Blocking => 0, ) || die $!; event_new( $server, EV_READ|EV_PERSIST, \&_s_accept )->add(); event_mainloop; ########################################################## ### accept new client on server socket ########################################################## sub _s_accept { my $fds = shift->fh; my $fdc = $fds->accept || return; DEBUG( "new client" ); $fdc = IO::Socket::SSL->start_SSL( $fdc, SSL_startHandshake => 0, SSL_server => 1, ) || die $!; $fdc->blocking(0); _ssl_accept( undef,$fdc ); } ########################################################## ### ssl handshake with client ### called again and again until the handshake is done ### this is called first from _s_accept w/o an event ### and later enters itself as new event until the ### handshake is done ### if the handshake is done it inits the buffers for the ### client socket and adds an event for reading the HTTP header ########################################################## sub _ssl_accept { my ($event,$fdc) = @_; $fdc ||= $event->fh; if ( $fdc->accept_SSL ) { DEBUG( "new client ssl handshake done" ); # setup the client ${*$fdc}{rbuf} = ${*$fdc}{wbuf} = ''; event_new( $fdc, EV_READ, \&_client_read_header )->add; } elsif ( $! != EWOULDBLOCK && $! != EAGAIN ) { die "new client failed: $!|$SSL_ERROR"; } else { DEBUG( "new client need to retry accept: $SSL_ERROR" ); my $what = $SSL_ERROR == SSL_WANT_READ ? EV_READ : $SSL_ERROR == SSL_WANT_WRITE ? EV_WRITE : die "unknown error"; event_new( $fdc, $what, \&_ssl_accept )->add; } } ########################################################## ### read http header ### this will re-add itself as an event until the full ### http header was read ### after reading the header it will setup the response ### which will for now just send the header back as text/plain ########################################################## sub _client_read_header { my $event = shift; my $fdc = $event->fh; DEBUG( "reading header" ); my $rbuf_ref = \${*$fdc}{rbuf}; my $n = sysread( $fdc,$$rbuf_ref,16384,length($$rbuf_ref)); if ( !defined($n)) { die $! if $! != EWOULDBLOCK && $! != EAGAIN; DEBUG( $SSL_ERROR ); if ( $SSL_ERROR == SSL_WANT_WRITE ) { # retry read once I can write event_new( $fdc, EV_WRITE, \&_client_read_header )->add; } else { $event->add; # retry } } elsif ( $n == 0 ) { DEBUG( "connection closed" ); close($fdc); } else { # check if we have the whole http header my $i = index( $$rbuf_ref,"\r\n\r\n" ); # check \r\n\r\n $i = index( $$rbuf_ref,"\n\n" ) if $i<0; # bad clients send \n\n only if ( $i<0 ) { $event->add; # read more from header return; } # got full header, send request back (we don't serve real pages yet) my $header = substr( $$rbuf_ref,0,$i,'' ); DEBUG( "got header:\n$header" ); my $wbuf_ref = \${*$fdc}{wbuf}; $$wbuf_ref = "HTTP/1.0 200 Ok\r\nContent-type: text/plain\r\n\r\n".$header; DEBUG( "will send $$wbuf_ref" ); event_new( $fdc, EV_WRITE, \&_client_write_response )->add; } } ########################################################## ### this is called to write the response to the client ### this will re-add itself as an event as until the full ### response was send ### if it's done it will just close the socket ########################################################## sub _client_write_response { my $event = shift; DEBUG( "writing response" ); my $fdc = $event->fh; my $wbuf_ref = \${*$fdc}{wbuf}; my $n = syswrite( $fdc,$$wbuf_ref ); if ( !defined($n) && ( $! == EWOULDBLOCK || $! == EAGAIN ) ) { # retry DEBUG( $SSL_ERROR ); if ( $SSL_ERROR == SSL_WANT_READ ) { # retry write once we can read event_new( $fdc, EV_READ, \&_client_write_response )->add; } else { $event->add; # retry again } } elsif ( $n == 0 ) { DEBUG( "connection closed: $!" ); close($fdc); } else { DEBUG( "wrote $n bytes" ); substr($$wbuf_ref,0,$n,'' ); if ($$wbuf_ref eq '') { DEBUG( "done" ); close($fdc); } else { # send more $event->add } } } IO-Socket-SSL-2.085/example/ssl_mitm.pl0000644000175000017500000000341614521466373017430 0ustar steffensteffen#!/usr/bin/perl # simple HTTPS proxy with SSL bridging, uses Net::PcapWriter to # to log unencrypted traffic my $listen = '127.0.0.1:8443'; # where to listen my $connect = 'www.google.com:443'; # where to connect use strict; use warnings; use IO::Socket::SSL; use IO::Socket::SSL::Intercept; use IO::Socket::SSL::Utils; my ($proxy_cert,$proxy_key) = CERT_create( CA => 1, subject => { commonName => 'foobar' } ); my $mitm = IO::Socket::SSL::Intercept->new( proxy_cert => $proxy_cert, proxy_key => $proxy_key, ); my $listener = IO::Socket::INET->new( LocalAddr => $listen, Listen => 10, Reuse => 1, ) or die "failed to create listener: $!"; while (1) { # get connection from client my $toc = $listener->accept or next; # create new connection to server my $tos = IO::Socket::SSL->new( PeerAddr => $connect, SSL_verify_mode => 1, SSL_ca_path => '/etc/ssl/certs', ) or die "ssl connect to $connect failed: $!,$SSL_ERROR"; # clone cert from server my ($cert,$key) = $mitm->clone_cert( $tos->peer_certificate ); # and upgrade connection to client to SSL with cloned cert IO::Socket::SSL->start_SSL($toc, SSL_server => 1, SSL_cert => $cert, SSL_key => $key, ) or die "failed to ssl upgrade: $SSL_ERROR"; # transfer data my $readmask = ''; vec($readmask,fileno($tos),1) = 1; vec($readmask,fileno($toc),1) = 1; while (1) { select( my $can_read = $readmask,undef,undef,undef ) >0 or die $!; # try to read the maximum frame size of SSL to avoid issues # with pending data if ( vec($can_read,fileno($tos),1)) { sysread($tos,my $buf,16384) or last; print $toc $buf; } if ( vec($can_read,fileno($toc),1)) { sysread($toc,my $buf,16384) or last; print $tos $buf; } } } IO-Socket-SSL-2.085/example/lwp-with-verifycn.pl0000644000175000017500000000057614521466373021203 0ustar steffensteffenuse strict; use warnings; ## !!! make sure that Net::SSL never gets loaded, otherwise it will ## be used instead of IO::Socket::SSL from LWP use IO::Socket::SSL 'debug0'; use LWP::Simple; IO::Socket::SSL::set_ctx_defaults( SSL_verifycn_scheme => 'www', SSL_verify_mode => 1, SSL_ca_file => 'verisign.pem', # root CA of verisign ); print get( 'https://signin.ebay.com' ); IO-Socket-SSL-2.085/example/simulate_proxy.pl0000644000175000017500000002164214521466373020666 0ustar steffensteffenuse strict; use warnings; use IO::Socket::SSL; use IO::Socket::SSL::Utils; use IO::Select; use Socket 'MSG_PEEK'; use Getopt::Long qw(:config posix_default bundling); my $DEBUG; { my $addr = '0.0.0.0:8080'; my $ciphers; my $version; my $deny_tls12 = my $deny_tls11 = 0; my $issuer; my $wildcards = 0; GetOptions( 'h|help' => sub { usage() }, 'd|debug' => \$DEBUG, 'C|ciphers=s' => \$ciphers, 'V|version=s' => \$version, 'deny-tls12' => \$deny_tls12, 'deny-tls11' => \$deny_tls11, 'wildcards=i' => \$wildcards, 'issuer=s' => \$issuer, ); sub usage { print STDERR < } : do { local $/; }; my $issuer_cert = PEM_string2cert($data) or die "no issuer cert found"; my $issuer_key = PEM_string2key($data) or die "no issuer key found"; proxy_server( $addr, deny_tls12 => $deny_tls12, deny_tls11 => $deny_tls11, $ciphers ? ( SSL_cipher_list => $ciphers ):(), $version ? ( SSL_version => $version ):(), issuer_cert => $issuer_cert, issuer_key => $issuer_key, wildcards => $wildcards, ); } # ---------------------------------------------------------------------------- # simulate Proxy # ---------------------------------------------------------------------------- sub proxy_server { my ($addr,%args) = @_; my %sslargs; $sslargs{$_} = delete $args{$_} for grep { m{^SSL_} } keys %args; # dynamically create server certs my $wildcards = delete $args{wildcards} || 0; my $issuer_cert = delete $args{issuer_cert}; my $issuer_key = delete $args{issuer_key}; my $get_cert = do { my %cache; sub { my $host = my $cn = shift; $cn =~s{(^|\.)([\w\-]+)}{$1*} for(1..$wildcards); if ( $cache{$cn} ) { debug("reusing cert for $cn ($host) wildcards=$wildcards"); } else { debug("creating cert for $cn ($host) wildcards=$wildcards"); $cache{$cn} = [ CERT_create( subject => { commonName => $cn }, issuer_cert => $issuer_cert, issuer_key => $issuer_key, )]; } return @{ $cache{$cn} }; } }; debug("listen on $addr"); my $srv = IO::Socket::INET->new( LocalAddr => $addr, Listen => 1, Reuse => 1 ) or die $!; my $cl; while (1) { ACCEPT: $cl = undef; debug("waiting for request..."); $cl = $srv->accept or next; # peek into socket to determine if this is SSL or not # minimal request is "GET / HTTP/1.1\n\n" my $buf = ''; _peek($cl,\$buf,15) or do { debug("failed to get data from client"); goto ACCEPT; }; my $ssl_host = undef; if ( $buf =~m{\A[A-Z]{3,} } ) { # looks like HTTP $buf = ''; } else { # does not look like HTTP, assume direct SSL $ssl_host = "direct.ssl.access"; } SSL_UPGRADE: my $got_ciphers = ''; if ( $ssl_host ) { if ( $args{deny_tls12} || $args{deny_tls11} ) { _peek($cl,\$buf,11) or do { debug("failed to get client hello"); goto ACCEPT; }; if ( $args{deny_tls12} && $buf =~m{^.{9}\x03\x03}s ) { debug("got TLSv1.2 handshake - cut!"); goto ACCEPT; } elsif ( $args{deny_tls11} && $buf =~m{^.{9}\x03\x02}s ) { debug("got TLSv1.1 handshake - cut!"); goto ACCEPT; } } my ($cert,$key) = $get_cert->($ssl_host); debug("upgrade to SSL with certificate for $ssl_host"); IO::Socket::SSL->start_SSL( $cl, SSL_server => 1, SSL_cert => $cert, SSL_key => $key, %sslargs, ) or do { debug("SSL handshake failed: $SSL_ERROR"); goto ACCEPT; }; $got_ciphers = $cl->get_cipher; } REQUEST: # read header my $req = ''; while (<$cl>) { $_ eq "\r\n" and last; $req .= $_; } if ( $req =~m{\ACONNECT ([^\s:]+)} ) { if ( $ssl_host ) { debug("CONNECT inside SSL tunnel - cut"); next ACCEPT; } $ssl_host = $1; # simulate proxy print $cl "HTTP/1.0 200 ok\r\n\r\n"; debug("got proxy request to establish tunnel: CONNECT $ssl_host"); goto SSL_UPGRADE; } my ($met,$ver,$hdr) = $req =~m{\A([A-Z]+) \S+ HTTP/(1\.[01])\r?\n(.*)\Z}s or do { debug("bad request $req"); goto ACCEPT; }; $hdr =~s{\r?\n([ \t])}{$1}g; # continuation lines my $rqbody = ''; my $rqchunked; if ( $ver eq '1.1' and $hdr =~m{^Transfer-Encoding: *chunked}mi ) { $rqchunked = 1; debug("chunked request body"); while (1) { my $h = <$cl>; my $len = $h =~m{\A([\da-fA-F]+)\s*(?:;.*)?\r?\n\Z} && hex($1) // do { debug("bad chunking header in request body"); goto ACCEPT }; if ($len) { my $n = read($cl,$rqbody,$len,length($rqbody)); if ( $n != $len ) { debug("eof inside chunk in request body"); goto ACCEPT; } } $h = <$cl>; $h =~m{\A\r?\n\Z} or do { debug("expected newline after chunk, got '$h'"); goto ACCEPT; }; last if ! $len; } } elsif ( my $len = $hdr=~m{^Content-length: *(\d+)}mi && $1 ) { debug("request body with content-length=$len"); my $n = read($cl,$rqbody,$len); if ( $n != $len ) { debug("eof while reading request body, got $n of $len bytes"); goto ACCEPT; } } my $body = ( $ssl_host ? "SSL_HOST: $ssl_host\nCIPHERS: $got_ciphers\n": "NO SSL\n" ) . "---------\n" . $req; if ( $rqchunked ) { $body .= "--------- (chunked) body size=".(length($rqbody))."------\n$rqbody\n"; } elsif ( $rqbody ne '' ) { $body .= "--------- body size=".(length($rqbody))." ------\n$rqbody\n"; } print $cl "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n". "Content-length: ".length($body)."\r\n". "\r\n". $body; } } sub debug { $DEBUG or return; my $msg = shift; $msg = sprintf($msg,@_) if @_; print STDERR "DEBUG: $msg\n"; } sub _peek { my ($cl,$rbuf,$len) = @_; while (length($$rbuf)<$len) { my $lbuf; if ( ! IO::Select->new($cl)->can_read(30) or ! defined recv($cl,$lbuf,20,MSG_PEEK)) { return; } $$rbuf .= $lbuf; } return 1; } # ---------------------------------------------------------------------------- # this was used to create CA cert # ---------------------------------------------------------------------------- #| use IO::Socket::SSL::Utils; #| my ($cacert,$key) = CERT_create( CA => 1, #| subject => { organizationName => 'genua mbh', commonName => 'Test CA' } #| ); #| print PEM_cert2string($cacert).PEM_key2string($key); __DATA__ -----BEGIN CERTIFICATE----- MIICVjCCAb+gAwIBAgIFAIbQ7t4wDQYJKoZIhvcNAQEFBQAwJjEQMA4GA1UEAxMH VGVzdCBDQTESMBAGA1UEChMJZ2VudWEgbWJoMB4XDTEzMTAyMzA4MjI0MFoXDTE0 MTAyMzA4MjI0MFowJjEQMA4GA1UEAxMHVGVzdCBDQTESMBAGA1UEChMJZ2VudWEg bWJoMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBD9oBSf8pueg3BxNdf6Mm PKGmh46R0O3xNOE/HfXc9Z2WxgLEX4PaYMwdzgFuPcVTZycI5NdhM53yydnTilsX eFct5D2Bz3faiIOB2WnoiNft15YGCdyeue9kf2NkYRLs3eBQDPeU/cXKyfcHb1dS QpQNKiyL/ono1c0kZRoP3wIDAQABo4GPMIGMMB0GA1UdDgQWBBReUpKjaiNSYfZT X2+XsfQsYZef0zAfBgNVHSMEGDAWgBReUpKjaiNSYfZTX2+XsfQsYZef0zA8BgNV HSMENTAzoSqkKDAmMRAwDgYDVQQDEwdUZXN0IENBMRIwEAYDVQQKEwlnZW51YSBt YmiCBQCG0O7eMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg9H/7umS 4bKSEyyCzzqyR1vf735wPnUmTL7NrduPCaT/bLVRPmDwhyRrpNVedICxyU3NK9fc r0Fj12oBBbvLACm8Xfnt23x8IbnGXIz7n5aTFvrv2l3rVMkZOFqo/DFtFnfYGuY8 /N4DtEHG21dwpMrDxXE1pAE5IY+vRMlNEtA= -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMEP2gFJ/ym56DcH E11/oyY8oaaHjpHQ7fE04T8d9dz1nZbGAsRfg9pgzB3OAW49xVNnJwjk12EznfLJ 2dOKWxd4Vy3kPYHPd9qIg4HZaeiI1+3XlgYJ3J6572R/Y2RhEuzd4FAM95T9xcrJ 9wdvV1JClA0qLIv+iejVzSRlGg/fAgMBAAECgYBK8Hs/6tg3+yjPS1jR/zx2GCzr Nk05/q6N5WfVlyybg1+TafMjBKxqtQ4mN5PIlgOldzHouuN7oIyb9IwwF9F5YeUb 8WTK1iLzTmrcfFJmtRyj0ITF5gb+r6PhPxGr4yt8f9bzaIj7G57a+QT9gXKnLKao AN4Vxx51MAPvMeREYQJBAPstPjOyWxLsT8yBphlok2w4MnWQASsrflrL6MzuJYOq zpVxQF3lwSHukhoUhDoyee9miY2kcB9H9PoXWbq4io8CQQDExOwxTlYnyqyvKjFq vXchcNZ4wCU5sf6pzXF2l6Hb6eCuqYlarMu2JN0h7CC0Jq4qr1BalgesS3WUT1M8 dw2xAkB6Kfgd5rp7CqqJOemSZBWHxhFssnyPBZlwCcsRmSZv0qylbK60vKFhooo2 2xGwyIob0RBH7tmFrVbOKHtA4K6rAkA3sRi8t9RQvN91UHbeJDP0phA96vxeQQ+4 Faq4iyBHswFhziBPJrsdmX9xG3kCJDSFZktS6EXRsSXdTTpc0cFxAkEAo5GS9dAY 7WLAcqNDUorHhFOcZouCYX3LRssikmwc0/dvc9DjwqpNqF1BHT6ucX0pqdQI+fp1 VHJ5f4e/SUTV3g== -----END PRIVATE KEY----- ; IO-Socket-SSL-2.085/example/ssl_client.pl0000644000175000017500000000567314521466373017747 0ustar steffensteffen# # a test client for testing IO::Socket::SSL-class's behavior use strict; use warnings; use IO::Socket::SSL; use Getopt::Long qw(:config posix_default bundling); use Digest::MD5 'md5_hex'; my ($cert_file,$key_file,$key_pass,$ca,$name,$no_verify); GetOptions( 'd|debug:i' => \$IO::Socket::SSL::DEBUG, 'h|help' => sub { usage() }, 'C|cert=s' => \$cert_file, 'K|key=s' => \$key_file, 'P|pass=s' => \$key_pass, 'ca=s' => \$ca, 'name=s' => \$name, 'no-verify' => \$no_verify, ) or usage("bad option"); sub usage { print STDERR "Error: @_\n" if @_; print STDERR <new( PeerAddr => $addr, $ca ? ( -d $ca ? ( SSL_ca_path => $ca ):( SSL_ca_file => $ca ) ):(), $name ? ( SSL_hostname => $name ):(), $no_verify ? ( SSL_verify_mode => 0 ):(), $cert_file ? ( SSL_cert_file => $cert_file, SSL_key_file => $key_file, defined($key_pass) ? ( SSL_passwd_cb => sub { $key_pass } ):(), ):(), SSL_startHandshake => 0, ) or die "failed to connect to $addr: $!,$SSL_ERROR"; my $ja3s; $cl->set_msg_callback(\&msgcb, \$ja3s); $cl->connect_SSL() or die "failed SSL handshake: $SSL_ERROR"; warn "new SSL connection with cipher=".$cl->get_cipher." version=".$cl->get_sslversion." certificate:\n". "\tsubject=".$cl->peer_certificate('subject')."\n". "\tissuer=".$cl->peer_certificate('issuer')."\n". "\tja3s=".md5_hex($ja3s)." $ja3s\n"; sub msgcb { my ($self, $direction, $ssl_ver, $content_type, $buf, $len, $ssl, $ja3s_r) = @_; $content_type == 22 or return; # TLS handshake # 1 byte: msg type # 3 byte: length (my $msg_type, $buf) = unpack('c x3 a*', $buf); if ($msg_type == 2) { # Server Hello $self->set_msg_callback(undef); # no need to look further # 2 byte: protocol version # 32 byte: random # 1/... : session id # 2 byte: cipher suite # 1 byte: compression method # 2/... : extensions my ($ver, $cipher, $ext) = unpack("n x32 c/x n x n/a", $buf); my @ext; while (length($ext)>2) { # 2 byte: extension type # 2|... : extension data (my $ext_type, $ext) = unpack("n n/x a*", $ext); push @ext, $ext_type; } $$ja3s_r = join(",", $ver, $cipher, join("-", @ext) ); } } IO-Socket-SSL-2.085/Makefile.PL0000644000175000017500000001353214522250032015543 0ustar steffensteffen# vim: set sts=4 sw=4 ts=8 ai: use 5.008; use ExtUtils::MakeMaker; # Test to make sure that Net::SSLeay can be properly seeded! unless (defined $ENV{EGD_PATH}) { foreach (qw(/var/run/egd-pool /dev/egd-pool /etc/egd-pool /etc/entropy)) { if (-S) { $ENV{EGD_PATH}=$_; last } } } $| = 1; my $yesno = sub { my ($msg,$default) = @_; return $default if defined $default && $ENV{PERL_MM_USE_DEFAULT}; # Taken from ExtUtils::MakeMaker 6.16 (Michael Schwern) so that # the prompt() function can be emulated for older versions of ExtUtils::MakeMaker. while ( -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT))) { print "$msg "; my $choice = ; $choice =~s{\s+$}{}; $choice ||= $default; next if $choice !~m{^\s*([yn])}i; return lc($1); } return $default; }; { # issue warning, if Net::SSLeay cannot find random generator # redefine __WARN__ only locally to allow detection of failures # in PREREQ_PM local $SIG{__WARN__} = sub { undef $SIG{__WARN__}; my $warning = shift; return unless $warning =~ /random/i; print "Net::SSLeay could not find a random number generator on\n"; print "your system. This will likely cause most of the tests\n"; print "to fail. Please see the README file for more information.\n"; print "the message from Net::SSLeay was: $warning\n"; $yesno->("Do you REALLY want to continue? y/[N]","n") eq 'y' or die "Install cancelled.\n"; }; if (! defined $ENV{SKIP_RNG_TEST}) { eval { require Net::SSLeay; $Net::SSLeay::trace=1; Net::SSLeay::randomize(); }; die $@ if $@ =~ /cancelled/; } else { print "Random Number Generator test skipped.\n"; } } if (my $compiled = eval { require Net::SSLeay; Net::SSLeay::OPENSSL_VERSION_NUMBER() }) { # don't support too old OpenSSL versions anymore, only causes trouble die sprintf( "minimal required version for OpenSSL is 0.9.8, but your Net::SSLeay reports 0x%08x", $compiled) if $compiled < 0x00908000; my $linked = Net::SSLeay::SSLeay(); # OpenSSL 1.1.1e introduced behavior changes breaking various code # will likely be reverted in 1.1.1f - enforce to not use this version if ($linked == 0x1010105f) { die "detected OpenSSL 1.1.1e - please use a different version\n"; } # For old versions we need to be rather strict, however OpenSSL explicitly # declares that from 3.0 on x.y versions are for all y ABI-compatible. # https://www.openssl.org/policies/releasestrat.html if ($linked < 0x30000000) { if (($compiled ^ $linked) >= 0x00001000) { die sprintf("API-different OpenSSL versions compiled in (0x%08x) vs linked (0x%08x)", $compiled,$linked); } } else { if (($compiled ^ $linked) >= 0x10000000) { die sprintf("API-different OpenSSL versions compiled in (0x%08x) vs linked (0x%08x)", $compiled,$linked); } } } # make sure that we have dualvar from the XS Version of Scalar::Util if ( eval { require Scalar::Util } ) { eval { Scalar::Util::dualvar( 0,'' ) }; die "You need the XS Version of Scalar::Util for dualvar() support" if ($@); } # check if we have something which handles IDN if ( ! eval { require Net::IDN::Encode } and ! eval { require Net::LibIDN } and ! eval { require URI; URI->VERSION(1.50) }) { warn <<'EOM'; WARNING No library for handling international domain names found. It will work but croak if you try to verify an international name against a certificate. It's recommended to install URI version>=1.50. Net::IDN::Encode and Net::LibIDN are also still supported. EOM } # check if we have usable CA store # on windows we might need to install Mozilla::CA # settings for default path from openssl crypto/cryptlib.h my %usable_ca; { my $openssldir = eval { require Net::SSLeay; Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} && $1 || ''; }; my $dir = $ENV{SSL_CERT_DIR} || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" ); if ( opendir(my $dh,$dir)) { FILES: for my $f ( grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) { open( my $fh,'<',"$dir/$f") or next; while (<$fh>) { m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next; $usable_ca{SSL_ca_path} = $dir; last FILES; } } } my $file = $ENV{SSL_CERT_FILE} || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" ); if ( open(my $fh,'<',$file)) { while (<$fh>) { m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next; $usable_ca{SSL_ca_file} = $file; last; } } } my $xt = $ENV{NO_NETWORK_TESTING} && 'n'; $xt ||= $yesno->( "Should I do external tests?\n". "These test will detect if there are network problems and fail soft,\n". "so please disable them only if you definitely don't want to have any\n". "network traffic to external sites. [Y/n]", 'y' ); # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'IO::Socket::SSL', 'ABSTRACT' => 'Nearly transparent SSL encapsulation for IO::Socket::INET.', 'AUTHOR' => 'Steffen Ullrich , Peter Behroozi, Marko Asplund', 'LICENSE' => 'perl', 'DISTNAME' => 'IO-Socket-SSL', 'VERSION_FROM' => 'lib/IO/Socket/SSL.pm', 'PREREQ_PM' => { 'Net::SSLeay' => 1.46, 'Scalar::Util' => 0, ! %usable_ca ? ( 'Mozilla::CA' => 0 ):(), }, 'dist' => { COMPRESS => 'gzip', SUFFIX => 'gz', }, $xt eq 'y' ? ( test => { TESTS => 't/*.t t/external/*.t' }):(), $ExtUtils::MakeMaker::VERSION >= 6.46 ? ( 'META_MERGE' => { resources => { license => 'http://dev.perl.org/licenses/', repository => 'https://github.com/noxxi/p5-io-socket-ssl', homepage => 'https://github.com/noxxi/p5-io-socket-ssl', bugtracker => 'https://github.com/noxxi/p5-io-socket-ssl/issues', }, }, ):(), $ExtUtils::MakeMaker::VERSION >= 6.52 ? ( 'CONFIGURE_REQUIRES' => { "ExtUtils::MakeMaker" => 0, 'Net::SSLeay' => 1.46, }, ):(), ); IO-Socket-SSL-2.085/Changes0000644000175000017500000023265714553536217015117 0ustar steffensteffen2.085 2024/01/22 - #147 fix test which failed due to behavior changes in OpenSSL 3.2 - update PublicSuffix - add examples for TLS JA3/JA4 fingerprinting to tls_fingerprint/ 2.084 2023/11/06 - various fixes for edge cases and build: #136, #141, #142, #143, #145 - update documentation to reflect default SSL_version 2.083 2023/05/18 - fix t/protocol_version.t for OpenSSL versions which don't support SECLEVEL (regression from #122) 2.082 2023/05/17 - SSL_version default now TLS 1.2+ since TLS 1.1 and lower deprecated #122 - fix output of alert string when debugging #132 - improve regex for hostname validation #130, #126 - add can_ciphersuites subroutine for feature checking #127 - Utils::CERT_create - die if unexpected arguments are given instead of ignoring these 2.081 2023/01/25 - new function set_msg_callback for user defined callback on each SSL message - showcase function in example/ssl_client.pl and example/ssl_server.pl for computing JA3S/JA3 fingerprints - fix tracing added in 2.076 to no longer include SSL3_RT_HEADER (noise) 2.080 2023/01/18 - move certs into t/ so that distributions like CentOS don't install the test certificates as part of the documentation any longer. 2.079 2023/01/16 - properly extract IPv6 address for verification from PeerAddr if not explicitly given as SSL_verifycn_name. https://github.com/noxxi/p5-io-socket-ssl/issues/123 2.078 2022/12/11 - revert decision from 2014 to not verify hostname by default if hostname is IP address but no explicit verification scheme given https://github.com/noxxi/p5-io-socket-ssl/issues/121 2.077 2022/11/21 - fix memory leak in session cache, thanks to genuaboro https://github.com/noxxi/p5-io-socket-ssl/pull/118 - more race conditions in tests fixed thanks to jddurand https://github.com/noxxi/p5-io-socket-ssl/issues/97 2.076 2022/11/12 - added curl like tracing based on contribution from jddurand https://github.com/noxxi/p5-io-socket-ssl/pull/117 - fixed race condition in t/sni_verify.t based on analysis from jddurand https://github.com/noxxi/p5-io-socket-ssl/issues/97 2.075 - treat SSL_write returning 0 same as previously -1, as suggested by both OpenSSL and LibreSSL documentation - propagate error from SSL_shutdown, but if the shutdown is caused by an outer SSL error keep the original error - small tests fixes 2.074 - add SSL_ciphersuites option for TLS 1.3 ciphers - no longer use own default for ciphers, instead use system default but disable some weak ciphers which might still be enabled on older systems 2.073 - fix behavior and tests for openssl 3.0.1 - fix #110 - prevent internal error warning in some cases 2.072 - add PEM_certs2file and PEM_file2certs in IO::Socket::SSL::Utils based on idea by rovo89 in #101 - certs/*.p12 used for testing should now work with OpenSSL 3.0 too #108 - update public suffix database 2.071 2021/05/23 - fix t/nonblock.t race on some systems. Fixes issue #102, maybe #98 too. 2.070 2021/02/26 - changed bugtracker in Makefile.PL to github, away from obsolete rt.cpan.org 2.069 2021/01/22 - IO::Socket::Utils CERT_asHash and CERT_create now support subject and issuer with multiple same parts (like multiple OU). In this case an array ref instead of a scalar is used as hash value. https://github.com/noxxi/p5-io-socket-ssl/issues/95 2.068 2020/03/31 - treat OpenSSL 1.1.1e as broken and refuse to build with it in order to prevent follow-up problems in tests and user code https://github.com/noxxi/p5-io-socket-ssl/issues/93 https://github.com/openssl/openssl/issues/11388 https://github.com/openssl/openssl/issues/11378 - update PublicSuffix with latest data from publicsuffix.org 2.067 2020/02/14 - fix memory leak on incomplete handshake https://github.com/noxxi/p5-io-socket-ssl/issues/92 Thanks to olegwtf - add support for SSL_MODE_RELEASE_BUFFERS via SSL_mode_release_buffers This can decrease memory usage at the costs of more allocations https://rt.cpan.org/Ticket/Display.html?id=129463 - more detailed error messages when loading of certificate file failed https://github.com/noxxi/p5-io-socket-ssl/issues/89 - fix for ip_in_cn == 6 in verify_hostname scheme https://rt.cpan.org/Ticket/Display.html?id=131384 - deal with new MODE_AUTO_RETRY default in OpenSSL 1.1.1 - fix warning when no ecdh support is available - documentation update regarding use of select and TLS 1.3 - various fixes in documentation https://github.com/noxxi/p5-io-socket-ssl/issues/91 https://github.com/noxxi/p5-io-socket-ssl/issues/90 https://github.com/noxxi/p5-io-socket-ssl/issues/87 https://github.com/noxxi/p5-io-socket-ssl/issues/81 - stability fix t/core.t 2.066 2019/03/06 - fix test t/verify_partial_chain.t by using the newly exposed function can_partial_chain instead of guessing (wrongly) if the functionality is available 2.065 2019/03/05 - make sure that Net::SSLeay::CTX_get0_param is defined before using X509_V_FLAG_PARTIAL_CHAIN. Net::SSLeay 1.85 defined only the second with LibreSSL 2.7.4 but not the first https://rt.cpan.org/Ticket/Display.html?id=128716 - prefer AES for server side cipher default since it is usually hardware-accelerated 2.064 2019/03/04 - make algorithm for fingerprint optional, i.e. detect based on length of fingerprint - https://rt.cpan.org/Ticket/Display.html?id=127773 - fix t/sessions.t and improve stability of t/verify_hostname.t on windows - use CTX_set_ecdh_auto when needed (OpenSSL 1.0.2) if explicit curves are set - update fingerprints for live tests 2.063 2019/03/01 - support for both RSA and ECDSA certificate on same domain - update PublicSuffix - Refuse to build if Net::SSLeay is compiled with one version of OpenSSL but then linked against another API-incompatible version (ie. more than just the patchlevel differs). 2.062 2019/02/24 - Enable X509_V_FLAG_PARTIAL_CHAIN if supported by Net::SSLeay (1.83+) and OpenSSL (1.1.0+). This makes leaf certificates or intermediate certificates in the trust store be usable as full trust anchors too. 2.061 2019/02/23 - Support for TLS 1.3 session reuse. Needs Net::SSLeay 1.86+. Note that the previous (and undocumented) API for the session cache has been changed. - Support for multiple curves, automatic setting of curves and setting of supported curves in client. Needs Net::SSLeay 1.86+. - Enable Post-Handshake-Authentication (TLSv1.3 feature) client-side when client certificates are provided. Thanks to jorton[AT]redhat[DOT]com. Needs Net::SSLeay 1.86+. 2.060 2018/09/16 - support for TLS 1.3 with OpenSSL 1.1.1 (needs Net::SSLeay 1.86+) Thanks to ppisar[AT]redhat.com for major help see also https://rt.cpan.org/Ticket/Display.html?id=126899 TLS 1.3 support is not complete yet for session reuse 2.059 2018/08/15 - fix memleak when CRL are used. Thanks to Franz Skale for report and patch https://rt.cpan.org/Ticket/Display.html?id=125867 - fix memleak when using stop_SSL and threads, reported by Paul Evans https://rt.cpan.org/Ticket/Display.html?id=125867#txn-1797132 2.058 2018/07/19 - fix t/session_ticket.t: it failed with OpenSSL 1.1.* since this version expects the extKeyUsage of clientAuth in the client cert also to be allowed by the CA if CA uses extKeyUsage 2.057 2018/07/18 - fix memory leak which occurred with explicit stop_SSL in connection with non-blocking sockets or timeout - https://rt.cpan.org/Ticket/Display.html?id=125867 Thanks to Paul Evans for reporting - fix redefine warnings in case Socket6 is installed but neither IO::Socket::IP nor IO::Socket::INET6 - https://rt.cpan.org/Ticket/Display.html?id=124963 - IO::Socket::SSL::Intercept - optional 'serial' argument can be starting number or callback to create serial number based on the original certificate - new function get_session_reused to check if a session got reused - IO::Socket::SSL::Utils::CERT_asHash: fingerprint_xxx now set to the correct value 2.056 2018/02/19 - Intercept - fix creation of serial number: base it on binary digest instead of treating hex fingerprint as binary. Allow use of own serial numbers again. - t/io-socket-ip.t - skip test if no IPv6 support on system RT#124464 - update PublicSuffix 2.055 2018/02/15 - use SNI also if hostname was given all-uppercase - Utils::CERT_create - don't add authority key for issuer since Chrome does not like this - Intercept: - change behavior of code based cache to better support synchronizing within multiprocess/threaded setups - don't use counter for serial number but somehow base it on original certificate in order to avoid conflicts with reuse of serial numbers after restart - RT#124431 - better support platforms w/o IPv6 - RT#124306 - spelling fixes in documentation 2.054 2018/01/22 - added missing test certificates to MANIFEST 2.053 2018/01/21 - small behavior fixes - if SSL_fingerprint is used and matches don't check for OCSP - Utils::CERT_create - small fixes to properly specific purpose, ability to use predefined complex purpose but disable some features - update PublicSuffix - updates for documentation, especially regarding pitfalls with forking or using non-blocking sockets. Spelling fixes. - test fixes and improvements - stability improvements for live tests - regenerate certificate in certs/ and make sure they are limited to the correct purpose. Checkin program used to generate certificates. - adjust tests since certificates have changed and some tests used certificates intended for client authentication as server certificates, which now no longer works 2.052 2017/10/22 - disable NPN support if LibreSSL>=2.6.1 is detected since they've replaced the functions with dummies instead of removing NPN completly or setting OPENSSL_NO_NEXTPROTONEG - t/01loadmodule.t shows more output helpful in debugging problems - update fingerprints for extenal tests - update documentation to make behavior of syswrite more clear 2.051 2017/09/05 - syswrite: if SSL_write sets SSL_ERROR_SYSCALL but no $! (as seen with OpenSSL 1.1.0 on Windows) set $! to EPIPE to propagate a useful error up https://github.com/noxxi/p5-io-socket-ssl/issues/62 2.050 2017/08/18 - removed unnecessary settings of SSL_version and SSL_cipher_list from tests - protocol_version.t can now deal when TLS 1.0 and/or TLS 1.1 are not supported as is the case with openssl versions in latest Debian (buster) 2.049 2017/06/12 - fixed problem caused by typo in the context of session cache https://github.com/noxxi/p5-io-socket-ssl/issues/60 - update PublicSuffix information from publicsuffix.org 2.048 2017/04/16 - fixed small memory leaks during destruction of socket and context, RT#120643 2.047 2017/02/16 - better fix for problem which 2.046 tried to fix but broke LWP this way 2.046 2017/02/15 - cleanup everything in DESTROY and make sure to start with a fresh %{*self} in configure_SSL because it can happen that a GLOB gets used again without calling DESTROY (https://github.com/noxxi/p5-io-socket-ssl/issues/56) 2.045 2017/02/13 - fixed memory leak caused by not destroying CREATED_IN_THIS_THREAD for SSL objects -> github pull#55 - optimization: don't track SSL objects and CTX in *CREATED_IN_THIS_THREAD if perl is compiled w/o thread support - small fix in t/protocol_version.t to use older versions of Net::SSLeay with openssl build w/o SSLv3 support - when setting SSL_keepSocketOnError to true the socket will not be closed on fatal error. This is a modified version of https://github.com/noxxi/p5-io-socket-ssl/pull/53/ 2.044 2017/01/26 - protect various 'eval'-based capability detections at startup with a localized __DIE__ handler. This way dynamically requiring IO::Socket::SSL as done by various third party software should cause less problems even if there is a global __DIE__ handler which does not properly deal with 'eval'. 2.043 2017/01/06 - make t/session_ticket.t work with OpenSSL 1.1.0. With this version the session does not get reused any longer if it was not properly closed which is now done using an explicit close by the client which causes a proper SSL_shutdown 2.042 2017/01/05 - enable session ticket callback with Net::SSLeay>=1.80 2.041 2017/01/04 - leave session ticket callback off for now until the needed patch is included in Net::SSLeay. See https://rt.cpan.org/Ticket/Display.html?id=116118#txn-1696146 2.040 2016/12/17 - fix detection of default CA path for OpenSSL 1.1.x - Utils::CERT_asHash now includes the signature algorithm used - Utils::CERT_asHash can now deal with large serial numbers 2.039 2016/11/20 - OpenSSL 1.1.0c changed the behavior of SSL_read so that it now returns -1 on EOF without proper SSL shutdown. Since it looks like that this behavior will be kept at least for 1.1.1+ adapt to the changed API by treating errno=NOERR on SSL_ERROR_SYSCALL as EOF. 2.038 2016/09/17 - restrict session ticket callback to Net::SSLeay 1.79+ since version before contains bug. Add test for session reuse - extend SSL fingerprint to pubkey digest, i.e. 'sha1$pub$xxxxxx....' - fix t/external/ocsp.t to use different server (under my control) to check OCSP stapling 2.037 2016/08/22 - fix session cache del_session: it freed the session but did not properly remove it from the cache. Further reuse causes crash. 2.036 2016/08/11 - disable OCSP support when Net::SSLeay 1.75..1.77 is used, see RT#116795 2.035 2016/08/11 - fixes for issues introduced in 2.034 - return with error in configure_SSL if context creation failed. This might otherwise result in a segmentation fault later. - apply builtin defaults before any (user configurable) global settings (i.e. done with set_defaults, set_default_context...) so that builtins don't replace user settings Thanks to joel[DOT]a[DOT]berger[AT]gmail[DOT]com for reporting 2.034 2016/08/08 - move handling of global SSL arguments into creation of context, so that these get also applied when creating a context only. 2.033 2016/07/15 - support for session ticket reuse over multiple contexts and processes (if supported by Net::SSLeay) - small optimizations, like saving various Net::SSLeay constants into variables and access variables instead of calling the constant sub all the time - make t/dhe.t work with openssl 1.1.0 2.032 2016/07/12 - Set session id context only on the server side. Even if the documentation for SSL_CTX_set_session_id_context makes clear that this function is server side only it actually affects hndling of session reuse on the client side too and can result in error "SSL3_GET_SERVER_HELLO:attempt to reuse session in different context" at the client. 2.031 2016/07/08 - fix for bug in session handling introduced in 2.031, RT#115975 Thanks to paul[AT]city-fan[DOT]org for reporting 2.030 2016/07/08 - Utils::CERT_create - don't add given extensions again if they were already added. Firefox croaks with sec_error_extension_value_invalid if (specific?) extensions are given twice. - assume that Net::SSLeay::P_PKCS12_load_file will return the CA certificates with the reverse order as in the PKCS12 file, because that's what it does. - support for creating ECC keys in Utils once supported by Net::SSLeay - remove internal sub session_cache and access cache directly (faster) 2.029 2016/06/26 - fix del_session method in case a single item was in the cache - use SSL_session_key as the real key for the cache and not some derivative of it, so that it works to remove the entry using the same key 2.028 2016/06/26 - add del_session method to session cache 2.027 2016/04/20 - only added Changes for 2.026 2.026 2016/04/20 - update default server and client ciphers based on recommendation of Mozilla and what the current browsers use. Notably this finally disables RC4 for the client (was disabled for server long ago) and adds CHACHA20. 2.025 2016/04/04 - Resolved memleak if SSL_crl_file was used: RT#113257, RT#113530 Thanks to avi[DOT]maslati[AT]forescout[DOT]com and mark[DOT]kurman[AT]gmail[DOT]com for reporting the problem 2.024 2016/02/06 - Work around issue where the connect fails on systems having only a loopback interface and where IO::Socket::IP is used as super class (default when available). Since IO::Socket::IP sets AI_ADDRCONFIG by default connect to localhost would fail on this systems. This happened at least for the tests, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813796 Workaround is to explicitly set GetAddrInfoFlags to 0 if no GetAddrInfoFlags is set but the Family/Domain is given. In this case AI_ADDRCONFIG would not be useful anyway but would cause at most harm. 2.023 2016/01/30 - OpenSSL 1.0.2f changed the behavior of SSL shutdown in case the TLS connection was not fully established (commit: f73c737c7ac908c5d6407c419769123392a3b0a9). This somehow resulted in Net::SSLeay::shutdown returning 0 (i.e. keep trying) which caused an endless loop. It will now ignore this result in case the TLS connection was not yet established and consider the TLS connection closed instead. 2.022 2015/12/10 - fix stringification of IPv6 inside subjectAltNames in Utils::CERT_asHash. Thanks to Mark.Martinec[AT]ijs[DOT]si for reporting in #110253 2.021 2015/12/02 - Fixes for documentation and typos thanks to DavsX and jwilk. - Update PublicSuffix with latest version from publicsuffix.org 2.020 2015/09/20 - support multiple directories in SSL_ca_path as proposed in RT#106711 by dr1027[AT]evocat[DOT]ne. Directories can be given as array or as string with a path separator, see documentation. - typos fixed thanks to jwilk https://github.com/noxxi/p5-io-socket-ssl/pull/34 2.019 2015/09/01 - work around different behavior of getnameinfo from Socket and Socket6 by using a different wrapper depending on which module I use for IPv6. Thanks to bluhm for reporting. 2.018 2015/08/27 - RT#106687 - startssl.t failed on darwin with old openssl since server requested client certificate but offered also anon ciphers 2.017 2015/08/24 - checks for readability of files/dirs for certificates and CA no longer use -r because this is not safe when ACLs are used. Thanks to BBYRD, RT#106295 - new method sock_certificate similar to peer_certificate based on idea of Paul Evans, RT#105733 - get_fingerprint can now take optional certificate as argument and compute the fingerprint of it. Useful in connection with sock_certificate. - check for both EWOULDBLOCK and EAGAIN since these codes are different on some platforms. Thanks to Andy Grundman, RT#106573 - enforce default verification scheme if none was specified, i.e. no longer just warn but accept. If really no verification is wanted a scheme of 'none' must be explicitly specified. - support different cipher suites per SNI hosts 2.016 2015/06/02 - add flag X509_V_FLAG_TRUSTED_FIRST by default if available in OpenSSL (since 1.02) and available with Net::SSLeay. RT#104759 (thanks GAAS) - work around hanging prompt() with older perl in Makefile.PL RT#104731 - make t/memleak_bad_handshake.t work on cygwin and other systems having /proc/pid/statm, see RT#104659 - add better debugging based on patch from H.Merijn Brand 2.015 2015/05/13 - work around problem with IO::Socket::INET6 on windows, by explicitly using Domain AF_INET in the tests. Fixes RT#104226 reported by CHORNY 2.014 2015/05/05 - Utils::CERT_create - work around problems with authorityInfoAccess, where OpenSSL i2v does not create the same string as v2i expects - Intercept - don't clone some specific extensions which make only sense with the original certificate 2.013 2015/05/01 - assign severities to internal error handling and make sure that follow-up errors like "configuration failed" or "certificate verify error" don't replace more specific "hostname verification failed" when reporting in sub errstr/$SSL_ERROR. see also RT#103423 - enhanced documentation thanks to Chase Whitener https://github.com/noxxi/p5-io-socket-ssl/pull/26 2.012 2015/02/02 - fix t/ocsp.t in case no HTTP::Tiny is installed 2.011 2015/02/01 - fix t/ocsp.t - don't count on revoked.grc.com using OCSP stapling #101855 - added option 'purpose' to Utils::CERT_create to get better control of the certificates purpose. Default is 'server,client' for non-CA (contrary to only 'server' before) - removed RC4 from default cipher suites on the server site https://github.com/noxxi/p5-io-socket-ssl/issues/22 - refactoring of some tests using Test::More thanks to Sweet-kid and the 2015 Pull Request Challenge 2.010 2015/01/14 - new options SSL_client_ca_file and SSL_client_ca to let the server send the list of acceptable CAs for the client certificate. - t/protocol_version.t - fix in case SSLv3 is not supported in Net::SSLeay. RT#101485, thanks to TEAM. 2.009 2015/01/12 - remove util/analyze.pl. This tool is now together with other SSL tools in https://github.com/noxxi/p5-ssl-tools - added ALPN support (needs OpenSSL1.02, Net::SSLeay 1.56+) thanks to TEAM, RT#101452 2.008 2014/12/16 - work around recent OCSP verification errors for revoked.grc.com (badly signed OCSP response, Firefox also complains about it) in test t/external/ocsp.t. - util/analyze.pl - report more details about preferred cipher for specific TLS versions 2.007 2014/11/26 - make getline/readline fall back to super class if class is not sslified yet, i.e. behave the same as sysread, syswrite etc. This fixes RT#100529 2.006 2014/11/22 - Make (hopefully) non-blocking work on windows by using EWOULDBLOCK instead of EAGAIN. While this is the same on UNIX it is different on Windows and socket operations return there (WSA)EWOULDBLOCK and not EAGAIN. Enable non-blocking tests on Windows too. - make PublicSuffix::_default_data thread safe - update PublicSuffix with latest list from publicsuffix.org 2.005 2014/11/15 - next try to fix t/protocol_version.t for OpenSSL w/o SSLv3 support 2.004 2014/11/15 - only test fix: fix t/protocol_version.t to deal with OpenSSL installations which are compiled without SSLv3 support. 2.003 2014/11/14 - make SSLv3 available even if the SSL library disables it by default in SSL_CTX_new (like done in LibreSSL). Default will stay to disable SSLv3, so this will be only done when setting SSL_version explicitly. - fix possible segmentation fault when trying to use an invalid certificate, reported by Nick Andrew. - Use only the ICANN part of the default public suffix list and not the private domains. This makes existing exceptions for s3.amazonaws.com and googleapis.com obsolete. Thanks to Gervase Markham from mozilla.org. 2.002 2014/10/21 - fix check for (invalid) IPv4 when validating hostname against certificate. Do not use inet_aton any longer because it can cause DNS lookups for malformed IP. RT#99448, thanks to justincase[AT]yopmail[DOT]com. - Update PublicSuffix with latest version from publicsuffix.org - lots of new top level domains. - Add exception to PublicSuffix for s3.amazonaws.com - RT#99702, thanks to cpan[AT]cpanel[DOT]net. 2.001 2014/10/21 - Add SSL_OP_SINGLE_(DH|ECDH)_USE to default options to increase PFS security. Thanks to Heikki Vatiainen for suggesting. - Update external tests with currently expected fingerprints of hosts. - Some fixes to make it still work on 5.8.1. 2.000 2014/10/15 - consider SSL3.0 as broken because of POODLE and disable it by default. - Skip live tests without asking if environment NO_NETWORK_TESTING is set. Thanks to ntyni[AT]debian[DOT]org for suggestion. - skip tests which require fork on non-default windows setups without proper fork. Thanks to SHAY for https://github.com/noxxi/p5-io-socket-ssl/pull/18 1.999 2014/10/09 - make sure we don't use version 0.30 of IO::Socket::IP - make sure that PeerHost is checked on all places where PeerAddr is checked, because these are synonyms and IO::Socket::IP prefers PeerHost while others prefer PeerAddr. Also accept PeerService additionally to PeerPort. See https://github.com/noxxi/p5-io-socket-ssl/issues/16 for details. - add ability to use client certificates and to overwrite hostname with util/analyze-ssl.pl. 1.998 2014/09/07 - make client authentication work at the server side when SNI is in by use having CA path and other settings in all SSL contexts instead of only the main one. Based on code from lundstrom[DOT]jerry[AT]gmail[DOT]com, https://github.com/noxxi/p5-io-socket-ssl/pull/15 1.997 2014/07/12 - thanks to return code 1 from Net::SSLeay::library_init if the library needed initialization and 0 if not we can now clearly distinguish if initialization was needed and do not need any work-arounds for perlcc by the user. 1.996 2014/07/12 - move initialization of OpenSSL-internals out of INIT again because this breaks if module is used with require. Since there is no right place to work in all circumstances just document the work-arounds needed for perlcc. RT#97166 1.995 2014/07/11 - RT#95452 - move initialization and creation of OpenSSL-internals into INIT section, so they get executed after compilation and perlcc is happy. - refresh option for peer_certificate, so that it checks if the certificate changed in the mean time (on renegotiation) - fix fingerprint checking - now applies only to topmost certificate - IO::Socket::SSL::Utils - accept extensions within CERT_create - documentations fixes thanks to frioux - fix documentation bug RT#96765, thanks to Salvatore Bonaccorso. 1.994 2014/06/22 - IO::Socket::SSL can now be used as dual-use socket, e.g. start plain, upgrade to SSL and downgrade again all with the same object. See documentation of SSL_startHandshake and chapter Advanced Usage. - try to apply SSL_ca* even if verify_mode is 0, but don't complain if this fails. This is needed if one wants to explicitly verify OCSP lookups even if verification is otherwise off, because otherwise the signature check would fail. This is mostly useful for testing. - reorder documentation of attributes for new, so that the more important ones are at the top. 1.993 2014/06/13 - major rewrite of documentation, now in separate file - rework error handling to distinguish between SSL errors and internal errors (like missing capabilities). - fix handling of default_ca if given during the run of the program (Debian#750646) - util/analyze-ssl.pl - fix hostname check if SNI does not work 1.992 2014/06/01 - set $! to undef before doing IO (accept, read..). On Windows a connection reset could cause SSL read error without setting $!, so make sure we don't keep the old value and maybe thus run into endless loop. 1.991 2014/05/27 - new option SSL_OCSP_TRY_STAPLE to enforce staple request even if VERIFY_NONE - work around for RT#96013 in peer_certificates 1.990 2014/05/27 - added option SSL_ocsp_staple_callback to get the stapled OCSP response and verify it somewhere else - try to fix warnings on Windows again (#95967) - work around temporary OCSP error in t/external/ocsp.t 1.989 2014/05/24 - fix #95881 (warnings on windows), thanks to TMHALL 1.988 2014/05/17 - add transparent support for DER and PKCS#12 files to specify cert and key, e.g. it will autodetect the format - if SSL_cert_file is PEM and no SSL_key_file is given it will check if the key is in SSL_cert_file too 1.987 2014/05/17 - fix t/verify_hostname_standalone.t on systems without usable IDNA or IPv6 #95719, thanks srchulo - enable IPv6 support only if we have a usable inet_pton - remove stale entries from MANIFEST (thanks seen[AT]myfairpoint[DOT]net) 1.986 2014/05/16 - allow IPv4 in common name, because browsers allow this too. But only for scheme www/http, not for rfc2818 (because RC2818 does not allow this). In default scheme IPv6 and IPv4 are allowed in CN. Thanks to heiko[DOT]hund[AT]sophos[DOT]com for reporting the problem. - Fix handling of public suffix. Add exemption for *.googleapis.com wildcard, which should be better not allowed according to public suffix list but actually is used. - Add hostname verification test based on older test of chromium. But change some of the test expectations because we don't want to support IP as SAN DNS and because we enforce a public suffix list (and thus *.co.uk should not be allowed) 1.985 2014/05/15 - make OCSP callback return 1 even if it was called on the server side because of bad setup of the socket. Otherwise we get an endless calling of the OCSP callback. - consider an OCSP response which is not yet or no longer valid a soft error instead of a hard error - fix skip in t/external/ocsp.t in case fingerprint does not match - RT#95633 call EVP_PKEY_free not EVP_KEY_free in IO::Socket::SSL::Utils::KEY_free. Thanks to paul[AT]city-fan[DOT]org - util/analyze.pl - with --show-chain check if chain with SNI is different from chain w/o SNI. 1.984 2014/05/10 - added OCSP support: - needs Net::SSLeay >=1.59 - for usage see documentation of IO::Socket::SSL (examples and anything with OCSP in the name) - new tool util/analyze-ssl.pl which is intended to help in debugging of SSL problems and to get information about capabilities of server. Works also as en example of how to use various features (like OCSP, SNI..) - fix peer_certificates (returns leaf certificate only once on client side) - added timeout for stop_SSL (either with Timeout or with the default timeout for IO::Socket) - fix IO::Socket::SSL::Utils mapping between ASN1_TIME and time_t when local time is not GMT. Use Net::SSLeay::ASN1_TIME_timet if available. - fix t/external/usable_ca.t for system with junk in CA files 1.983 2014/05/03 - fix public suffix handling: ajax.googleapis.com should be ok even if googleapis.com is in public suffix list (e.g. check one level less) #95317, thanks to purification[AT]ukr[DOT]net - usable_ca.t - update fingerprints after heartbleed attack - usable_ca.t - make sure we have usable CA for tested hosts in CA store 1.982 2014/04/24 - fix for using subroutine as argument to set_args_filter_hack 1.981 2014/04/08 - #95432 fix ecdhe Test for openssl1.0.1d, thanks to paul[AT]city-fan[DOT]org - fix detection of openssl1.0.1d (detected 1.0.1e instead) - new function can_ecdh in IO::Socket::SSL 1.980 2014/04/08 - fixed incorrect calculation of certificate fingerprint in get_fingerprint* and comparison in SSL_fingerprint. Thanks to david[DT]palmer[AT]gradwell[DOT]com for reporting. - disable elliptic curve support for openssl 1.0.1d on 64bit because of openssl rt#2975 1.979 2014/04/06 - hostname checking: - configuration of 'leftmost' is renamed to 'full_label', but the old version is kept for compatibility reasons. - documentation of predefined schemes fixed to match reality 1.978 2014/04/04 - RT#94424 again, fix test on older openssl version with no SNI support 1.977 2014/04/04 - fix publicsuffix for IDNA, more tests with various IDNA libs RT#94424. Thanks to paul[AT]city-fan[DOT]org - reuse result of IDN lib detection from PublicSuffix.pm in SSL.pm - add more checks to external/usable_ca.t. Now it is enough that at least one of the hosts verifies against the builtin CA store - add openssl and Net::SSleay version to diagnostics in load test 1.976 2014/04/03 - added public prefix checking to verification of wildcard certificates, e.g. accept *.foo.com but not *.co.uk. See documentation of SSL_verifycn_publicsuffix and IO::Socket::SSL::PublicSuffix Thanks to noloader for pointing out the problem. 1.975 2014/04/02 - BEHAVIOR CHANGE: work around TEA misfeature on OS X builtin openssl, e.g. guarantee that only the explicitly given CA or the openssl default CA will be used. This means that certificates inside the OS X keyring will no longer be used, because there is no way to control the use by openssl (e.g. certificate pinning etc) - make external tests run by default to make sure default CA works on all platforms, it skips automatically on network problems like timeouts or ssl interception, can also use http(s)_proxy environment variables 1.974 2014/04/02 - new function peer_certificates to get the whole certificate chain, needs Net::SSLeay>=1.58 - extended IO::Socket::Utils::CERT_asHash to provide way more information, like issuer information, cert and pubkey digests, all extensions, CRL distributions points and OCSP uri 1.973 2014/03/25 - with SSL_ca certificate handles can now be used additionally to SSL_ca_file and SSL_ca_path - do not complain longer if SSL_ca_file and SSL_ca_path are both given, instead add both as options to the CA store - Shortcut 'issuer' to give both issuer_cert and issuer_key in CERT_create. 1.972 2014/03/23 - make sure t/external/usable_ca.t works also with older openssl without support for SNI. RT#94117. Thanks to paul[AT]city-fan[DOT]org 1.971 2014/03/22 - try to use SSL_hostname for hostname verification if no SSL_verifycn_name is given. This way hostname for SNI and verification can be specified in one step. - new test program example/simulate_proxy.pl 1.970 2014/03/19 - fix rt#93987 by making sure sub default_ca does use a local $_ and not a version of an outer scope which might be read-only. Thanks to gshank 1.969 2014/03/13 - fix set_defaults to match documentation regarding short names - new function set_args_filter_hack to make it possible to override bad SSL settings from other code at the last moment. - determine default_ca on module load (and not on first use in each thread) - don't try default hostname verification if verify_mode 0 - fix hostname verification when reusing context 1.968 2014/03/13 - BEHAVIOR CHANGE: removed implicit defaults of certs/server-{cert,key}.pem for SSL_{cert,key}_file and ca/,certs/my-ca.pem for SSL_ca_file. These defaults were depreceated since 1.951 (2013/7/3). - Usable CA verification path on Windows etc: Do not use Net::SSLeay::CTX_set_default_verify_paths any longer to set system/build dependent default verification path, because there was no way to retrieve these default values and check if they contained usable CA. Instead re-implement the same algorithm and export the results with public function default_ca() and make it possible to overwrite it. Also check for usable verification path during build. If no usable path are detected require Mozilla::CA at build and try to use it at runtime. 1.967 2014/02/06 - verify the hostname inside a certificate by default with a superset of common verification schemes instead of not verifying identity at all. For now it will only complain if name verification failed, in the future it will fail certificate verification, forcing you to set the expected SSL_verifycn_name if you want to accept the certificate. - new option SSL_fingerprint and new methods get_fingerprint and get_fingerprint_bin. Together they can be used to selectively accept specific certificates which would otherwise fail verification, like self-signed, outdated or from unknown CAs. This makes another reason to disable verification obsolete. - Utils: - default RSA key length 2048 - digest algorithm to sign certificate in CERT_create can be given, defaults to SHA-256 - CERT_create can now issue non-CA selfsigned certificate - CERT_create add some more useful constraints to certificate - spelling fixes, thanks to ville[dot]skytta[at]iki[dot]fi 1.966 2014/01/21 - fixed bug introduced in 1.964 - disabling TLSv1_2 worked no longer with specifying !TLSv12, only !TLSv1_2 worked - fixed leak of session objects in SessionCache, if another session replaced an existing session (introduced in 1.965) 1.965 2014/01/16 - new key SSL_session_key to influence how sessions are inserted and looked up in the clients session cache. This makes it possible to share sessions over different ip:host (like required with some FTPS servers) - t/core.t - handle case, were default loopback source is not 127.0.0.1, like in FreeBSD jails 1.964 2014/01/15 - Disabling TLSv1_1 did not work, because the constant was wrong. Now it gets the constants from calling Net::SSLeay::SSL_OP_NO_TLSv1_1 etc - The new syntax for the protocols is TLSv1_1 instead of TLSv11. This matches the syntax from OpenSSL. The old syntax continues to work in SSL_version. - New functions get_sslversion and get_sslversion_int which get the SSL version of the establish session as string or int. - disable t/io-socket-inet6.t if Acme::Override::INET is installed 1.963 2014/01/13 - fix behavior of stop_SSL: for blocking sockets it now enough to call it once, for non-blocking it should be called again as long as EAGAIN and SSL_ERROR is set to SSL_WANT_(READ|WRITE). - don't call blocking if start_SSL failed and downgraded socket has no blocking method, thanks to tokuhirom - documentation enhancements: - special section for differences to IO::Socket - describe problem with blocking accept on non-blocking socket - describe arguments to new_from_fd and make clear, that for upgrading an existing IO::Socket start_SSL should be used directly 1.962 2013/11/27 - work around problems with older F5 BIG-IP by offering fewer ciphers on the client side by default, so that the client hello stays below 255 byte 1.961 2013/11/26 - IO::Socket::SSL::Utils::CERT_create can now create CA-certificates which are not self-signed (by giving issuer_*) 1.960 2013/11/12 only documentation enhancements: - clarify with text and example code, that within event loops not only select/poll should be used, but also pending has to be called. - better introduction into SSL, at least mention anonymous authentication as something you don't want and should take care with the right cipher - make it more clear, that user better does not change the cipher list, unless he really know what he is doing 1.959 2013/11/12 - bugfix test core.t windows only 1.958 2013/11/11 - cleanup: remove workaround for old IO::Socket::INET6 but instead require at least version 2.55 which is now 5 years old - fix t/session.t #RT90240, thanks to paul[AT]city-fan[DOT]org 1.957 2013/11/11 - fixed t/core.t: test uses cipher_list of HIGH, which includes anonymous authorization. With the DH param given by default since 1.956 old versions of openssl (like 0.9.8k) used cipher ADH-AES256-SHA (e.g. anonymous authorization) instead of AES256-SHA and thus the check for the peer certificate failed (because ADH does not exchanges certificates). Fixed by explicitly specifying HIGH:!aNULL as cipher RT#90221, thanks to paul[AT]city-fan[DOT]org - cleaned up tests: - remove ssl_settings.req and 02settings.t, because all tests now create a simple socket at 127.0.0.1 and thus global settings are no longer needed. - some tests did not have use strict(!), fixed it. - removed special handling for older Net::SSLeay versions, which are less than our minimum requirement - some syntax enhancements, removed some SSL_version and SSL_cipher_list options where they were not really needed 1.956 2013/11/10 lots of behavior changes for more secure defaults: - BEHAVIOR CHANGE: make default cipher list more secure, especially - no longer support MD5 by default (broken) - no longer support anonymous authentication by default (vulnerable to man in the middle attacks) - prefer ECDHE/DHE ciphers and add necessary ECDH curve and DH keys, so that it uses by default forward secrecy, if underlying Net::SSLeay/openssl supports it - move RC4 at the end, e.g. 3DES is preferred (BEAST attack should hopefully been fixed and now RC4 is considered less safe than 3DES) - default SSL_honor_cipher_order to 1, e.g. when used as server it tries to get the best cipher even if client prefers other ciphers PLEASE NOTE that this might break connections with older, less secure implementations. In this case revert to 'ALL:!LOW:!EXP:!aNULL' or so. - BEHAVIOR CHANGE: SSL_cipher_list now gets set on context not SSL object and thus gets reused if context gets reused. PLEASE NOTE that using SSL_cipher_list together with SSL_reuse_ctx has no longer effect on the ciphers of the context. - rework hostname verification schemes - add rfc names as scheme (e.g. 'rfc2818',...) - add SIP, SNMP, syslog, netconf, GIST - BEHAVIOR CHANGE: fix SMTP - now accept wildcards in CN and subjectAltName - BEHAVIOR CHANGE: fix IMAP, POP3, ACAP, NNTP - now accept wildcards in CN - BEHAVIOR CHANGE: anywhere wildcards like www* now match only 'www1', 'www2'.. but not 'www' - anywhere wildcards like x* are no longer applied to IDNA names (which start with 'xn--') - fix crash of Utils::CERT_free - support TLSv11, TLSv12 as handshake protocols 1.955 2013/10/11 - support for forward secrecy using ECDH, if the Net::SSLeay/openssl version supports it. 1.954 2013/9/15 - accept older versions of ExtUtils::MakeMaker and add meta information like link to repository only for newer versions. 1.953 2013/7/22 - fixes to IO::Socket::SSL::Utils, thanks to rurban[AT]x-ray[DOT]at, RT#87052 1.952 2013/7/11 - fix t/acceptSSL-timeout.t on Win32, RT#86862 1.951 2013/7/3 - better document builtin defaults for key,cert,CA and how they are depreceated - use Net::SSLeay::CTX_set_default_verify_paths to use openssl's builtin defaults for CA unless CA path/file was given (or IO::Socket::SSL builtins used) 1.950 2013/7/3 - MAJOR BEHAVIOR CHANGE: ssl_verify_mode now defaults to verify_peer for client. Until now it used verify_none, but loudly complained since 1.79 about it. It will not complain any longer, but the connection might probably fail. Please don't simply disable ssl verification, but instead set SSL_ca_file etc so that verification succeeds! - MAJOR BEHAVIOR CHANGE: it will now complain if the builtin defaults of certs/my-ca.pem or ca/ for CA and certs/{server,client}-{key,cert}.pem for cert and key are used, e.g. no certificates are specified explicitly. In the future these insecure (relative path!) defaults will be removed and the CA replaced with the system defaults. v1.94 2013.06.01 - Makefile.PL reported wrong version of openssl, if Net::SSLeay was not installed instead of reporting missing dependency to Net::SSLeay. v1.93 2013.05.31 - need at least OpenSSL version 0.9.8 now, since last 0.9.7 was released 6 years ago. Remove code to work around older releases. - changed AUTHOR in Makefile.PL from array back to string, because the array feature is not available in MakeMaker shipped with 5.8.9 (RT#85739) v1.92 2013.05.30 - Intercept: use sha1-fingerprint of original cert for id into cache unless otherwise given - Fix pod error in IO::Socket::SSL::Utils RT#85733 v1.91 2013.05.30 - added IO::Socket::SSL::Utils for easier manipulation of certificates and keys - moved SSL interception into IO::Socket::SSL::Intercept and simplified it using IO::Socket::SSL::Utils - enhance meta information in Makefile.PL v1.90 2013.05.27 - RT#85290, support more digest, especially SHA-2. Thanks to ujvari[AT]microsec[DOT]hu - added support for easy SSL interception (man in the middle) based on ideas found in mojo-mitm proxy (which was written by Karel Miko) - make 1.46 the minimal required version for Net::SSLeay, because it introduced lots of useful functions. v1.89 2013.05.14 - if IO::Socket::IP is used it should be at least version 0.20, otherwise we get problems with HTTP::Daemon::SSL and maybe others (RT#81932) - Spelling corrections, thanks to dsteinbrunner v1.88 2013.05.02 - consider a value of '' the same as undef for SSL_ca_(path|file), SSL_key* and SSL_cert* - some apps like Net::LDAP use it that way. Thanks to alexander[AT]kuehn[AT]nagilum[DOT]de for reporting the problem. v1.87 2013.04.24 - RT#84829 - complain if given SSL_(key|cert|ca)_(file|path) do not exist or if they are not readable. Thanks to perl[AT]minty[DOT]org - fix use of SSL_key|SSL_file objects instead of files, broken with 1.83 v1.86 2013.04.17 - RT#84686 - don't complain about SSL_verify_mode is SSL_reuse_ctx, thanks to CLEACH v1.85 2013.04.14 - probe for available modules with local __DIE__ and __WARN__handlers. fixes RT#84574, thanks to FRAZER - fix warning, when IO::Socket::IP is installed and inet6 support gets explicitly requested. RT#84619, thanks to Prashant[DOT]Tekriwal[AT]netapp[DOT]com v1.84 2013.02.15 - disabled client side SNI for openssl version < 1.0.0 because of RT#83289 - added functions can_client_sni, can_server_sni, can_npn to check availability of SNI and NPN features. Added more documentation for SNI and NPN. v1.83_1 2013.02.14 - separated documentation of non-blocking I/O from error handling - changed and documented behavior of readline to return the read data on EAGAIN/EWOULDBLOCK in case of non-blocking socket. See https://github.com/noxxi/p5-io-socket-ssl/issues/1, thanks to mytram v1.83 2013.02.03 - Server Name Indication (SNI) support on the server side, inspired by patch provided by karel[DOT]miko[AT]gmail[DOT]com. https://rt.cpan.org/Ticket/Display.html?id=82761 - reworked part of the documentation, like providing better examples. v1.82 2013.01.28 - sub error sets $SSL_ERROR etc only if there really is an error, otherwise it will keep the latest error. This causes IO::Socket::SSL->new.. to report the correct problem, even if the problem is deeper in the code (like in connect) - correct spelling, rt#8270. Thanks to ETHER v1.81 2012.12.06 - deprecated set_ctx_defaults, new name ist set_defaults (but old name still available) - changed handling of default path for SSL_(ca|cert|key)* keys: either if one of these keys is user defined don't add defaults for the others, e.g. don't mix user settings and defaults - cleaner handling of module defaults vs. global settings vs. socket specific settings. Global and socket specific settings are both provided by the user, while module defaults not. - make IO::Socket::INET6 and IO::Socket::IP specific tests run both, even if both modules are installed by faking a failed load of the other module. v1.80 2012.11.30 - removed some warnings in test (missing SSL_verify_mode => 0) which caused tests to hang on Windows. https://rt.cpan.org/Ticket/Display.html?id=81493 v1.79 2012.11.25 - prepare transition to a more secure default for SSL_verify_mode. The use of the current default SSL_VERIFY_NONE will cause a big warning for clients, unless SSL_verify_mode was explicitly set inside the application to this insecure value. In the near future the default will be SSL_VERIFY_PEER, and thus causing verification failures in unchanged applications. v1.78 2012.11.25 - use getnameinfo instead of unpack_sockaddr_in6 to get PeerAddr and PeerPort from sockaddr in _update_peer, because this provides scope too. Thanks to bluhm[AT]genua[DOT]de. - work around systems which don't defined AF_INET6 https://rt.cpan.org/Ticket/Display.html?id=81216 Thanks to GAAS for reporting v1.77 2012.10.05 - update_peer for IPv6 also, applied fix to https://rt.cpan.org/Ticket/Display.html?id=79916 by tlhackque[AT]yahoo[DOT]com v1.76 2012.06.18 - no longer depend on Socket.pm 1.95 for inet_pton, but use Socket6.pm if no current Socket.pm is available. Thanks to paul[AT]city-fan[DOT]org for pointing out the problem and providing first patch v1.75 2012.06.15 - made it possible to explicitly disable TLSv11 and TLSv12 in SSL_version v1.74_2 2012.06.07 - fixed documentation errors, reported by MARSCHAP https://rt.cpan.org/Ticket/Display.html?id=77690 v1.74_1 2012.06.07 - add support to IO::Socket::IP which support inet6 and inet4 by integrating patch from PEVANS for https://rt.cpan.org/Ticket/Display.html?id=75218 v1.74 2012.05.13 - accept a version of SSLv2/3 as SSLv23, because older documentation could be interpreted like this v1.73 2012.05.11 - make test t/dhe.t hopefully work for more version of openssl Thanks to paul[AT]city-fan[DOT]org for providing bug reports and testing environment v1.72 2012.05.10 - set DEFAULT_CIPHER_LIST to ALL:!LOW instead of HIGH:!LOW Thanks to dcostas[AT]gmail[DOT]com for problem report v1.71 2012.05.09 - 1.70 done right. Also don't disable SSLv2 ciphers, SSLv2 support is better disabled by the default SSL_version of 'SSLv23:!SSLv2' v1.70 2012.05.08 - make it possible to disable protocols using SSL_version, make SSL_version default to 'SSLv23:!SSLv2' v1.69 2012.05.08 - re-added workaround in t/dhe.t v1.68 2012.05.07 - remove SSLv2 from default cipher list, which makes failed tests after last change work again, fix behavior for empty cipher list (use default) v1.67 2012.05.07 - https://rt.cpan.org/Ticket/Display.html?id=76929 thanks to d[DOT]thomas[AT]its[DOT]uq[DOT]edu[DOT]au for reporting - if no explicit cipher list is given it will now default to ALL:!LOW instead of the openssl default, which usually includes weak ciphers like DES. - new config key SSL_honor_cipher_order and documented how to use it to fight BEAST attack. v1.66 2012.04.16 - make it thread safer, thanks to bug report from vega[DOT]james[AT]gmail [DOT]com, https://rt.cpan.org/Ticket/Display.html?id=76538 v1.65 2012.04.16 - added NPN (Next Protocol Negotiation) support based on patch from kmx https://rt.cpan.org/Ticket/Display.html?id=76223 v1.64 2012.04.06 - clarify some behavior regarding hostname verification. Thanks to DOHERTY for reporting. v1.63 2012.04.06 - applied patch of DOUGDUDE to ignore die from within eval to make tests more stable on Win32, https://rt.cpan.org/Ticket/Display.html?id=76147 v1.62 2012.03.28 - small fix to last version v1.61 2012.03.27 - call CTX_set_session_id_context so that servers session caching works with client certificates too. https://rt.cpan.org/Ticket/Display.html?id=76053 v1.60 2012.03.20 - don't make blocking readline if socket was set nonblocking, but return as soon no more data are available https://rt.cpan.org/Ticket/Display.html?id=75910 - fix BUG section about threading so that it shows package as thread safe as long as Net::SSLeay >= 1.43 is used https://rt.cpan.org/Ticket/Display.html?id=75749 v1.59 2012.03.08 - if SSLv2 is not supported by Net::SSLeay set SSL_ERROR with useful message when attempting to use it. - modify constant declarations so that 5.6.1 should work again v1.58 2012.02.26 - fix t/dhe.t again to enable the workaround only for newer openssl versions, because this would cause failures on older versions v1.57 2012.02.26 - fix t/dhe.t for openssl 1.0.1 beta by forcing tlsv1, so that it does not complain about the too small rsa key which it should not use anyway. Thanks to paul[AT]city-fan[DOT]org for reporting. https://rt.cpan.org/Ticket/Display.html?id=75165 v1.56 2012.02.22 - add automatic or explicit (via SSL_hostname) SNI support, needed for multiple SSL hostnames with same IP. Currently only supported for the client. v1.55 2012.02.20 - work around IO::Sockets work around for systems returning EISCONN etc on connect retry for non-blocking sockets by clearing $! if SUPER::connect returned true. https://rt.cpan.org/Ticket/Display.html?id=75101 Thanks for Manoj Kumar for reporting. v1.54 2012.01.11 - return 0 instead of undef in SSL_verify_callback to fix uninitialized warnings. Thanks to d[DOT]thomas[AT]its[DOT]uq[DOT]edu[DOT]au for reporting the bug and MIKEM for the fix. https://rt.cpan.org/Ticket/Display.html?id=73629 v1.53 2011.12.11 - kill child in t/memleak_bad_handshake.t if test fails https://rt.cpan.org/Ticket/Display.html?id=73146 Thanks to CLEACH ofr reporting v1.52 2011.12.07 - fix syntax error in t/memleak_bad_handshake.t thanks to cazzaniga[DOT]sandro[AT]gmail[DOT]com for reporting v1.51 2011.12.06 - disable t/memleak_bad_handshake.t on AIX, because it might hang https://rt.cpan.org/Ticket/Display.html?id=72170 v1.50 2011.12.06 Thanks to HMBRAND for reporting and Rainer Tammer tammer[AT]tammer[DOT]net for providing access to AIX system v1.49 2011.10.28 - another regression for readline fix, this time it failed to return lines at eof which don't end with newline. Extended t/readline.t to catch this case and the fix for 1.48 Thanks to christoph[DOT]mallon[AT]gmx[DOT]de for reporting v1.48 2011.10.26 - bugfix for readline fix in 1.45. If the pending data where false (like '0') it failed to read rest of line. Thanks to Victor Popov for reporting https://rt.cpan.org/Ticket/Display.html?id=71953 v1.47 2011.10.21 - fix for 1.46 - check for mswin32 needs to be /i. Thanks to Alexandr Ciornii for reporting v1.46 2011.10.18 - disable test t/signal-readline.t on windows, because signals are not relevant for this platform and test does not work. https://rt.cpan.org/Ticket/Display.html?id=71699 v1.45 2011.10.12 - fix readline to continue when getting interrupt waiting for more data. Thanks to kgc[AT]corp[DOT]sonic[DOT]net for reporting problem v1.44 2011.05.27 - fix invalid call to inet_pton in verify_hostname_of_cert when identity should be verified as ipv6 address, because it contains colon. v1.43_1 2011.05.12 - try to make t/nonblock.t more stable, especially on Mac OS X v1.43 2011.05.11 - fix t/nonblock.t - stability improvements t/inet6.t v1.42 2011.05.10 - add SSL_create_ctx_callback to have a way to adjust context on creation. https://rt.cpan.org/Ticket/Display.html?id=67799 - describe problem of fake memory leak because of big session cache and how to fix it, see https://rt.cpan.org/Ticket/Display.html?id=68073 v1.41 2011.05.09 - fix issue in stop_SSL where it did not issue a shutdown of the SSL connection if it first received the shutdown from the other side. Thanks to fencingleo[AT]gmail[DOT]com for reporting - try to make t/nonblock.t more reliable, at least report the real cause of ssl connection errors v1.40 2011.05.02 - integrated patch from GAAS to get IDN support from URI. https://rt.cpan.org/Ticket/Display.html?id=67676 v1.39_1 2011.05.02 - fix in exampel/async_https_server. Thanks to DetlefPilzecker[AT]web[DOT]de for reporting v1.39 2011.03.03 - fixed documentation of http verification: wildcards in cn is allowed v1.38_1 2011.01.24 - close should undef _SSL_fileno, because the fileno is no longer valid (SSL connection and socket are closed) v1.38 2011.01.18 - fixed wildcards_in_cn setting for http (wrongly set in 1.34 to 1 instead of anywhere). Thanks to dagolden[AT]cpan[DOT]org for reporting https://rt.cpan.org/Ticket/Display.html?id=64864 v1.37 2010.12.09 - don't complain about invalid certificate locations if user explicitly set SSL_ca_path and SSL_ca_file to undef. Assume that user knows what he is doing and will work around the problems by itself. http://rt.cpan.org/Ticket/Display.html?id=63741 v1.36 2010.12.08 - update documentation for SSL_verify_callback based on https://rt.cpan.org/Ticket/Display.html?id=63743 https://rt.cpan.org/Ticket/Display.html?id=63740 v1.35 2010.12.06 - if verify_mode is not VERIFY_NONE and the ca_file/ca_path cannot be verified as valid it will no longer fall back to VERIFY_NONE but throw an error. Thanks to Salvatore Bonaccorso and Daniel Kahn Gillmor for pointing out the problem, see also http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=606058 v1.34 2010.11.01 - scheme http for certificate verification changed to wildcards_in_cn=1, because according to rfc2818 this is valid and also seen in the wild - if upgrading socket from inet to ssl fails due to handshake problems the socket gets downgraded, but is still open. See https://rt.cpan.org/Ticket/Display.html?id=61466 - deprecate kill_socket, just use close() v1.33 2010.03.17 - attempt to make t/memleak_bad_handshake.t more stable, it fails for unknown reason on various systems - fix hostname checking: an IP should only be checked against subjectAltName GEN_IPADD, never against GEN_DNS or CN. Thanks to rusch[AT]genua[DOT]de for bug report v1.32 2010.02.22 - Makefile.PL: die if Scalar::Util has no dualvar support instead of only complaining. Thanks to w[DOT]phillip[DOT]moore[AT]gmail[DOT]com for reporting. v1.31 2009.09.25 - add and export constants for SSL_VERIFY_* - set SSL_use_cert if cert is given and not SSL_server - support alternative CRL file with SSL_crl_file thanks to patch of w[DOT]phillip[DOT]moore[AT]gmail[DOT]com v1.30_3 2009.09.03 - make t/memleak_bad_handshake.t more stable (increase listen queue, ignore errors on connect, don't run on windows..) v1.30_2 2009.09.01 - t/memleak_bad_handshake.t don't write errors with ps to stderr, -o vsize argument is not supported on all platforms, just skip test then v1.30_1 2009.08.31 - make sure that idn_to_ascii gets no \0 bytes from identity, because it simply cuts the string their (using C semantics). Not really a security problem because IDN like identity is provided by user in hostname, not by certificate. v1.30 2009.08.19 - fix test t/memleak_bad_handshake.t v1.29 2009.08.19 - fixed thanks for version 1.28 v1.28 2009.08.19 - fix memleak when SSL handshake failed. Thanks richardhundtu[AT]gmail[DOT]com v1.27 2009.07.24 - changed possible local/utf-8 depended \w in some regex against more explicit [a-zA-Z0-9_]. Fixed one regex, where it assumed, that service names can't have '-' inside - fixed bug https://rt.cpan.org/Ticket/Display.html?id=48131 where eli[AT]dvns[DOT]com reported warnings when perl -w was used. While there made it more aware of errors in Net::ssl_write_all (return undef not 0 in generic_write) v1.26 2009.07.03 - SECURITY BUGFIX! fix Bug in verify_hostname_of_cert where it matched only the prefix for the hostname when no wildcard was given, e.g. www.example.org matched against a certificate with name www.exam in it Thanks to MLEHMANN for reporting v1.25 2009.07.02 - t/nonblock.t: increase number of bytes written to fix bug with OS X 10.5 https://rt.cpan.org/Ticket/Display.html?id=47240 v1.24 2009.04.01 - add verify hostname scheme ftp, same as http - renew test certificates again (root CA expired, now valid for 10 years) v1.23 2009.02.23 - if neither SSL_ca_file nor SSL_ca_path are known (e.g. not given and the default values have no existing file|path) disable checking of certificates, but carp about the problem - new test certificates, the old ones expired and caused tests to fail v1.22 2009.01.24 - Net::SSLeay stores verify callbacks inside hash and never clears them, so set verify callback to NULL in destroy of context v1.21 2009.01.22 - auto verification of name in certificate created circular reference between SSL and CTX object with the verify_callback, which caused the objects to be destroyed only at program end. Fix it be no longer access $self from inside the callback. Thanks to odenbach[AT]uni-paderborn[DOT]de for reporting v1.20 2009.01.15 - only changes on test suite to make it ready for win32 (tested with strawberry perl 5.8.8) v1.19 2008.12.31 - fix verifycn_name autodetection from PeerAddr/PeerHost v1.18 2008.11.17 - fixed typo in argument: wildcars_in_cn -> wildcards_in_cn http://rt.cpan.org/Ticket/Display.html?id=40997 thanks to ludwig[DOT]nussel[AT]suse[DOT]de for reporting v1.17 2008.10.13 - no code changes, publish v.16_3 as v.17 because it looks better than v.16 - document win32 behavior regarding non-blocking and timeouts v1.16_3 2008.09.25 - fix t/nonblock.t with workaround for problems with IO::Socket::INET on some systems (Mac,5.6.2) where it cannot do nonblocking connect and leaves socket blocked. - make some tests less verbose by fixing diag in t/testlib.t (send output to STDOUT not STDERR and prefix with '#') v1.16_2 2008.09.24 - work around Bug in IO::Socket::INET6 on BSD systems http://rt.cpan.org/Ticket/Display.html?id=39550 by setting Domain based on PeerAddr Thanks to srezic for report and support - remove tests of recv/send from t/core.t. Might badly interact with SSL handshake and cause crashes as seen on OS X 10.4 v1.16_1 2008.09.19 - better support for IPv6: - IPv6 is enabled by default if IO::Socket::INET6 is available - t/inet6.t for basic tests v1.16 2008.09.19 - change code for SSL_check_crl to use X509_STORE_set_flags instead of X509_STORE_CTX_set_flags based on bug report from - change opened() to report -1 if the IO::Handle is open, but the SSL connection failed, needed with HTTP::Daemon::SSL which will send an error message over the unencrypted socket v1.15 - change internal behavior when SSL handshake failed (like when verify callback returned an error) in the hope to fix spurious errors in t/auto_verify_hostname.t v1.14 - added support for verification of hostname from certificate including subjectAltNames, support for IDN etc based on patch and input from christopher[AT]odenbachs[DOT]de and achim[AT]grolmsnet[DOT]de. It is also possible to get more information from peer_certificate based on this patch. See documentation for peer_certificate and verify_hostname - automatic verification of hostnames with SSL_verifycn_scheme and SSL_verifycn_name - global setting of default context options like SSL_verifycn_scheme, SSL_verify_mode with set_ctx_defaults - fix import of inet4,inet6 which got broken within 1.13_X. Thanks to for bugreport and patch - clarified and enhanced debugging support based on bugreport http://rt.cpan.org/Ticket/Display.html?id=32960 - put information into README regarding the supported and recommended version of Net::SSLeay v1.13 - removed CLONE_SKIP which was added in 1.03 because this breaks windows forking. Handled threads/windows forking better by making sure that CTX from Net::SSLeay gets not freed multiple times from different threads after cloning/forking - removed setting LocalPort to 0 in tests, instead leave it undef if a random port should be allocated. This should fix build problems with 5.6.1. Thanks to v1.12 - treat timeouts of 0 for accept_SSL and connect_SSL like no timeout, like IO::Socket does. v1.11 - fixed errors in accept_SSL which would work when called from start_SSL but not from accept v1.10 - start_SSL, accept_SSL and connect_SSL have argument for Timeout so that the SSL handshake will not block forever. Only used if the socket is blocking. If not set the Timeout value from the underlying IO::Socket is used v1.09 - new method stop_SSL as opposite of start_SSL based on an idea of Bron Gondwana To support this method the SSL_shutdown handling had to be fixed, e.g. in close a proper unidirectional shutdown should be done while in stop_SSL a bidirectional shutdown - try to make it clearer that thread support is buggy v1.08 - make sure that Scalar::Util has support for dualvar (Makefile.PL,SSL.pm) because the perl-only version has has no dualvar v1.07 - fix t/nonblock.t on systems which have by default a larger socket buffer. Set SO_SNDBUF explicitly with setsockopt to force smaller writes on the socket v1.06 - instead of setting undef args to '' in configure_SSL drop them. This makes Net::SMTP::SSL working again because it does not give LocalPort of '' to IO::Socket::INET any more v1.05 - make session cache working even if the IO::Socket::SSL object was not created with IO::Socket::SSL->new but with IO::Socket::SSL->start_SSL on an established socket v1.04 - added way to create SSL object with predefined session cache, thus making it possible to share the cache between objects even if the rest of the context is not shared key SSL_session_cache Note that the arguments of IO::Socket::SSL::SessionCache::new changed (but you should never have used this class directly because it's internal to IO::Socket::SSL) v1.03 - add CLONE_SKIP as proposed by Jarrod Johnson jbjohnso at us dot ibm dot com v1.02 - added some info to BUGS and to BUGS section of pod - added TELL and BINMODE to IO::Socket::SSL::SSL_HANDLE, even if they do nothing useful. - all tests allocate now the ports dynamically, so there should be no longer a conflict with open ports on the system where the tests run v1.01 - work around Bug in Net::HTTPS where it defines sub blocking as {}, e.g. force scalar context when calling sub blocking (in IO::Socket::SSL::write) see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=383106 v1.0 - fix deprecated and practically undocumented function get_peer_certificate so that LWP Net::HTTPS works again - set arg 'Blocking' while calling SUPER::configure only if it was set by the caller to work around Problem in LWP Net::HTTPS v0.999 - If SSL_cipher_list is not given it uses the openssl default instead of setting it to 'ALL:!LOW:!EXP' like before. The old value included ADH and this might be a bad idea, see BUGS why. v0.998 - declare socket as opened before calling fatal_ssl_error because the SSL_error_trap set up from HTTP::Daemon needs this - accept_SSL sets errors on $socket (the accepted socket) not $self (the listening socket if called from accept) so it can be queried from SSL_error_trap - note in BUGS section that IO::Socket::SSL is not thread-safe v0.997 - fix readline (e.g. getline,getlines,<>) so that it behaves regarding $/ like written in the $/ documentation. v0.996 - removed links and comments to unofficial release of Net::SSLeay, because there is a newer version already v0.995 - add support for Diffie Hellman Key Exchange. See parameter SSL_dh_file and SSL_dh. v0.994 - hide DEBUG statements and remove test to load Debug.pm because packages like SpamAssassin cannot cope with it (at least the OpenBSD port) v0.993 - added SSL_cert and SSL_key parameter which do not take a file name like SSL_cert_file and SSL_key_file but an internal X509* resp. EVP_PKEY* value. Useful for dynamically created certificates and keys. - added test for sysread/syswrite behavior (which was changed in v0.991) v0.992 - _set_rw_error does $!||=EAGAIN only if error is one of SSL_WANT_READ|SSL_WANT_WRITE (patch from Mike Smith ) - Fix Makefile.PL to allow detection of failures in PREREQ_PM (http://rt.cpan.org/Public/Bug/Display.html?id=20563, patch by alexchorny at gmail dot com) v0.991 - sysread and syswrite ar no longer the same as read and write, but can return already if only parts of the data are read or written (which is the usual semantic for sysread and syswrite) This should fix problems with HTTP::Daemon::SSL v0.99 - just upgrade Version number because I've screwed up upload of v0.98 to cpan v0.98 - Maintainer changed to - Better support for nonblocking sockets: . exports $SSL_ERROR which contains the latest error from the openssl library. Exports constants SSL_WANT_READ and SSL_WANT_WRITE es special errors which will be set if openssl wants to write or read during nonblocking connects, accepts, reads or writes. . accept,accept_SSL,connect and connect_SSL don't block anymore if the socket is nonblocking. Instead $! will be set from the underlying IO::Socket::INET connect or accept if it failed there (usually EAGAIN or EINPROGRESS) or if the underlying openssl needs to read or write $! will be set to EAGAIN and $SSL_ERROR will be set to SSL_WANT_READ or SSL_WANT_WRITE . syswrite returns undef and sets $!,$SSL_ERROR if it fails to write instead of returning 0. - Bugfixes (http://rt.cpan.org/Public/Bug/Display.html?id=Bugid) . Bug 18439: fileno 0 should be valid . Bug 15001: sysread interprets buffer "0" as "" - peer_certificate returns X509 struct string if no field for extraction was specified - get_peer_certificate returns the certificate instead of the IO::Socket::SSL object v0.97 - Writes now correctly return errors. (Problem noted by Dominique Quatravaux ). - CA paths now work without passing an empty SSL_ca_file argument. (Problem found by Phil Pennock, ). - IO::Socket::SSL now automatically passes Proto => tcp (if not already specified) to IO::Socket::INET to work around /etc/services files with udp entries listed first. (Fix suggested by Phil Pennock). - $socket->accept() now returns the peer address in array context for better conformance with IO::Socket::INET. However, if you were doing "map { $_->accept } (@sockets)", or similar tricks, you will need to use "scalar" to get the old behavior back. (Problem noted by Nils Sowen, ). - IO::Socket::SSL should now properly block on reads larger than the buffer size of Net::SSLeay. (Problem found by Eric Jergensen, ). - IO::Socket::SSL should now send CA Certs (if necessary) along with certificates. (Problem found by ). - Timeouts should now work, but be aware that if multiple reads/writes are necessary to complete a connection, then each one may have a separate timeout. (Request from Dominique Quatravaux ). - In certain cases, start_SSL() would misplace a socket's fileno, causing problems with starting SSL. This should now be fixed. (Problem found by ). - IO::Socket::SSL now requires a minimum of Net::SSLeay 1.21. --- Old Versions -------------------------------------------------- v0.96 2004.4.30 - Makefile's error messages now correct if output is redirected (patch from Ilya Zakharevich ). - Non-blocking connects/accepts now work (Problem found by Uri Guttman ). - new_from_fd() now works. - getline() and <> in scalar context now return undef instead of '' if the read failed. (Problem found by Christian Gilmore ). - Broken pipe signals are now ignored during socket close to prevent a SSL shutdown message from killing the parent program. (Problem found by Christian Gilmore). - Tests should proceed much more quickly, and a semi-race was fixed, meaning that on slow machines the tests should be more reliable. - Check for Scalar::Util and Weakref now uses default $SIG{__DIE__} instead of a potentially user-altered one (suggestion from Olaf Schneider ). This only applies to Perl 5.6.0 & above. - Session caching support (patch from Marko Asplund ). - set_default_context() added to alter the behavior of modules that use IO::Socket::SSL from the main program. - get_ssl_object() renamed to _get_ssl_object() to reflect the fact that it's only supposed to be used internally (not that you should have cared, of course). - Added patch for Net::SSLeay to take advantage of client-side session caching. v0.95 2003.8.25 - Changed PeerAddr in example/ssl_client.pl back to localhost. - Update of examples to automatically switch to the proper directory if they cannot find the necessary SSL certificates. - Minor documentation update with more INET6 info. - Corrected some error messages for IO::Socket::INET6. - Better opened() behavior when sockets close unexpectedly. - Added note about random number generators for Solaris users (Problem found by Christian Gilmore ). - Added support for WeakRef and Scalar::Util to allow IO::Socket::SSL objects to auto-destroy themselves when they go out of scope. - Added croak()ing for unimplemented send() and recv() methods so they are not accidentally used to transmit unencrypted data. The Perl builtin functions cannot be reliably trapped and are still dangerous, a fact that the POD now reflects (Problem noted by Michal Ludvig ). v0.94 2003.6.26 - Changed accept() to use inherited accept() instead of IO::Socket::accept, so that IPv6 inheritance is possible. - Added options to import() so that a user could specify IPv6 or IPv4 mode of operation. - Documentation fixes, esp. e-mail address. v0.93 2003.6.24 - Fixed error-checking slip in connect_SSL() (Problem found by Uri Guttman ). - All functions now return the empty list () on errors. - Added note about the above change to appease Graham Barr . - Fixed Net::SSLeay giving warnings when arguments are undef; in all cases, undef arguments may be set to '' without any change in behavior except for removing the warnings. (Problem found by Dominique Quatravaux ) - If accept() or connect() fails in SSL negotiation, the user now has the option to print something to the failed socket before it is closed. (error_trap option in new()) - Added support for CRLs (SSL_check_crl option in new()) for versions of OpenSSL >= 0.9.7b (Original patch from Brian Lindauer ) - Finally added decent support for certificate callbacks. (SSL_verify_callback option in new(), suggestion from Dariush Pietrzak ). - accept()/connect()/socket_to_SSL() now fail immediately if the socket in question does not have a fileno. - Added the kill_socket() method to guarantee that a socket dies. - Fixed extra warning when printing errors in debug mode. - Deprecated socket_to_SSL() in favor of the class method start_SSL() (Class method suggestion from Graham Barr ). - Added the class method start_SSL() to allow for cases when the desired class of the socket is not IO::Socket::SSL (Request from Dariush Pietrzak ) - Changed socket_to_SSL to rebless socket to original class if SSL negotiation failed (Request from Graham Barr ) - Removed the daemon.pl example, as it did not work with the standard distribution of HTTP::Daemon (use HTTP::Daemon::SSL instead). v0.92 2002.10.22 - Changed the fileno() function to support returning the fileno of server sockets. (Problem found by Roland Giersig ). - Fixed SSL_version incorrectly defaulting to SSLv2 (patch from Roland Alder ). v0.91 2002.08.31 - Added support for SSL_peek and SSL_pending (peek() and pending()). Updated documentation, tests, etc. to reflect this. v0.901 2002.08.19 - Fixed the warning that happens when sockets are not explicitly closed() before the program terminates. v0.90 2002.08.13 - This version is a complete rewrite of IO::Socket::SSL. It now has about half the lines of code, twice the amount of documentation, and a slightly more polished interface. - IO::Socket::SSL now works properly with mod_perl and taint mode. - Major documentation update. - Update of the BUGS file to reflect changes made in the rewrite. - Update of the test suite for Perl v5.8.0 (or, more precisely, for Scalar::Util). - Update of the test suite for Perl v5.00503 (or, more precisely, for the lack of several nice features added in v5.6.0) (Marko Asplund ). - New test suite that does not need the Internet to function. - Update of all the files in example/ to use more current features of IO::Socket::SSL. - Removal of SSL_SSL and X509_Certificate classes. - There have been a few name changes (like socketToSSL -> socket_to_SSL) for better consistency. - The functionality of get_peer_certificate() and friends is deprecated. - The functionality of want_write() and want_read() is deprecated. - The functionality of context_init() is deprecated for normal use. - Support for all SSL context options in the new() call. - SSL contexts are no longer global. The SSL_reuse_ctx option is provided for those who want to re-use a context. - The default verify mode is now VERIFY_NONE. - IO::Socket::SSL::DEBUG is now linked to Net::SSLeay::trace to provide different levels of debugging information. - There is a uniform interface for error reporting, so on error all functions will return undef and the error will be available by calling errstr(). - The dump_peer_certificate() and peer_certificate() functions have been added. - sysread() will now behave correctly if the offset argument is greater than the length of the read buffer. It also will truncate the read buffer properly, according to the Perl documentation for sysread(). - getline(), getlines(), and getc() have been added. - syswrite() now uses references to avoid copying large amounts of data. - readline() uses ssl_read_all in array context for improved speed. - close() now uses SSL_shutdown() to properly close an SSL connection, unless you tell it not to. - If you have Net::SSLeay version 1.18 or greater, X509 certificates will be properly freed. - All other known bugs have been fixed. v0.81a (Not publicly released) - Added support for SSL_passwd_cb. - Added accept() server socket support to socketToSSL(). v0.81 2002.04.10 - calling context_init twice destroyed global context. fix from Jason Heiss . - file handle tying interface implementation moved to a separate class to prevent problems resulting from self-tying filehandles. Harmon S. Nine . - docs/debugging.txt file added - require Net::SSLeay v1.08 - preliminary support for non-blocking read/write - socketToSSL() now respects context's SSL verify setting reported by Uri Guttman . v0.80 2001.08.19 - fixed startTLS support (socketToSSL) (Graham Barr ) - make accept() set fileno attribute on newly created IO::Socket::SSL object (Martin Oldfield ). - certificate updates. - use SSL_CTX_use_PrivateKey_file in SSL_Context::new. v0.79 2001.06.04 - angle bracket readline operator support (David Darville ). - eliminate warnings in choosing SSL protocol version. - implement our own opened method and make length parameter optional in syswrite (Robert Bihlmeyer ). v0.78 2001.04.24 - test script targets changed, certificate setup fixed - support for TLS in SSL_version. SSL_version parameter values changed from integer to string. NB: this is an incompatible change. all SSL_version parameter values have to be changed. valid values include: 'sslv2', 'sslv3', 'sslv23'. Stephen C. Koehler . - enable selecting SSL version for connections. patch from Takanori Ugai . - allow setting SSL_ca_file to ''. this is needed for being able to use SSL_ca_path (Robert Bihlmeyer ). - include the Apache CA bundle file in the distribution (my-ca.pem). - BUGS file added. v0.77 2001.01.15 - don't setup SSL CA verification unless cert verification is actually used for the connections. - default SSL protocol version selection in SSL.pm. v0.76 2000.11.17 - patch from Kwok Chern Yue for making IO::Socket::SSL work with HTTP::Daemon. v0.75 2000.07.26 - IO::Socket::SSL should now work with perl v5.6.0 - demo/*.pl and t/*.t now turn module debugging on if DEBUG command line argument is given - default certificates changed v0.74 2000.07.05 - Changes file added - bugfix in IO::Socket::SSL::sysread() (zliu2 at acsu.buffalo.edu) - libwww-perl and IO::Socket::SSL UML models added in docs - URL changes in test scripts - preliminary support for startTLS in IO::Socket::SSL::socketToSSL() - miscellaneous patches for Net::SSLeay added in diffs IO-Socket-SSL-2.085/lib/0000755000175000017500000000000014553536272014354 5ustar steffensteffenIO-Socket-SSL-2.085/lib/IO/0000755000175000017500000000000014553536272014663 5ustar steffensteffenIO-Socket-SSL-2.085/lib/IO/Socket/0000755000175000017500000000000014553536272016113 5ustar steffensteffenIO-Socket-SSL-2.085/lib/IO/Socket/SSL/0000755000175000017500000000000014553536272016554 5ustar steffensteffenIO-Socket-SSL-2.085/lib/IO/Socket/SSL/Utils.pm0000644000175000017500000005475314521466373020227 0ustar steffensteffen package IO::Socket::SSL::Utils; use strict; use warnings; use Carp 'croak'; use Net::SSLeay; # old versions of Exporter do not export 'import' yet require Exporter; *import = \&Exporter::import; our $VERSION = '2.015'; our @EXPORT = qw( PEM_file2cert PEM_file2certs PEM_string2cert PEM_cert2file PEM_certs2file PEM_cert2string PEM_file2key PEM_string2key PEM_key2file PEM_key2string KEY_free CERT_free KEY_create_rsa CERT_asHash CERT_create ); sub PEM_file2cert { my $file = shift; my $bio = Net::SSLeay::BIO_new_file($file,'r') or croak "cannot read $file: $!"; my $cert = Net::SSLeay::PEM_read_bio_X509($bio); Net::SSLeay::BIO_free($bio); $cert or croak "cannot parse $file as PEM X509 cert: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $cert; } sub PEM_cert2file { my ($cert,$file) = @_; my $string = Net::SSLeay::PEM_get_string_X509($cert) or croak("cannot get string from cert"); open( my $fh,'>',$file ) or croak("cannot write $file: $!"); print $fh $string; } use constant PEM_R_NO_START_LINE => 108; sub PEM_file2certs { my $file = shift; my $bio = Net::SSLeay::BIO_new_file($file,'r') or croak "cannot read $file: $!"; my @certs; while (1) { if (my $cert = Net::SSLeay::PEM_read_bio_X509($bio)) { push @certs, $cert; } else { Net::SSLeay::BIO_free($bio); my $error = Net::SSLeay::ERR_get_error(); last if ($error & 0xfff) == PEM_R_NO_START_LINE && @certs; croak "cannot parse $file as PEM X509 cert: " . Net::SSLeay::ERR_error_string($error); } } return @certs; } sub PEM_certs2file { my $file = shift; open( my $fh,'>',$file ) or croak("cannot write $file: $!"); for my $cert (@_) { my $string = Net::SSLeay::PEM_get_string_X509($cert) or croak("cannot get string from cert"); print $fh $string; } } sub PEM_string2cert { my $string = shift; my $bio = Net::SSLeay::BIO_new( Net::SSLeay::BIO_s_mem()); Net::SSLeay::BIO_write($bio,$string); my $cert = Net::SSLeay::PEM_read_bio_X509($bio); Net::SSLeay::BIO_free($bio); $cert or croak "cannot parse string as PEM X509 cert: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $cert; } sub PEM_cert2string { my $cert = shift; return Net::SSLeay::PEM_get_string_X509($cert) || croak("cannot get string from cert"); } sub PEM_file2key { my $file = shift; my $bio = Net::SSLeay::BIO_new_file($file,'r') or croak "cannot read $file: $!"; my $key = Net::SSLeay::PEM_read_bio_PrivateKey($bio); Net::SSLeay::BIO_free($bio); $key or croak "cannot parse $file as PEM private key: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $key; } sub PEM_key2file { my ($key,$file) = @_; my $string = Net::SSLeay::PEM_get_string_PrivateKey($key) or croak("cannot get string from key"); open( my $fh,'>',$file ) or croak("cannot write $file: $!"); print $fh $string; } sub PEM_string2key { my $string = shift; my $bio = Net::SSLeay::BIO_new( Net::SSLeay::BIO_s_mem()); Net::SSLeay::BIO_write($bio,$string); my $key = Net::SSLeay::PEM_read_bio_PrivateKey($bio); Net::SSLeay::BIO_free($bio); $key or croak "cannot parse string as PEM private key: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $key; } sub PEM_key2string { my $key = shift; return Net::SSLeay::PEM_get_string_PrivateKey($key) || croak("cannot get string from key"); } sub CERT_free { Net::SSLeay::X509_free($_) for @_; } sub KEY_free { Net::SSLeay::EVP_PKEY_free($_) for @_; } sub KEY_create_rsa { my $bits = shift || 2048; my $key = Net::SSLeay::EVP_PKEY_new(); my $rsa = Net::SSLeay::RSA_generate_key($bits, 0x10001); # 0x10001 = RSA_F4 Net::SSLeay::EVP_PKEY_assign_RSA($key,$rsa); return $key; } if (defined &Net::SSLeay::EC_KEY_generate_key) { push @EXPORT,'KEY_create_ec'; *KEY_create_ec = sub { my $curve = shift || 'prime256v1'; my $key = Net::SSLeay::EVP_PKEY_new(); my $ec = Net::SSLeay::EC_KEY_generate_key($curve); Net::SSLeay::EVP_PKEY_assign_EC_KEY($key,$ec); return $key; } } # extract information from cert my %gen2i = qw( OTHERNAME 0 EMAIL 1 DNS 2 X400 3 DIRNAME 4 EDIPARTY 5 URI 6 IP 7 RID 8 ); my %i2gen = reverse %gen2i; sub CERT_asHash { my $cert = shift; my $digest_name = shift || 'sha256'; my %hash = ( version => Net::SSLeay::X509_get_version($cert), not_before => _asn1t2t(Net::SSLeay::X509_get_notBefore($cert)), not_after => _asn1t2t(Net::SSLeay::X509_get_notAfter($cert)), serial => Net::SSLeay::P_ASN1_INTEGER_get_dec( Net::SSLeay::X509_get_serialNumber($cert)), signature_alg => Net::SSLeay::OBJ_obj2txt ( Net::SSLeay::P_X509_get_signature_alg($cert)), crl_uri => [ Net::SSLeay::P_X509_get_crl_distribution_points($cert) ], keyusage => [ Net::SSLeay::P_X509_get_key_usage($cert) ], extkeyusage => { oid => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,0) ], nid => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,1) ], sn => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,2) ], ln => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,3) ], }, "pubkey_digest_$digest_name" => Net::SSLeay::X509_pubkey_digest( $cert,_digest($digest_name)), "x509_digest_$digest_name" => Net::SSLeay::X509_digest( $cert,_digest($digest_name)), "fingerprint_$digest_name" => Net::SSLeay::X509_get_fingerprint( $cert,$digest_name), ); for([ subject => Net::SSLeay::X509_get_subject_name($cert) ], [ issuer => Net::SSLeay::X509_get_issuer_name($cert) ]) { my ($what,$subj) = @$_; my %subj; for ( 0..Net::SSLeay::X509_NAME_entry_count($subj)-1 ) { my $e = Net::SSLeay::X509_NAME_get_entry($subj,$_); my $k = Net::SSLeay::OBJ_obj2txt( Net::SSLeay::X509_NAME_ENTRY_get_object($e)); my $v = Net::SSLeay::P_ASN1_STRING_get( Net::SSLeay::X509_NAME_ENTRY_get_data($e)); if (!exists $subj{$k}) { $subj{$k} = $v; } elsif (!ref $subj{$k}) { $subj{$k} = [ $subj{$k}, $v ]; } else { push @{$subj{$k}}, $v; } } $hash{$what} = \%subj; } if ( my @names = Net::SSLeay::X509_get_subjectAltNames($cert) ) { my $alt = $hash{subjectAltNames} = []; while (my ($t,$v) = splice(@names,0,2)) { $t = $i2gen{$t} || die "unknown type $t in subjectAltName"; if ( $t eq 'IP' ) { if (length($v) == 4) { $v = join('.',unpack("CCCC",$v)); } elsif ( length($v) == 16 ) { my @v = unpack("nnnnnnnn",$v); my ($best0,$last0); for(my $i=0;$i<@v;$i++) { if ($v[$i] == 0) { if ($last0) { $last0->[1] = $i; $last0->[2]++; $best0 = $last0 if ++$last0->[2]>$best0->[2]; } else { $last0 = [ $i,$i,0 ]; $best0 ||= $last0; } } else { $last0 = undef; } } if ($best0) { $v = ''; $v .= join(':', map { sprintf( "%x",$_) } @v[0..$best0->[0]-1]) if $best0->[0]>0; $v .= '::'; $v .= join(':', map { sprintf( "%x",$_) } @v[$best0->[1]+1..$#v]) if $best0->[1]<$#v; } else { $v = join(':', map { sprintf( "%x",$_) } @v); } } } push @$alt,[$t,$v] } } my @ext; for( 0..Net::SSLeay::X509_get_ext_count($cert)-1 ) { my $e = Net::SSLeay::X509_get_ext($cert,$_); my $o = Net::SSLeay::X509_EXTENSION_get_object($e); my $nid = Net::SSLeay::OBJ_obj2nid($o); push @ext, { oid => Net::SSLeay::OBJ_obj2txt($o), nid => ( $nid > 0 ) ? $nid : undef, sn => ( $nid > 0 ) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, critical => Net::SSLeay::X509_EXTENSION_get_critical($e), data => Net::SSLeay::X509V3_EXT_print($e), } } $hash{ext} = \@ext; if ( defined(&Net::SSLeay::P_X509_get_ocsp_uri)) { $hash{ocsp_uri} = [ Net::SSLeay::P_X509_get_ocsp_uri($cert) ]; } else { $hash{ocsp_uri} = []; for( @ext ) { $_->{sn} or next; $_->{sn} eq 'authorityInfoAccess' or next; push @{ $hash{ocsp_uri}}, $_->{data} =~m{\bOCSP - URI:(\S+)}g; } } return \%hash; } sub CERT_create { my %args = @_%2 ? %{ shift() } : @_; my $cert = Net::SSLeay::X509_new(); my $digest_name = delete $args{digest} || 'sha256'; Net::SSLeay::ASN1_INTEGER_set( Net::SSLeay::X509_get_serialNumber($cert), delete $args{serial} || rand(2**32), ); # version default to 2 (V3) Net::SSLeay::X509_set_version($cert, delete $args{version} || 2 ); # not_before default to now Net::SSLeay::ASN1_TIME_set( Net::SSLeay::X509_get_notBefore($cert), delete $args{not_before} || time() ); # not_after default to now+365 days Net::SSLeay::ASN1_TIME_set( Net::SSLeay::X509_get_notAfter($cert), delete $args{not_after} || time() + 365*86400 ); # set subject my $subj_e = Net::SSLeay::X509_get_subject_name($cert); my $subj = delete $args{subject} || { organizationName => 'IO::Socket::SSL', commonName => 'IO::Socket::SSL Test' }; while ( my ($k,$v) = each %$subj ) { # Not everything we get is nice - try with MBSTRING_UTF8 first and if it # fails try V_ASN1_T61STRING and finally V_ASN1_OCTET_STRING for (ref($v) ? @$v : ($v)) { Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,0x1000,$_,-1,0) or Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,20,$_,-1,0) or Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,4,$_,-1,0) or croak("failed to add entry for $k - ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error())); } } my @ext = ( &Net::SSLeay::NID_subject_key_identifier => 'hash', &Net::SSLeay::NID_authority_key_identifier => 'keyid', ); if ( my $altsubj = delete $args{subjectAltNames} ) { push @ext, &Net::SSLeay::NID_subject_alt_name => join(',', map { "$_->[0]:$_->[1]" } @$altsubj) } my $key = delete $args{key} || KEY_create_rsa(); Net::SSLeay::X509_set_pubkey($cert,$key); my $is = delete $args{issuer}; my $issuer_cert = delete $args{issuer_cert} || $is && $is->[0] || $cert; my $issuer_key = delete $args{issuer_key} || $is && $is->[1] || $key; my %purpose; if (my $p = delete $args{purpose}) { if (!ref($p)) { $purpose{lc($2)} = (!$1 || $1 eq '+') ? 1:0 while $p =~m{([+-]?)(\w+)}g; } elsif (ref($p) eq 'ARRAY') { for(@$p) { m{^([+-]?)(\w+)$} or die "invalid entry in purpose: $_"; $purpose{lc($2)} = (!$1 || $1 eq '+') ? 1:0 } } else { while( my ($k,$v) = each %$p) { $purpose{lc($k)} = ($v && $v ne '-')?1:0; } } } if (delete $args{CA}) { # add defaults for CA %purpose = ( ca => 1, sslca => 1, emailca => 1, objca => 1, %purpose ); } if (!%purpose) { %purpose = (server => 1, client => 1); } my (%key_usage,%ext_key_usage,%cert_type,%basic_constraints); my %dS = ( digitalSignature => \%key_usage ); my %kE = ( keyEncipherment => \%key_usage ); my %CA = ( 'CA:TRUE' => \%basic_constraints, %dS, keyCertSign => \%key_usage ); my @disable; for( [ client => { %dS, %kE, clientAuth => \%ext_key_usage, client => \%cert_type } ], [ server => { %dS, %kE, serverAuth => \%ext_key_usage, server => \%cert_type } ], [ email => { %dS, %kE, emailProtection => \%ext_key_usage, email => \%cert_type } ], [ objsign => { %dS, %kE, codeSigning => \%ext_key_usage, objsign => \%cert_type } ], [ CA => { %CA }], [ sslCA => { %CA, sslCA => \%cert_type }], [ emailCA => { %CA, emailCA => \%cert_type }], [ objCA => { %CA, objCA => \%cert_type }], [ emailProtection => { %dS, %kE, emailProtection => \%ext_key_usage, email => \%cert_type } ], [ codeSigning => { %dS, %kE, codeSigning => \%ext_key_usage, objsign => \%cert_type } ], [ timeStamping => { timeStamping => \%ext_key_usage } ], [ digitalSignature => { digitalSignature => \%key_usage } ], [ nonRepudiation => { nonRepudiation => \%key_usage } ], [ keyEncipherment => { keyEncipherment => \%key_usage } ], [ dataEncipherment => { dataEncipherment => \%key_usage } ], [ keyAgreement => { keyAgreement => \%key_usage } ], [ keyCertSign => { keyCertSign => \%key_usage } ], [ cRLSign => { cRLSign => \%key_usage } ], [ encipherOnly => { encipherOnly => \%key_usage } ], [ decipherOnly => { decipherOnly => \%key_usage } ], [ clientAuth => { clientAuth => \%ext_key_usage } ], [ serverAuth => { serverAuth => \%ext_key_usage } ], ) { exists $purpose{lc($_->[0])} or next; if (delete $purpose{lc($_->[0])}) { while (my($k,$h) = each %{$_->[1]}) { $h->{$k} = 1; } } else { push @disable, $_->[1]; } } die "unknown purpose ".join(",",keys %purpose) if %purpose; for(@disable) { while (my($k,$h) = each %$_) { delete $h->{$k}; } } if (%basic_constraints) { push @ext,&Net::SSLeay::NID_basic_constraints, => join(",",'critical', sort keys %basic_constraints); } else { push @ext, &Net::SSLeay::NID_basic_constraints => 'critical,CA:FALSE'; } push @ext,&Net::SSLeay::NID_key_usage => join(",",'critical', sort keys %key_usage) if %key_usage; push @ext,&Net::SSLeay::NID_netscape_cert_type => join(",",sort keys %cert_type) if %cert_type; push @ext,&Net::SSLeay::NID_ext_key_usage => join(",",sort keys %ext_key_usage) if %ext_key_usage; Net::SSLeay::P_X509_add_extensions($cert, $issuer_cert, @ext); my %have_ext; for(my $i=0;$i<@ext;$i+=2) { $have_ext{ $ext[$i] }++ } for my $ext (@{ delete $args{ext} || [] }) { my $nid = $ext->{nid} || $ext->{sn} && Net::SSLeay::OBJ_sn2nid($ext->{sn}) || croak "cannot determine NID of extension"; $have_ext{$nid} and next; my $val = $ext->{data}; if ($nid == 177) { # authorityInfoAccess: # OpenSSL i2v does not output the same way as expected by i2v :( for (split(/\n/,$val)) { s{ - }{;}; # "OCSP - URI:..." -> "OCSP;URI:..." $_ = "critical,$_" if $ext->{critical}; Net::SSLeay::P_X509_add_extensions($cert,$issuer_cert,$nid,$_); } } else { $val = "critical,$val" if $ext->{critical}; Net::SSLeay::P_X509_add_extensions($cert, $issuer_cert, $nid, $val); } } die "unknown arguments: ". join(" ", sort keys %args) if !delete $args{ignore_invalid_args} && %args; Net::SSLeay::X509_set_issuer_name($cert, Net::SSLeay::X509_get_subject_name($issuer_cert)); Net::SSLeay::X509_sign($cert,$issuer_key,_digest($digest_name)); return ($cert,$key); } if ( defined &Net::SSLeay::ASN1_TIME_timet ) { *_asn1t2t = \&Net::SSLeay::ASN1_TIME_timet } else { require Time::Local; my %mon2i = qw( Jan 0 Feb 1 Mar 2 Apr 3 May 4 Jun 5 Jul 6 Aug 7 Sep 8 Oct 9 Nov 10 Dec 11 ); *_asn1t2t = sub { my $t = Net::SSLeay::P_ASN1_TIME_put2string( shift ); my ($mon,$d,$h,$m,$s,$y,$tz) = split(/[\s:]+/,$t); defined( $mon = $mon2i{$mon} ) or die "invalid month in $t"; $tz ||= $y =~s{^(\d+)([A-Z]\S*)}{$1} && $2; if ( ! $tz ) { return Time::Local::timelocal($s,$m,$h,$d,$mon,$y) } elsif ( $tz eq 'GMT' ) { return Time::Local::timegm($s,$m,$h,$d,$mon,$y) } else { die "unexpected TZ $tz from ASN1_TIME_print"; } } } { my %digest; sub _digest { my $digest_name = shift; return $digest{$digest_name} ||= do { Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::EVP_get_digestbyname($digest_name) or die "Digest algorithm $digest_name is not available"; }; } } 1; __END__ =head1 NAME IO::Socket::SSL::Utils -- loading, storing, creating certificates and keys =head1 SYNOPSIS use IO::Socket::SSL::Utils; $cert = PEM_file2cert('cert.pem'); # load certificate from file my $hash = CERT_asHash($cert); # get details from certificate PEM_cert2file($cert,'cert.pem'); # write certificate to file CERT_free($cert); # free memory within OpenSSL @certs = PEM_file2certs('chain.pem'); # load multiple certificates from file PEM_certs2file('chain.pem', @certs); # write multiple certificates to file CERT_free(@certs); # free memory for all within OpenSSL my $cert = PEM_string2cert($pem); # load certificate from PEM string $pem = PEM_cert2string($cert); # convert certificate to PEM string $key = KEY_create_rsa(2048); # create new 2048-bit RSA key PEM_key2file($key,"key.pem"); # and write it to file KEY_free($key); # free memory within OpenSSL =head1 DESCRIPTION This module provides various utility functions to work with certificates and private keys, shielding some of the complexity of the underlying Net::SSLeay and OpenSSL. =head1 FUNCTIONS =over 4 =item * Functions converting between string or file and certificates and keys. They croak if the operation cannot be completed. =over 8 =item PEM_file2cert(file) -> cert =item PEM_cert2file(cert,file) =item PEM_file2certs(file) -> @certs =item PEM_certs2file(file,@certs) =item PEM_string2cert(string) -> cert =item PEM_cert2string(cert) -> string =item PEM_file2key(file) -> key =item PEM_key2file(key,file) =item PEM_string2key(string) -> key =item PEM_key2string(key) -> string =back =item * Functions for cleaning up. Each loaded or created cert and key must be freed to not leak memory. =over 8 =item CERT_free(@certs) =item KEY_free(@keys) =back =item * KEY_create_rsa(bits) -> key Creates an RSA key pair, bits defaults to 2048. =item * KEY_create_ec(curve) -> key Creates an EC key, curve defaults to C. =item * CERT_asHash(cert,[digest_algo]) -> hash Extracts the information from the certificate into a hash and uses the given digest_algo (default: SHA-256) to determine digest of pubkey and cert. The resulting hash contains: =over 8 =item subject Hash with the parts of the subject, e.g. commonName, countryName, organizationName, stateOrProvinceName, localityName. If there are multiple values for any of these parts the hash value will be an array ref with the values in order instead of just a scalar. =item subjectAltNames Array with list of alternative names. Each entry in the list is of C<[type,value]>, where C can be OTHERNAME, EMAIL, DNS, X400, DIRNAME, EDIPARTY, URI, IP or RID. =item issuer Hash with the parts of the issuer, e.g. commonName, countryName, organizationName, stateOrProvinceName, localityName. If there are multiple values for any of these parts the hash value will be an array ref with the values in order instead of just a scalar. =item not_before, not_after The time frame, where the certificate is valid, as time_t, e.g. can be converted with localtime or similar functions. =item serial The serial number =item crl_uri List of URIs for CRL distribution. =item ocsp_uri List of URIs for revocation checking using OCSP. =item keyusage List of keyUsage information in the certificate. =item extkeyusage List of extended key usage information from the certificate. Each entry in this list consists of a hash with oid, nid, ln and sn. =item pubkey_digest_xxx Binary digest of the pubkey using the given digest algorithm, e.g. pubkey_digest_sha256 if (the default) SHA-256 was used. =item x509_digest_xxx Binary digest of the X.509 certificate using the given digest algorithm, e.g. x509_digest_sha256 if (the default) SHA-256 was used. =item fingerprint_xxx Fingerprint of the certificate using the given digest algorithm, e.g. fingerprint_sha256 if (the default) SHA-256 was used. Contrary to digest_* this is an ASCII string with a list if hexadecimal numbers, e.g. "73:59:75:5C:6D...". =item signature_alg Algorithm used to sign certificate, e.g. C. =item ext List of extensions. Each entry in the list is a hash with oid, nid, sn, critical flag (boolean) and data (string representation given by X509V3_EXT_print). =item version Certificate version, usually 2 (x509v3) =back =item * CERT_create(hash) -> (cert,key) Creates a certificate based on the given hash. If the issuer is not specified the certificate will be self-signed. The following keys can be given: =over 8 =item subject Hash with the parts of the subject, e.g. commonName, countryName, ... as described in C. Default points to IO::Socket::SSL. =item not_before A time_t value when the certificate starts to be valid. Defaults to current time. =item not_after A time_t value when the certificate ends to be valid. Defaults to current time plus one 365 days. =item serial The serial number. If not given a random number will be used. =item version The version of the certificate, default 2 (x509v3). =item CA true|false If true declare certificate as CA, defaults to false. =item purpose string|array|hash Set the purpose of the certificate. The different purposes can be given as a string separated by non-word character, as array or hash. With string or array each purpose can be prefixed with '+' (enable) or '-' (disable) and same can be done with the value when given as a hash. By default enabling the purpose is assumed. If the CA option is given and true the defaults "ca,sslca,emailca,objca" are assumed, but can be overridden with explicit purpose. If the CA option is given and false the defaults "server,client" are assumed. If no CA option and no purpose is given it defaults to "server,client". Purpose affects basicConstraints, keyUsage, extKeyUsage and netscapeCertType. The following purposes are defined (case is not important): client server email objsign CA sslCA emailCA objCA emailProtection codeSigning timeStamping digitalSignature nonRepudiation keyEncipherment dataEncipherment keyAgreement keyCertSign cRLSign encipherOnly decipherOnly Examples: # root-CA for SSL certificates purpose => 'sslCA' # or CA => 1 # server certificate and CA (typically self-signed) purpose => 'sslCA,server' # client certificate purpose => 'client', =item ext [{ sn => .., data => ... }, ... ] List of extensions. The type of the extension can be specified as name with C or as NID with C and the data with C. These data must be in the same syntax as expected within openssl.cnf, e.g. something like C. Additionally the critical flag can be set with C 1>. =item key key use given key as key for certificate, otherwise a new one will be generated and returned =item issuer_cert cert set issuer for new certificate =item issuer_key key sign new certificate with given key =item issuer [ cert, key ] Instead of giving issuer_key and issuer_cert as separate arguments they can be given both together. =item digest algorithm specify the algorithm used to sign the certificate, default SHA-256. =item ignore_invalid_args ignore any unknown arguments which might be in the argument list (which might be in the arguments for example as result from CERT_asHash) =back =back =head1 AUTHOR Steffen Ullrich IO-Socket-SSL-2.085/lib/IO/Socket/SSL/PublicSuffix.pm0000644000175000017500000115041414553534324021517 0ustar steffensteffen use strict; use warnings; package IO::Socket::SSL::PublicSuffix; use Carp; # for updates use constant URL => 'http://publicsuffix.org/list/effective_tld_names.dat'; =head1 NAME IO::Socket::SSL::PublicSuffix - provide access to Mozilla's list of effective TLD names =head1 SYNOPSIS # use builtin default use IO::Socket::SSL::PublicSuffix; $ps = IO::Socket::SSL::PublicSuffix->default; # load from string $ps = IO::Socket::SSL::PublicSuffix->from_string("*.uk\n*"); # load from file or file handle $ps = IO::Socket::SSL::PublicSuffix->from_file($filename); $ps = IO::Socket::SSL::PublicSuffix->from_file(\*STDIN); # --- string in -> string out # $rest -> whatever.host # $tld -> co.uk my ($rest,$tld) = $ps->public_suffix('whatever.host.co.uk'); my $tld = $ps->public_suffix('whatever.host.co.uk'); # $root_domain -> host.co.uk my $root_domain = $ps->public_suffix('whatever.host.co.uk', 1); # --- array in -> array out # $rest -> [qw(whatever host)] # $tld -> [qw(co uk)] my ($rest,$tld) = $ps->public_suffix([qw(whatever host co uk)]); ---- # To update this file with the current list: perl -MIO::Socket::SSL::PublicSuffix -e 'IO::Socket::SSL::PublicSuffix::update_self_from_url()' =head1 DESCRIPTION This module uses the list of effective top level domain names from the mozilla project to determine the public top level domain for a given hostname. =head2 Method =over 4 =item class->default(%args) Returns object with builtin default. C can be given in C<%args> to specify the minimal suffix, default is 1. =item class->from_string(string,%args) Returns object with configuration from string. See method C for C<%args>. =item class->from_file( file name| file handle, %args ) Returns object with configuration from file or file handle. See method C for C<%args>. =item $self->public_suffix( $host|\@host, [ $add ] ) In array context the function returns the non-tld part and the tld part of the given hostname, in scalar context only the tld part. It adds C<$add> parts of the non-tld part to the tld, e.g. with C<$add=1> it will return the root domain. If there were no explicit matches against the public suffix configuration it will fall back to a suffix of length 1. The function accepts a string or an array-ref (e.g. host split by C<.>). In the first case it will return string(s), in the latter case array-ref(s). International hostnames or labels can be in ASCII (IDNA form starting with C) or unicode. In the latter case an IDNA handling library needs to be available. L is preferred, but L, L are still supported. =item ($self|class)->can_idn Returns true if IDN support is available. =back =head1 FILES http://publicsuffix.org/list/effective_tld_names.dat =head1 SEE ALSO Domain::PublicSuffix, Mozilla::PublicSuffix =head1 BUGS Q: Why yet another module, we already have L and L. A: Because the public suffix data change more often than these modules do, IO::Socket::SSL needs this list and it is more easy this way to keep it up-to-date. =head1 AUTHOR Steffen Ullrich =cut BEGIN { if ( eval { require URI::_idna; defined &URI::_idna::encode && defined &URI::_idna::decode }) { *idn_to_ascii = \&URI::_idna::encode; *idn_to_unicode = \&URI::_idna::decode; *can_idn = sub { 1 }; } elsif ( eval { require Net::IDN::Encode } ) { *idn_to_ascii = \&Net::IDN::Encode::domain_to_ascii; *idn_to_unicode = \&Net::IDN::Encode::domain_to_unicode; *can_idn = sub { 1 }; } elsif ( eval { require Net::LibIDN; require Encode } ) { # Net::LibIDN does not use utf-8 flag and expects raw data *idn_to_ascii = sub { Net::LibIDN::idn_to_ascii(Encode::encode('utf-8',$_[0]),'utf-8'); }, *idn_to_unicode = sub { Encode::decode('utf-8',Net::LibIDN::idn_to_unicode($_[0],'utf-8')); }, *can_idn = sub { 1 }; } else { *idn_to_ascii = sub { croak "idn_to_ascii(@_) - no IDNA library installed" }; *idn_to_unicode = sub { croak "idn_to_unicode(@_) - no IDNA library installed" }; *can_idn = sub { 0 }; } } { my %default; sub default { my (undef,%args) = @_; my $min_suffix = delete $args{min_suffix}; $min_suffix = 1 if ! defined $min_suffix; %args and die "unknown args: ".join(" ",sort keys %args); return $default{$min_suffix} ||= shift->from_string(_default_data(), min_suffix => $min_suffix); } } sub from_string { my $class = shift; my $data = shift; open( my $fh,'<', \$data ); return $class->from_file($fh,@_); } sub from_file { my ($class,$file,%args) = @_; my $min_suffix = delete $args{min_suffix}; $min_suffix = 1 if ! defined $min_suffix; %args and die "unknown args: ".join(" ",sort keys %args); my $fh; if ( ref($file)) { $fh = $file } elsif ( ! open($fh,'<',$file)) { die "failed to open $file: $!"; } my %tree; local $/ = "\n"; while ( my $line = <$fh>) { $line =~s{//.*}{}; $line =~s{\s+$}{}; $line eq '' and next; my $p = \%tree; $line = idn_to_ascii($line) if $line !~m{\A[\x00-\x7f]*\Z}; my $not = $line =~s{^!}{}; my @path = split(m{\.},$line); for(reverse @path) { $p = $p->{$_} ||= {} } $p->{'\0'} = $not ? -1:1; } return bless { tree => \%tree, min_suffix => $min_suffix },$class; } sub public_suffix { my ($self,$name,$add) = @_; my $want; # [a]rray, [s]tring, [u]nicode-string if ( ref($name)) { $want = 'a'; $name = [ @$name ]; # don't change input } else { return if ! defined $name; if ( $name !~m{\A[\x00-\x7f]*\Z} ) { $name = idn_to_ascii($name); $want = 'u'; } else { $want = 's'; } $name = lc($name); $name =~s{\.$}{}; $name = [ $name =~m{([^.]+)}g ]; } @$name or return; $_ = lc($_) for(@$name); my (%wild,%host,%xcept,@stack,$choices); my $p = $self->{tree}; for( my $i=0; $i<@$name; $i++ ) { $choices = []; if ( my $px = $p->{ $name->[$#$name-$i] } ) { # name match, continue with next path element push @$choices,$px; if ( my $end = $px->{'\0'} ) { ( $end>0 ? \%host : \%xcept )->{$i+1} = $end; } } if ( my $px = $p->{'*'} ) { # wildcard match, continue with next path element push @$choices,$px; if ( my $end = $px->{'\0'} ) { ( $end>0 ? \%wild : \%xcept )->{$i+1} = $end; } } next_choice: if ( @$choices ) { $p = shift(@$choices); push @stack, [ $choices, $i ] if @$choices; next; # go deeper } # backtrack @stack or last; ($choices,$i) = @{ pop(@stack) }; goto next_choice; } #warn Dumper([\%wild,\%host,\%xcept]); use Data::Dumper; # remove all exceptions from wildcards delete @wild{ keys %xcept } if %xcept; # get longest match my ($len) = sort { $b <=> $a } ( keys(%wild), keys(%host), map { $_-1 } keys(%xcept)); # if we have no matches use a minimum of min_suffix $len = $self->{min_suffix} if ! defined $len; $len += $add if $add; my $suffix; if ( $len < @$name ) { $suffix = [ splice( @$name, -$len, $len ) ]; } elsif ( $len > 0 ) { $suffix = $name; $name = [] } else { $suffix = [] } if ( $want ne 'a' ) { $suffix = join('.',@$suffix); $name = join('.',@$name); if ( $want eq 'u' ) { $suffix = idn_to_unicode($suffix); $name = idn_to_unicode($name); } } return wantarray ? ($name,$suffix):$suffix; } { my $data; sub _default_data { if ( ! defined $data ) { $data = _builtin_data(); $data =~s{^// ===END ICANN DOMAINS.*}{}ms or die "cannot find END ICANN DOMAINS"; } return $data; } } sub update_self_from_url { my $url = shift || URL(); my $dst = __FILE__; -w $dst or die "cannot write $dst"; open( my $fh,'<',$dst ) or die "open $dst: $!"; my $code = ''; local $/ = "\n"; while (<$fh>) { $code .= $_; m{<<\'END_BUILTIN_DATA\'} and last; } my $tail; while (<$fh>) { m{\AEND_BUILTIN_DATA\r?\n} or next; $tail = $_; last; } $tail .= do { local $/; <$fh> }; close($fh); require LWP::UserAgent; my $resp = LWP::UserAgent->new->get($url) or die "no response from $url"; die "no success url=$url code=".$resp->code." ".$resp->message if ! $resp->is_success; my $content = $resp->decoded_content; while ( $content =~m{(.*\n)}g ) { my $line = $1; if ( $line =~m{\S} && $line !~m{\A\s*//} ) { $line =~s{//.*}{}; $line =~s{\s+$}{}; $line eq '' and next; if ( $line !~m{\A[\x00-\x7f]+\Z} ) { $line = idn_to_ascii($line); } $code .= "$line\n"; } else { $code .= "$line"; } } open( $fh,'>:utf8',$dst ) or die "open $dst: $!"; print $fh $code.$tail; } sub _builtin_data { return <<'END_BUILTIN_DATA' } // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. // ===BEGIN ICANN DOMAINS=== // ac : http://nic.ac/rules.htm ac com.ac edu.ac gov.ac net.ac mil.ac org.ac // ad : https://en.wikipedia.org/wiki/.ad ad nom.ad // ae : https://tdra.gov.ae/en/aeda/ae-policies ae co.ae net.ae org.ae sch.ae ac.ae gov.ae mil.ae // aero : see https://www.information.aero/index.php?id=66 aero accident-investigation.aero accident-prevention.aero aerobatic.aero aeroclub.aero aerodrome.aero agents.aero aircraft.aero airline.aero airport.aero air-surveillance.aero airtraffic.aero air-traffic-control.aero ambulance.aero amusement.aero association.aero author.aero ballooning.aero broker.aero caa.aero cargo.aero catering.aero certification.aero championship.aero charter.aero civilaviation.aero club.aero conference.aero consultant.aero consulting.aero control.aero council.aero crew.aero design.aero dgca.aero educator.aero emergency.aero engine.aero engineer.aero entertainment.aero equipment.aero exchange.aero express.aero federation.aero flight.aero fuel.aero gliding.aero government.aero groundhandling.aero group.aero hanggliding.aero homebuilt.aero insurance.aero journal.aero journalist.aero leasing.aero logistics.aero magazine.aero maintenance.aero media.aero microlight.aero modelling.aero navigation.aero parachuting.aero paragliding.aero passenger-association.aero pilot.aero press.aero production.aero recreation.aero repbody.aero res.aero research.aero rotorcraft.aero safety.aero scientist.aero services.aero show.aero skydiving.aero software.aero student.aero trader.aero trading.aero trainer.aero union.aero workinggroup.aero works.aero // af : http://www.nic.af/help.jsp af gov.af com.af org.af net.af edu.af // ag : http://www.nic.ag/prices.htm ag com.ag org.ag net.ag co.ag nom.ag // ai : http://nic.com.ai/ ai off.ai com.ai net.ai org.ai // al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 al com.al edu.al gov.al mil.al net.al org.al // am : https://www.amnic.net/policy/en/Policy_EN.pdf am co.am com.am commune.am net.am org.am // ao : https://en.wikipedia.org/wiki/.ao // http://www.dns.ao/REGISTR.DOC ao ed.ao gv.ao og.ao co.ao pb.ao it.ao // aq : https://en.wikipedia.org/wiki/.aq aq // ar : https://nic.ar/es/nic-argentina/normativa ar bet.ar com.ar coop.ar edu.ar gob.ar gov.ar int.ar mil.ar musica.ar mutual.ar net.ar org.ar senasa.ar tur.ar // arpa : https://en.wikipedia.org/wiki/.arpa // Confirmed by registry 2008-06-18 arpa e164.arpa in-addr.arpa ip6.arpa iris.arpa uri.arpa urn.arpa // as : https://en.wikipedia.org/wiki/.as as gov.as // asia : https://en.wikipedia.org/wiki/.asia asia // at : https://en.wikipedia.org/wiki/.at // Confirmed by registry 2008-06-17 at ac.at co.at gv.at or.at sth.ac.at // au : https://en.wikipedia.org/wiki/.au // http://www.auda.org.au/ au // 2LDs com.au net.au org.au edu.au gov.au asn.au id.au // Historic 2LDs (closed to new registration, but sites still exist) info.au conf.au oz.au // CGDNs - http://www.cgdn.org.au/ act.au nsw.au nt.au qld.au sa.au tas.au vic.au wa.au // 3LDs act.edu.au catholic.edu.au // eq.edu.au - Removed at the request of the Queensland Department of Education nsw.edu.au nt.edu.au qld.edu.au sa.edu.au tas.edu.au vic.edu.au wa.edu.au // act.gov.au Bug 984824 - Removed at request of Greg Tankard // nsw.gov.au Bug 547985 - Removed at request of // nt.gov.au Bug 940478 - Removed at request of Greg Connors qld.gov.au sa.gov.au tas.gov.au vic.gov.au wa.gov.au // 4LDs // education.tas.edu.au - Removed at the request of the Department of Education Tasmania schools.nsw.edu.au // aw : https://en.wikipedia.org/wiki/.aw aw com.aw // ax : https://en.wikipedia.org/wiki/.ax ax // az : https://en.wikipedia.org/wiki/.az az com.az net.az int.az gov.az org.az edu.az info.az pp.az mil.az name.az pro.az biz.az // ba : http://nic.ba/users_data/files/pravilnik_o_registraciji.pdf ba com.ba edu.ba gov.ba mil.ba net.ba org.ba // bb : https://en.wikipedia.org/wiki/.bb bb biz.bb co.bb com.bb edu.bb gov.bb info.bb net.bb org.bb store.bb tv.bb // bd : https://en.wikipedia.org/wiki/.bd *.bd // be : https://en.wikipedia.org/wiki/.be // Confirmed by registry 2008-06-08 be ac.be // bf : https://en.wikipedia.org/wiki/.bf bf gov.bf // bg : https://en.wikipedia.org/wiki/.bg // https://www.register.bg/user/static/rules/en/index.html bg a.bg b.bg c.bg d.bg e.bg f.bg g.bg h.bg i.bg j.bg k.bg l.bg m.bg n.bg o.bg p.bg q.bg r.bg s.bg t.bg u.bg v.bg w.bg x.bg y.bg z.bg 0.bg 1.bg 2.bg 3.bg 4.bg 5.bg 6.bg 7.bg 8.bg 9.bg // bh : https://en.wikipedia.org/wiki/.bh bh com.bh edu.bh net.bh org.bh gov.bh // bi : https://en.wikipedia.org/wiki/.bi // http://whois.nic.bi/ bi co.bi com.bi edu.bi or.bi org.bi // biz : https://en.wikipedia.org/wiki/.biz biz // bj : https://nic.bj/bj-suffixes.txt // submitted by registry bj africa.bj agro.bj architectes.bj assur.bj avocats.bj co.bj com.bj eco.bj econo.bj edu.bj info.bj loisirs.bj money.bj net.bj org.bj ote.bj resto.bj restaurant.bj tourism.bj univ.bj // bm : http://www.bermudanic.bm/dnr-text.txt bm com.bm edu.bm gov.bm net.bm org.bm // bn : http://www.bnnic.bn/faqs bn com.bn edu.bn gov.bn net.bn org.bn // bo : https://nic.bo/delegacion2015.php#h-1.10 bo com.bo edu.bo gob.bo int.bo org.bo net.bo mil.bo tv.bo web.bo // Social Domains academia.bo agro.bo arte.bo blog.bo bolivia.bo ciencia.bo cooperativa.bo democracia.bo deporte.bo ecologia.bo economia.bo empresa.bo indigena.bo industria.bo info.bo medicina.bo movimiento.bo musica.bo natural.bo nombre.bo noticias.bo patria.bo politica.bo profesional.bo plurinacional.bo pueblo.bo revista.bo salud.bo tecnologia.bo tksat.bo transporte.bo wiki.bo // br : http://registro.br/dominio/categoria.html // Submitted by registry br 9guacu.br abc.br adm.br adv.br agr.br aju.br am.br anani.br aparecida.br app.br arq.br art.br ato.br b.br barueri.br belem.br bhz.br bib.br bio.br blog.br bmd.br boavista.br bsb.br campinagrande.br campinas.br caxias.br cim.br cng.br cnt.br com.br contagem.br coop.br coz.br cri.br cuiaba.br curitiba.br def.br des.br det.br dev.br ecn.br eco.br edu.br emp.br enf.br eng.br esp.br etc.br eti.br far.br feira.br flog.br floripa.br fm.br fnd.br fortal.br fot.br foz.br fst.br g12.br geo.br ggf.br goiania.br gov.br // gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil ac.gov.br al.gov.br am.gov.br ap.gov.br ba.gov.br ce.gov.br df.gov.br es.gov.br go.gov.br ma.gov.br mg.gov.br ms.gov.br mt.gov.br pa.gov.br pb.gov.br pe.gov.br pi.gov.br pr.gov.br rj.gov.br rn.gov.br ro.gov.br rr.gov.br rs.gov.br sc.gov.br se.gov.br sp.gov.br to.gov.br gru.br imb.br ind.br inf.br jab.br jampa.br jdf.br joinville.br jor.br jus.br leg.br lel.br log.br londrina.br macapa.br maceio.br manaus.br maringa.br mat.br med.br mil.br morena.br mp.br mus.br natal.br net.br niteroi.br *.nom.br not.br ntr.br odo.br ong.br org.br osasco.br palmas.br poa.br ppg.br pro.br psc.br psi.br pvh.br qsl.br radio.br rec.br recife.br rep.br ribeirao.br rio.br riobranco.br riopreto.br salvador.br sampa.br santamaria.br santoandre.br saobernardo.br saogonca.br seg.br sjc.br slg.br slz.br sorocaba.br srv.br taxi.br tc.br tec.br teo.br the.br tmp.br trd.br tur.br tv.br udi.br vet.br vix.br vlog.br wiki.br zlg.br // bs : http://www.nic.bs/rules.html bs com.bs net.bs org.bs edu.bs gov.bs // bt : https://en.wikipedia.org/wiki/.bt bt com.bt edu.bt gov.bt net.bt org.bt // bv : No registrations at this time. // Submitted by registry bv // bw : https://en.wikipedia.org/wiki/.bw // http://www.gobin.info/domainname/bw.doc // list of other 2nd level tlds ? bw co.bw org.bw // by : https://en.wikipedia.org/wiki/.by // http://tld.by/rules_2006_en.html // list of other 2nd level tlds ? by gov.by mil.by // Official information does not indicate that com.by is a reserved // second-level domain, but it's being used as one (see www.google.com.by and // www.yahoo.com.by, for example), so we list it here for safety's sake. com.by // http://hoster.by/ of.by // bz : https://en.wikipedia.org/wiki/.bz // http://www.belizenic.bz/ bz com.bz net.bz org.bz edu.bz gov.bz // ca : https://en.wikipedia.org/wiki/.ca ca // ca geographical names ab.ca bc.ca mb.ca nb.ca nf.ca nl.ca ns.ca nt.ca nu.ca on.ca pe.ca qc.ca sk.ca yk.ca // gc.ca: https://en.wikipedia.org/wiki/.gc.ca // see also: http://registry.gc.ca/en/SubdomainFAQ gc.ca // cat : https://en.wikipedia.org/wiki/.cat cat // cc : https://en.wikipedia.org/wiki/.cc cc // cd : https://en.wikipedia.org/wiki/.cd // see also: https://www.nic.cd/domain/insertDomain_2.jsp?act=1 cd gov.cd // cf : https://en.wikipedia.org/wiki/.cf cf // cg : https://en.wikipedia.org/wiki/.cg cg // ch : https://en.wikipedia.org/wiki/.ch ch // ci : https://en.wikipedia.org/wiki/.ci // http://www.nic.ci/index.php?page=charte ci org.ci or.ci com.ci co.ci edu.ci ed.ci ac.ci net.ci go.ci asso.ci xn--aroport-bya.ci int.ci presse.ci md.ci gouv.ci // ck : https://en.wikipedia.org/wiki/.ck *.ck !www.ck // cl : https://www.nic.cl // Confirmed by .CL registry cl co.cl gob.cl gov.cl mil.cl // cm : https://en.wikipedia.org/wiki/.cm plus bug 981927 cm co.cm com.cm gov.cm net.cm // cn : https://en.wikipedia.org/wiki/.cn // Submitted by registry cn ac.cn com.cn edu.cn gov.cn net.cn org.cn mil.cn xn--55qx5d.cn xn--io0a7i.cn xn--od0alg.cn // cn geographic names ah.cn bj.cn cq.cn fj.cn gd.cn gs.cn gz.cn gx.cn ha.cn hb.cn he.cn hi.cn hl.cn hn.cn jl.cn js.cn jx.cn ln.cn nm.cn nx.cn qh.cn sc.cn sd.cn sh.cn sn.cn sx.cn tj.cn xj.cn xz.cn yn.cn zj.cn hk.cn mo.cn tw.cn // co : https://en.wikipedia.org/wiki/.co // Submitted by registry co arts.co com.co edu.co firm.co gov.co info.co int.co mil.co net.co nom.co org.co rec.co web.co // com : https://en.wikipedia.org/wiki/.com com // coop : https://en.wikipedia.org/wiki/.coop coop // cr : http://www.nic.cr/niccr_publico/showRegistroDominiosScreen.do cr ac.cr co.cr ed.cr fi.cr go.cr or.cr sa.cr // cu : https://en.wikipedia.org/wiki/.cu cu com.cu edu.cu org.cu net.cu gov.cu inf.cu // cv : https://en.wikipedia.org/wiki/.cv // cv : http://www.dns.cv/tldcv_portal/do?com=DS;5446457100;111;+PAGE(4000018)+K-CAT-CODIGO(RDOM)+RCNT(100); <- registration rules cv com.cv edu.cv int.cv nome.cv org.cv // cw : http://www.una.cw/cw_registry/ // Confirmed by registry 2013-03-26 cw com.cw edu.cw net.cw org.cw // cx : https://en.wikipedia.org/wiki/.cx // list of other 2nd level tlds ? cx gov.cx // cy : http://www.nic.cy/ // Submitted by registry Panayiotou Fotia // namespace policies URL https://www.nic.cy/portal//sites/default/files/symfonia_gia_eggrafi.pdf cy ac.cy biz.cy com.cy ekloges.cy gov.cy ltd.cy mil.cy net.cy org.cy press.cy pro.cy tm.cy // cz : https://en.wikipedia.org/wiki/.cz cz // de : https://en.wikipedia.org/wiki/.de // Confirmed by registry (with technical // reservations) 2008-07-01 de // dj : https://en.wikipedia.org/wiki/.dj dj // dk : https://en.wikipedia.org/wiki/.dk // Confirmed by registry 2008-06-17 dk // dm : https://en.wikipedia.org/wiki/.dm dm com.dm net.dm org.dm edu.dm gov.dm // do : https://en.wikipedia.org/wiki/.do do art.do com.do edu.do gob.do gov.do mil.do net.do org.do sld.do web.do // dz : http://www.nic.dz/images/pdf_nic/charte.pdf dz art.dz asso.dz com.dz edu.dz gov.dz org.dz net.dz pol.dz soc.dz tm.dz // ec : http://www.nic.ec/reg/paso1.asp // Submitted by registry ec com.ec info.ec net.ec fin.ec k12.ec med.ec pro.ec org.ec edu.ec gov.ec gob.ec mil.ec // edu : https://en.wikipedia.org/wiki/.edu edu // ee : http://www.eenet.ee/EENet/dom_reeglid.html#lisa_B ee edu.ee gov.ee riik.ee lib.ee med.ee com.ee pri.ee aip.ee org.ee fie.ee // eg : https://en.wikipedia.org/wiki/.eg eg com.eg edu.eg eun.eg gov.eg mil.eg name.eg net.eg org.eg sci.eg // er : https://en.wikipedia.org/wiki/.er *.er // es : https://www.nic.es/site_ingles/ingles/dominios/index.html es com.es nom.es org.es gob.es edu.es // et : https://en.wikipedia.org/wiki/.et et com.et gov.et org.et edu.et biz.et name.et info.et net.et // eu : https://en.wikipedia.org/wiki/.eu eu // fi : https://en.wikipedia.org/wiki/.fi fi // aland.fi : https://en.wikipedia.org/wiki/.ax // This domain is being phased out in favor of .ax. As there are still many // domains under aland.fi, we still keep it on the list until aland.fi is // completely removed. // TODO: Check for updates (expected to be phased out around Q1/2009) aland.fi // fj : http://domains.fj/ // Submitted by registry 2020-02-11 fj ac.fj biz.fj com.fj gov.fj info.fj mil.fj name.fj net.fj org.fj pro.fj // fk : https://en.wikipedia.org/wiki/.fk *.fk // fm : https://en.wikipedia.org/wiki/.fm com.fm edu.fm net.fm org.fm fm // fo : https://en.wikipedia.org/wiki/.fo fo // fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf fr asso.fr com.fr gouv.fr nom.fr prd.fr tm.fr // Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes avoues.fr cci.fr greta.fr huissier-justice.fr // ga : https://en.wikipedia.org/wiki/.ga ga // gb : This registry is effectively dormant // Submitted by registry gb // gd : https://en.wikipedia.org/wiki/.gd edu.gd gov.gd gd // ge : http://www.nic.net.ge/policy_en.pdf ge com.ge edu.ge gov.ge org.ge mil.ge net.ge pvt.ge // gf : https://en.wikipedia.org/wiki/.gf gf // gg : http://www.channelisles.net/register-domains/ // Confirmed by registry 2013-11-28 gg co.gg net.gg org.gg // gh : https://en.wikipedia.org/wiki/.gh // see also: http://www.nic.gh/reg_now.php // Although domains directly at second level are not possible at the moment, // they have been possible for some time and may come back. gh com.gh edu.gh gov.gh org.gh mil.gh // gi : http://www.nic.gi/rules.html gi com.gi ltd.gi gov.gi mod.gi edu.gi org.gi // gl : https://en.wikipedia.org/wiki/.gl // http://nic.gl gl co.gl com.gl edu.gl net.gl org.gl // gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm gm // gn : http://psg.com/dns/gn/gn.txt // Submitted by registry gn ac.gn com.gn edu.gn gov.gn org.gn net.gn // gov : https://en.wikipedia.org/wiki/.gov gov // gp : http://www.nic.gp/index.php?lang=en gp com.gp net.gp mobi.gp edu.gp org.gp asso.gp // gq : https://en.wikipedia.org/wiki/.gq gq // gr : https://grweb.ics.forth.gr/english/1617-B-2005.html // Submitted by registry gr com.gr edu.gr net.gr org.gr gov.gr // gs : https://en.wikipedia.org/wiki/.gs gs // gt : https://www.gt/sitio/registration_policy.php?lang=en gt com.gt edu.gt gob.gt ind.gt mil.gt net.gt org.gt // gu : http://gadao.gov.gu/register.html // University of Guam : https://www.uog.edu // Submitted by uognoc@triton.uog.edu gu com.gu edu.gu gov.gu guam.gu info.gu net.gu org.gu web.gu // gw : https://en.wikipedia.org/wiki/.gw // gw : https://nic.gw/regras/ gw // gy : https://en.wikipedia.org/wiki/.gy // http://registry.gy/ gy co.gy com.gy edu.gy gov.gy net.gy org.gy // hk : https://www.hkirc.hk // Submitted by registry hk com.hk edu.hk gov.hk idv.hk net.hk org.hk xn--55qx5d.hk xn--wcvs22d.hk xn--lcvr32d.hk xn--mxtq1m.hk xn--gmqw5a.hk xn--ciqpn.hk xn--gmq050i.hk xn--zf0avx.hk xn--io0a7i.hk xn--mk0axi.hk xn--od0alg.hk xn--od0aq3b.hk xn--tn0ag.hk xn--uc0atv.hk xn--uc0ay4a.hk // hm : https://en.wikipedia.org/wiki/.hm hm // hn : http://www.nic.hn/politicas/ps02,,05.html hn com.hn edu.hn org.hn net.hn mil.hn gob.hn // hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf hr iz.hr from.hr name.hr com.hr // ht : http://www.nic.ht/info/charte.cfm ht com.ht shop.ht firm.ht info.ht adult.ht net.ht pro.ht org.ht med.ht art.ht coop.ht pol.ht asso.ht edu.ht rel.ht gouv.ht perso.ht // hu : http://www.domain.hu/domain/English/sld.html // Confirmed by registry 2008-06-12 hu co.hu info.hu org.hu priv.hu sport.hu tm.hu 2000.hu agrar.hu bolt.hu casino.hu city.hu erotica.hu erotika.hu film.hu forum.hu games.hu hotel.hu ingatlan.hu jogasz.hu konyvelo.hu lakas.hu media.hu news.hu reklam.hu sex.hu shop.hu suli.hu szex.hu tozsde.hu utazas.hu video.hu // id : https://pandi.id/en/domain/registration-requirements/ id ac.id biz.id co.id desa.id go.id mil.id my.id net.id or.id ponpes.id sch.id web.id // ie : https://en.wikipedia.org/wiki/.ie ie gov.ie // il : http://www.isoc.org.il/domains/ // see also: https://en.isoc.org.il/il-cctld/registration-rules // ISOC-IL (operated by .il Registry) il ac.il co.il gov.il idf.il k12.il muni.il net.il org.il // xn--4dbrk0ce ("Israel", Hebrew) : IL xn--4dbrk0ce // xn--4dbgdty6c.xn--4dbrk0ce. xn--4dbgdty6c.xn--4dbrk0ce // xn--5dbhl8d.xn--4dbrk0ce. xn--5dbhl8d.xn--4dbrk0ce // xn--8dbq2a.xn--4dbrk0ce. xn--8dbq2a.xn--4dbrk0ce // xn--hebda8b.xn--4dbrk0ce. xn--hebda8b.xn--4dbrk0ce // im : https://www.nic.im/ // Submitted by registry im ac.im co.im com.im ltd.co.im net.im org.im plc.co.im tt.im tv.im // in : https://en.wikipedia.org/wiki/.in // see also: https://registry.in/policies // Please note, that nic.in is not an official eTLD, but used by most // government institutions. in 5g.in 6g.in ac.in ai.in am.in bihar.in biz.in business.in ca.in cn.in co.in com.in coop.in cs.in delhi.in dr.in edu.in er.in firm.in gen.in gov.in gujarat.in ind.in info.in int.in internet.in io.in me.in mil.in net.in nic.in org.in pg.in post.in pro.in res.in travel.in tv.in uk.in up.in us.in // info : https://en.wikipedia.org/wiki/.info info // int : https://en.wikipedia.org/wiki/.int // Confirmed by registry 2008-06-18 int eu.int // io : http://www.nic.io/rules.htm // list of other 2nd level tlds ? io com.io // iq : http://www.cmc.iq/english/iq/iqregister1.htm iq gov.iq edu.iq mil.iq com.iq org.iq net.iq // ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules // Also see http://www.nic.ir/Internationalized_Domain_Names // Two .ir entries added at request of , 2010-04-16 ir ac.ir co.ir gov.ir id.ir net.ir org.ir sch.ir // xn--mgba3a4f16a.ir (.ir, Persian YEH) xn--mgba3a4f16a.ir // xn--mgba3a4fra.ir (.ir, Arabic YEH) xn--mgba3a4fra.ir // is : http://www.isnic.is/domain/rules.php // Confirmed by registry 2008-12-06 is net.is com.is edu.is gov.is org.is int.is // it : https://en.wikipedia.org/wiki/.it it gov.it edu.it // Reserved geo-names (regions and provinces): // https://www.nic.it/sites/default/files/archivio/docs/Regulation_assignation_v7.1.pdf // Regions abr.it abruzzo.it aosta-valley.it aostavalley.it bas.it basilicata.it cal.it calabria.it cam.it campania.it emilia-romagna.it emiliaromagna.it emr.it friuli-v-giulia.it friuli-ve-giulia.it friuli-vegiulia.it friuli-venezia-giulia.it friuli-veneziagiulia.it friuli-vgiulia.it friuliv-giulia.it friulive-giulia.it friulivegiulia.it friulivenezia-giulia.it friuliveneziagiulia.it friulivgiulia.it fvg.it laz.it lazio.it lig.it liguria.it lom.it lombardia.it lombardy.it lucania.it mar.it marche.it mol.it molise.it piedmont.it piemonte.it pmn.it pug.it puglia.it sar.it sardegna.it sardinia.it sic.it sicilia.it sicily.it taa.it tos.it toscana.it trentin-sud-tirol.it xn--trentin-sd-tirol-rzb.it trentin-sudtirol.it xn--trentin-sdtirol-7vb.it trentin-sued-tirol.it trentin-suedtirol.it trentino-a-adige.it trentino-aadige.it trentino-alto-adige.it trentino-altoadige.it trentino-s-tirol.it trentino-stirol.it trentino-sud-tirol.it xn--trentino-sd-tirol-c3b.it trentino-sudtirol.it xn--trentino-sdtirol-szb.it trentino-sued-tirol.it trentino-suedtirol.it trentino.it trentinoa-adige.it trentinoaadige.it trentinoalto-adige.it trentinoaltoadige.it trentinos-tirol.it trentinostirol.it trentinosud-tirol.it xn--trentinosd-tirol-rzb.it trentinosudtirol.it xn--trentinosdtirol-7vb.it trentinosued-tirol.it trentinosuedtirol.it trentinsud-tirol.it xn--trentinsd-tirol-6vb.it trentinsudtirol.it xn--trentinsdtirol-nsb.it trentinsued-tirol.it trentinsuedtirol.it tuscany.it umb.it umbria.it val-d-aosta.it val-daosta.it vald-aosta.it valdaosta.it valle-aosta.it valle-d-aosta.it valle-daosta.it valleaosta.it valled-aosta.it valledaosta.it vallee-aoste.it xn--valle-aoste-ebb.it vallee-d-aoste.it xn--valle-d-aoste-ehb.it valleeaoste.it xn--valleaoste-e7a.it valleedaoste.it xn--valledaoste-ebb.it vao.it vda.it ven.it veneto.it // Provinces ag.it agrigento.it al.it alessandria.it alto-adige.it altoadige.it an.it ancona.it andria-barletta-trani.it andria-trani-barletta.it andriabarlettatrani.it andriatranibarletta.it ao.it aosta.it aoste.it ap.it aq.it aquila.it ar.it arezzo.it ascoli-piceno.it ascolipiceno.it asti.it at.it av.it avellino.it ba.it balsan-sudtirol.it xn--balsan-sdtirol-nsb.it balsan-suedtirol.it balsan.it bari.it barletta-trani-andria.it barlettatraniandria.it belluno.it benevento.it bergamo.it bg.it bi.it biella.it bl.it bn.it bo.it bologna.it bolzano-altoadige.it bolzano.it bozen-sudtirol.it xn--bozen-sdtirol-2ob.it bozen-suedtirol.it bozen.it br.it brescia.it brindisi.it bs.it bt.it bulsan-sudtirol.it xn--bulsan-sdtirol-nsb.it bulsan-suedtirol.it bulsan.it bz.it ca.it cagliari.it caltanissetta.it campidano-medio.it campidanomedio.it campobasso.it carbonia-iglesias.it carboniaiglesias.it carrara-massa.it carraramassa.it caserta.it catania.it catanzaro.it cb.it ce.it cesena-forli.it xn--cesena-forl-mcb.it cesenaforli.it xn--cesenaforl-i8a.it ch.it chieti.it ci.it cl.it cn.it co.it como.it cosenza.it cr.it cremona.it crotone.it cs.it ct.it cuneo.it cz.it dell-ogliastra.it dellogliastra.it en.it enna.it fc.it fe.it fermo.it ferrara.it fg.it fi.it firenze.it florence.it fm.it foggia.it forli-cesena.it xn--forl-cesena-fcb.it forlicesena.it xn--forlcesena-c8a.it fr.it frosinone.it ge.it genoa.it genova.it go.it gorizia.it gr.it grosseto.it iglesias-carbonia.it iglesiascarbonia.it im.it imperia.it is.it isernia.it kr.it la-spezia.it laquila.it laspezia.it latina.it lc.it le.it lecce.it lecco.it li.it livorno.it lo.it lodi.it lt.it lu.it lucca.it macerata.it mantova.it massa-carrara.it massacarrara.it matera.it mb.it mc.it me.it medio-campidano.it mediocampidano.it messina.it mi.it milan.it milano.it mn.it mo.it modena.it monza-brianza.it monza-e-della-brianza.it monza.it monzabrianza.it monzaebrianza.it monzaedellabrianza.it ms.it mt.it na.it naples.it napoli.it no.it novara.it nu.it nuoro.it og.it ogliastra.it olbia-tempio.it olbiatempio.it or.it oristano.it ot.it pa.it padova.it padua.it palermo.it parma.it pavia.it pc.it pd.it pe.it perugia.it pesaro-urbino.it pesarourbino.it pescara.it pg.it pi.it piacenza.it pisa.it pistoia.it pn.it po.it pordenone.it potenza.it pr.it prato.it pt.it pu.it pv.it pz.it ra.it ragusa.it ravenna.it rc.it re.it reggio-calabria.it reggio-emilia.it reggiocalabria.it reggioemilia.it rg.it ri.it rieti.it rimini.it rm.it rn.it ro.it roma.it rome.it rovigo.it sa.it salerno.it sassari.it savona.it si.it siena.it siracusa.it so.it sondrio.it sp.it sr.it ss.it suedtirol.it xn--sdtirol-n2a.it sv.it ta.it taranto.it te.it tempio-olbia.it tempioolbia.it teramo.it terni.it tn.it to.it torino.it tp.it tr.it trani-andria-barletta.it trani-barletta-andria.it traniandriabarletta.it tranibarlettaandria.it trapani.it trento.it treviso.it trieste.it ts.it turin.it tv.it ud.it udine.it urbino-pesaro.it urbinopesaro.it va.it varese.it vb.it vc.it ve.it venezia.it venice.it verbania.it vercelli.it verona.it vi.it vibo-valentia.it vibovalentia.it vicenza.it viterbo.it vr.it vs.it vt.it vv.it // je : http://www.channelisles.net/register-domains/ // Confirmed by registry 2013-11-28 je co.je net.je org.je // jm : http://www.com.jm/register.html *.jm // jo : http://www.dns.jo/Registration_policy.aspx jo com.jo org.jo net.jo edu.jo sch.jo gov.jo mil.jo name.jo // jobs : https://en.wikipedia.org/wiki/.jobs jobs // jp : https://en.wikipedia.org/wiki/.jp // http://jprs.co.jp/en/jpdomain.html // Submitted by registry jp // jp organizational type names ac.jp ad.jp co.jp ed.jp go.jp gr.jp lg.jp ne.jp or.jp // jp prefecture type names aichi.jp akita.jp aomori.jp chiba.jp ehime.jp fukui.jp fukuoka.jp fukushima.jp gifu.jp gunma.jp hiroshima.jp hokkaido.jp hyogo.jp ibaraki.jp ishikawa.jp iwate.jp kagawa.jp kagoshima.jp kanagawa.jp kochi.jp kumamoto.jp kyoto.jp mie.jp miyagi.jp miyazaki.jp nagano.jp nagasaki.jp nara.jp niigata.jp oita.jp okayama.jp okinawa.jp osaka.jp saga.jp saitama.jp shiga.jp shimane.jp shizuoka.jp tochigi.jp tokushima.jp tokyo.jp tottori.jp toyama.jp wakayama.jp yamagata.jp yamaguchi.jp yamanashi.jp xn--4pvxs.jp xn--vgu402c.jp xn--c3s14m.jp xn--f6qx53a.jp xn--8pvr4u.jp xn--uist22h.jp xn--djrs72d6uy.jp xn--mkru45i.jp xn--0trq7p7nn.jp xn--8ltr62k.jp xn--2m4a15e.jp xn--efvn9s.jp xn--32vp30h.jp xn--4it797k.jp xn--1lqs71d.jp xn--5rtp49c.jp xn--5js045d.jp xn--ehqz56n.jp xn--1lqs03n.jp xn--qqqt11m.jp xn--kbrq7o.jp xn--pssu33l.jp xn--ntsq17g.jp xn--uisz3g.jp xn--6btw5a.jp xn--1ctwo.jp xn--6orx2r.jp xn--rht61e.jp xn--rht27z.jp xn--djty4k.jp xn--nit225k.jp xn--rht3d.jp xn--klty5x.jp xn--kltx9a.jp xn--kltp7d.jp xn--uuwu58a.jp xn--zbx025d.jp xn--ntso0iqx3a.jp xn--elqq16h.jp xn--4it168d.jp xn--klt787d.jp xn--rny31h.jp xn--7t0a264c.jp xn--5rtq34k.jp xn--k7yn95e.jp xn--tor131o.jp xn--d5qv7z876c.jp // jp geographic type names // http://jprs.jp/doc/rule/saisoku-1.html *.kawasaki.jp *.kitakyushu.jp *.kobe.jp *.nagoya.jp *.sapporo.jp *.sendai.jp *.yokohama.jp !city.kawasaki.jp !city.kitakyushu.jp !city.kobe.jp !city.nagoya.jp !city.sapporo.jp !city.sendai.jp !city.yokohama.jp // 4th level registration aisai.aichi.jp ama.aichi.jp anjo.aichi.jp asuke.aichi.jp chiryu.aichi.jp chita.aichi.jp fuso.aichi.jp gamagori.aichi.jp handa.aichi.jp hazu.aichi.jp hekinan.aichi.jp higashiura.aichi.jp ichinomiya.aichi.jp inazawa.aichi.jp inuyama.aichi.jp isshiki.aichi.jp iwakura.aichi.jp kanie.aichi.jp kariya.aichi.jp kasugai.aichi.jp kira.aichi.jp kiyosu.aichi.jp komaki.aichi.jp konan.aichi.jp kota.aichi.jp mihama.aichi.jp miyoshi.aichi.jp nishio.aichi.jp nisshin.aichi.jp obu.aichi.jp oguchi.aichi.jp oharu.aichi.jp okazaki.aichi.jp owariasahi.aichi.jp seto.aichi.jp shikatsu.aichi.jp shinshiro.aichi.jp shitara.aichi.jp tahara.aichi.jp takahama.aichi.jp tobishima.aichi.jp toei.aichi.jp togo.aichi.jp tokai.aichi.jp tokoname.aichi.jp toyoake.aichi.jp toyohashi.aichi.jp toyokawa.aichi.jp toyone.aichi.jp toyota.aichi.jp tsushima.aichi.jp yatomi.aichi.jp akita.akita.jp daisen.akita.jp fujisato.akita.jp gojome.akita.jp hachirogata.akita.jp happou.akita.jp higashinaruse.akita.jp honjo.akita.jp honjyo.akita.jp ikawa.akita.jp kamikoani.akita.jp kamioka.akita.jp katagami.akita.jp kazuno.akita.jp kitaakita.akita.jp kosaka.akita.jp kyowa.akita.jp misato.akita.jp mitane.akita.jp moriyoshi.akita.jp nikaho.akita.jp noshiro.akita.jp odate.akita.jp oga.akita.jp ogata.akita.jp semboku.akita.jp yokote.akita.jp yurihonjo.akita.jp aomori.aomori.jp gonohe.aomori.jp hachinohe.aomori.jp hashikami.aomori.jp hiranai.aomori.jp hirosaki.aomori.jp itayanagi.aomori.jp kuroishi.aomori.jp misawa.aomori.jp mutsu.aomori.jp nakadomari.aomori.jp noheji.aomori.jp oirase.aomori.jp owani.aomori.jp rokunohe.aomori.jp sannohe.aomori.jp shichinohe.aomori.jp shingo.aomori.jp takko.aomori.jp towada.aomori.jp tsugaru.aomori.jp tsuruta.aomori.jp abiko.chiba.jp asahi.chiba.jp chonan.chiba.jp chosei.chiba.jp choshi.chiba.jp chuo.chiba.jp funabashi.chiba.jp futtsu.chiba.jp hanamigawa.chiba.jp ichihara.chiba.jp ichikawa.chiba.jp ichinomiya.chiba.jp inzai.chiba.jp isumi.chiba.jp kamagaya.chiba.jp kamogawa.chiba.jp kashiwa.chiba.jp katori.chiba.jp katsuura.chiba.jp kimitsu.chiba.jp kisarazu.chiba.jp kozaki.chiba.jp kujukuri.chiba.jp kyonan.chiba.jp matsudo.chiba.jp midori.chiba.jp mihama.chiba.jp minamiboso.chiba.jp mobara.chiba.jp mutsuzawa.chiba.jp nagara.chiba.jp nagareyama.chiba.jp narashino.chiba.jp narita.chiba.jp noda.chiba.jp oamishirasato.chiba.jp omigawa.chiba.jp onjuku.chiba.jp otaki.chiba.jp sakae.chiba.jp sakura.chiba.jp shimofusa.chiba.jp shirako.chiba.jp shiroi.chiba.jp shisui.chiba.jp sodegaura.chiba.jp sosa.chiba.jp tako.chiba.jp tateyama.chiba.jp togane.chiba.jp tohnosho.chiba.jp tomisato.chiba.jp urayasu.chiba.jp yachimata.chiba.jp yachiyo.chiba.jp yokaichiba.chiba.jp yokoshibahikari.chiba.jp yotsukaido.chiba.jp ainan.ehime.jp honai.ehime.jp ikata.ehime.jp imabari.ehime.jp iyo.ehime.jp kamijima.ehime.jp kihoku.ehime.jp kumakogen.ehime.jp masaki.ehime.jp matsuno.ehime.jp matsuyama.ehime.jp namikata.ehime.jp niihama.ehime.jp ozu.ehime.jp saijo.ehime.jp seiyo.ehime.jp shikokuchuo.ehime.jp tobe.ehime.jp toon.ehime.jp uchiko.ehime.jp uwajima.ehime.jp yawatahama.ehime.jp echizen.fukui.jp eiheiji.fukui.jp fukui.fukui.jp ikeda.fukui.jp katsuyama.fukui.jp mihama.fukui.jp minamiechizen.fukui.jp obama.fukui.jp ohi.fukui.jp ono.fukui.jp sabae.fukui.jp sakai.fukui.jp takahama.fukui.jp tsuruga.fukui.jp wakasa.fukui.jp ashiya.fukuoka.jp buzen.fukuoka.jp chikugo.fukuoka.jp chikuho.fukuoka.jp chikujo.fukuoka.jp chikushino.fukuoka.jp chikuzen.fukuoka.jp chuo.fukuoka.jp dazaifu.fukuoka.jp fukuchi.fukuoka.jp hakata.fukuoka.jp higashi.fukuoka.jp hirokawa.fukuoka.jp hisayama.fukuoka.jp iizuka.fukuoka.jp inatsuki.fukuoka.jp kaho.fukuoka.jp kasuga.fukuoka.jp kasuya.fukuoka.jp kawara.fukuoka.jp keisen.fukuoka.jp koga.fukuoka.jp kurate.fukuoka.jp kurogi.fukuoka.jp kurume.fukuoka.jp minami.fukuoka.jp miyako.fukuoka.jp miyama.fukuoka.jp miyawaka.fukuoka.jp mizumaki.fukuoka.jp munakata.fukuoka.jp nakagawa.fukuoka.jp nakama.fukuoka.jp nishi.fukuoka.jp nogata.fukuoka.jp ogori.fukuoka.jp okagaki.fukuoka.jp okawa.fukuoka.jp oki.fukuoka.jp omuta.fukuoka.jp onga.fukuoka.jp onojo.fukuoka.jp oto.fukuoka.jp saigawa.fukuoka.jp sasaguri.fukuoka.jp shingu.fukuoka.jp shinyoshitomi.fukuoka.jp shonai.fukuoka.jp soeda.fukuoka.jp sue.fukuoka.jp tachiarai.fukuoka.jp tagawa.fukuoka.jp takata.fukuoka.jp toho.fukuoka.jp toyotsu.fukuoka.jp tsuiki.fukuoka.jp ukiha.fukuoka.jp umi.fukuoka.jp usui.fukuoka.jp yamada.fukuoka.jp yame.fukuoka.jp yanagawa.fukuoka.jp yukuhashi.fukuoka.jp aizubange.fukushima.jp aizumisato.fukushima.jp aizuwakamatsu.fukushima.jp asakawa.fukushima.jp bandai.fukushima.jp date.fukushima.jp fukushima.fukushima.jp furudono.fukushima.jp futaba.fukushima.jp hanawa.fukushima.jp higashi.fukushima.jp hirata.fukushima.jp hirono.fukushima.jp iitate.fukushima.jp inawashiro.fukushima.jp ishikawa.fukushima.jp iwaki.fukushima.jp izumizaki.fukushima.jp kagamiishi.fukushima.jp kaneyama.fukushima.jp kawamata.fukushima.jp kitakata.fukushima.jp kitashiobara.fukushima.jp koori.fukushima.jp koriyama.fukushima.jp kunimi.fukushima.jp miharu.fukushima.jp mishima.fukushima.jp namie.fukushima.jp nango.fukushima.jp nishiaizu.fukushima.jp nishigo.fukushima.jp okuma.fukushima.jp omotego.fukushima.jp ono.fukushima.jp otama.fukushima.jp samegawa.fukushima.jp shimogo.fukushima.jp shirakawa.fukushima.jp showa.fukushima.jp soma.fukushima.jp sukagawa.fukushima.jp taishin.fukushima.jp tamakawa.fukushima.jp tanagura.fukushima.jp tenei.fukushima.jp yabuki.fukushima.jp yamato.fukushima.jp yamatsuri.fukushima.jp yanaizu.fukushima.jp yugawa.fukushima.jp anpachi.gifu.jp ena.gifu.jp gifu.gifu.jp ginan.gifu.jp godo.gifu.jp gujo.gifu.jp hashima.gifu.jp hichiso.gifu.jp hida.gifu.jp higashishirakawa.gifu.jp ibigawa.gifu.jp ikeda.gifu.jp kakamigahara.gifu.jp kani.gifu.jp kasahara.gifu.jp kasamatsu.gifu.jp kawaue.gifu.jp kitagata.gifu.jp mino.gifu.jp minokamo.gifu.jp mitake.gifu.jp mizunami.gifu.jp motosu.gifu.jp nakatsugawa.gifu.jp ogaki.gifu.jp sakahogi.gifu.jp seki.gifu.jp sekigahara.gifu.jp shirakawa.gifu.jp tajimi.gifu.jp takayama.gifu.jp tarui.gifu.jp toki.gifu.jp tomika.gifu.jp wanouchi.gifu.jp yamagata.gifu.jp yaotsu.gifu.jp yoro.gifu.jp annaka.gunma.jp chiyoda.gunma.jp fujioka.gunma.jp higashiagatsuma.gunma.jp isesaki.gunma.jp itakura.gunma.jp kanna.gunma.jp kanra.gunma.jp katashina.gunma.jp kawaba.gunma.jp kiryu.gunma.jp kusatsu.gunma.jp maebashi.gunma.jp meiwa.gunma.jp midori.gunma.jp minakami.gunma.jp naganohara.gunma.jp nakanojo.gunma.jp nanmoku.gunma.jp numata.gunma.jp oizumi.gunma.jp ora.gunma.jp ota.gunma.jp shibukawa.gunma.jp shimonita.gunma.jp shinto.gunma.jp showa.gunma.jp takasaki.gunma.jp takayama.gunma.jp tamamura.gunma.jp tatebayashi.gunma.jp tomioka.gunma.jp tsukiyono.gunma.jp tsumagoi.gunma.jp ueno.gunma.jp yoshioka.gunma.jp asaminami.hiroshima.jp daiwa.hiroshima.jp etajima.hiroshima.jp fuchu.hiroshima.jp fukuyama.hiroshima.jp hatsukaichi.hiroshima.jp higashihiroshima.hiroshima.jp hongo.hiroshima.jp jinsekikogen.hiroshima.jp kaita.hiroshima.jp kui.hiroshima.jp kumano.hiroshima.jp kure.hiroshima.jp mihara.hiroshima.jp miyoshi.hiroshima.jp naka.hiroshima.jp onomichi.hiroshima.jp osakikamijima.hiroshima.jp otake.hiroshima.jp saka.hiroshima.jp sera.hiroshima.jp seranishi.hiroshima.jp shinichi.hiroshima.jp shobara.hiroshima.jp takehara.hiroshima.jp abashiri.hokkaido.jp abira.hokkaido.jp aibetsu.hokkaido.jp akabira.hokkaido.jp akkeshi.hokkaido.jp asahikawa.hokkaido.jp ashibetsu.hokkaido.jp ashoro.hokkaido.jp assabu.hokkaido.jp atsuma.hokkaido.jp bibai.hokkaido.jp biei.hokkaido.jp bifuka.hokkaido.jp bihoro.hokkaido.jp biratori.hokkaido.jp chippubetsu.hokkaido.jp chitose.hokkaido.jp date.hokkaido.jp ebetsu.hokkaido.jp embetsu.hokkaido.jp eniwa.hokkaido.jp erimo.hokkaido.jp esan.hokkaido.jp esashi.hokkaido.jp fukagawa.hokkaido.jp fukushima.hokkaido.jp furano.hokkaido.jp furubira.hokkaido.jp haboro.hokkaido.jp hakodate.hokkaido.jp hamatonbetsu.hokkaido.jp hidaka.hokkaido.jp higashikagura.hokkaido.jp higashikawa.hokkaido.jp hiroo.hokkaido.jp hokuryu.hokkaido.jp hokuto.hokkaido.jp honbetsu.hokkaido.jp horokanai.hokkaido.jp horonobe.hokkaido.jp ikeda.hokkaido.jp imakane.hokkaido.jp ishikari.hokkaido.jp iwamizawa.hokkaido.jp iwanai.hokkaido.jp kamifurano.hokkaido.jp kamikawa.hokkaido.jp kamishihoro.hokkaido.jp kamisunagawa.hokkaido.jp kamoenai.hokkaido.jp kayabe.hokkaido.jp kembuchi.hokkaido.jp kikonai.hokkaido.jp kimobetsu.hokkaido.jp kitahiroshima.hokkaido.jp kitami.hokkaido.jp kiyosato.hokkaido.jp koshimizu.hokkaido.jp kunneppu.hokkaido.jp kuriyama.hokkaido.jp kuromatsunai.hokkaido.jp kushiro.hokkaido.jp kutchan.hokkaido.jp kyowa.hokkaido.jp mashike.hokkaido.jp matsumae.hokkaido.jp mikasa.hokkaido.jp minamifurano.hokkaido.jp mombetsu.hokkaido.jp moseushi.hokkaido.jp mukawa.hokkaido.jp muroran.hokkaido.jp naie.hokkaido.jp nakagawa.hokkaido.jp nakasatsunai.hokkaido.jp nakatombetsu.hokkaido.jp nanae.hokkaido.jp nanporo.hokkaido.jp nayoro.hokkaido.jp nemuro.hokkaido.jp niikappu.hokkaido.jp niki.hokkaido.jp nishiokoppe.hokkaido.jp noboribetsu.hokkaido.jp numata.hokkaido.jp obihiro.hokkaido.jp obira.hokkaido.jp oketo.hokkaido.jp okoppe.hokkaido.jp otaru.hokkaido.jp otobe.hokkaido.jp otofuke.hokkaido.jp otoineppu.hokkaido.jp oumu.hokkaido.jp ozora.hokkaido.jp pippu.hokkaido.jp rankoshi.hokkaido.jp rebun.hokkaido.jp rikubetsu.hokkaido.jp rishiri.hokkaido.jp rishirifuji.hokkaido.jp saroma.hokkaido.jp sarufutsu.hokkaido.jp shakotan.hokkaido.jp shari.hokkaido.jp shibecha.hokkaido.jp shibetsu.hokkaido.jp shikabe.hokkaido.jp shikaoi.hokkaido.jp shimamaki.hokkaido.jp shimizu.hokkaido.jp shimokawa.hokkaido.jp shinshinotsu.hokkaido.jp shintoku.hokkaido.jp shiranuka.hokkaido.jp shiraoi.hokkaido.jp shiriuchi.hokkaido.jp sobetsu.hokkaido.jp sunagawa.hokkaido.jp taiki.hokkaido.jp takasu.hokkaido.jp takikawa.hokkaido.jp takinoue.hokkaido.jp teshikaga.hokkaido.jp tobetsu.hokkaido.jp tohma.hokkaido.jp tomakomai.hokkaido.jp tomari.hokkaido.jp toya.hokkaido.jp toyako.hokkaido.jp toyotomi.hokkaido.jp toyoura.hokkaido.jp tsubetsu.hokkaido.jp tsukigata.hokkaido.jp urakawa.hokkaido.jp urausu.hokkaido.jp uryu.hokkaido.jp utashinai.hokkaido.jp wakkanai.hokkaido.jp wassamu.hokkaido.jp yakumo.hokkaido.jp yoichi.hokkaido.jp aioi.hyogo.jp akashi.hyogo.jp ako.hyogo.jp amagasaki.hyogo.jp aogaki.hyogo.jp asago.hyogo.jp ashiya.hyogo.jp awaji.hyogo.jp fukusaki.hyogo.jp goshiki.hyogo.jp harima.hyogo.jp himeji.hyogo.jp ichikawa.hyogo.jp inagawa.hyogo.jp itami.hyogo.jp kakogawa.hyogo.jp kamigori.hyogo.jp kamikawa.hyogo.jp kasai.hyogo.jp kasuga.hyogo.jp kawanishi.hyogo.jp miki.hyogo.jp minamiawaji.hyogo.jp nishinomiya.hyogo.jp nishiwaki.hyogo.jp ono.hyogo.jp sanda.hyogo.jp sannan.hyogo.jp sasayama.hyogo.jp sayo.hyogo.jp shingu.hyogo.jp shinonsen.hyogo.jp shiso.hyogo.jp sumoto.hyogo.jp taishi.hyogo.jp taka.hyogo.jp takarazuka.hyogo.jp takasago.hyogo.jp takino.hyogo.jp tamba.hyogo.jp tatsuno.hyogo.jp toyooka.hyogo.jp yabu.hyogo.jp yashiro.hyogo.jp yoka.hyogo.jp yokawa.hyogo.jp ami.ibaraki.jp asahi.ibaraki.jp bando.ibaraki.jp chikusei.ibaraki.jp daigo.ibaraki.jp fujishiro.ibaraki.jp hitachi.ibaraki.jp hitachinaka.ibaraki.jp hitachiomiya.ibaraki.jp hitachiota.ibaraki.jp ibaraki.ibaraki.jp ina.ibaraki.jp inashiki.ibaraki.jp itako.ibaraki.jp iwama.ibaraki.jp joso.ibaraki.jp kamisu.ibaraki.jp kasama.ibaraki.jp kashima.ibaraki.jp kasumigaura.ibaraki.jp koga.ibaraki.jp miho.ibaraki.jp mito.ibaraki.jp moriya.ibaraki.jp naka.ibaraki.jp namegata.ibaraki.jp oarai.ibaraki.jp ogawa.ibaraki.jp omitama.ibaraki.jp ryugasaki.ibaraki.jp sakai.ibaraki.jp sakuragawa.ibaraki.jp shimodate.ibaraki.jp shimotsuma.ibaraki.jp shirosato.ibaraki.jp sowa.ibaraki.jp suifu.ibaraki.jp takahagi.ibaraki.jp tamatsukuri.ibaraki.jp tokai.ibaraki.jp tomobe.ibaraki.jp tone.ibaraki.jp toride.ibaraki.jp tsuchiura.ibaraki.jp tsukuba.ibaraki.jp uchihara.ibaraki.jp ushiku.ibaraki.jp yachiyo.ibaraki.jp yamagata.ibaraki.jp yawara.ibaraki.jp yuki.ibaraki.jp anamizu.ishikawa.jp hakui.ishikawa.jp hakusan.ishikawa.jp kaga.ishikawa.jp kahoku.ishikawa.jp kanazawa.ishikawa.jp kawakita.ishikawa.jp komatsu.ishikawa.jp nakanoto.ishikawa.jp nanao.ishikawa.jp nomi.ishikawa.jp nonoichi.ishikawa.jp noto.ishikawa.jp shika.ishikawa.jp suzu.ishikawa.jp tsubata.ishikawa.jp tsurugi.ishikawa.jp uchinada.ishikawa.jp wajima.ishikawa.jp fudai.iwate.jp fujisawa.iwate.jp hanamaki.iwate.jp hiraizumi.iwate.jp hirono.iwate.jp ichinohe.iwate.jp ichinoseki.iwate.jp iwaizumi.iwate.jp iwate.iwate.jp joboji.iwate.jp kamaishi.iwate.jp kanegasaki.iwate.jp karumai.iwate.jp kawai.iwate.jp kitakami.iwate.jp kuji.iwate.jp kunohe.iwate.jp kuzumaki.iwate.jp miyako.iwate.jp mizusawa.iwate.jp morioka.iwate.jp ninohe.iwate.jp noda.iwate.jp ofunato.iwate.jp oshu.iwate.jp otsuchi.iwate.jp rikuzentakata.iwate.jp shiwa.iwate.jp shizukuishi.iwate.jp sumita.iwate.jp tanohata.iwate.jp tono.iwate.jp yahaba.iwate.jp yamada.iwate.jp ayagawa.kagawa.jp higashikagawa.kagawa.jp kanonji.kagawa.jp kotohira.kagawa.jp manno.kagawa.jp marugame.kagawa.jp mitoyo.kagawa.jp naoshima.kagawa.jp sanuki.kagawa.jp tadotsu.kagawa.jp takamatsu.kagawa.jp tonosho.kagawa.jp uchinomi.kagawa.jp utazu.kagawa.jp zentsuji.kagawa.jp akune.kagoshima.jp amami.kagoshima.jp hioki.kagoshima.jp isa.kagoshima.jp isen.kagoshima.jp izumi.kagoshima.jp kagoshima.kagoshima.jp kanoya.kagoshima.jp kawanabe.kagoshima.jp kinko.kagoshima.jp kouyama.kagoshima.jp makurazaki.kagoshima.jp matsumoto.kagoshima.jp minamitane.kagoshima.jp nakatane.kagoshima.jp nishinoomote.kagoshima.jp satsumasendai.kagoshima.jp soo.kagoshima.jp tarumizu.kagoshima.jp yusui.kagoshima.jp aikawa.kanagawa.jp atsugi.kanagawa.jp ayase.kanagawa.jp chigasaki.kanagawa.jp ebina.kanagawa.jp fujisawa.kanagawa.jp hadano.kanagawa.jp hakone.kanagawa.jp hiratsuka.kanagawa.jp isehara.kanagawa.jp kaisei.kanagawa.jp kamakura.kanagawa.jp kiyokawa.kanagawa.jp matsuda.kanagawa.jp minamiashigara.kanagawa.jp miura.kanagawa.jp nakai.kanagawa.jp ninomiya.kanagawa.jp odawara.kanagawa.jp oi.kanagawa.jp oiso.kanagawa.jp sagamihara.kanagawa.jp samukawa.kanagawa.jp tsukui.kanagawa.jp yamakita.kanagawa.jp yamato.kanagawa.jp yokosuka.kanagawa.jp yugawara.kanagawa.jp zama.kanagawa.jp zushi.kanagawa.jp aki.kochi.jp geisei.kochi.jp hidaka.kochi.jp higashitsuno.kochi.jp ino.kochi.jp kagami.kochi.jp kami.kochi.jp kitagawa.kochi.jp kochi.kochi.jp mihara.kochi.jp motoyama.kochi.jp muroto.kochi.jp nahari.kochi.jp nakamura.kochi.jp nankoku.kochi.jp nishitosa.kochi.jp niyodogawa.kochi.jp ochi.kochi.jp okawa.kochi.jp otoyo.kochi.jp otsuki.kochi.jp sakawa.kochi.jp sukumo.kochi.jp susaki.kochi.jp tosa.kochi.jp tosashimizu.kochi.jp toyo.kochi.jp tsuno.kochi.jp umaji.kochi.jp yasuda.kochi.jp yusuhara.kochi.jp amakusa.kumamoto.jp arao.kumamoto.jp aso.kumamoto.jp choyo.kumamoto.jp gyokuto.kumamoto.jp kamiamakusa.kumamoto.jp kikuchi.kumamoto.jp kumamoto.kumamoto.jp mashiki.kumamoto.jp mifune.kumamoto.jp minamata.kumamoto.jp minamioguni.kumamoto.jp nagasu.kumamoto.jp nishihara.kumamoto.jp oguni.kumamoto.jp ozu.kumamoto.jp sumoto.kumamoto.jp takamori.kumamoto.jp uki.kumamoto.jp uto.kumamoto.jp yamaga.kumamoto.jp yamato.kumamoto.jp yatsushiro.kumamoto.jp ayabe.kyoto.jp fukuchiyama.kyoto.jp higashiyama.kyoto.jp ide.kyoto.jp ine.kyoto.jp joyo.kyoto.jp kameoka.kyoto.jp kamo.kyoto.jp kita.kyoto.jp kizu.kyoto.jp kumiyama.kyoto.jp kyotamba.kyoto.jp kyotanabe.kyoto.jp kyotango.kyoto.jp maizuru.kyoto.jp minami.kyoto.jp minamiyamashiro.kyoto.jp miyazu.kyoto.jp muko.kyoto.jp nagaokakyo.kyoto.jp nakagyo.kyoto.jp nantan.kyoto.jp oyamazaki.kyoto.jp sakyo.kyoto.jp seika.kyoto.jp tanabe.kyoto.jp uji.kyoto.jp ujitawara.kyoto.jp wazuka.kyoto.jp yamashina.kyoto.jp yawata.kyoto.jp asahi.mie.jp inabe.mie.jp ise.mie.jp kameyama.mie.jp kawagoe.mie.jp kiho.mie.jp kisosaki.mie.jp kiwa.mie.jp komono.mie.jp kumano.mie.jp kuwana.mie.jp matsusaka.mie.jp meiwa.mie.jp mihama.mie.jp minamiise.mie.jp misugi.mie.jp miyama.mie.jp nabari.mie.jp shima.mie.jp suzuka.mie.jp tado.mie.jp taiki.mie.jp taki.mie.jp tamaki.mie.jp toba.mie.jp tsu.mie.jp udono.mie.jp ureshino.mie.jp watarai.mie.jp yokkaichi.mie.jp furukawa.miyagi.jp higashimatsushima.miyagi.jp ishinomaki.miyagi.jp iwanuma.miyagi.jp kakuda.miyagi.jp kami.miyagi.jp kawasaki.miyagi.jp marumori.miyagi.jp matsushima.miyagi.jp minamisanriku.miyagi.jp misato.miyagi.jp murata.miyagi.jp natori.miyagi.jp ogawara.miyagi.jp ohira.miyagi.jp onagawa.miyagi.jp osaki.miyagi.jp rifu.miyagi.jp semine.miyagi.jp shibata.miyagi.jp shichikashuku.miyagi.jp shikama.miyagi.jp shiogama.miyagi.jp shiroishi.miyagi.jp tagajo.miyagi.jp taiwa.miyagi.jp tome.miyagi.jp tomiya.miyagi.jp wakuya.miyagi.jp watari.miyagi.jp yamamoto.miyagi.jp zao.miyagi.jp aya.miyazaki.jp ebino.miyazaki.jp gokase.miyazaki.jp hyuga.miyazaki.jp kadogawa.miyazaki.jp kawaminami.miyazaki.jp kijo.miyazaki.jp kitagawa.miyazaki.jp kitakata.miyazaki.jp kitaura.miyazaki.jp kobayashi.miyazaki.jp kunitomi.miyazaki.jp kushima.miyazaki.jp mimata.miyazaki.jp miyakonojo.miyazaki.jp miyazaki.miyazaki.jp morotsuka.miyazaki.jp nichinan.miyazaki.jp nishimera.miyazaki.jp nobeoka.miyazaki.jp saito.miyazaki.jp shiiba.miyazaki.jp shintomi.miyazaki.jp takaharu.miyazaki.jp takanabe.miyazaki.jp takazaki.miyazaki.jp tsuno.miyazaki.jp achi.nagano.jp agematsu.nagano.jp anan.nagano.jp aoki.nagano.jp asahi.nagano.jp azumino.nagano.jp chikuhoku.nagano.jp chikuma.nagano.jp chino.nagano.jp fujimi.nagano.jp hakuba.nagano.jp hara.nagano.jp hiraya.nagano.jp iida.nagano.jp iijima.nagano.jp iiyama.nagano.jp iizuna.nagano.jp ikeda.nagano.jp ikusaka.nagano.jp ina.nagano.jp karuizawa.nagano.jp kawakami.nagano.jp kiso.nagano.jp kisofukushima.nagano.jp kitaaiki.nagano.jp komagane.nagano.jp komoro.nagano.jp matsukawa.nagano.jp matsumoto.nagano.jp miasa.nagano.jp minamiaiki.nagano.jp minamimaki.nagano.jp minamiminowa.nagano.jp minowa.nagano.jp miyada.nagano.jp miyota.nagano.jp mochizuki.nagano.jp nagano.nagano.jp nagawa.nagano.jp nagiso.nagano.jp nakagawa.nagano.jp nakano.nagano.jp nozawaonsen.nagano.jp obuse.nagano.jp ogawa.nagano.jp okaya.nagano.jp omachi.nagano.jp omi.nagano.jp ookuwa.nagano.jp ooshika.nagano.jp otaki.nagano.jp otari.nagano.jp sakae.nagano.jp sakaki.nagano.jp saku.nagano.jp sakuho.nagano.jp shimosuwa.nagano.jp shinanomachi.nagano.jp shiojiri.nagano.jp suwa.nagano.jp suzaka.nagano.jp takagi.nagano.jp takamori.nagano.jp takayama.nagano.jp tateshina.nagano.jp tatsuno.nagano.jp togakushi.nagano.jp togura.nagano.jp tomi.nagano.jp ueda.nagano.jp wada.nagano.jp yamagata.nagano.jp yamanouchi.nagano.jp yasaka.nagano.jp yasuoka.nagano.jp chijiwa.nagasaki.jp futsu.nagasaki.jp goto.nagasaki.jp hasami.nagasaki.jp hirado.nagasaki.jp iki.nagasaki.jp isahaya.nagasaki.jp kawatana.nagasaki.jp kuchinotsu.nagasaki.jp matsuura.nagasaki.jp nagasaki.nagasaki.jp obama.nagasaki.jp omura.nagasaki.jp oseto.nagasaki.jp saikai.nagasaki.jp sasebo.nagasaki.jp seihi.nagasaki.jp shimabara.nagasaki.jp shinkamigoto.nagasaki.jp togitsu.nagasaki.jp tsushima.nagasaki.jp unzen.nagasaki.jp ando.nara.jp gose.nara.jp heguri.nara.jp higashiyoshino.nara.jp ikaruga.nara.jp ikoma.nara.jp kamikitayama.nara.jp kanmaki.nara.jp kashiba.nara.jp kashihara.nara.jp katsuragi.nara.jp kawai.nara.jp kawakami.nara.jp kawanishi.nara.jp koryo.nara.jp kurotaki.nara.jp mitsue.nara.jp miyake.nara.jp nara.nara.jp nosegawa.nara.jp oji.nara.jp ouda.nara.jp oyodo.nara.jp sakurai.nara.jp sango.nara.jp shimoichi.nara.jp shimokitayama.nara.jp shinjo.nara.jp soni.nara.jp takatori.nara.jp tawaramoto.nara.jp tenkawa.nara.jp tenri.nara.jp uda.nara.jp yamatokoriyama.nara.jp yamatotakada.nara.jp yamazoe.nara.jp yoshino.nara.jp aga.niigata.jp agano.niigata.jp gosen.niigata.jp itoigawa.niigata.jp izumozaki.niigata.jp joetsu.niigata.jp kamo.niigata.jp kariwa.niigata.jp kashiwazaki.niigata.jp minamiuonuma.niigata.jp mitsuke.niigata.jp muika.niigata.jp murakami.niigata.jp myoko.niigata.jp nagaoka.niigata.jp niigata.niigata.jp ojiya.niigata.jp omi.niigata.jp sado.niigata.jp sanjo.niigata.jp seiro.niigata.jp seirou.niigata.jp sekikawa.niigata.jp shibata.niigata.jp tagami.niigata.jp tainai.niigata.jp tochio.niigata.jp tokamachi.niigata.jp tsubame.niigata.jp tsunan.niigata.jp uonuma.niigata.jp yahiko.niigata.jp yoita.niigata.jp yuzawa.niigata.jp beppu.oita.jp bungoono.oita.jp bungotakada.oita.jp hasama.oita.jp hiji.oita.jp himeshima.oita.jp hita.oita.jp kamitsue.oita.jp kokonoe.oita.jp kuju.oita.jp kunisaki.oita.jp kusu.oita.jp oita.oita.jp saiki.oita.jp taketa.oita.jp tsukumi.oita.jp usa.oita.jp usuki.oita.jp yufu.oita.jp akaiwa.okayama.jp asakuchi.okayama.jp bizen.okayama.jp hayashima.okayama.jp ibara.okayama.jp kagamino.okayama.jp kasaoka.okayama.jp kibichuo.okayama.jp kumenan.okayama.jp kurashiki.okayama.jp maniwa.okayama.jp misaki.okayama.jp nagi.okayama.jp niimi.okayama.jp nishiawakura.okayama.jp okayama.okayama.jp satosho.okayama.jp setouchi.okayama.jp shinjo.okayama.jp shoo.okayama.jp soja.okayama.jp takahashi.okayama.jp tamano.okayama.jp tsuyama.okayama.jp wake.okayama.jp yakage.okayama.jp aguni.okinawa.jp ginowan.okinawa.jp ginoza.okinawa.jp gushikami.okinawa.jp haebaru.okinawa.jp higashi.okinawa.jp hirara.okinawa.jp iheya.okinawa.jp ishigaki.okinawa.jp ishikawa.okinawa.jp itoman.okinawa.jp izena.okinawa.jp kadena.okinawa.jp kin.okinawa.jp kitadaito.okinawa.jp kitanakagusuku.okinawa.jp kumejima.okinawa.jp kunigami.okinawa.jp minamidaito.okinawa.jp motobu.okinawa.jp nago.okinawa.jp naha.okinawa.jp nakagusuku.okinawa.jp nakijin.okinawa.jp nanjo.okinawa.jp nishihara.okinawa.jp ogimi.okinawa.jp okinawa.okinawa.jp onna.okinawa.jp shimoji.okinawa.jp taketomi.okinawa.jp tarama.okinawa.jp tokashiki.okinawa.jp tomigusuku.okinawa.jp tonaki.okinawa.jp urasoe.okinawa.jp uruma.okinawa.jp yaese.okinawa.jp yomitan.okinawa.jp yonabaru.okinawa.jp yonaguni.okinawa.jp zamami.okinawa.jp abeno.osaka.jp chihayaakasaka.osaka.jp chuo.osaka.jp daito.osaka.jp fujiidera.osaka.jp habikino.osaka.jp hannan.osaka.jp higashiosaka.osaka.jp higashisumiyoshi.osaka.jp higashiyodogawa.osaka.jp hirakata.osaka.jp ibaraki.osaka.jp ikeda.osaka.jp izumi.osaka.jp izumiotsu.osaka.jp izumisano.osaka.jp kadoma.osaka.jp kaizuka.osaka.jp kanan.osaka.jp kashiwara.osaka.jp katano.osaka.jp kawachinagano.osaka.jp kishiwada.osaka.jp kita.osaka.jp kumatori.osaka.jp matsubara.osaka.jp minato.osaka.jp minoh.osaka.jp misaki.osaka.jp moriguchi.osaka.jp neyagawa.osaka.jp nishi.osaka.jp nose.osaka.jp osakasayama.osaka.jp sakai.osaka.jp sayama.osaka.jp sennan.osaka.jp settsu.osaka.jp shijonawate.osaka.jp shimamoto.osaka.jp suita.osaka.jp tadaoka.osaka.jp taishi.osaka.jp tajiri.osaka.jp takaishi.osaka.jp takatsuki.osaka.jp tondabayashi.osaka.jp toyonaka.osaka.jp toyono.osaka.jp yao.osaka.jp ariake.saga.jp arita.saga.jp fukudomi.saga.jp genkai.saga.jp hamatama.saga.jp hizen.saga.jp imari.saga.jp kamimine.saga.jp kanzaki.saga.jp karatsu.saga.jp kashima.saga.jp kitagata.saga.jp kitahata.saga.jp kiyama.saga.jp kouhoku.saga.jp kyuragi.saga.jp nishiarita.saga.jp ogi.saga.jp omachi.saga.jp ouchi.saga.jp saga.saga.jp shiroishi.saga.jp taku.saga.jp tara.saga.jp tosu.saga.jp yoshinogari.saga.jp arakawa.saitama.jp asaka.saitama.jp chichibu.saitama.jp fujimi.saitama.jp fujimino.saitama.jp fukaya.saitama.jp hanno.saitama.jp hanyu.saitama.jp hasuda.saitama.jp hatogaya.saitama.jp hatoyama.saitama.jp hidaka.saitama.jp higashichichibu.saitama.jp higashimatsuyama.saitama.jp honjo.saitama.jp ina.saitama.jp iruma.saitama.jp iwatsuki.saitama.jp kamiizumi.saitama.jp kamikawa.saitama.jp kamisato.saitama.jp kasukabe.saitama.jp kawagoe.saitama.jp kawaguchi.saitama.jp kawajima.saitama.jp kazo.saitama.jp kitamoto.saitama.jp koshigaya.saitama.jp kounosu.saitama.jp kuki.saitama.jp kumagaya.saitama.jp matsubushi.saitama.jp minano.saitama.jp misato.saitama.jp miyashiro.saitama.jp miyoshi.saitama.jp moroyama.saitama.jp nagatoro.saitama.jp namegawa.saitama.jp niiza.saitama.jp ogano.saitama.jp ogawa.saitama.jp ogose.saitama.jp okegawa.saitama.jp omiya.saitama.jp otaki.saitama.jp ranzan.saitama.jp ryokami.saitama.jp saitama.saitama.jp sakado.saitama.jp satte.saitama.jp sayama.saitama.jp shiki.saitama.jp shiraoka.saitama.jp soka.saitama.jp sugito.saitama.jp toda.saitama.jp tokigawa.saitama.jp tokorozawa.saitama.jp tsurugashima.saitama.jp urawa.saitama.jp warabi.saitama.jp yashio.saitama.jp yokoze.saitama.jp yono.saitama.jp yorii.saitama.jp yoshida.saitama.jp yoshikawa.saitama.jp yoshimi.saitama.jp aisho.shiga.jp gamo.shiga.jp higashiomi.shiga.jp hikone.shiga.jp koka.shiga.jp konan.shiga.jp kosei.shiga.jp koto.shiga.jp kusatsu.shiga.jp maibara.shiga.jp moriyama.shiga.jp nagahama.shiga.jp nishiazai.shiga.jp notogawa.shiga.jp omihachiman.shiga.jp otsu.shiga.jp ritto.shiga.jp ryuoh.shiga.jp takashima.shiga.jp takatsuki.shiga.jp torahime.shiga.jp toyosato.shiga.jp yasu.shiga.jp akagi.shimane.jp ama.shimane.jp gotsu.shimane.jp hamada.shimane.jp higashiizumo.shimane.jp hikawa.shimane.jp hikimi.shimane.jp izumo.shimane.jp kakinoki.shimane.jp masuda.shimane.jp matsue.shimane.jp misato.shimane.jp nishinoshima.shimane.jp ohda.shimane.jp okinoshima.shimane.jp okuizumo.shimane.jp shimane.shimane.jp tamayu.shimane.jp tsuwano.shimane.jp unnan.shimane.jp yakumo.shimane.jp yasugi.shimane.jp yatsuka.shimane.jp arai.shizuoka.jp atami.shizuoka.jp fuji.shizuoka.jp fujieda.shizuoka.jp fujikawa.shizuoka.jp fujinomiya.shizuoka.jp fukuroi.shizuoka.jp gotemba.shizuoka.jp haibara.shizuoka.jp hamamatsu.shizuoka.jp higashiizu.shizuoka.jp ito.shizuoka.jp iwata.shizuoka.jp izu.shizuoka.jp izunokuni.shizuoka.jp kakegawa.shizuoka.jp kannami.shizuoka.jp kawanehon.shizuoka.jp kawazu.shizuoka.jp kikugawa.shizuoka.jp kosai.shizuoka.jp makinohara.shizuoka.jp matsuzaki.shizuoka.jp minamiizu.shizuoka.jp mishima.shizuoka.jp morimachi.shizuoka.jp nishiizu.shizuoka.jp numazu.shizuoka.jp omaezaki.shizuoka.jp shimada.shizuoka.jp shimizu.shizuoka.jp shimoda.shizuoka.jp shizuoka.shizuoka.jp susono.shizuoka.jp yaizu.shizuoka.jp yoshida.shizuoka.jp ashikaga.tochigi.jp bato.tochigi.jp haga.tochigi.jp ichikai.tochigi.jp iwafune.tochigi.jp kaminokawa.tochigi.jp kanuma.tochigi.jp karasuyama.tochigi.jp kuroiso.tochigi.jp mashiko.tochigi.jp mibu.tochigi.jp moka.tochigi.jp motegi.tochigi.jp nasu.tochigi.jp nasushiobara.tochigi.jp nikko.tochigi.jp nishikata.tochigi.jp nogi.tochigi.jp ohira.tochigi.jp ohtawara.tochigi.jp oyama.tochigi.jp sakura.tochigi.jp sano.tochigi.jp shimotsuke.tochigi.jp shioya.tochigi.jp takanezawa.tochigi.jp tochigi.tochigi.jp tsuga.tochigi.jp ujiie.tochigi.jp utsunomiya.tochigi.jp yaita.tochigi.jp aizumi.tokushima.jp anan.tokushima.jp ichiba.tokushima.jp itano.tokushima.jp kainan.tokushima.jp komatsushima.tokushima.jp matsushige.tokushima.jp mima.tokushima.jp minami.tokushima.jp miyoshi.tokushima.jp mugi.tokushima.jp nakagawa.tokushima.jp naruto.tokushima.jp sanagochi.tokushima.jp shishikui.tokushima.jp tokushima.tokushima.jp wajiki.tokushima.jp adachi.tokyo.jp akiruno.tokyo.jp akishima.tokyo.jp aogashima.tokyo.jp arakawa.tokyo.jp bunkyo.tokyo.jp chiyoda.tokyo.jp chofu.tokyo.jp chuo.tokyo.jp edogawa.tokyo.jp fuchu.tokyo.jp fussa.tokyo.jp hachijo.tokyo.jp hachioji.tokyo.jp hamura.tokyo.jp higashikurume.tokyo.jp higashimurayama.tokyo.jp higashiyamato.tokyo.jp hino.tokyo.jp hinode.tokyo.jp hinohara.tokyo.jp inagi.tokyo.jp itabashi.tokyo.jp katsushika.tokyo.jp kita.tokyo.jp kiyose.tokyo.jp kodaira.tokyo.jp koganei.tokyo.jp kokubunji.tokyo.jp komae.tokyo.jp koto.tokyo.jp kouzushima.tokyo.jp kunitachi.tokyo.jp machida.tokyo.jp meguro.tokyo.jp minato.tokyo.jp mitaka.tokyo.jp mizuho.tokyo.jp musashimurayama.tokyo.jp musashino.tokyo.jp nakano.tokyo.jp nerima.tokyo.jp ogasawara.tokyo.jp okutama.tokyo.jp ome.tokyo.jp oshima.tokyo.jp ota.tokyo.jp setagaya.tokyo.jp shibuya.tokyo.jp shinagawa.tokyo.jp shinjuku.tokyo.jp suginami.tokyo.jp sumida.tokyo.jp tachikawa.tokyo.jp taito.tokyo.jp tama.tokyo.jp toshima.tokyo.jp chizu.tottori.jp hino.tottori.jp kawahara.tottori.jp koge.tottori.jp kotoura.tottori.jp misasa.tottori.jp nanbu.tottori.jp nichinan.tottori.jp sakaiminato.tottori.jp tottori.tottori.jp wakasa.tottori.jp yazu.tottori.jp yonago.tottori.jp asahi.toyama.jp fuchu.toyama.jp fukumitsu.toyama.jp funahashi.toyama.jp himi.toyama.jp imizu.toyama.jp inami.toyama.jp johana.toyama.jp kamiichi.toyama.jp kurobe.toyama.jp nakaniikawa.toyama.jp namerikawa.toyama.jp nanto.toyama.jp nyuzen.toyama.jp oyabe.toyama.jp taira.toyama.jp takaoka.toyama.jp tateyama.toyama.jp toga.toyama.jp tonami.toyama.jp toyama.toyama.jp unazuki.toyama.jp uozu.toyama.jp yamada.toyama.jp arida.wakayama.jp aridagawa.wakayama.jp gobo.wakayama.jp hashimoto.wakayama.jp hidaka.wakayama.jp hirogawa.wakayama.jp inami.wakayama.jp iwade.wakayama.jp kainan.wakayama.jp kamitonda.wakayama.jp katsuragi.wakayama.jp kimino.wakayama.jp kinokawa.wakayama.jp kitayama.wakayama.jp koya.wakayama.jp koza.wakayama.jp kozagawa.wakayama.jp kudoyama.wakayama.jp kushimoto.wakayama.jp mihama.wakayama.jp misato.wakayama.jp nachikatsuura.wakayama.jp shingu.wakayama.jp shirahama.wakayama.jp taiji.wakayama.jp tanabe.wakayama.jp wakayama.wakayama.jp yuasa.wakayama.jp yura.wakayama.jp asahi.yamagata.jp funagata.yamagata.jp higashine.yamagata.jp iide.yamagata.jp kahoku.yamagata.jp kaminoyama.yamagata.jp kaneyama.yamagata.jp kawanishi.yamagata.jp mamurogawa.yamagata.jp mikawa.yamagata.jp murayama.yamagata.jp nagai.yamagata.jp nakayama.yamagata.jp nanyo.yamagata.jp nishikawa.yamagata.jp obanazawa.yamagata.jp oe.yamagata.jp oguni.yamagata.jp ohkura.yamagata.jp oishida.yamagata.jp sagae.yamagata.jp sakata.yamagata.jp sakegawa.yamagata.jp shinjo.yamagata.jp shirataka.yamagata.jp shonai.yamagata.jp takahata.yamagata.jp tendo.yamagata.jp tozawa.yamagata.jp tsuruoka.yamagata.jp yamagata.yamagata.jp yamanobe.yamagata.jp yonezawa.yamagata.jp yuza.yamagata.jp abu.yamaguchi.jp hagi.yamaguchi.jp hikari.yamaguchi.jp hofu.yamaguchi.jp iwakuni.yamaguchi.jp kudamatsu.yamaguchi.jp mitou.yamaguchi.jp nagato.yamaguchi.jp oshima.yamaguchi.jp shimonoseki.yamaguchi.jp shunan.yamaguchi.jp tabuse.yamaguchi.jp tokuyama.yamaguchi.jp toyota.yamaguchi.jp ube.yamaguchi.jp yuu.yamaguchi.jp chuo.yamanashi.jp doshi.yamanashi.jp fuefuki.yamanashi.jp fujikawa.yamanashi.jp fujikawaguchiko.yamanashi.jp fujiyoshida.yamanashi.jp hayakawa.yamanashi.jp hokuto.yamanashi.jp ichikawamisato.yamanashi.jp kai.yamanashi.jp kofu.yamanashi.jp koshu.yamanashi.jp kosuge.yamanashi.jp minami-alps.yamanashi.jp minobu.yamanashi.jp nakamichi.yamanashi.jp nanbu.yamanashi.jp narusawa.yamanashi.jp nirasaki.yamanashi.jp nishikatsura.yamanashi.jp oshino.yamanashi.jp otsuki.yamanashi.jp showa.yamanashi.jp tabayama.yamanashi.jp tsuru.yamanashi.jp uenohara.yamanashi.jp yamanakako.yamanashi.jp yamanashi.yamanashi.jp // ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains ke ac.ke co.ke go.ke info.ke me.ke mobi.ke ne.ke or.ke sc.ke // kg : http://www.domain.kg/dmn_n.html kg org.kg net.kg com.kg edu.kg gov.kg mil.kg // kh : http://www.mptc.gov.kh/dns_registration.htm *.kh // ki : http://www.ki/dns/index.html ki edu.ki biz.ki net.ki org.ki gov.ki info.ki com.ki // km : https://en.wikipedia.org/wiki/.km // http://www.domaine.km/documents/charte.doc km org.km nom.km gov.km prd.km tm.km edu.km mil.km ass.km com.km // These are only mentioned as proposed suggestions at domaine.km, but // https://en.wikipedia.org/wiki/.km says they're available for registration: coop.km asso.km presse.km medecin.km notaires.km pharmaciens.km veterinaire.km gouv.km // kn : https://en.wikipedia.org/wiki/.kn // http://www.dot.kn/domainRules.html kn net.kn org.kn edu.kn gov.kn // kp : http://www.kcce.kp/en_index.php kp com.kp edu.kp gov.kp org.kp rep.kp tra.kp // kr : https://en.wikipedia.org/wiki/.kr // see also: http://domain.nida.or.kr/eng/registration.jsp kr ac.kr co.kr es.kr go.kr hs.kr kg.kr mil.kr ms.kr ne.kr or.kr pe.kr re.kr sc.kr // kr geographical names busan.kr chungbuk.kr chungnam.kr daegu.kr daejeon.kr gangwon.kr gwangju.kr gyeongbuk.kr gyeonggi.kr gyeongnam.kr incheon.kr jeju.kr jeonbuk.kr jeonnam.kr seoul.kr ulsan.kr // kw : https://www.nic.kw/policies/ // Confirmed by registry kw com.kw edu.kw emb.kw gov.kw ind.kw net.kw org.kw // ky : http://www.icta.ky/da_ky_reg_dom.php // Confirmed by registry 2008-06-17 ky com.ky edu.ky net.ky org.ky // kz : https://en.wikipedia.org/wiki/.kz // see also: http://www.nic.kz/rules/index.jsp kz org.kz edu.kz net.kz gov.kz mil.kz com.kz // la : https://en.wikipedia.org/wiki/.la // Submitted by registry la int.la net.la info.la edu.la gov.la per.la com.la org.la // lb : https://en.wikipedia.org/wiki/.lb // Submitted by registry lb com.lb edu.lb gov.lb net.lb org.lb // lc : https://en.wikipedia.org/wiki/.lc // see also: http://www.nic.lc/rules.htm lc com.lc net.lc co.lc org.lc edu.lc gov.lc // li : https://en.wikipedia.org/wiki/.li li // lk : https://www.nic.lk/index.php/domain-registration/lk-domain-naming-structure lk gov.lk sch.lk net.lk int.lk com.lk org.lk edu.lk ngo.lk soc.lk web.lk ltd.lk assn.lk grp.lk hotel.lk ac.lk // lr : http://psg.com/dns/lr/lr.txt // Submitted by registry lr com.lr edu.lr gov.lr org.lr net.lr // ls : http://www.nic.ls/ // Confirmed by registry ls ac.ls biz.ls co.ls edu.ls gov.ls info.ls net.ls org.ls sc.ls // lt : https://en.wikipedia.org/wiki/.lt lt // gov.lt : http://www.gov.lt/index_en.php gov.lt // lu : http://www.dns.lu/en/ lu // lv : http://www.nic.lv/DNS/En/generic.php lv com.lv edu.lv gov.lv org.lv mil.lv id.lv net.lv asn.lv conf.lv // ly : http://www.nic.ly/regulations.php ly com.ly net.ly gov.ly plc.ly edu.ly sch.ly med.ly org.ly id.ly // ma : https://en.wikipedia.org/wiki/.ma // http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf ma co.ma net.ma gov.ma org.ma ac.ma press.ma // mc : http://www.nic.mc/ mc tm.mc asso.mc // md : https://en.wikipedia.org/wiki/.md md // me : https://en.wikipedia.org/wiki/.me me co.me net.me org.me edu.me ac.me gov.me its.me priv.me // mg : http://nic.mg/nicmg/?page_id=39 mg org.mg nom.mg gov.mg prd.mg tm.mg edu.mg mil.mg com.mg co.mg // mh : https://en.wikipedia.org/wiki/.mh mh // mil : https://en.wikipedia.org/wiki/.mil mil // mk : https://en.wikipedia.org/wiki/.mk // see also: http://dns.marnet.net.mk/postapka.php mk com.mk org.mk net.mk edu.mk gov.mk inf.mk name.mk // ml : http://www.gobin.info/domainname/ml-template.doc // see also: https://en.wikipedia.org/wiki/.ml ml com.ml edu.ml gouv.ml gov.ml net.ml org.ml presse.ml // mm : https://en.wikipedia.org/wiki/.mm *.mm // mn : https://en.wikipedia.org/wiki/.mn mn gov.mn edu.mn org.mn // mo : http://www.monic.net.mo/ mo com.mo net.mo org.mo edu.mo gov.mo // mobi : https://en.wikipedia.org/wiki/.mobi mobi // mp : http://www.dot.mp/ // Confirmed by registry 2008-06-17 mp // mq : https://en.wikipedia.org/wiki/.mq mq // mr : https://en.wikipedia.org/wiki/.mr mr gov.mr // ms : http://www.nic.ms/pdf/MS_Domain_Name_Rules.pdf ms com.ms edu.ms gov.ms net.ms org.ms // mt : https://www.nic.org.mt/go/policy // Submitted by registry mt com.mt edu.mt net.mt org.mt // mu : https://en.wikipedia.org/wiki/.mu mu com.mu net.mu org.mu gov.mu ac.mu co.mu or.mu // museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ museum // mv : https://en.wikipedia.org/wiki/.mv // "mv" included because, contra Wikipedia, google.mv exists. mv aero.mv biz.mv com.mv coop.mv edu.mv gov.mv info.mv int.mv mil.mv museum.mv name.mv net.mv org.mv pro.mv // mw : http://www.registrar.mw/ mw ac.mw biz.mw co.mw com.mw coop.mw edu.mw gov.mw int.mw museum.mw net.mw org.mw // mx : http://www.nic.mx/ // Submitted by registry mx com.mx org.mx gob.mx edu.mx net.mx // my : http://www.mynic.my/ // Available strings: https://mynic.my/resources/domains/buying-a-domain/ my biz.my com.my edu.my gov.my mil.my name.my net.my org.my // mz : http://www.uem.mz/ // Submitted by registry mz ac.mz adv.mz co.mz edu.mz gov.mz mil.mz net.mz org.mz // na : http://www.na-nic.com.na/ // http://www.info.na/domain/ na info.na pro.na name.na school.na or.na dr.na us.na mx.na ca.na in.na cc.na tv.na ws.na mobi.na co.na com.na org.na // name : has 2nd-level tlds, but there's no list of them name // nc : http://www.cctld.nc/ nc asso.nc nom.nc // ne : https://en.wikipedia.org/wiki/.ne ne // net : https://en.wikipedia.org/wiki/.net net // nf : https://en.wikipedia.org/wiki/.nf nf com.nf net.nf per.nf rec.nf web.nf arts.nf firm.nf info.nf other.nf store.nf // ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds ng com.ng edu.ng gov.ng i.ng mil.ng mobi.ng name.ng net.ng org.ng sch.ng // ni : http://www.nic.ni/ ni ac.ni biz.ni co.ni com.ni edu.ni gob.ni in.ni info.ni int.ni mil.ni net.ni nom.ni org.ni web.ni // nl : https://en.wikipedia.org/wiki/.nl // https://www.sidn.nl/ // ccTLD for the Netherlands nl // no : https://www.norid.no/en/om-domenenavn/regelverk-for-no/ // Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ // Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ // Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ // RSS feed: https://teknisk.norid.no/en/feed/ no // Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ fhs.no vgs.no fylkesbibl.no folkebibl.no museum.no idrett.no priv.no // Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ mil.no stat.no dep.no kommune.no herad.no // Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ // counties aa.no ah.no bu.no fm.no hl.no hm.no jan-mayen.no mr.no nl.no nt.no of.no ol.no oslo.no rl.no sf.no st.no svalbard.no tm.no tr.no va.no vf.no // primary and lower secondary schools per county gs.aa.no gs.ah.no gs.bu.no gs.fm.no gs.hl.no gs.hm.no gs.jan-mayen.no gs.mr.no gs.nl.no gs.nt.no gs.of.no gs.ol.no gs.oslo.no gs.rl.no gs.sf.no gs.st.no gs.svalbard.no gs.tm.no gs.tr.no gs.va.no gs.vf.no // cities akrehamn.no xn--krehamn-dxa.no algard.no xn--lgrd-poac.no arna.no brumunddal.no bryne.no bronnoysund.no xn--brnnysund-m8ac.no drobak.no xn--drbak-wua.no egersund.no fetsund.no floro.no xn--flor-jra.no fredrikstad.no hokksund.no honefoss.no xn--hnefoss-q1a.no jessheim.no jorpeland.no xn--jrpeland-54a.no kirkenes.no kopervik.no krokstadelva.no langevag.no xn--langevg-jxa.no leirvik.no mjondalen.no xn--mjndalen-64a.no mo-i-rana.no mosjoen.no xn--mosjen-eya.no nesoddtangen.no orkanger.no osoyro.no xn--osyro-wua.no raholt.no xn--rholt-mra.no sandnessjoen.no xn--sandnessjen-ogb.no skedsmokorset.no slattum.no spjelkavik.no stathelle.no stavern.no stjordalshalsen.no xn--stjrdalshalsen-sqb.no tananger.no tranby.no vossevangen.no // communities afjord.no xn--fjord-lra.no agdenes.no al.no xn--l-1fa.no alesund.no xn--lesund-hua.no alstahaug.no alta.no xn--lt-liac.no alaheadju.no xn--laheadju-7ya.no alvdal.no amli.no xn--mli-tla.no amot.no xn--mot-tla.no andebu.no andoy.no xn--andy-ira.no andasuolo.no ardal.no xn--rdal-poa.no aremark.no arendal.no xn--s-1fa.no aseral.no xn--seral-lra.no asker.no askim.no askvoll.no askoy.no xn--asky-ira.no asnes.no xn--snes-poa.no audnedaln.no aukra.no aure.no aurland.no aurskog-holand.no xn--aurskog-hland-jnb.no austevoll.no austrheim.no averoy.no xn--avery-yua.no balestrand.no ballangen.no balat.no xn--blt-elab.no balsfjord.no bahccavuotna.no xn--bhccavuotna-k7a.no bamble.no bardu.no beardu.no beiarn.no bajddar.no xn--bjddar-pta.no baidar.no xn--bidr-5nac.no berg.no bergen.no berlevag.no xn--berlevg-jxa.no bearalvahki.no xn--bearalvhki-y4a.no bindal.no birkenes.no bjarkoy.no xn--bjarky-fya.no bjerkreim.no bjugn.no bodo.no xn--bod-2na.no badaddja.no xn--bdddj-mrabd.no budejju.no bokn.no bremanger.no bronnoy.no xn--brnny-wuac.no bygland.no bykle.no barum.no xn--brum-voa.no bo.telemark.no xn--b-5ga.telemark.no bo.nordland.no xn--b-5ga.nordland.no bievat.no xn--bievt-0qa.no bomlo.no xn--bmlo-gra.no batsfjord.no xn--btsfjord-9za.no bahcavuotna.no xn--bhcavuotna-s4a.no dovre.no drammen.no drangedal.no dyroy.no xn--dyry-ira.no donna.no xn--dnna-gra.no eid.no eidfjord.no eidsberg.no eidskog.no eidsvoll.no eigersund.no elverum.no enebakk.no engerdal.no etne.no etnedal.no evenes.no evenassi.no xn--eveni-0qa01ga.no evje-og-hornnes.no farsund.no fauske.no fuossko.no fuoisku.no fedje.no fet.no finnoy.no xn--finny-yua.no fitjar.no fjaler.no fjell.no flakstad.no flatanger.no flekkefjord.no flesberg.no flora.no fla.no xn--fl-zia.no folldal.no forsand.no fosnes.no frei.no frogn.no froland.no frosta.no frana.no xn--frna-woa.no froya.no xn--frya-hra.no fusa.no fyresdal.no forde.no xn--frde-gra.no gamvik.no gangaviika.no xn--ggaviika-8ya47h.no gaular.no gausdal.no gildeskal.no xn--gildeskl-g0a.no giske.no gjemnes.no gjerdrum.no gjerstad.no gjesdal.no gjovik.no xn--gjvik-wua.no gloppen.no gol.no gran.no grane.no granvin.no gratangen.no grimstad.no grong.no kraanghke.no xn--kranghke-b0a.no grue.no gulen.no hadsel.no halden.no halsa.no hamar.no hamaroy.no habmer.no xn--hbmer-xqa.no hapmir.no xn--hpmir-xqa.no hammerfest.no hammarfeasta.no xn--hmmrfeasta-s4ac.no haram.no hareid.no harstad.no hasvik.no aknoluokta.no xn--koluokta-7ya57h.no hattfjelldal.no aarborte.no haugesund.no hemne.no hemnes.no hemsedal.no heroy.more-og-romsdal.no xn--hery-ira.xn--mre-og-romsdal-qqb.no heroy.nordland.no xn--hery-ira.nordland.no hitra.no hjartdal.no hjelmeland.no hobol.no xn--hobl-ira.no hof.no hol.no hole.no holmestrand.no holtalen.no xn--holtlen-hxa.no hornindal.no horten.no hurdal.no hurum.no hvaler.no hyllestad.no hagebostad.no xn--hgebostad-g3a.no hoyanger.no xn--hyanger-q1a.no hoylandet.no xn--hylandet-54a.no ha.no xn--h-2fa.no ibestad.no inderoy.no xn--indery-fya.no iveland.no jevnaker.no jondal.no jolster.no xn--jlster-bya.no karasjok.no karasjohka.no xn--krjohka-hwab49j.no karlsoy.no galsa.no xn--gls-elac.no karmoy.no xn--karmy-yua.no kautokeino.no guovdageaidnu.no klepp.no klabu.no xn--klbu-woa.no kongsberg.no kongsvinger.no kragero.no xn--krager-gya.no kristiansand.no kristiansund.no krodsherad.no xn--krdsherad-m8a.no kvalsund.no rahkkeravju.no xn--rhkkervju-01af.no kvam.no kvinesdal.no kvinnherad.no kviteseid.no kvitsoy.no xn--kvitsy-fya.no kvafjord.no xn--kvfjord-nxa.no giehtavuoatna.no kvanangen.no xn--kvnangen-k0a.no navuotna.no xn--nvuotna-hwa.no kafjord.no xn--kfjord-iua.no gaivuotna.no xn--givuotna-8ya.no larvik.no lavangen.no lavagis.no loabat.no xn--loabt-0qa.no lebesby.no davvesiida.no leikanger.no leirfjord.no leka.no leksvik.no lenvik.no leangaviika.no xn--leagaviika-52b.no lesja.no levanger.no lier.no lierne.no lillehammer.no lillesand.no lindesnes.no lindas.no xn--linds-pra.no lom.no loppa.no lahppi.no xn--lhppi-xqa.no lund.no lunner.no luroy.no xn--lury-ira.no luster.no lyngdal.no lyngen.no ivgu.no lardal.no lerdal.no xn--lrdal-sra.no lodingen.no xn--ldingen-q1a.no lorenskog.no xn--lrenskog-54a.no loten.no xn--lten-gra.no malvik.no masoy.no xn--msy-ula0h.no muosat.no xn--muost-0qa.no mandal.no marker.no marnardal.no masfjorden.no meland.no meldal.no melhus.no meloy.no xn--mely-ira.no meraker.no xn--merker-kua.no moareke.no xn--moreke-jua.no midsund.no midtre-gauldal.no modalen.no modum.no molde.no moskenes.no moss.no mosvik.no malselv.no xn--mlselv-iua.no malatvuopmi.no xn--mlatvuopmi-s4a.no namdalseid.no aejrie.no namsos.no namsskogan.no naamesjevuemie.no xn--nmesjevuemie-tcba.no laakesvuemie.no nannestad.no narvik.no narviika.no naustdal.no nedre-eiker.no nes.akershus.no nes.buskerud.no nesna.no nesodden.no nesseby.no unjarga.no xn--unjrga-rta.no nesset.no nissedal.no nittedal.no nord-aurdal.no nord-fron.no nord-odal.no norddal.no nordkapp.no davvenjarga.no xn--davvenjrga-y4a.no nordre-land.no nordreisa.no raisa.no xn--risa-5na.no nore-og-uvdal.no notodden.no naroy.no xn--nry-yla5g.no notteroy.no xn--nttery-byae.no odda.no oksnes.no xn--ksnes-uua.no oppdal.no oppegard.no xn--oppegrd-ixa.no orkdal.no orland.no xn--rland-uua.no orskog.no xn--rskog-uua.no orsta.no xn--rsta-fra.no os.hedmark.no os.hordaland.no osen.no osteroy.no xn--ostery-fya.no ostre-toten.no xn--stre-toten-zcb.no overhalla.no ovre-eiker.no xn--vre-eiker-k8a.no oyer.no xn--yer-zna.no oygarden.no xn--ygarden-p1a.no oystre-slidre.no xn--ystre-slidre-ujb.no porsanger.no porsangu.no xn--porsgu-sta26f.no porsgrunn.no radoy.no xn--rady-ira.no rakkestad.no rana.no ruovat.no randaberg.no rauma.no rendalen.no rennebu.no rennesoy.no xn--rennesy-v1a.no rindal.no ringebu.no ringerike.no ringsaker.no rissa.no risor.no xn--risr-ira.no roan.no rollag.no rygge.no ralingen.no xn--rlingen-mxa.no rodoy.no xn--rdy-0nab.no romskog.no xn--rmskog-bya.no roros.no xn--rros-gra.no rost.no xn--rst-0na.no royken.no xn--ryken-vua.no royrvik.no xn--ryrvik-bya.no rade.no xn--rde-ula.no salangen.no siellak.no saltdal.no salat.no xn--slt-elab.no xn--slat-5na.no samnanger.no sande.more-og-romsdal.no sande.xn--mre-og-romsdal-qqb.no sande.vestfold.no sandefjord.no sandnes.no sandoy.no xn--sandy-yua.no sarpsborg.no sauda.no sauherad.no sel.no selbu.no selje.no seljord.no sigdal.no siljan.no sirdal.no skaun.no skedsmo.no ski.no skien.no skiptvet.no skjervoy.no xn--skjervy-v1a.no skierva.no xn--skierv-uta.no skjak.no xn--skjk-soa.no skodje.no skanland.no xn--sknland-fxa.no skanit.no xn--sknit-yqa.no smola.no xn--smla-hra.no snillfjord.no snasa.no xn--snsa-roa.no snoasa.no snaase.no xn--snase-nra.no sogndal.no sokndal.no sola.no solund.no songdalen.no sortland.no spydeberg.no stange.no stavanger.no steigen.no steinkjer.no stjordal.no xn--stjrdal-s1a.no stokke.no stor-elvdal.no stord.no stordal.no storfjord.no omasvuotna.no strand.no stranda.no stryn.no sula.no suldal.no sund.no sunndal.no surnadal.no sveio.no svelvik.no sykkylven.no sogne.no xn--sgne-gra.no somna.no xn--smna-gra.no sondre-land.no xn--sndre-land-0cb.no sor-aurdal.no xn--sr-aurdal-l8a.no sor-fron.no xn--sr-fron-q1a.no sor-odal.no xn--sr-odal-q1a.no sor-varanger.no xn--sr-varanger-ggb.no matta-varjjat.no xn--mtta-vrjjat-k7af.no sorfold.no xn--srfold-bya.no sorreisa.no xn--srreisa-q1a.no sorum.no xn--srum-gra.no tana.no deatnu.no time.no tingvoll.no tinn.no tjeldsund.no dielddanuorri.no tjome.no xn--tjme-hra.no tokke.no tolga.no torsken.no tranoy.no xn--trany-yua.no tromso.no xn--troms-zua.no tromsa.no romsa.no trondheim.no troandin.no trysil.no trana.no xn--trna-woa.no trogstad.no xn--trgstad-r1a.no tvedestrand.no tydal.no tynset.no tysfjord.no divtasvuodna.no divttasvuotna.no tysnes.no tysvar.no xn--tysvr-vra.no tonsberg.no xn--tnsberg-q1a.no ullensaker.no ullensvang.no ulvik.no utsira.no vadso.no xn--vads-jra.no cahcesuolo.no xn--hcesuolo-7ya35b.no vaksdal.no valle.no vang.no vanylven.no vardo.no xn--vard-jra.no varggat.no xn--vrggt-xqad.no vefsn.no vaapste.no vega.no vegarshei.no xn--vegrshei-c0a.no vennesla.no verdal.no verran.no vestby.no vestnes.no vestre-slidre.no vestre-toten.no vestvagoy.no xn--vestvgy-ixa6o.no vevelstad.no vik.no vikna.no vindafjord.no volda.no voss.no varoy.no xn--vry-yla5g.no vagan.no xn--vgan-qoa.no voagat.no vagsoy.no xn--vgsy-qoa0j.no vaga.no xn--vg-yiab.no valer.ostfold.no xn--vler-qoa.xn--stfold-9xa.no valer.hedmark.no xn--vler-qoa.hedmark.no // np : http://www.mos.com.np/register.html *.np // nr : http://cenpac.net.nr/dns/index.html // Submitted by registry nr biz.nr info.nr gov.nr edu.nr org.nr net.nr com.nr // nu : https://en.wikipedia.org/wiki/.nu nu // nz : https://en.wikipedia.org/wiki/.nz // Submitted by registry nz ac.nz co.nz cri.nz geek.nz gen.nz govt.nz health.nz iwi.nz kiwi.nz maori.nz mil.nz xn--mori-qsa.nz net.nz org.nz parliament.nz school.nz // om : https://en.wikipedia.org/wiki/.om om co.om com.om edu.om gov.om med.om museum.om net.om org.om pro.om // onion : https://tools.ietf.org/html/rfc7686 onion // org : https://en.wikipedia.org/wiki/.org org // pa : http://www.nic.pa/ // Some additional second level "domains" resolve directly as hostnames, such as // pannet.pa, so we add a rule for "pa". pa ac.pa gob.pa com.pa org.pa sld.pa edu.pa net.pa ing.pa abo.pa med.pa nom.pa // pe : https://www.nic.pe/InformeFinalComision.pdf pe edu.pe gob.pe nom.pe mil.pe org.pe com.pe net.pe // pf : http://www.gobin.info/domainname/formulaire-pf.pdf pf com.pf org.pf edu.pf // pg : https://en.wikipedia.org/wiki/.pg *.pg // ph : http://www.domains.ph/FAQ2.asp // Submitted by registry ph com.ph net.ph org.ph gov.ph edu.ph ngo.ph mil.ph i.ph // pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK pk com.pk net.pk edu.pk org.pk fam.pk biz.pk web.pk gov.pk gob.pk gok.pk gon.pk gop.pk gos.pk info.pk // pl http://www.dns.pl/english/index.html // Submitted by registry pl com.pl net.pl org.pl // pl functional domains (http://www.dns.pl/english/index.html) aid.pl agro.pl atm.pl auto.pl biz.pl edu.pl gmina.pl gsm.pl info.pl mail.pl miasta.pl media.pl mil.pl nieruchomosci.pl nom.pl pc.pl powiat.pl priv.pl realestate.pl rel.pl sex.pl shop.pl sklep.pl sos.pl szkola.pl targi.pl tm.pl tourism.pl travel.pl turystyka.pl // Government domains gov.pl ap.gov.pl griw.gov.pl ic.gov.pl is.gov.pl kmpsp.gov.pl konsulat.gov.pl kppsp.gov.pl kwp.gov.pl kwpsp.gov.pl mup.gov.pl mw.gov.pl oia.gov.pl oirm.gov.pl oke.gov.pl oow.gov.pl oschr.gov.pl oum.gov.pl pa.gov.pl pinb.gov.pl piw.gov.pl po.gov.pl pr.gov.pl psp.gov.pl psse.gov.pl pup.gov.pl rzgw.gov.pl sa.gov.pl sdn.gov.pl sko.gov.pl so.gov.pl sr.gov.pl starostwo.gov.pl ug.gov.pl ugim.gov.pl um.gov.pl umig.gov.pl upow.gov.pl uppo.gov.pl us.gov.pl uw.gov.pl uzs.gov.pl wif.gov.pl wiih.gov.pl winb.gov.pl wios.gov.pl witd.gov.pl wiw.gov.pl wkz.gov.pl wsa.gov.pl wskr.gov.pl wsse.gov.pl wuoz.gov.pl wzmiuw.gov.pl zp.gov.pl zpisdn.gov.pl // pl regional domains (http://www.dns.pl/english/index.html) augustow.pl babia-gora.pl bedzin.pl beskidy.pl bialowieza.pl bialystok.pl bielawa.pl bieszczady.pl boleslawiec.pl bydgoszcz.pl bytom.pl cieszyn.pl czeladz.pl czest.pl dlugoleka.pl elblag.pl elk.pl glogow.pl gniezno.pl gorlice.pl grajewo.pl ilawa.pl jaworzno.pl jelenia-gora.pl jgora.pl kalisz.pl kazimierz-dolny.pl karpacz.pl kartuzy.pl kaszuby.pl katowice.pl kepno.pl ketrzyn.pl klodzko.pl kobierzyce.pl kolobrzeg.pl konin.pl konskowola.pl kutno.pl lapy.pl lebork.pl legnica.pl lezajsk.pl limanowa.pl lomza.pl lowicz.pl lubin.pl lukow.pl malbork.pl malopolska.pl mazowsze.pl mazury.pl mielec.pl mielno.pl mragowo.pl naklo.pl nowaruda.pl nysa.pl olawa.pl olecko.pl olkusz.pl olsztyn.pl opoczno.pl opole.pl ostroda.pl ostroleka.pl ostrowiec.pl ostrowwlkp.pl pila.pl pisz.pl podhale.pl podlasie.pl polkowice.pl pomorze.pl pomorskie.pl prochowice.pl pruszkow.pl przeworsk.pl pulawy.pl radom.pl rawa-maz.pl rybnik.pl rzeszow.pl sanok.pl sejny.pl slask.pl slupsk.pl sosnowiec.pl stalowa-wola.pl skoczow.pl starachowice.pl stargard.pl suwalki.pl swidnica.pl swiebodzin.pl swinoujscie.pl szczecin.pl szczytno.pl tarnobrzeg.pl tgory.pl turek.pl tychy.pl ustka.pl walbrzych.pl warmia.pl warszawa.pl waw.pl wegrow.pl wielun.pl wlocl.pl wloclawek.pl wodzislaw.pl wolomin.pl wroclaw.pl zachpomor.pl zagan.pl zarow.pl zgora.pl zgorzelec.pl // pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf pm // pn : http://www.government.pn/PnRegistry/policies.htm pn gov.pn co.pn org.pn edu.pn net.pn // post : https://en.wikipedia.org/wiki/.post post // pr : http://www.nic.pr/index.asp?f=1 pr com.pr net.pr org.pr gov.pr edu.pr isla.pr pro.pr biz.pr info.pr name.pr // these aren't mentioned on nic.pr, but on https://en.wikipedia.org/wiki/.pr est.pr prof.pr ac.pr // pro : http://registry.pro/get-pro pro aaa.pro aca.pro acct.pro avocat.pro bar.pro cpa.pro eng.pro jur.pro law.pro med.pro recht.pro // ps : https://en.wikipedia.org/wiki/.ps // http://www.nic.ps/registration/policy.html#reg ps edu.ps gov.ps sec.ps plo.ps com.ps org.ps net.ps // pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/ pt net.pt gov.pt org.pt edu.pt int.pt publ.pt com.pt nome.pt // pw : https://en.wikipedia.org/wiki/.pw pw co.pw ne.pw or.pw ed.pw go.pw belau.pw // py : http://www.nic.py/pautas.html#seccion_9 // Submitted by registry py com.py coop.py edu.py gov.py mil.py net.py org.py // qa : http://domains.qa/en/ qa com.qa edu.qa gov.qa mil.qa name.qa net.qa org.qa sch.qa // re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf re asso.re com.re nom.re // ro : http://www.rotld.ro/ ro arts.ro com.ro firm.ro info.ro nom.ro nt.ro org.ro rec.ro store.ro tm.ro www.ro // rs : https://www.rnids.rs/en/domains/national-domains rs ac.rs co.rs edu.rs gov.rs in.rs org.rs // ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf // Submitted by George Georgievsky ru // rw : https://www.ricta.org.rw/sites/default/files/resources/registry_registrar_contract_0.pdf rw ac.rw co.rw coop.rw gov.rw mil.rw net.rw org.rw // sa : http://www.nic.net.sa/ sa com.sa net.sa org.sa gov.sa med.sa pub.sa edu.sa sch.sa // sb : http://www.sbnic.net.sb/ // Submitted by registry sb com.sb edu.sb gov.sb net.sb org.sb // sc : http://www.nic.sc/ sc com.sc gov.sc net.sc org.sc edu.sc // sd : http://www.isoc.sd/sudanic.isoc.sd/billing_pricing.htm // Submitted by registry sd com.sd net.sd org.sd edu.sd med.sd tv.sd gov.sd info.sd // se : https://en.wikipedia.org/wiki/.se // Submitted by registry se a.se ac.se b.se bd.se brand.se c.se d.se e.se f.se fh.se fhsk.se fhv.se g.se h.se i.se k.se komforb.se kommunalforbund.se komvux.se l.se lanbib.se m.se n.se naturbruksgymn.se o.se org.se p.se parti.se pp.se press.se r.se s.se t.se tm.se u.se w.se x.se y.se z.se // sg : http://www.nic.net.sg/page/registration-policies-procedures-and-guidelines sg com.sg net.sg org.sg gov.sg edu.sg per.sg // sh : http://nic.sh/rules.htm sh com.sh net.sh gov.sh org.sh mil.sh // si : https://en.wikipedia.org/wiki/.si si // sj : No registrations at this time. // Submitted by registry sj // sk : https://en.wikipedia.org/wiki/.sk // list of 2nd level domains ? sk // sl : http://www.nic.sl // Submitted by registry sl com.sl net.sl edu.sl gov.sl org.sl // sm : https://en.wikipedia.org/wiki/.sm sm // sn : https://en.wikipedia.org/wiki/.sn sn art.sn com.sn edu.sn gouv.sn org.sn perso.sn univ.sn // so : http://sonic.so/policies/ so com.so edu.so gov.so me.so net.so org.so // sr : https://en.wikipedia.org/wiki/.sr sr // ss : https://registry.nic.ss/ // Submitted by registry ss biz.ss com.ss edu.ss gov.ss me.ss net.ss org.ss sch.ss // st : http://www.nic.st/html/policyrules/ st co.st com.st consulado.st edu.st embaixada.st mil.st net.st org.st principe.st saotome.st store.st // su : https://en.wikipedia.org/wiki/.su su // sv : http://www.svnet.org.sv/niveldos.pdf sv com.sv edu.sv gob.sv org.sv red.sv // sx : https://en.wikipedia.org/wiki/.sx // Submitted by registry sx gov.sx // sy : https://en.wikipedia.org/wiki/.sy // see also: http://www.gobin.info/domainname/sy.doc sy edu.sy gov.sy net.sy mil.sy com.sy org.sy // sz : https://en.wikipedia.org/wiki/.sz // http://www.sispa.org.sz/ sz co.sz ac.sz org.sz // tc : https://en.wikipedia.org/wiki/.tc tc // td : https://en.wikipedia.org/wiki/.td td // tel: https://en.wikipedia.org/wiki/.tel // http://www.telnic.org/ tel // tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf tf // tg : https://en.wikipedia.org/wiki/.tg // http://www.nic.tg/ tg // th : https://en.wikipedia.org/wiki/.th // Submitted by registry th ac.th co.th go.th in.th mi.th net.th or.th // tj : http://www.nic.tj/policy.html tj ac.tj biz.tj co.tj com.tj edu.tj go.tj gov.tj int.tj mil.tj name.tj net.tj nic.tj org.tj test.tj web.tj // tk : https://en.wikipedia.org/wiki/.tk tk // tl : https://en.wikipedia.org/wiki/.tl tl gov.tl // tm : http://www.nic.tm/local.html tm com.tm co.tm org.tm net.tm nom.tm gov.tm mil.tm edu.tm // tn : http://www.registre.tn/fr/ // https://whois.ati.tn/ tn com.tn ens.tn fin.tn gov.tn ind.tn info.tn intl.tn mincom.tn nat.tn net.tn org.tn perso.tn tourism.tn // to : https://en.wikipedia.org/wiki/.to // Submitted by registry to com.to gov.to net.to org.to edu.to mil.to // tr : https://nic.tr/ // https://nic.tr/forms/eng/policies.pdf // https://nic.tr/index.php?USRACTN=PRICELST tr av.tr bbs.tr bel.tr biz.tr com.tr dr.tr edu.tr gen.tr gov.tr info.tr mil.tr k12.tr kep.tr name.tr net.tr org.tr pol.tr tel.tr tsk.tr tv.tr web.tr // Used by Northern Cyprus nc.tr // Used by government agencies of Northern Cyprus gov.nc.tr // tt : http://www.nic.tt/ tt co.tt com.tt org.tt net.tt biz.tt info.tt pro.tt int.tt coop.tt jobs.tt mobi.tt travel.tt museum.tt aero.tt name.tt gov.tt edu.tt // tv : https://en.wikipedia.org/wiki/.tv // Not listing any 2LDs as reserved since none seem to exist in practice, // Wikipedia notwithstanding. tv // tw : https://en.wikipedia.org/wiki/.tw tw edu.tw gov.tw mil.tw com.tw net.tw org.tw idv.tw game.tw ebiz.tw club.tw xn--zf0ao64a.tw xn--uc0atv.tw xn--czrw28b.tw // tz : http://www.tznic.or.tz/index.php/domains // Submitted by registry tz ac.tz co.tz go.tz hotel.tz info.tz me.tz mil.tz mobi.tz ne.tz or.tz sc.tz tv.tz // ua : https://hostmaster.ua/policy/?ua // Submitted by registry ua // ua 2LD com.ua edu.ua gov.ua in.ua net.ua org.ua // ua geographic names // https://hostmaster.ua/2ld/ cherkassy.ua cherkasy.ua chernigov.ua chernihiv.ua chernivtsi.ua chernovtsy.ua ck.ua cn.ua cr.ua crimea.ua cv.ua dn.ua dnepropetrovsk.ua dnipropetrovsk.ua donetsk.ua dp.ua if.ua ivano-frankivsk.ua kh.ua kharkiv.ua kharkov.ua kherson.ua khmelnitskiy.ua khmelnytskyi.ua kiev.ua kirovograd.ua km.ua kr.ua kropyvnytskyi.ua krym.ua ks.ua kv.ua kyiv.ua lg.ua lt.ua lugansk.ua luhansk.ua lutsk.ua lv.ua lviv.ua mk.ua mykolaiv.ua nikolaev.ua od.ua odesa.ua odessa.ua pl.ua poltava.ua rivne.ua rovno.ua rv.ua sb.ua sebastopol.ua sevastopol.ua sm.ua sumy.ua te.ua ternopil.ua uz.ua uzhgorod.ua uzhhorod.ua vinnica.ua vinnytsia.ua vn.ua volyn.ua yalta.ua zakarpattia.ua zaporizhzhe.ua zaporizhzhia.ua zhitomir.ua zhytomyr.ua zp.ua zt.ua // ug : https://www.registry.co.ug/ ug co.ug or.ug ac.ug sc.ug go.ug ne.ug com.ug org.ug // uk : https://en.wikipedia.org/wiki/.uk // Submitted by registry uk ac.uk co.uk gov.uk ltd.uk me.uk net.uk nhs.uk org.uk plc.uk police.uk *.sch.uk // us : https://en.wikipedia.org/wiki/.us us dni.us fed.us isa.us kids.us nsn.us // us geographic names ak.us al.us ar.us as.us az.us ca.us co.us ct.us dc.us de.us fl.us ga.us gu.us hi.us ia.us id.us il.us in.us ks.us ky.us la.us ma.us md.us me.us mi.us mn.us mo.us ms.us mt.us nc.us nd.us ne.us nh.us nj.us nm.us nv.us ny.us oh.us ok.us or.us pa.us pr.us ri.us sc.us sd.us tn.us tx.us ut.us vi.us vt.us va.us wa.us wi.us wv.us wy.us // The registrar notes several more specific domains available in each state, // such as state.*.us, dst.*.us, etc., but resolution of these is somewhat // haphazard; in some states these domains resolve as addresses, while in others // only subdomains are available, or even nothing at all. We include the // most common ones where it's clear that different sites are different // entities. k12.ak.us k12.al.us k12.ar.us k12.as.us k12.az.us k12.ca.us k12.co.us k12.ct.us k12.dc.us k12.fl.us k12.ga.us k12.gu.us // k12.hi.us Bug 614565 - Hawaii has a state-wide DOE login k12.ia.us k12.id.us k12.il.us k12.in.us k12.ks.us k12.ky.us k12.la.us k12.ma.us k12.md.us k12.me.us k12.mi.us k12.mn.us k12.mo.us k12.ms.us k12.mt.us k12.nc.us // k12.nd.us Bug 1028347 - Removed at request of Travis Rosso k12.ne.us k12.nh.us k12.nj.us k12.nm.us k12.nv.us k12.ny.us k12.oh.us k12.ok.us k12.or.us k12.pa.us k12.pr.us // k12.ri.us Removed at request of Kim Cournoyer k12.sc.us // k12.sd.us Bug 934131 - Removed at request of James Booze k12.tn.us k12.tx.us k12.ut.us k12.vi.us k12.vt.us k12.va.us k12.wa.us k12.wi.us // k12.wv.us Bug 947705 - Removed at request of Verne Britton k12.wy.us cc.ak.us cc.al.us cc.ar.us cc.as.us cc.az.us cc.ca.us cc.co.us cc.ct.us cc.dc.us cc.de.us cc.fl.us cc.ga.us cc.gu.us cc.hi.us cc.ia.us cc.id.us cc.il.us cc.in.us cc.ks.us cc.ky.us cc.la.us cc.ma.us cc.md.us cc.me.us cc.mi.us cc.mn.us cc.mo.us cc.ms.us cc.mt.us cc.nc.us cc.nd.us cc.ne.us cc.nh.us cc.nj.us cc.nm.us cc.nv.us cc.ny.us cc.oh.us cc.ok.us cc.or.us cc.pa.us cc.pr.us cc.ri.us cc.sc.us cc.sd.us cc.tn.us cc.tx.us cc.ut.us cc.vi.us cc.vt.us cc.va.us cc.wa.us cc.wi.us cc.wv.us cc.wy.us lib.ak.us lib.al.us lib.ar.us lib.as.us lib.az.us lib.ca.us lib.co.us lib.ct.us lib.dc.us // lib.de.us Issue #243 - Moved to Private section at request of Ed Moore lib.fl.us lib.ga.us lib.gu.us lib.hi.us lib.ia.us lib.id.us lib.il.us lib.in.us lib.ks.us lib.ky.us lib.la.us lib.ma.us lib.md.us lib.me.us lib.mi.us lib.mn.us lib.mo.us lib.ms.us lib.mt.us lib.nc.us lib.nd.us lib.ne.us lib.nh.us lib.nj.us lib.nm.us lib.nv.us lib.ny.us lib.oh.us lib.ok.us lib.or.us lib.pa.us lib.pr.us lib.ri.us lib.sc.us lib.sd.us lib.tn.us lib.tx.us lib.ut.us lib.vi.us lib.vt.us lib.va.us lib.wa.us lib.wi.us // lib.wv.us Bug 941670 - Removed at request of Larry W Arnold lib.wy.us // k12.ma.us contains school districts in Massachusetts. The 4LDs are // managed independently except for private (PVT), charter (CHTR) and // parochial (PAROCH) schools. Those are delegated directly to the // 5LD operators. pvt.k12.ma.us chtr.k12.ma.us paroch.k12.ma.us // Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following // see also: http://domreg.merit.edu // see also: whois -h whois.domreg.merit.edu help ann-arbor.mi.us cog.mi.us dst.mi.us eaton.mi.us gen.mi.us mus.mi.us tec.mi.us washtenaw.mi.us // uy : http://www.nic.org.uy/ uy com.uy edu.uy gub.uy mil.uy net.uy org.uy // uz : http://www.reg.uz/ uz co.uz com.uz net.uz org.uz // va : https://en.wikipedia.org/wiki/.va va // vc : https://en.wikipedia.org/wiki/.vc // Submitted by registry vc com.vc net.vc org.vc gov.vc mil.vc edu.vc // ve : https://registro.nic.ve/ // Submitted by registry nic@nic.ve and nicve@conatel.gob.ve ve arts.ve bib.ve co.ve com.ve e12.ve edu.ve firm.ve gob.ve gov.ve info.ve int.ve mil.ve net.ve nom.ve org.ve rar.ve rec.ve store.ve tec.ve web.ve // vg : https://en.wikipedia.org/wiki/.vg vg // vi : http://www.nic.vi/newdomainform.htm // http://www.nic.vi/Domain_Rules/body_domain_rules.html indicates some other // TLDs are "reserved", such as edu.vi and gov.vi, but doesn't actually say they // are available for registration (which they do not seem to be). vi co.vi com.vi k12.vi net.vi org.vi // vn : https://www.vnnic.vn/en/domain/cctld-vn // https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt vn ac.vn ai.vn biz.vn com.vn edu.vn gov.vn health.vn id.vn info.vn int.vn io.vn name.vn net.vn org.vn pro.vn // vn geographical names angiang.vn bacgiang.vn backan.vn baclieu.vn bacninh.vn baria-vungtau.vn bentre.vn binhdinh.vn binhduong.vn binhphuoc.vn binhthuan.vn camau.vn cantho.vn caobang.vn daklak.vn daknong.vn danang.vn dienbien.vn dongnai.vn dongthap.vn gialai.vn hagiang.vn haiduong.vn haiphong.vn hanam.vn hanoi.vn hatinh.vn haugiang.vn hoabinh.vn hungyen.vn khanhhoa.vn kiengiang.vn kontum.vn laichau.vn lamdong.vn langson.vn laocai.vn longan.vn namdinh.vn nghean.vn ninhbinh.vn ninhthuan.vn phutho.vn phuyen.vn quangbinh.vn quangnam.vn quangngai.vn quangninh.vn quangtri.vn soctrang.vn sonla.vn tayninh.vn thaibinh.vn thainguyen.vn thanhhoa.vn thanhphohochiminh.vn thuathienhue.vn tiengiang.vn travinh.vn tuyenquang.vn vinhlong.vn vinhphuc.vn yenbai.vn // vu : https://en.wikipedia.org/wiki/.vu // http://www.vunic.vu/ vu com.vu edu.vu net.vu org.vu // wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf wf // ws : https://en.wikipedia.org/wiki/.ws // http://samoanic.ws/index.dhtml ws com.ws net.ws org.ws gov.ws edu.ws // yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf yt // IDN ccTLDs // When submitting patches, please maintain a sort by ISO 3166 ccTLD, then // U-label, and follow this format: // // A-Label ("", [, variant info]) : // // [sponsoring org] // U-Label // xn--mgbaam7a8h ("Emerat", Arabic) : AE // http://nic.ae/english/arabicdomain/rules.jsp xn--mgbaam7a8h // xn--y9a3aq ("hye", Armenian) : AM // ISOC AM (operated by .am Registry) xn--y9a3aq // xn--54b7fta0cc ("Bangla", Bangla) : BD xn--54b7fta0cc // xn--90ae ("bg", Bulgarian) : BG xn--90ae // xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH xn--mgbcpq6gpa1a // xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY // Operated by .by registry xn--90ais // xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN // CNNIC // http://cnnic.cn/html/Dir/2005/10/11/3218.htm xn--fiqs8s // xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN // CNNIC // http://cnnic.cn/html/Dir/2005/10/11/3218.htm xn--fiqz9s // xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ xn--lgbbat1ad8j // xn--wgbh1c ("Egypt/Masr", Arabic) : EG // http://www.dotmasr.eg/ xn--wgbh1c // xn--e1a4c ("eu", Cyrillic) : EU // https://eurid.eu xn--e1a4c // xn--qxa6a ("eu", Greek) : EU // https://eurid.eu xn--qxa6a // xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR xn--mgbah1a3hjkrd // xn--node ("ge", Georgian Mkhedruli) : GE xn--node // xn--qxam ("el", Greek) : GR // Hellenic Ministry of Infrastructure, Transport, and Networks xn--qxam // xn--j6w193g ("Hong Kong", Chinese) : HK // https://www.hkirc.hk // Submitted by registry // https://www.hkirc.hk/content.jsp?id=30#!/34 xn--j6w193g xn--55qx5d.xn--j6w193g xn--wcvs22d.xn--j6w193g xn--mxtq1m.xn--j6w193g xn--gmqw5a.xn--j6w193g xn--od0alg.xn--j6w193g xn--uc0atv.xn--j6w193g // xn--2scrj9c ("Bharat", Kannada) : IN // India xn--2scrj9c // xn--3hcrj9c ("Bharat", Oriya) : IN // India xn--3hcrj9c // xn--45br5cyl ("Bharatam", Assamese) : IN // India xn--45br5cyl // xn--h2breg3eve ("Bharatam", Sanskrit) : IN // India xn--h2breg3eve // xn--h2brj9c8c ("Bharot", Santali) : IN // India xn--h2brj9c8c // xn--mgbgu82a ("Bharat", Sindhi) : IN // India xn--mgbgu82a // xn--rvc1e0am3e ("Bharatam", Malayalam) : IN // India xn--rvc1e0am3e // xn--h2brj9c ("Bharat", Devanagari) : IN // India xn--h2brj9c // xn--mgbbh1a ("Bharat", Kashmiri) : IN // India xn--mgbbh1a // xn--mgbbh1a71e ("Bharat", Arabic) : IN // India xn--mgbbh1a71e // xn--fpcrj9c3d ("Bharat", Telugu) : IN // India xn--fpcrj9c3d // xn--gecrj9c ("Bharat", Gujarati) : IN // India xn--gecrj9c // xn--s9brj9c ("Bharat", Gurmukhi) : IN // India xn--s9brj9c // xn--45brj9c ("Bharat", Bengali) : IN // India xn--45brj9c // xn--xkc2dl3a5ee0h ("India", Tamil) : IN // India xn--xkc2dl3a5ee0h // xn--mgba3a4f16a ("Iran", Persian) : IR xn--mgba3a4f16a // xn--mgba3a4fra ("Iran", Arabic) : IR xn--mgba3a4fra // xn--mgbtx2b ("Iraq", Arabic) : IQ // Communications and Media Commission xn--mgbtx2b // xn--mgbayh7gpa ("al-Ordon", Arabic) : JO // National Information Technology Center (NITC) // Royal Scientific Society, Al-Jubeiha xn--mgbayh7gpa // xn--3e0b707e ("Republic of Korea", Hangul) : KR xn--3e0b707e // xn--80ao21a ("Kaz", Kazakh) : KZ xn--80ao21a // xn--q7ce6a ("Lao", Lao) : LA xn--q7ce6a // xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK // https://nic.lk xn--fzc2c9e2c // xn--xkc2al3hye2a ("Ilangai", Tamil) : LK // https://nic.lk xn--xkc2al3hye2a // xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA xn--mgbc0a9azcg // xn--d1alf ("mkd", Macedonian) : MK // MARnet xn--d1alf // xn--l1acc ("mon", Mongolian) : MN xn--l1acc // xn--mix891f ("Macao", Chinese, Traditional) : MO // MONIC / HNET Asia (Registry Operator for .mo) xn--mix891f // xn--mix082f ("Macao", Chinese, Simplified) : MO xn--mix082f // xn--mgbx4cd0ab ("Malaysia", Malay) : MY xn--mgbx4cd0ab // xn--mgb9awbf ("Oman", Arabic) : OM xn--mgb9awbf // xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK xn--mgbai9azgqp6j // xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK xn--mgbai9a5eva00b // xn--ygbi2ammx ("Falasteen", Arabic) : PS // The Palestinian National Internet Naming Authority (PNINA) // http://www.pnina.ps xn--ygbi2ammx // xn--90a3ac ("srb", Cyrillic) : RS // https://www.rnids.rs/en/domains/national-domains xn--90a3ac xn--o1ac.xn--90a3ac xn--c1avg.xn--90a3ac xn--90azh.xn--90a3ac xn--d1at.xn--90a3ac xn--o1ach.xn--90a3ac xn--80au.xn--90a3ac // xn--p1ai ("rf", Russian-Cyrillic) : RU // https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf // Submitted by George Georgievsky xn--p1ai // xn--wgbl6a ("Qatar", Arabic) : QA // http://www.ict.gov.qa/ xn--wgbl6a // xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA // http://www.nic.net.sa/ xn--mgberp4a5d4ar // xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant) : SA xn--mgberp4a5d4a87g // xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA xn--mgbqly7c0a67fbc // xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA xn--mgbqly7cvafr // xn--mgbpl2fh ("sudan", Arabic) : SD // Operated by .sd registry xn--mgbpl2fh // xn--yfro4i67o Singapore ("Singapore", Chinese) : SG xn--yfro4i67o // xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG xn--clchc0ea0b2g2a9gcd // xn--ogbpf8fl ("Syria", Arabic) : SY xn--ogbpf8fl // xn--mgbtf8fl ("Syria", Arabic, variant) : SY xn--mgbtf8fl // xn--o3cw4h ("Thai", Thai) : TH // http://www.thnic.co.th xn--o3cw4h xn--12c1fe0br.xn--o3cw4h xn--12co0c3b4eva.xn--o3cw4h xn--h3cuzk1di.xn--o3cw4h xn--o3cyx2a.xn--o3cw4h xn--m3ch0j3a.xn--o3cw4h xn--12cfi8ixb8l.xn--o3cw4h // xn--pgbs0dh ("Tunisia", Arabic) : TN // http://nic.tn xn--pgbs0dh // xn--kpry57d ("Taiwan", Chinese, Traditional) : TW // http://www.twnic.net/english/dn/dn_07a.htm xn--kpry57d // xn--kprw13d ("Taiwan", Chinese, Simplified) : TW // http://www.twnic.net/english/dn/dn_07a.htm xn--kprw13d // xn--nnx388a ("Taiwan", Chinese, variant) : TW xn--nnx388a // xn--j1amh ("ukr", Cyrillic) : UA xn--j1amh // xn--mgb2ddes ("AlYemen", Arabic) : YE xn--mgb2ddes // xxx : http://icmregistry.com xxx // ye : http://www.y.net.ye/services/domain_name.htm ye com.ye edu.ye gov.ye net.ye mil.ye org.ye // za : https://www.zadna.org.za/content/page/domain-information/ ac.za agric.za alt.za co.za edu.za gov.za grondar.za law.za mil.za net.za ngo.za nic.za nis.za nom.za org.za school.za tm.za web.za // zm : https://zicta.zm/ // Submitted by registry zm ac.zm biz.zm co.zm com.zm edu.zm gov.zm info.zm mil.zm net.zm org.zm sch.zm // zw : https://www.potraz.gov.zw/ // Confirmed by registry 2017-01-25 zw ac.zw co.zw gov.zw mil.zw org.zw // newGTLDs // List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-01-06T15:12:04Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html aaa // aarp : AARP // https://www.iana.org/domains/root/db/aarp.html aarp // abb : ABB Ltd // https://www.iana.org/domains/root/db/abb.html abb // abbott : Abbott Laboratories, Inc. // https://www.iana.org/domains/root/db/abbott.html abbott // abbvie : AbbVie Inc. // https://www.iana.org/domains/root/db/abbvie.html abbvie // abc : Disney Enterprises, Inc. // https://www.iana.org/domains/root/db/abc.html abc // able : Able Inc. // https://www.iana.org/domains/root/db/able.html able // abogado : Registry Services, LLC // https://www.iana.org/domains/root/db/abogado.html abogado // abudhabi : Abu Dhabi Systems and Information Centre // https://www.iana.org/domains/root/db/abudhabi.html abudhabi // academy : Binky Moon, LLC // https://www.iana.org/domains/root/db/academy.html academy // accenture : Accenture plc // https://www.iana.org/domains/root/db/accenture.html accenture // accountant : dot Accountant Limited // https://www.iana.org/domains/root/db/accountant.html accountant // accountants : Binky Moon, LLC // https://www.iana.org/domains/root/db/accountants.html accountants // aco : ACO Severin Ahlmann GmbH & Co. KG // https://www.iana.org/domains/root/db/aco.html aco // actor : Dog Beach, LLC // https://www.iana.org/domains/root/db/actor.html actor // ads : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/ads.html ads // adult : ICM Registry AD LLC // https://www.iana.org/domains/root/db/adult.html adult // aeg : Aktiebolaget Electrolux // https://www.iana.org/domains/root/db/aeg.html aeg // aetna : Aetna Life Insurance Company // https://www.iana.org/domains/root/db/aetna.html aetna // afl : Australian Football League // https://www.iana.org/domains/root/db/afl.html afl // africa : ZA Central Registry NPC trading as Registry.Africa // https://www.iana.org/domains/root/db/africa.html africa // agakhan : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/agakhan.html agakhan // agency : Binky Moon, LLC // https://www.iana.org/domains/root/db/agency.html agency // aig : American International Group, Inc. // https://www.iana.org/domains/root/db/aig.html aig // airbus : Airbus S.A.S. // https://www.iana.org/domains/root/db/airbus.html airbus // airforce : Dog Beach, LLC // https://www.iana.org/domains/root/db/airforce.html airforce // airtel : Bharti Airtel Limited // https://www.iana.org/domains/root/db/airtel.html airtel // akdn : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/akdn.html akdn // alibaba : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/alibaba.html alibaba // alipay : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/alipay.html alipay // allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft // https://www.iana.org/domains/root/db/allfinanz.html allfinanz // allstate : Allstate Fire and Casualty Insurance Company // https://www.iana.org/domains/root/db/allstate.html allstate // ally : Ally Financial Inc. // https://www.iana.org/domains/root/db/ally.html ally // alsace : Region Grand Est // https://www.iana.org/domains/root/db/alsace.html alsace // alstom : ALSTOM // https://www.iana.org/domains/root/db/alstom.html alstom // amazon : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/amazon.html amazon // americanexpress : American Express Travel Related Services Company, Inc. // https://www.iana.org/domains/root/db/americanexpress.html americanexpress // americanfamily : AmFam, Inc. // https://www.iana.org/domains/root/db/americanfamily.html americanfamily // amex : American Express Travel Related Services Company, Inc. // https://www.iana.org/domains/root/db/amex.html amex // amfam : AmFam, Inc. // https://www.iana.org/domains/root/db/amfam.html amfam // amica : Amica Mutual Insurance Company // https://www.iana.org/domains/root/db/amica.html amica // amsterdam : Gemeente Amsterdam // https://www.iana.org/domains/root/db/amsterdam.html amsterdam // analytics : Campus IP LLC // https://www.iana.org/domains/root/db/analytics.html analytics // android : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/android.html android // anquan : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/anquan.html anquan // anz : Australia and New Zealand Banking Group Limited // https://www.iana.org/domains/root/db/anz.html anz // aol : Oath Inc. // https://www.iana.org/domains/root/db/aol.html aol // apartments : Binky Moon, LLC // https://www.iana.org/domains/root/db/apartments.html apartments // app : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/app.html app // apple : Apple Inc. // https://www.iana.org/domains/root/db/apple.html apple // aquarelle : Aquarelle.com // https://www.iana.org/domains/root/db/aquarelle.html aquarelle // arab : League of Arab States // https://www.iana.org/domains/root/db/arab.html arab // aramco : Aramco Services Company // https://www.iana.org/domains/root/db/aramco.html aramco // archi : Identity Digital Limited // https://www.iana.org/domains/root/db/archi.html archi // army : Dog Beach, LLC // https://www.iana.org/domains/root/db/army.html army // art : UK Creative Ideas Limited // https://www.iana.org/domains/root/db/art.html art // arte : Association Relative à la Télévision Européenne G.E.I.E. // https://www.iana.org/domains/root/db/arte.html arte // asda : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/asda.html asda // associates : Binky Moon, LLC // https://www.iana.org/domains/root/db/associates.html associates // athleta : The Gap, Inc. // https://www.iana.org/domains/root/db/athleta.html athleta // attorney : Dog Beach, LLC // https://www.iana.org/domains/root/db/attorney.html attorney // auction : Dog Beach, LLC // https://www.iana.org/domains/root/db/auction.html auction // audi : AUDI Aktiengesellschaft // https://www.iana.org/domains/root/db/audi.html audi // audible : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/audible.html audible // audio : XYZ.COM LLC // https://www.iana.org/domains/root/db/audio.html audio // auspost : Australian Postal Corporation // https://www.iana.org/domains/root/db/auspost.html auspost // author : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/author.html author // auto : XYZ.COM LLC // https://www.iana.org/domains/root/db/auto.html auto // autos : XYZ.COM LLC // https://www.iana.org/domains/root/db/autos.html autos // avianca : Avianca Inc. // https://www.iana.org/domains/root/db/avianca.html avianca // aws : AWS Registry LLC // https://www.iana.org/domains/root/db/aws.html aws // axa : AXA Group Operations SAS // https://www.iana.org/domains/root/db/axa.html axa // azure : Microsoft Corporation // https://www.iana.org/domains/root/db/azure.html azure // baby : XYZ.COM LLC // https://www.iana.org/domains/root/db/baby.html baby // baidu : Baidu, Inc. // https://www.iana.org/domains/root/db/baidu.html baidu // banamex : Citigroup Inc. // https://www.iana.org/domains/root/db/banamex.html banamex // bananarepublic : The Gap, Inc. // https://www.iana.org/domains/root/db/bananarepublic.html bananarepublic // band : Dog Beach, LLC // https://www.iana.org/domains/root/db/band.html band // bank : fTLD Registry Services LLC // https://www.iana.org/domains/root/db/bank.html bank // bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable // https://www.iana.org/domains/root/db/bar.html bar // barcelona : Municipi de Barcelona // https://www.iana.org/domains/root/db/barcelona.html barcelona // barclaycard : Barclays Bank PLC // https://www.iana.org/domains/root/db/barclaycard.html barclaycard // barclays : Barclays Bank PLC // https://www.iana.org/domains/root/db/barclays.html barclays // barefoot : Gallo Vineyards, Inc. // https://www.iana.org/domains/root/db/barefoot.html barefoot // bargains : Binky Moon, LLC // https://www.iana.org/domains/root/db/bargains.html bargains // baseball : MLB Advanced Media DH, LLC // https://www.iana.org/domains/root/db/baseball.html baseball // basketball : Fédération Internationale de Basketball (FIBA) // https://www.iana.org/domains/root/db/basketball.html basketball // bauhaus : Werkhaus GmbH // https://www.iana.org/domains/root/db/bauhaus.html bauhaus // bayern : Bayern Connect GmbH // https://www.iana.org/domains/root/db/bayern.html bayern // bbc : British Broadcasting Corporation // https://www.iana.org/domains/root/db/bbc.html bbc // bbt : BB&T Corporation // https://www.iana.org/domains/root/db/bbt.html bbt // bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. // https://www.iana.org/domains/root/db/bbva.html bbva // bcg : The Boston Consulting Group, Inc. // https://www.iana.org/domains/root/db/bcg.html bcg // bcn : Municipi de Barcelona // https://www.iana.org/domains/root/db/bcn.html bcn // beats : Beats Electronics, LLC // https://www.iana.org/domains/root/db/beats.html beats // beauty : XYZ.COM LLC // https://www.iana.org/domains/root/db/beauty.html beauty // beer : Registry Services, LLC // https://www.iana.org/domains/root/db/beer.html beer // bentley : Bentley Motors Limited // https://www.iana.org/domains/root/db/bentley.html bentley // berlin : dotBERLIN GmbH & Co. KG // https://www.iana.org/domains/root/db/berlin.html berlin // best : BestTLD Pty Ltd // https://www.iana.org/domains/root/db/best.html best // bestbuy : BBY Solutions, Inc. // https://www.iana.org/domains/root/db/bestbuy.html bestbuy // bet : Identity Digital Limited // https://www.iana.org/domains/root/db/bet.html bet // bharti : Bharti Enterprises (Holding) Private Limited // https://www.iana.org/domains/root/db/bharti.html bharti // bible : American Bible Society // https://www.iana.org/domains/root/db/bible.html bible // bid : dot Bid Limited // https://www.iana.org/domains/root/db/bid.html bid // bike : Binky Moon, LLC // https://www.iana.org/domains/root/db/bike.html bike // bing : Microsoft Corporation // https://www.iana.org/domains/root/db/bing.html bing // bingo : Binky Moon, LLC // https://www.iana.org/domains/root/db/bingo.html bingo // bio : Identity Digital Limited // https://www.iana.org/domains/root/db/bio.html bio // black : Identity Digital Limited // https://www.iana.org/domains/root/db/black.html black // blackfriday : Registry Services, LLC // https://www.iana.org/domains/root/db/blackfriday.html blackfriday // blockbuster : Dish DBS Corporation // https://www.iana.org/domains/root/db/blockbuster.html blockbuster // blog : Knock Knock WHOIS There, LLC // https://www.iana.org/domains/root/db/blog.html blog // bloomberg : Bloomberg IP Holdings LLC // https://www.iana.org/domains/root/db/bloomberg.html bloomberg // blue : Identity Digital Limited // https://www.iana.org/domains/root/db/blue.html blue // bms : Bristol-Myers Squibb Company // https://www.iana.org/domains/root/db/bms.html bms // bmw : Bayerische Motoren Werke Aktiengesellschaft // https://www.iana.org/domains/root/db/bmw.html bmw // bnpparibas : BNP Paribas // https://www.iana.org/domains/root/db/bnpparibas.html bnpparibas // boats : XYZ.COM LLC // https://www.iana.org/domains/root/db/boats.html boats // boehringer : Boehringer Ingelheim International GmbH // https://www.iana.org/domains/root/db/boehringer.html boehringer // bofa : Bank of America Corporation // https://www.iana.org/domains/root/db/bofa.html bofa // bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br // https://www.iana.org/domains/root/db/bom.html bom // bond : ShortDot SA // https://www.iana.org/domains/root/db/bond.html bond // boo : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/boo.html boo // book : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/book.html book // booking : Booking.com B.V. // https://www.iana.org/domains/root/db/booking.html booking // bosch : Robert Bosch GMBH // https://www.iana.org/domains/root/db/bosch.html bosch // bostik : Bostik SA // https://www.iana.org/domains/root/db/bostik.html bostik // boston : Registry Services, LLC // https://www.iana.org/domains/root/db/boston.html boston // bot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/bot.html bot // boutique : Binky Moon, LLC // https://www.iana.org/domains/root/db/boutique.html boutique // box : Intercap Registry Inc. // https://www.iana.org/domains/root/db/box.html box // bradesco : Banco Bradesco S.A. // https://www.iana.org/domains/root/db/bradesco.html bradesco // bridgestone : Bridgestone Corporation // https://www.iana.org/domains/root/db/bridgestone.html bridgestone // broadway : Celebrate Broadway, Inc. // https://www.iana.org/domains/root/db/broadway.html broadway // broker : Dog Beach, LLC // https://www.iana.org/domains/root/db/broker.html broker // brother : Brother Industries, Ltd. // https://www.iana.org/domains/root/db/brother.html brother // brussels : DNS.be vzw // https://www.iana.org/domains/root/db/brussels.html brussels // build : Plan Bee LLC // https://www.iana.org/domains/root/db/build.html build // builders : Binky Moon, LLC // https://www.iana.org/domains/root/db/builders.html builders // business : Binky Moon, LLC // https://www.iana.org/domains/root/db/business.html business // buy : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/buy.html buy // buzz : DOTSTRATEGY CO. // https://www.iana.org/domains/root/db/buzz.html buzz // bzh : Association www.bzh // https://www.iana.org/domains/root/db/bzh.html bzh // cab : Binky Moon, LLC // https://www.iana.org/domains/root/db/cab.html cab // cafe : Binky Moon, LLC // https://www.iana.org/domains/root/db/cafe.html cafe // cal : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/cal.html cal // call : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/call.html call // calvinklein : PVH gTLD Holdings LLC // https://www.iana.org/domains/root/db/calvinklein.html calvinklein // cam : Cam Connecting SARL // https://www.iana.org/domains/root/db/cam.html cam // camera : Binky Moon, LLC // https://www.iana.org/domains/root/db/camera.html camera // camp : Binky Moon, LLC // https://www.iana.org/domains/root/db/camp.html camp // canon : Canon Inc. // https://www.iana.org/domains/root/db/canon.html canon // capetown : ZA Central Registry NPC trading as ZA Central Registry // https://www.iana.org/domains/root/db/capetown.html capetown // capital : Binky Moon, LLC // https://www.iana.org/domains/root/db/capital.html capital // capitalone : Capital One Financial Corporation // https://www.iana.org/domains/root/db/capitalone.html capitalone // car : XYZ.COM LLC // https://www.iana.org/domains/root/db/car.html car // caravan : Caravan International, Inc. // https://www.iana.org/domains/root/db/caravan.html caravan // cards : Binky Moon, LLC // https://www.iana.org/domains/root/db/cards.html cards // care : Binky Moon, LLC // https://www.iana.org/domains/root/db/care.html care // career : dotCareer LLC // https://www.iana.org/domains/root/db/career.html career // careers : Binky Moon, LLC // https://www.iana.org/domains/root/db/careers.html careers // cars : XYZ.COM LLC // https://www.iana.org/domains/root/db/cars.html cars // casa : Registry Services, LLC // https://www.iana.org/domains/root/db/casa.html casa // case : Digity, LLC // https://www.iana.org/domains/root/db/case.html case // cash : Binky Moon, LLC // https://www.iana.org/domains/root/db/cash.html cash // casino : Binky Moon, LLC // https://www.iana.org/domains/root/db/casino.html casino // catering : Binky Moon, LLC // https://www.iana.org/domains/root/db/catering.html catering // catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/catholic.html catholic // cba : COMMONWEALTH BANK OF AUSTRALIA // https://www.iana.org/domains/root/db/cba.html cba // cbn : The Christian Broadcasting Network, Inc. // https://www.iana.org/domains/root/db/cbn.html cbn // cbre : CBRE, Inc. // https://www.iana.org/domains/root/db/cbre.html cbre // center : Binky Moon, LLC // https://www.iana.org/domains/root/db/center.html center // ceo : XYZ.COM LLC // https://www.iana.org/domains/root/db/ceo.html ceo // cern : European Organization for Nuclear Research ("CERN") // https://www.iana.org/domains/root/db/cern.html cern // cfa : CFA Institute // https://www.iana.org/domains/root/db/cfa.html cfa // cfd : ShortDot SA // https://www.iana.org/domains/root/db/cfd.html cfd // chanel : Chanel International B.V. // https://www.iana.org/domains/root/db/chanel.html chanel // channel : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/channel.html channel // charity : Public Interest Registry // https://www.iana.org/domains/root/db/charity.html charity // chase : JPMorgan Chase Bank, National Association // https://www.iana.org/domains/root/db/chase.html chase // chat : Binky Moon, LLC // https://www.iana.org/domains/root/db/chat.html chat // cheap : Binky Moon, LLC // https://www.iana.org/domains/root/db/cheap.html cheap // chintai : CHINTAI Corporation // https://www.iana.org/domains/root/db/chintai.html chintai // christmas : XYZ.COM LLC // https://www.iana.org/domains/root/db/christmas.html christmas // chrome : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/chrome.html chrome // church : Binky Moon, LLC // https://www.iana.org/domains/root/db/church.html church // cipriani : Hotel Cipriani Srl // https://www.iana.org/domains/root/db/cipriani.html cipriani // circle : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/circle.html circle // cisco : Cisco Technology, Inc. // https://www.iana.org/domains/root/db/cisco.html cisco // citadel : Citadel Domain LLC // https://www.iana.org/domains/root/db/citadel.html citadel // citi : Citigroup Inc. // https://www.iana.org/domains/root/db/citi.html citi // citic : CITIC Group Corporation // https://www.iana.org/domains/root/db/citic.html citic // city : Binky Moon, LLC // https://www.iana.org/domains/root/db/city.html city // claims : Binky Moon, LLC // https://www.iana.org/domains/root/db/claims.html claims // cleaning : Binky Moon, LLC // https://www.iana.org/domains/root/db/cleaning.html cleaning // click : Internet Naming Company LLC // https://www.iana.org/domains/root/db/click.html click // clinic : Binky Moon, LLC // https://www.iana.org/domains/root/db/clinic.html clinic // clinique : The Estée Lauder Companies Inc. // https://www.iana.org/domains/root/db/clinique.html clinique // clothing : Binky Moon, LLC // https://www.iana.org/domains/root/db/clothing.html clothing // cloud : Aruba PEC S.p.A. // https://www.iana.org/domains/root/db/cloud.html cloud // club : Registry Services, LLC // https://www.iana.org/domains/root/db/club.html club // clubmed : Club Méditerranée S.A. // https://www.iana.org/domains/root/db/clubmed.html clubmed // coach : Binky Moon, LLC // https://www.iana.org/domains/root/db/coach.html coach // codes : Binky Moon, LLC // https://www.iana.org/domains/root/db/codes.html codes // coffee : Binky Moon, LLC // https://www.iana.org/domains/root/db/coffee.html coffee // college : XYZ.COM LLC // https://www.iana.org/domains/root/db/college.html college // cologne : dotKoeln GmbH // https://www.iana.org/domains/root/db/cologne.html cologne // comcast : Comcast IP Holdings I, LLC // https://www.iana.org/domains/root/db/comcast.html comcast // commbank : COMMONWEALTH BANK OF AUSTRALIA // https://www.iana.org/domains/root/db/commbank.html commbank // community : Binky Moon, LLC // https://www.iana.org/domains/root/db/community.html community // company : Binky Moon, LLC // https://www.iana.org/domains/root/db/company.html company // compare : Registry Services, LLC // https://www.iana.org/domains/root/db/compare.html compare // computer : Binky Moon, LLC // https://www.iana.org/domains/root/db/computer.html computer // comsec : VeriSign, Inc. // https://www.iana.org/domains/root/db/comsec.html comsec // condos : Binky Moon, LLC // https://www.iana.org/domains/root/db/condos.html condos // construction : Binky Moon, LLC // https://www.iana.org/domains/root/db/construction.html construction // consulting : Dog Beach, LLC // https://www.iana.org/domains/root/db/consulting.html consulting // contact : Dog Beach, LLC // https://www.iana.org/domains/root/db/contact.html contact // contractors : Binky Moon, LLC // https://www.iana.org/domains/root/db/contractors.html contractors // cooking : Registry Services, LLC // https://www.iana.org/domains/root/db/cooking.html cooking // cool : Binky Moon, LLC // https://www.iana.org/domains/root/db/cool.html cool // corsica : Collectivité de Corse // https://www.iana.org/domains/root/db/corsica.html corsica // country : Internet Naming Company LLC // https://www.iana.org/domains/root/db/country.html country // coupon : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/coupon.html coupon // coupons : Binky Moon, LLC // https://www.iana.org/domains/root/db/coupons.html coupons // courses : Registry Services, LLC // https://www.iana.org/domains/root/db/courses.html courses // cpa : American Institute of Certified Public Accountants // https://www.iana.org/domains/root/db/cpa.html cpa // credit : Binky Moon, LLC // https://www.iana.org/domains/root/db/credit.html credit // creditcard : Binky Moon, LLC // https://www.iana.org/domains/root/db/creditcard.html creditcard // creditunion : DotCooperation LLC // https://www.iana.org/domains/root/db/creditunion.html creditunion // cricket : dot Cricket Limited // https://www.iana.org/domains/root/db/cricket.html cricket // crown : Crown Equipment Corporation // https://www.iana.org/domains/root/db/crown.html crown // crs : Federated Co-operatives Limited // https://www.iana.org/domains/root/db/crs.html crs // cruise : Viking River Cruises (Bermuda) Ltd. // https://www.iana.org/domains/root/db/cruise.html cruise // cruises : Binky Moon, LLC // https://www.iana.org/domains/root/db/cruises.html cruises // cuisinella : SCHMIDT GROUPE S.A.S. // https://www.iana.org/domains/root/db/cuisinella.html cuisinella // cymru : Nominet UK // https://www.iana.org/domains/root/db/cymru.html cymru // cyou : ShortDot SA // https://www.iana.org/domains/root/db/cyou.html cyou // dabur : Dabur India Limited // https://www.iana.org/domains/root/db/dabur.html dabur // dad : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/dad.html dad // dance : Dog Beach, LLC // https://www.iana.org/domains/root/db/dance.html dance // data : Dish DBS Corporation // https://www.iana.org/domains/root/db/data.html data // date : dot Date Limited // https://www.iana.org/domains/root/db/date.html date // dating : Binky Moon, LLC // https://www.iana.org/domains/root/db/dating.html dating // datsun : NISSAN MOTOR CO., LTD. // https://www.iana.org/domains/root/db/datsun.html datsun // day : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/day.html day // dclk : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/dclk.html dclk // dds : Registry Services, LLC // https://www.iana.org/domains/root/db/dds.html dds // deal : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/deal.html deal // dealer : Intercap Registry Inc. // https://www.iana.org/domains/root/db/dealer.html dealer // deals : Binky Moon, LLC // https://www.iana.org/domains/root/db/deals.html deals // degree : Dog Beach, LLC // https://www.iana.org/domains/root/db/degree.html degree // delivery : Binky Moon, LLC // https://www.iana.org/domains/root/db/delivery.html delivery // dell : Dell Inc. // https://www.iana.org/domains/root/db/dell.html dell // deloitte : Deloitte Touche Tohmatsu // https://www.iana.org/domains/root/db/deloitte.html deloitte // delta : Delta Air Lines, Inc. // https://www.iana.org/domains/root/db/delta.html delta // democrat : Dog Beach, LLC // https://www.iana.org/domains/root/db/democrat.html democrat // dental : Binky Moon, LLC // https://www.iana.org/domains/root/db/dental.html dental // dentist : Dog Beach, LLC // https://www.iana.org/domains/root/db/dentist.html dentist // desi // https://www.iana.org/domains/root/db/desi.html desi // design : Registry Services, LLC // https://www.iana.org/domains/root/db/design.html design // dev : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/dev.html dev // dhl : Deutsche Post AG // https://www.iana.org/domains/root/db/dhl.html dhl // diamonds : Binky Moon, LLC // https://www.iana.org/domains/root/db/diamonds.html diamonds // diet : XYZ.COM LLC // https://www.iana.org/domains/root/db/diet.html diet // digital : Binky Moon, LLC // https://www.iana.org/domains/root/db/digital.html digital // direct : Binky Moon, LLC // https://www.iana.org/domains/root/db/direct.html direct // directory : Binky Moon, LLC // https://www.iana.org/domains/root/db/directory.html directory // discount : Binky Moon, LLC // https://www.iana.org/domains/root/db/discount.html discount // discover : Discover Financial Services // https://www.iana.org/domains/root/db/discover.html discover // dish : Dish DBS Corporation // https://www.iana.org/domains/root/db/dish.html dish // diy : Internet Naming Company LLC // https://www.iana.org/domains/root/db/diy.html diy // dnp : Dai Nippon Printing Co., Ltd. // https://www.iana.org/domains/root/db/dnp.html dnp // docs : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/docs.html docs // doctor : Binky Moon, LLC // https://www.iana.org/domains/root/db/doctor.html doctor // dog : Binky Moon, LLC // https://www.iana.org/domains/root/db/dog.html dog // domains : Binky Moon, LLC // https://www.iana.org/domains/root/db/domains.html domains // dot : Dish DBS Corporation // https://www.iana.org/domains/root/db/dot.html dot // download : dot Support Limited // https://www.iana.org/domains/root/db/download.html download // drive : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/drive.html drive // dtv : Dish DBS Corporation // https://www.iana.org/domains/root/db/dtv.html dtv // dubai : Dubai Smart Government Department // https://www.iana.org/domains/root/db/dubai.html dubai // dunlop : The Goodyear Tire & Rubber Company // https://www.iana.org/domains/root/db/dunlop.html dunlop // dupont : DuPont Specialty Products USA, LLC // https://www.iana.org/domains/root/db/dupont.html dupont // durban : ZA Central Registry NPC trading as ZA Central Registry // https://www.iana.org/domains/root/db/durban.html durban // dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/dvag.html dvag // dvr : DISH Technologies L.L.C. // https://www.iana.org/domains/root/db/dvr.html dvr // earth : Interlink Systems Innovation Institute K.K. // https://www.iana.org/domains/root/db/earth.html earth // eat : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/eat.html eat // eco : Big Room Inc. // https://www.iana.org/domains/root/db/eco.html eco // edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. // https://www.iana.org/domains/root/db/edeka.html edeka // education : Binky Moon, LLC // https://www.iana.org/domains/root/db/education.html education // email : Binky Moon, LLC // https://www.iana.org/domains/root/db/email.html email // emerck : Merck KGaA // https://www.iana.org/domains/root/db/emerck.html emerck // energy : Binky Moon, LLC // https://www.iana.org/domains/root/db/energy.html energy // engineer : Dog Beach, LLC // https://www.iana.org/domains/root/db/engineer.html engineer // engineering : Binky Moon, LLC // https://www.iana.org/domains/root/db/engineering.html engineering // enterprises : Binky Moon, LLC // https://www.iana.org/domains/root/db/enterprises.html enterprises // epson : Seiko Epson Corporation // https://www.iana.org/domains/root/db/epson.html epson // equipment : Binky Moon, LLC // https://www.iana.org/domains/root/db/equipment.html equipment // ericsson : Telefonaktiebolaget L M Ericsson // https://www.iana.org/domains/root/db/ericsson.html ericsson // erni : ERNI Group Holding AG // https://www.iana.org/domains/root/db/erni.html erni // esq : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/esq.html esq // estate : Binky Moon, LLC // https://www.iana.org/domains/root/db/estate.html estate // eurovision : European Broadcasting Union (EBU) // https://www.iana.org/domains/root/db/eurovision.html eurovision // eus : Puntueus Fundazioa // https://www.iana.org/domains/root/db/eus.html eus // events : Binky Moon, LLC // https://www.iana.org/domains/root/db/events.html events // exchange : Binky Moon, LLC // https://www.iana.org/domains/root/db/exchange.html exchange // expert : Binky Moon, LLC // https://www.iana.org/domains/root/db/expert.html expert // exposed : Binky Moon, LLC // https://www.iana.org/domains/root/db/exposed.html exposed // express : Binky Moon, LLC // https://www.iana.org/domains/root/db/express.html express // extraspace : Extra Space Storage LLC // https://www.iana.org/domains/root/db/extraspace.html extraspace // fage : Fage International S.A. // https://www.iana.org/domains/root/db/fage.html fage // fail : Binky Moon, LLC // https://www.iana.org/domains/root/db/fail.html fail // fairwinds : FairWinds Partners, LLC // https://www.iana.org/domains/root/db/fairwinds.html fairwinds // faith : dot Faith Limited // https://www.iana.org/domains/root/db/faith.html faith // family : Dog Beach, LLC // https://www.iana.org/domains/root/db/family.html family // fan : Dog Beach, LLC // https://www.iana.org/domains/root/db/fan.html fan // fans : ZDNS International Limited // https://www.iana.org/domains/root/db/fans.html fans // farm : Binky Moon, LLC // https://www.iana.org/domains/root/db/farm.html farm // farmers : Farmers Insurance Exchange // https://www.iana.org/domains/root/db/farmers.html farmers // fashion : Registry Services, LLC // https://www.iana.org/domains/root/db/fashion.html fashion // fast : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/fast.html fast // fedex : Federal Express Corporation // https://www.iana.org/domains/root/db/fedex.html fedex // feedback : Top Level Spectrum, Inc. // https://www.iana.org/domains/root/db/feedback.html feedback // ferrari : Fiat Chrysler Automobiles N.V. // https://www.iana.org/domains/root/db/ferrari.html ferrari // ferrero : Ferrero Trading Lux S.A. // https://www.iana.org/domains/root/db/ferrero.html ferrero // fidelity : Fidelity Brokerage Services LLC // https://www.iana.org/domains/root/db/fidelity.html fidelity // fido : Rogers Communications Canada Inc. // https://www.iana.org/domains/root/db/fido.html fido // film : Motion Picture Domain Registry Pty Ltd // https://www.iana.org/domains/root/db/film.html film // final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br // https://www.iana.org/domains/root/db/final.html final // finance : Binky Moon, LLC // https://www.iana.org/domains/root/db/finance.html finance // financial : Binky Moon, LLC // https://www.iana.org/domains/root/db/financial.html financial // fire : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/fire.html fire // firestone : Bridgestone Licensing Services, Inc // https://www.iana.org/domains/root/db/firestone.html firestone // firmdale : Firmdale Holdings Limited // https://www.iana.org/domains/root/db/firmdale.html firmdale // fish : Binky Moon, LLC // https://www.iana.org/domains/root/db/fish.html fish // fishing : Registry Services, LLC // https://www.iana.org/domains/root/db/fishing.html fishing // fit : Registry Services, LLC // https://www.iana.org/domains/root/db/fit.html fit // fitness : Binky Moon, LLC // https://www.iana.org/domains/root/db/fitness.html fitness // flickr : Flickr, Inc. // https://www.iana.org/domains/root/db/flickr.html flickr // flights : Binky Moon, LLC // https://www.iana.org/domains/root/db/flights.html flights // flir : FLIR Systems, Inc. // https://www.iana.org/domains/root/db/flir.html flir // florist : Binky Moon, LLC // https://www.iana.org/domains/root/db/florist.html florist // flowers : XYZ.COM LLC // https://www.iana.org/domains/root/db/flowers.html flowers // fly : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/fly.html fly // foo : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/foo.html foo // food : Internet Naming Company LLC // https://www.iana.org/domains/root/db/food.html food // football : Binky Moon, LLC // https://www.iana.org/domains/root/db/football.html football // ford : Ford Motor Company // https://www.iana.org/domains/root/db/ford.html ford // forex : Dog Beach, LLC // https://www.iana.org/domains/root/db/forex.html forex // forsale : Dog Beach, LLC // https://www.iana.org/domains/root/db/forsale.html forsale // forum : Fegistry, LLC // https://www.iana.org/domains/root/db/forum.html forum // foundation : Public Interest Registry // https://www.iana.org/domains/root/db/foundation.html foundation // fox : FOX Registry, LLC // https://www.iana.org/domains/root/db/fox.html fox // free : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/free.html free // fresenius : Fresenius Immobilien-Verwaltungs-GmbH // https://www.iana.org/domains/root/db/fresenius.html fresenius // frl : FRLregistry B.V. // https://www.iana.org/domains/root/db/frl.html frl // frogans : OP3FT // https://www.iana.org/domains/root/db/frogans.html frogans // frontier : Frontier Communications Corporation // https://www.iana.org/domains/root/db/frontier.html frontier // ftr : Frontier Communications Corporation // https://www.iana.org/domains/root/db/ftr.html ftr // fujitsu : Fujitsu Limited // https://www.iana.org/domains/root/db/fujitsu.html fujitsu // fun : Radix FZC DMCC // https://www.iana.org/domains/root/db/fun.html fun // fund : Binky Moon, LLC // https://www.iana.org/domains/root/db/fund.html fund // furniture : Binky Moon, LLC // https://www.iana.org/domains/root/db/furniture.html furniture // futbol : Dog Beach, LLC // https://www.iana.org/domains/root/db/futbol.html futbol // fyi : Binky Moon, LLC // https://www.iana.org/domains/root/db/fyi.html fyi // gal : Asociación puntoGAL // https://www.iana.org/domains/root/db/gal.html gal // gallery : Binky Moon, LLC // https://www.iana.org/domains/root/db/gallery.html gallery // gallo : Gallo Vineyards, Inc. // https://www.iana.org/domains/root/db/gallo.html gallo // gallup : Gallup, Inc. // https://www.iana.org/domains/root/db/gallup.html gallup // game : XYZ.COM LLC // https://www.iana.org/domains/root/db/game.html game // games : Dog Beach, LLC // https://www.iana.org/domains/root/db/games.html games // gap : The Gap, Inc. // https://www.iana.org/domains/root/db/gap.html gap // garden : Registry Services, LLC // https://www.iana.org/domains/root/db/garden.html garden // gay : Registry Services, LLC // https://www.iana.org/domains/root/db/gay.html gay // gbiz : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/gbiz.html gbiz // gdn : Joint Stock Company "Navigation-information systems" // https://www.iana.org/domains/root/db/gdn.html gdn // gea : GEA Group Aktiengesellschaft // https://www.iana.org/domains/root/db/gea.html gea // gent : Easyhost BV // https://www.iana.org/domains/root/db/gent.html gent // genting : Resorts World Inc Pte. Ltd. // https://www.iana.org/domains/root/db/genting.html genting // george : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/george.html george // ggee : GMO Internet, Inc. // https://www.iana.org/domains/root/db/ggee.html ggee // gift : DotGift, LLC // https://www.iana.org/domains/root/db/gift.html gift // gifts : Binky Moon, LLC // https://www.iana.org/domains/root/db/gifts.html gifts // gives : Public Interest Registry // https://www.iana.org/domains/root/db/gives.html gives // giving : Public Interest Registry // https://www.iana.org/domains/root/db/giving.html giving // glass : Binky Moon, LLC // https://www.iana.org/domains/root/db/glass.html glass // gle : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/gle.html gle // global : Identity Digital Limited // https://www.iana.org/domains/root/db/global.html global // globo : Globo Comunicação e Participações S.A // https://www.iana.org/domains/root/db/globo.html globo // gmail : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/gmail.html gmail // gmbh : Binky Moon, LLC // https://www.iana.org/domains/root/db/gmbh.html gmbh // gmo : GMO Internet, Inc. // https://www.iana.org/domains/root/db/gmo.html gmo // gmx : 1&1 Mail & Media GmbH // https://www.iana.org/domains/root/db/gmx.html gmx // godaddy : Go Daddy East, LLC // https://www.iana.org/domains/root/db/godaddy.html godaddy // gold : Binky Moon, LLC // https://www.iana.org/domains/root/db/gold.html gold // goldpoint : YODOBASHI CAMERA CO.,LTD. // https://www.iana.org/domains/root/db/goldpoint.html goldpoint // golf : Binky Moon, LLC // https://www.iana.org/domains/root/db/golf.html golf // goo : NTT DOCOMO, INC. // https://www.iana.org/domains/root/db/goo.html goo // goodyear : The Goodyear Tire & Rubber Company // https://www.iana.org/domains/root/db/goodyear.html goodyear // goog : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/goog.html goog // google : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/google.html google // gop : Republican State Leadership Committee, Inc. // https://www.iana.org/domains/root/db/gop.html gop // got : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/got.html got // grainger : Grainger Registry Services, LLC // https://www.iana.org/domains/root/db/grainger.html grainger // graphics : Binky Moon, LLC // https://www.iana.org/domains/root/db/graphics.html graphics // gratis : Binky Moon, LLC // https://www.iana.org/domains/root/db/gratis.html gratis // green : Identity Digital Limited // https://www.iana.org/domains/root/db/green.html green // gripe : Binky Moon, LLC // https://www.iana.org/domains/root/db/gripe.html gripe // grocery : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/grocery.html grocery // group : Binky Moon, LLC // https://www.iana.org/domains/root/db/group.html group // guardian : The Guardian Life Insurance Company of America // https://www.iana.org/domains/root/db/guardian.html guardian // gucci : Guccio Gucci S.p.a. // https://www.iana.org/domains/root/db/gucci.html gucci // guge : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/guge.html guge // guide : Binky Moon, LLC // https://www.iana.org/domains/root/db/guide.html guide // guitars : XYZ.COM LLC // https://www.iana.org/domains/root/db/guitars.html guitars // guru : Binky Moon, LLC // https://www.iana.org/domains/root/db/guru.html guru // hair : XYZ.COM LLC // https://www.iana.org/domains/root/db/hair.html hair // hamburg : Hamburg Top-Level-Domain GmbH // https://www.iana.org/domains/root/db/hamburg.html hamburg // hangout : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/hangout.html hangout // haus : Dog Beach, LLC // https://www.iana.org/domains/root/db/haus.html haus // hbo : HBO Registry Services, Inc. // https://www.iana.org/domains/root/db/hbo.html hbo // hdfc : HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED // https://www.iana.org/domains/root/db/hdfc.html hdfc // hdfcbank : HDFC Bank Limited // https://www.iana.org/domains/root/db/hdfcbank.html hdfcbank // health : Registry Services, LLC // https://www.iana.org/domains/root/db/health.html health // healthcare : Binky Moon, LLC // https://www.iana.org/domains/root/db/healthcare.html healthcare // help : Innovation service Limited // https://www.iana.org/domains/root/db/help.html help // helsinki : City of Helsinki // https://www.iana.org/domains/root/db/helsinki.html helsinki // here : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/here.html here // hermes : HERMES INTERNATIONAL // https://www.iana.org/domains/root/db/hermes.html hermes // hiphop : Dot Hip Hop, LLC // https://www.iana.org/domains/root/db/hiphop.html hiphop // hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. // https://www.iana.org/domains/root/db/hisamitsu.html hisamitsu // hitachi : Hitachi, Ltd. // https://www.iana.org/domains/root/db/hitachi.html hitachi // hiv : Internet Naming Company LLC // https://www.iana.org/domains/root/db/hiv.html hiv // hkt : PCCW-HKT DataCom Services Limited // https://www.iana.org/domains/root/db/hkt.html hkt // hockey : Binky Moon, LLC // https://www.iana.org/domains/root/db/hockey.html hockey // holdings : Binky Moon, LLC // https://www.iana.org/domains/root/db/holdings.html holdings // holiday : Binky Moon, LLC // https://www.iana.org/domains/root/db/holiday.html holiday // homedepot : Home Depot Product Authority, LLC // https://www.iana.org/domains/root/db/homedepot.html homedepot // homegoods : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/homegoods.html homegoods // homes : XYZ.COM LLC // https://www.iana.org/domains/root/db/homes.html homes // homesense : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/homesense.html homesense // honda : Honda Motor Co., Ltd. // https://www.iana.org/domains/root/db/honda.html honda // horse : Registry Services, LLC // https://www.iana.org/domains/root/db/horse.html horse // hospital : Binky Moon, LLC // https://www.iana.org/domains/root/db/hospital.html hospital // host : Radix FZC DMCC // https://www.iana.org/domains/root/db/host.html host // hosting : XYZ.COM LLC // https://www.iana.org/domains/root/db/hosting.html hosting // hot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/hot.html hot // hotels : Booking.com B.V. // https://www.iana.org/domains/root/db/hotels.html hotels // hotmail : Microsoft Corporation // https://www.iana.org/domains/root/db/hotmail.html hotmail // house : Binky Moon, LLC // https://www.iana.org/domains/root/db/house.html house // how : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/how.html how // hsbc : HSBC Global Services (UK) Limited // https://www.iana.org/domains/root/db/hsbc.html hsbc // hughes : Hughes Satellite Systems Corporation // https://www.iana.org/domains/root/db/hughes.html hughes // hyatt : Hyatt GTLD, L.L.C. // https://www.iana.org/domains/root/db/hyatt.html hyatt // hyundai : Hyundai Motor Company // https://www.iana.org/domains/root/db/hyundai.html hyundai // ibm : International Business Machines Corporation // https://www.iana.org/domains/root/db/ibm.html ibm // icbc : Industrial and Commercial Bank of China Limited // https://www.iana.org/domains/root/db/icbc.html icbc // ice : IntercontinentalExchange, Inc. // https://www.iana.org/domains/root/db/ice.html ice // icu : ShortDot SA // https://www.iana.org/domains/root/db/icu.html icu // ieee : IEEE Global LLC // https://www.iana.org/domains/root/db/ieee.html ieee // ifm : ifm electronic gmbh // https://www.iana.org/domains/root/db/ifm.html ifm // ikano : Ikano S.A. // https://www.iana.org/domains/root/db/ikano.html ikano // imamat : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/imamat.html imamat // imdb : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/imdb.html imdb // immo : Binky Moon, LLC // https://www.iana.org/domains/root/db/immo.html immo // immobilien : Dog Beach, LLC // https://www.iana.org/domains/root/db/immobilien.html immobilien // inc : Intercap Registry Inc. // https://www.iana.org/domains/root/db/inc.html inc // industries : Binky Moon, LLC // https://www.iana.org/domains/root/db/industries.html industries // infiniti : NISSAN MOTOR CO., LTD. // https://www.iana.org/domains/root/db/infiniti.html infiniti // ing : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/ing.html ing // ink : Registry Services, LLC // https://www.iana.org/domains/root/db/ink.html ink // institute : Binky Moon, LLC // https://www.iana.org/domains/root/db/institute.html institute // insurance : fTLD Registry Services LLC // https://www.iana.org/domains/root/db/insurance.html insurance // insure : Binky Moon, LLC // https://www.iana.org/domains/root/db/insure.html insure // international : Binky Moon, LLC // https://www.iana.org/domains/root/db/international.html international // intuit : Intuit Administrative Services, Inc. // https://www.iana.org/domains/root/db/intuit.html intuit // investments : Binky Moon, LLC // https://www.iana.org/domains/root/db/investments.html investments // ipiranga : Ipiranga Produtos de Petroleo S.A. // https://www.iana.org/domains/root/db/ipiranga.html ipiranga // irish : Binky Moon, LLC // https://www.iana.org/domains/root/db/irish.html irish // ismaili : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/ismaili.html ismaili // ist : Istanbul Metropolitan Municipality // https://www.iana.org/domains/root/db/ist.html ist // istanbul : Istanbul Metropolitan Municipality // https://www.iana.org/domains/root/db/istanbul.html istanbul // itau : Itau Unibanco Holding S.A. // https://www.iana.org/domains/root/db/itau.html itau // itv : ITV Services Limited // https://www.iana.org/domains/root/db/itv.html itv // jaguar : Jaguar Land Rover Ltd // https://www.iana.org/domains/root/db/jaguar.html jaguar // java : Oracle Corporation // https://www.iana.org/domains/root/db/java.html java // jcb : JCB Co., Ltd. // https://www.iana.org/domains/root/db/jcb.html jcb // jeep : FCA US LLC. // https://www.iana.org/domains/root/db/jeep.html jeep // jetzt : Binky Moon, LLC // https://www.iana.org/domains/root/db/jetzt.html jetzt // jewelry : Binky Moon, LLC // https://www.iana.org/domains/root/db/jewelry.html jewelry // jio : Reliance Industries Limited // https://www.iana.org/domains/root/db/jio.html jio // jll : Jones Lang LaSalle Incorporated // https://www.iana.org/domains/root/db/jll.html jll // jmp : Matrix IP LLC // https://www.iana.org/domains/root/db/jmp.html jmp // jnj : Johnson & Johnson Services, Inc. // https://www.iana.org/domains/root/db/jnj.html jnj // joburg : ZA Central Registry NPC trading as ZA Central Registry // https://www.iana.org/domains/root/db/joburg.html joburg // jot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/jot.html jot // joy : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/joy.html joy // jpmorgan : JPMorgan Chase Bank, National Association // https://www.iana.org/domains/root/db/jpmorgan.html jpmorgan // jprs : Japan Registry Services Co., Ltd. // https://www.iana.org/domains/root/db/jprs.html jprs // juegos : Dog Beach, LLC // https://www.iana.org/domains/root/db/juegos.html juegos // juniper : JUNIPER NETWORKS, INC. // https://www.iana.org/domains/root/db/juniper.html juniper // kaufen : Dog Beach, LLC // https://www.iana.org/domains/root/db/kaufen.html kaufen // kddi : KDDI CORPORATION // https://www.iana.org/domains/root/db/kddi.html kddi // kerryhotels : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kerryhotels.html kerryhotels // kerrylogistics : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kerrylogistics.html kerrylogistics // kerryproperties : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kerryproperties.html kerryproperties // kfh : Kuwait Finance House // https://www.iana.org/domains/root/db/kfh.html kfh // kia : KIA MOTORS CORPORATION // https://www.iana.org/domains/root/db/kia.html kia // kids : DotKids Foundation Limited // https://www.iana.org/domains/root/db/kids.html kids // kim : Identity Digital Limited // https://www.iana.org/domains/root/db/kim.html kim // kindle : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/kindle.html kindle // kitchen : Binky Moon, LLC // https://www.iana.org/domains/root/db/kitchen.html kitchen // kiwi : DOT KIWI LIMITED // https://www.iana.org/domains/root/db/kiwi.html kiwi // koeln : dotKoeln GmbH // https://www.iana.org/domains/root/db/koeln.html koeln // komatsu : Komatsu Ltd. // https://www.iana.org/domains/root/db/komatsu.html komatsu // kosher : Kosher Marketing Assets LLC // https://www.iana.org/domains/root/db/kosher.html kosher // kpmg : KPMG International Cooperative (KPMG International Genossenschaft) // https://www.iana.org/domains/root/db/kpmg.html kpmg // kpn : Koninklijke KPN N.V. // https://www.iana.org/domains/root/db/kpn.html kpn // krd : KRG Department of Information Technology // https://www.iana.org/domains/root/db/krd.html krd // kred : KredTLD Pty Ltd // https://www.iana.org/domains/root/db/kred.html kred // kuokgroup : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kuokgroup.html kuokgroup // kyoto : Academic Institution: Kyoto Jyoho Gakuen // https://www.iana.org/domains/root/db/kyoto.html kyoto // lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” // https://www.iana.org/domains/root/db/lacaixa.html lacaixa // lamborghini : Automobili Lamborghini S.p.A. // https://www.iana.org/domains/root/db/lamborghini.html lamborghini // lamer : The Estée Lauder Companies Inc. // https://www.iana.org/domains/root/db/lamer.html lamer // lancaster : LANCASTER // https://www.iana.org/domains/root/db/lancaster.html lancaster // land : Binky Moon, LLC // https://www.iana.org/domains/root/db/land.html land // landrover : Jaguar Land Rover Ltd // https://www.iana.org/domains/root/db/landrover.html landrover // lanxess : LANXESS Corporation // https://www.iana.org/domains/root/db/lanxess.html lanxess // lasalle : Jones Lang LaSalle Incorporated // https://www.iana.org/domains/root/db/lasalle.html lasalle // lat : XYZ.COM LLC // https://www.iana.org/domains/root/db/lat.html lat // latino : Dish DBS Corporation // https://www.iana.org/domains/root/db/latino.html latino // latrobe : La Trobe University // https://www.iana.org/domains/root/db/latrobe.html latrobe // law : Registry Services, LLC // https://www.iana.org/domains/root/db/law.html law // lawyer : Dog Beach, LLC // https://www.iana.org/domains/root/db/lawyer.html lawyer // lds : IRI Domain Management, LLC // https://www.iana.org/domains/root/db/lds.html lds // lease : Binky Moon, LLC // https://www.iana.org/domains/root/db/lease.html lease // leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc // https://www.iana.org/domains/root/db/leclerc.html leclerc // lefrak : LeFrak Organization, Inc. // https://www.iana.org/domains/root/db/lefrak.html lefrak // legal : Binky Moon, LLC // https://www.iana.org/domains/root/db/legal.html legal // lego : LEGO Juris A/S // https://www.iana.org/domains/root/db/lego.html lego // lexus : TOYOTA MOTOR CORPORATION // https://www.iana.org/domains/root/db/lexus.html lexus // lgbt : Identity Digital Limited // https://www.iana.org/domains/root/db/lgbt.html lgbt // lidl : Schwarz Domains und Services GmbH & Co. KG // https://www.iana.org/domains/root/db/lidl.html lidl // life : Binky Moon, LLC // https://www.iana.org/domains/root/db/life.html life // lifeinsurance : American Council of Life Insurers // https://www.iana.org/domains/root/db/lifeinsurance.html lifeinsurance // lifestyle : Internet Naming Company LLC // https://www.iana.org/domains/root/db/lifestyle.html lifestyle // lighting : Binky Moon, LLC // https://www.iana.org/domains/root/db/lighting.html lighting // like : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/like.html like // lilly : Eli Lilly and Company // https://www.iana.org/domains/root/db/lilly.html lilly // limited : Binky Moon, LLC // https://www.iana.org/domains/root/db/limited.html limited // limo : Binky Moon, LLC // https://www.iana.org/domains/root/db/limo.html limo // lincoln : Ford Motor Company // https://www.iana.org/domains/root/db/lincoln.html lincoln // link : Nova Registry Ltd // https://www.iana.org/domains/root/db/link.html link // lipsy : Lipsy Ltd // https://www.iana.org/domains/root/db/lipsy.html lipsy // live : Dog Beach, LLC // https://www.iana.org/domains/root/db/live.html live // living : Internet Naming Company LLC // https://www.iana.org/domains/root/db/living.html living // llc : Identity Digital Limited // https://www.iana.org/domains/root/db/llc.html llc // llp : Intercap Registry Inc. // https://www.iana.org/domains/root/db/llp.html llp // loan : dot Loan Limited // https://www.iana.org/domains/root/db/loan.html loan // loans : Binky Moon, LLC // https://www.iana.org/domains/root/db/loans.html loans // locker : Orange Domains LLC // https://www.iana.org/domains/root/db/locker.html locker // locus : Locus Analytics LLC // https://www.iana.org/domains/root/db/locus.html locus // lol : XYZ.COM LLC // https://www.iana.org/domains/root/db/lol.html lol // london : Dot London Domains Limited // https://www.iana.org/domains/root/db/london.html london // lotte : Lotte Holdings Co., Ltd. // https://www.iana.org/domains/root/db/lotte.html lotte // lotto : Identity Digital Limited // https://www.iana.org/domains/root/db/lotto.html lotto // love : Merchant Law Group LLP // https://www.iana.org/domains/root/db/love.html love // lpl : LPL Holdings, Inc. // https://www.iana.org/domains/root/db/lpl.html lpl // lplfinancial : LPL Holdings, Inc. // https://www.iana.org/domains/root/db/lplfinancial.html lplfinancial // ltd : Binky Moon, LLC // https://www.iana.org/domains/root/db/ltd.html ltd // ltda : InterNetX, Corp // https://www.iana.org/domains/root/db/ltda.html ltda // lundbeck : H. Lundbeck A/S // https://www.iana.org/domains/root/db/lundbeck.html lundbeck // luxe : Registry Services, LLC // https://www.iana.org/domains/root/db/luxe.html luxe // luxury : Luxury Partners, LLC // https://www.iana.org/domains/root/db/luxury.html luxury // madrid : Comunidad de Madrid // https://www.iana.org/domains/root/db/madrid.html madrid // maif : Mutuelle Assurance Instituteur France (MAIF) // https://www.iana.org/domains/root/db/maif.html maif // maison : Binky Moon, LLC // https://www.iana.org/domains/root/db/maison.html maison // makeup : XYZ.COM LLC // https://www.iana.org/domains/root/db/makeup.html makeup // man : MAN SE // https://www.iana.org/domains/root/db/man.html man // management : Binky Moon, LLC // https://www.iana.org/domains/root/db/management.html management // mango : PUNTO FA S.L. // https://www.iana.org/domains/root/db/mango.html mango // map : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/map.html map // market : Dog Beach, LLC // https://www.iana.org/domains/root/db/market.html market // marketing : Binky Moon, LLC // https://www.iana.org/domains/root/db/marketing.html marketing // markets : Dog Beach, LLC // https://www.iana.org/domains/root/db/markets.html markets // marriott : Marriott Worldwide Corporation // https://www.iana.org/domains/root/db/marriott.html marriott // marshalls : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/marshalls.html marshalls // mattel : Mattel Sites, Inc. // https://www.iana.org/domains/root/db/mattel.html mattel // mba : Binky Moon, LLC // https://www.iana.org/domains/root/db/mba.html mba // mckinsey : McKinsey Holdings, Inc. // https://www.iana.org/domains/root/db/mckinsey.html mckinsey // med : Medistry LLC // https://www.iana.org/domains/root/db/med.html med // media : Binky Moon, LLC // https://www.iana.org/domains/root/db/media.html media // meet : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/meet.html meet // melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation // https://www.iana.org/domains/root/db/melbourne.html melbourne // meme : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/meme.html meme // memorial : Dog Beach, LLC // https://www.iana.org/domains/root/db/memorial.html memorial // men : Exclusive Registry Limited // https://www.iana.org/domains/root/db/men.html men // menu : Dot Menu Registry, LLC // https://www.iana.org/domains/root/db/menu.html menu // merckmsd : MSD Registry Holdings, Inc. // https://www.iana.org/domains/root/db/merckmsd.html merckmsd // miami : Registry Services, LLC // https://www.iana.org/domains/root/db/miami.html miami // microsoft : Microsoft Corporation // https://www.iana.org/domains/root/db/microsoft.html microsoft // mini : Bayerische Motoren Werke Aktiengesellschaft // https://www.iana.org/domains/root/db/mini.html mini // mint : Intuit Administrative Services, Inc. // https://www.iana.org/domains/root/db/mint.html mint // mit : Massachusetts Institute of Technology // https://www.iana.org/domains/root/db/mit.html mit // mitsubishi : Mitsubishi Corporation // https://www.iana.org/domains/root/db/mitsubishi.html mitsubishi // mlb : MLB Advanced Media DH, LLC // https://www.iana.org/domains/root/db/mlb.html mlb // mls : The Canadian Real Estate Association // https://www.iana.org/domains/root/db/mls.html mls // mma : MMA IARD // https://www.iana.org/domains/root/db/mma.html mma // mobile : Dish DBS Corporation // https://www.iana.org/domains/root/db/mobile.html mobile // moda : Dog Beach, LLC // https://www.iana.org/domains/root/db/moda.html moda // moe : Interlink Systems Innovation Institute K.K. // https://www.iana.org/domains/root/db/moe.html moe // moi : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/moi.html moi // mom : XYZ.COM LLC // https://www.iana.org/domains/root/db/mom.html mom // monash : Monash University // https://www.iana.org/domains/root/db/monash.html monash // money : Binky Moon, LLC // https://www.iana.org/domains/root/db/money.html money // monster : XYZ.COM LLC // https://www.iana.org/domains/root/db/monster.html monster // mormon : IRI Domain Management, LLC // https://www.iana.org/domains/root/db/mormon.html mormon // mortgage : Dog Beach, LLC // https://www.iana.org/domains/root/db/mortgage.html mortgage // moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) // https://www.iana.org/domains/root/db/moscow.html moscow // moto : Motorola Trademark Holdings, LLC // https://www.iana.org/domains/root/db/moto.html moto // motorcycles : XYZ.COM LLC // https://www.iana.org/domains/root/db/motorcycles.html motorcycles // mov : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/mov.html mov // movie : Binky Moon, LLC // https://www.iana.org/domains/root/db/movie.html movie // msd : MSD Registry Holdings, Inc. // https://www.iana.org/domains/root/db/msd.html msd // mtn : MTN Dubai Limited // https://www.iana.org/domains/root/db/mtn.html mtn // mtr : MTR Corporation Limited // https://www.iana.org/domains/root/db/mtr.html mtr // music : DotMusic Limited // https://www.iana.org/domains/root/db/music.html music // nab : National Australia Bank Limited // https://www.iana.org/domains/root/db/nab.html nab // nagoya : GMO Registry, Inc. // https://www.iana.org/domains/root/db/nagoya.html nagoya // natura : NATURA COSMÉTICOS S.A. // https://www.iana.org/domains/root/db/natura.html natura // navy : Dog Beach, LLC // https://www.iana.org/domains/root/db/navy.html navy // nba : NBA REGISTRY, LLC // https://www.iana.org/domains/root/db/nba.html nba // nec : NEC Corporation // https://www.iana.org/domains/root/db/nec.html nec // netbank : COMMONWEALTH BANK OF AUSTRALIA // https://www.iana.org/domains/root/db/netbank.html netbank // netflix : Netflix, Inc. // https://www.iana.org/domains/root/db/netflix.html netflix // network : Binky Moon, LLC // https://www.iana.org/domains/root/db/network.html network // neustar : NeuStar, Inc. // https://www.iana.org/domains/root/db/neustar.html neustar // new : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/new.html new // news : Dog Beach, LLC // https://www.iana.org/domains/root/db/news.html news // next : Next plc // https://www.iana.org/domains/root/db/next.html next // nextdirect : Next plc // https://www.iana.org/domains/root/db/nextdirect.html nextdirect // nexus : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/nexus.html nexus // nfl : NFL Reg Ops LLC // https://www.iana.org/domains/root/db/nfl.html nfl // ngo : Public Interest Registry // https://www.iana.org/domains/root/db/ngo.html ngo // nhk : Japan Broadcasting Corporation (NHK) // https://www.iana.org/domains/root/db/nhk.html nhk // nico : DWANGO Co., Ltd. // https://www.iana.org/domains/root/db/nico.html nico // nike : NIKE, Inc. // https://www.iana.org/domains/root/db/nike.html nike // nikon : NIKON CORPORATION // https://www.iana.org/domains/root/db/nikon.html nikon // ninja : Dog Beach, LLC // https://www.iana.org/domains/root/db/ninja.html ninja // nissan : NISSAN MOTOR CO., LTD. // https://www.iana.org/domains/root/db/nissan.html nissan // nissay : Nippon Life Insurance Company // https://www.iana.org/domains/root/db/nissay.html nissay // nokia : Nokia Corporation // https://www.iana.org/domains/root/db/nokia.html nokia // norton : NortonLifeLock Inc. // https://www.iana.org/domains/root/db/norton.html norton // now : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/now.html now // nowruz : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. // https://www.iana.org/domains/root/db/nowruz.html nowruz // nowtv : Starbucks (HK) Limited // https://www.iana.org/domains/root/db/nowtv.html nowtv // nra : NRA Holdings Company, INC. // https://www.iana.org/domains/root/db/nra.html nra // nrw : Minds + Machines GmbH // https://www.iana.org/domains/root/db/nrw.html nrw // ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION // https://www.iana.org/domains/root/db/ntt.html ntt // nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications // https://www.iana.org/domains/root/db/nyc.html nyc // obi : OBI Group Holding SE & Co. KGaA // https://www.iana.org/domains/root/db/obi.html obi // observer : Fegistry, LLC // https://www.iana.org/domains/root/db/observer.html observer // office : Microsoft Corporation // https://www.iana.org/domains/root/db/office.html office // okinawa : BRregistry, Inc. // https://www.iana.org/domains/root/db/okinawa.html okinawa // olayan : Competrol (Luxembourg) Sarl // https://www.iana.org/domains/root/db/olayan.html olayan // olayangroup : Competrol (Luxembourg) Sarl // https://www.iana.org/domains/root/db/olayangroup.html olayangroup // oldnavy : The Gap, Inc. // https://www.iana.org/domains/root/db/oldnavy.html oldnavy // ollo : Dish DBS Corporation // https://www.iana.org/domains/root/db/ollo.html ollo // omega : The Swatch Group Ltd // https://www.iana.org/domains/root/db/omega.html omega // one : One.com A/S // https://www.iana.org/domains/root/db/one.html one // ong : Public Interest Registry // https://www.iana.org/domains/root/db/ong.html ong // onl : iRegistry GmbH // https://www.iana.org/domains/root/db/onl.html onl // online : Radix FZC DMCC // https://www.iana.org/domains/root/db/online.html online // ooo : INFIBEAM AVENUES LIMITED // https://www.iana.org/domains/root/db/ooo.html ooo // open : American Express Travel Related Services Company, Inc. // https://www.iana.org/domains/root/db/open.html open // oracle : Oracle Corporation // https://www.iana.org/domains/root/db/oracle.html oracle // orange : Orange Brand Services Limited // https://www.iana.org/domains/root/db/orange.html orange // organic : Identity Digital Limited // https://www.iana.org/domains/root/db/organic.html organic // origins : The Estée Lauder Companies Inc. // https://www.iana.org/domains/root/db/origins.html origins // osaka : Osaka Registry Co., Ltd. // https://www.iana.org/domains/root/db/osaka.html osaka // otsuka : Otsuka Holdings Co., Ltd. // https://www.iana.org/domains/root/db/otsuka.html otsuka // ott : Dish DBS Corporation // https://www.iana.org/domains/root/db/ott.html ott // ovh : MédiaBC // https://www.iana.org/domains/root/db/ovh.html ovh // page : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/page.html page // panasonic : Panasonic Holdings Corporation // https://www.iana.org/domains/root/db/panasonic.html panasonic // paris : City of Paris // https://www.iana.org/domains/root/db/paris.html paris // pars : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. // https://www.iana.org/domains/root/db/pars.html pars // partners : Binky Moon, LLC // https://www.iana.org/domains/root/db/partners.html partners // parts : Binky Moon, LLC // https://www.iana.org/domains/root/db/parts.html parts // party : Blue Sky Registry Limited // https://www.iana.org/domains/root/db/party.html party // pay : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/pay.html pay // pccw : PCCW Enterprises Limited // https://www.iana.org/domains/root/db/pccw.html pccw // pet : Identity Digital Limited // https://www.iana.org/domains/root/db/pet.html pet // pfizer : Pfizer Inc. // https://www.iana.org/domains/root/db/pfizer.html pfizer // pharmacy : National Association of Boards of Pharmacy // https://www.iana.org/domains/root/db/pharmacy.html pharmacy // phd : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/phd.html phd // philips : Koninklijke Philips N.V. // https://www.iana.org/domains/root/db/philips.html philips // phone : Dish DBS Corporation // https://www.iana.org/domains/root/db/phone.html phone // photo : Registry Services, LLC // https://www.iana.org/domains/root/db/photo.html photo // photography : Binky Moon, LLC // https://www.iana.org/domains/root/db/photography.html photography // photos : Binky Moon, LLC // https://www.iana.org/domains/root/db/photos.html photos // physio : PhysBiz Pty Ltd // https://www.iana.org/domains/root/db/physio.html physio // pics : XYZ.COM LLC // https://www.iana.org/domains/root/db/pics.html pics // pictet : Pictet Europe S.A. // https://www.iana.org/domains/root/db/pictet.html pictet // pictures : Binky Moon, LLC // https://www.iana.org/domains/root/db/pictures.html pictures // pid : Top Level Spectrum, Inc. // https://www.iana.org/domains/root/db/pid.html pid // pin : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/pin.html pin // ping : Ping Registry Provider, Inc. // https://www.iana.org/domains/root/db/ping.html ping // pink : Identity Digital Limited // https://www.iana.org/domains/root/db/pink.html pink // pioneer : Pioneer Corporation // https://www.iana.org/domains/root/db/pioneer.html pioneer // pizza : Binky Moon, LLC // https://www.iana.org/domains/root/db/pizza.html pizza // place : Binky Moon, LLC // https://www.iana.org/domains/root/db/place.html place // play : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/play.html play // playstation : Sony Interactive Entertainment Inc. // https://www.iana.org/domains/root/db/playstation.html playstation // plumbing : Binky Moon, LLC // https://www.iana.org/domains/root/db/plumbing.html plumbing // plus : Binky Moon, LLC // https://www.iana.org/domains/root/db/plus.html plus // pnc : PNC Domain Co., LLC // https://www.iana.org/domains/root/db/pnc.html pnc // pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/pohl.html pohl // poker : Identity Digital Limited // https://www.iana.org/domains/root/db/poker.html poker // politie : Politie Nederland // https://www.iana.org/domains/root/db/politie.html politie // porn : ICM Registry PN LLC // https://www.iana.org/domains/root/db/porn.html porn // pramerica : Prudential Financial, Inc. // https://www.iana.org/domains/root/db/pramerica.html pramerica // praxi : Praxi S.p.A. // https://www.iana.org/domains/root/db/praxi.html praxi // press : Radix FZC DMCC // https://www.iana.org/domains/root/db/press.html press // prime : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/prime.html prime // prod : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/prod.html prod // productions : Binky Moon, LLC // https://www.iana.org/domains/root/db/productions.html productions // prof : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/prof.html prof // progressive : Progressive Casualty Insurance Company // https://www.iana.org/domains/root/db/progressive.html progressive // promo : Identity Digital Limited // https://www.iana.org/domains/root/db/promo.html promo // properties : Binky Moon, LLC // https://www.iana.org/domains/root/db/properties.html properties // property : Digital Property Infrastructure Limited // https://www.iana.org/domains/root/db/property.html property // protection : XYZ.COM LLC // https://www.iana.org/domains/root/db/protection.html protection // pru : Prudential Financial, Inc. // https://www.iana.org/domains/root/db/pru.html pru // prudential : Prudential Financial, Inc. // https://www.iana.org/domains/root/db/prudential.html prudential // pub : Dog Beach, LLC // https://www.iana.org/domains/root/db/pub.html pub // pwc : PricewaterhouseCoopers LLP // https://www.iana.org/domains/root/db/pwc.html pwc // qpon : dotQPON LLC // https://www.iana.org/domains/root/db/qpon.html qpon // quebec : PointQuébec Inc // https://www.iana.org/domains/root/db/quebec.html quebec // quest : XYZ.COM LLC // https://www.iana.org/domains/root/db/quest.html quest // racing : Premier Registry Limited // https://www.iana.org/domains/root/db/racing.html racing // radio : European Broadcasting Union (EBU) // https://www.iana.org/domains/root/db/radio.html radio // read : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/read.html read // realestate : dotRealEstate LLC // https://www.iana.org/domains/root/db/realestate.html realestate // realtor : Real Estate Domains LLC // https://www.iana.org/domains/root/db/realtor.html realtor // realty : Internet Naming Company LLC // https://www.iana.org/domains/root/db/realty.html realty // recipes : Binky Moon, LLC // https://www.iana.org/domains/root/db/recipes.html recipes // red : Identity Digital Limited // https://www.iana.org/domains/root/db/red.html red // redstone : Redstone Haute Couture Co., Ltd. // https://www.iana.org/domains/root/db/redstone.html redstone // redumbrella : Travelers TLD, LLC // https://www.iana.org/domains/root/db/redumbrella.html redumbrella // rehab : Dog Beach, LLC // https://www.iana.org/domains/root/db/rehab.html rehab // reise : Binky Moon, LLC // https://www.iana.org/domains/root/db/reise.html reise // reisen : Binky Moon, LLC // https://www.iana.org/domains/root/db/reisen.html reisen // reit : National Association of Real Estate Investment Trusts, Inc. // https://www.iana.org/domains/root/db/reit.html reit // reliance : Reliance Industries Limited // https://www.iana.org/domains/root/db/reliance.html reliance // ren : ZDNS International Limited // https://www.iana.org/domains/root/db/ren.html ren // rent : XYZ.COM LLC // https://www.iana.org/domains/root/db/rent.html rent // rentals : Binky Moon, LLC // https://www.iana.org/domains/root/db/rentals.html rentals // repair : Binky Moon, LLC // https://www.iana.org/domains/root/db/repair.html repair // report : Binky Moon, LLC // https://www.iana.org/domains/root/db/report.html report // republican : Dog Beach, LLC // https://www.iana.org/domains/root/db/republican.html republican // rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable // https://www.iana.org/domains/root/db/rest.html rest // restaurant : Binky Moon, LLC // https://www.iana.org/domains/root/db/restaurant.html restaurant // review : dot Review Limited // https://www.iana.org/domains/root/db/review.html review // reviews : Dog Beach, LLC // https://www.iana.org/domains/root/db/reviews.html reviews // rexroth : Robert Bosch GMBH // https://www.iana.org/domains/root/db/rexroth.html rexroth // rich : iRegistry GmbH // https://www.iana.org/domains/root/db/rich.html rich // richardli : Pacific Century Asset Management (HK) Limited // https://www.iana.org/domains/root/db/richardli.html richardli // ricoh : Ricoh Company, Ltd. // https://www.iana.org/domains/root/db/ricoh.html ricoh // ril : Reliance Industries Limited // https://www.iana.org/domains/root/db/ril.html ril // rio : Empresa Municipal de Informática SA - IPLANRIO // https://www.iana.org/domains/root/db/rio.html rio // rip : Dog Beach, LLC // https://www.iana.org/domains/root/db/rip.html rip // rocks : Dog Beach, LLC // https://www.iana.org/domains/root/db/rocks.html rocks // rodeo : Registry Services, LLC // https://www.iana.org/domains/root/db/rodeo.html rodeo // rogers : Rogers Communications Canada Inc. // https://www.iana.org/domains/root/db/rogers.html rogers // room : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/room.html room // rsvp : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/rsvp.html rsvp // rugby : World Rugby Strategic Developments Limited // https://www.iana.org/domains/root/db/rugby.html rugby // ruhr : dotSaarland GmbH // https://www.iana.org/domains/root/db/ruhr.html ruhr // run : Binky Moon, LLC // https://www.iana.org/domains/root/db/run.html run // rwe : RWE AG // https://www.iana.org/domains/root/db/rwe.html rwe // ryukyu : BRregistry, Inc. // https://www.iana.org/domains/root/db/ryukyu.html ryukyu // saarland : dotSaarland GmbH // https://www.iana.org/domains/root/db/saarland.html saarland // safe : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/safe.html safe // safety : Safety Registry Services, LLC. // https://www.iana.org/domains/root/db/safety.html safety // sakura : SAKURA Internet Inc. // https://www.iana.org/domains/root/db/sakura.html sakura // sale : Dog Beach, LLC // https://www.iana.org/domains/root/db/sale.html sale // salon : Binky Moon, LLC // https://www.iana.org/domains/root/db/salon.html salon // samsclub : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/samsclub.html samsclub // samsung : SAMSUNG SDS CO., LTD // https://www.iana.org/domains/root/db/samsung.html samsung // sandvik : Sandvik AB // https://www.iana.org/domains/root/db/sandvik.html sandvik // sandvikcoromant : Sandvik AB // https://www.iana.org/domains/root/db/sandvikcoromant.html sandvikcoromant // sanofi : Sanofi // https://www.iana.org/domains/root/db/sanofi.html sanofi // sap : SAP AG // https://www.iana.org/domains/root/db/sap.html sap // sarl : Binky Moon, LLC // https://www.iana.org/domains/root/db/sarl.html sarl // sas : Research IP LLC // https://www.iana.org/domains/root/db/sas.html sas // save : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/save.html save // saxo : Saxo Bank A/S // https://www.iana.org/domains/root/db/saxo.html saxo // sbi : STATE BANK OF INDIA // https://www.iana.org/domains/root/db/sbi.html sbi // sbs : ShortDot SA // https://www.iana.org/domains/root/db/sbs.html sbs // scb : The Siam Commercial Bank Public Company Limited ("SCB") // https://www.iana.org/domains/root/db/scb.html scb // schaeffler : Schaeffler Technologies AG & Co. KG // https://www.iana.org/domains/root/db/schaeffler.html schaeffler // schmidt : SCHMIDT GROUPE S.A.S. // https://www.iana.org/domains/root/db/schmidt.html schmidt // scholarships : Scholarships.com, LLC // https://www.iana.org/domains/root/db/scholarships.html scholarships // school : Binky Moon, LLC // https://www.iana.org/domains/root/db/school.html school // schule : Binky Moon, LLC // https://www.iana.org/domains/root/db/schule.html schule // schwarz : Schwarz Domains und Services GmbH & Co. KG // https://www.iana.org/domains/root/db/schwarz.html schwarz // science : dot Science Limited // https://www.iana.org/domains/root/db/science.html science // scot : Dot Scot Registry Limited // https://www.iana.org/domains/root/db/scot.html scot // search : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/search.html search // seat : SEAT, S.A. (Sociedad Unipersonal) // https://www.iana.org/domains/root/db/seat.html seat // secure : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/secure.html secure // security : XYZ.COM LLC // https://www.iana.org/domains/root/db/security.html security // seek : Seek Limited // https://www.iana.org/domains/root/db/seek.html seek // select : Registry Services, LLC // https://www.iana.org/domains/root/db/select.html select // sener : Sener Ingeniería y Sistemas, S.A. // https://www.iana.org/domains/root/db/sener.html sener // services : Binky Moon, LLC // https://www.iana.org/domains/root/db/services.html services // seven : Seven West Media Ltd // https://www.iana.org/domains/root/db/seven.html seven // sew : SEW-EURODRIVE GmbH & Co KG // https://www.iana.org/domains/root/db/sew.html sew // sex : ICM Registry SX LLC // https://www.iana.org/domains/root/db/sex.html sex // sexy : Internet Naming Company LLC // https://www.iana.org/domains/root/db/sexy.html sexy // sfr : Societe Francaise du Radiotelephone - SFR // https://www.iana.org/domains/root/db/sfr.html sfr // shangrila : Shangri‐La International Hotel Management Limited // https://www.iana.org/domains/root/db/shangrila.html shangrila // sharp : Sharp Corporation // https://www.iana.org/domains/root/db/sharp.html sharp // shaw : Shaw Cablesystems G.P. // https://www.iana.org/domains/root/db/shaw.html shaw // shell : Shell Information Technology International Inc // https://www.iana.org/domains/root/db/shell.html shell // shia : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. // https://www.iana.org/domains/root/db/shia.html shia // shiksha : Identity Digital Limited // https://www.iana.org/domains/root/db/shiksha.html shiksha // shoes : Binky Moon, LLC // https://www.iana.org/domains/root/db/shoes.html shoes // shop : GMO Registry, Inc. // https://www.iana.org/domains/root/db/shop.html shop // shopping : Binky Moon, LLC // https://www.iana.org/domains/root/db/shopping.html shopping // shouji : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/shouji.html shouji // show : Binky Moon, LLC // https://www.iana.org/domains/root/db/show.html show // silk : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/silk.html silk // sina : Sina Corporation // https://www.iana.org/domains/root/db/sina.html sina // singles : Binky Moon, LLC // https://www.iana.org/domains/root/db/singles.html singles // site : Radix FZC DMCC // https://www.iana.org/domains/root/db/site.html site // ski : Identity Digital Limited // https://www.iana.org/domains/root/db/ski.html ski // skin : XYZ.COM LLC // https://www.iana.org/domains/root/db/skin.html skin // sky : Sky International AG // https://www.iana.org/domains/root/db/sky.html sky // skype : Microsoft Corporation // https://www.iana.org/domains/root/db/skype.html skype // sling : DISH Technologies L.L.C. // https://www.iana.org/domains/root/db/sling.html sling // smart : Smart Communications, Inc. (SMART) // https://www.iana.org/domains/root/db/smart.html smart // smile : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/smile.html smile // sncf : Société Nationale SNCF // https://www.iana.org/domains/root/db/sncf.html sncf // soccer : Binky Moon, LLC // https://www.iana.org/domains/root/db/soccer.html soccer // social : Dog Beach, LLC // https://www.iana.org/domains/root/db/social.html social // softbank : SoftBank Group Corp. // https://www.iana.org/domains/root/db/softbank.html softbank // software : Dog Beach, LLC // https://www.iana.org/domains/root/db/software.html software // sohu : Sohu.com Limited // https://www.iana.org/domains/root/db/sohu.html sohu // solar : Binky Moon, LLC // https://www.iana.org/domains/root/db/solar.html solar // solutions : Binky Moon, LLC // https://www.iana.org/domains/root/db/solutions.html solutions // song : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/song.html song // sony : Sony Corporation // https://www.iana.org/domains/root/db/sony.html sony // soy : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/soy.html soy // spa : Asia Spa and Wellness Promotion Council Limited // https://www.iana.org/domains/root/db/spa.html spa // space : Radix FZC DMCC // https://www.iana.org/domains/root/db/space.html space // sport : SportAccord // https://www.iana.org/domains/root/db/sport.html sport // spot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/spot.html spot // srl : InterNetX, Corp // https://www.iana.org/domains/root/db/srl.html srl // stada : STADA Arzneimittel AG // https://www.iana.org/domains/root/db/stada.html stada // staples : Staples, Inc. // https://www.iana.org/domains/root/db/staples.html staples // star : Star India Private Limited // https://www.iana.org/domains/root/db/star.html star // statebank : STATE BANK OF INDIA // https://www.iana.org/domains/root/db/statebank.html statebank // statefarm : State Farm Mutual Automobile Insurance Company // https://www.iana.org/domains/root/db/statefarm.html statefarm // stc : Saudi Telecom Company // https://www.iana.org/domains/root/db/stc.html stc // stcgroup : Saudi Telecom Company // https://www.iana.org/domains/root/db/stcgroup.html stcgroup // stockholm : Stockholms kommun // https://www.iana.org/domains/root/db/stockholm.html stockholm // storage : XYZ.COM LLC // https://www.iana.org/domains/root/db/storage.html storage // store : Radix FZC DMCC // https://www.iana.org/domains/root/db/store.html store // stream : dot Stream Limited // https://www.iana.org/domains/root/db/stream.html stream // studio : Dog Beach, LLC // https://www.iana.org/domains/root/db/studio.html studio // study : Registry Services, LLC // https://www.iana.org/domains/root/db/study.html study // style : Binky Moon, LLC // https://www.iana.org/domains/root/db/style.html style // sucks : Vox Populi Registry Ltd. // https://www.iana.org/domains/root/db/sucks.html sucks // supplies : Binky Moon, LLC // https://www.iana.org/domains/root/db/supplies.html supplies // supply : Binky Moon, LLC // https://www.iana.org/domains/root/db/supply.html supply // support : Binky Moon, LLC // https://www.iana.org/domains/root/db/support.html support // surf : Registry Services, LLC // https://www.iana.org/domains/root/db/surf.html surf // surgery : Binky Moon, LLC // https://www.iana.org/domains/root/db/surgery.html surgery // suzuki : SUZUKI MOTOR CORPORATION // https://www.iana.org/domains/root/db/suzuki.html suzuki // swatch : The Swatch Group Ltd // https://www.iana.org/domains/root/db/swatch.html swatch // swiss : Swiss Confederation // https://www.iana.org/domains/root/db/swiss.html swiss // sydney : State of New South Wales, Department of Premier and Cabinet // https://www.iana.org/domains/root/db/sydney.html sydney // systems : Binky Moon, LLC // https://www.iana.org/domains/root/db/systems.html systems // tab : Tabcorp Holdings Limited // https://www.iana.org/domains/root/db/tab.html tab // taipei : Taipei City Government // https://www.iana.org/domains/root/db/taipei.html taipei // talk : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/talk.html talk // taobao : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/taobao.html taobao // target : Target Domain Holdings, LLC // https://www.iana.org/domains/root/db/target.html target // tatamotors : Tata Motors Ltd // https://www.iana.org/domains/root/db/tatamotors.html tatamotors // tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" // https://www.iana.org/domains/root/db/tatar.html tatar // tattoo : Registry Services, LLC // https://www.iana.org/domains/root/db/tattoo.html tattoo // tax : Binky Moon, LLC // https://www.iana.org/domains/root/db/tax.html tax // taxi : Binky Moon, LLC // https://www.iana.org/domains/root/db/taxi.html taxi // tci : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. // https://www.iana.org/domains/root/db/tci.html tci // tdk : TDK Corporation // https://www.iana.org/domains/root/db/tdk.html tdk // team : Binky Moon, LLC // https://www.iana.org/domains/root/db/team.html team // tech : Radix FZC DMCC // https://www.iana.org/domains/root/db/tech.html tech // technology : Binky Moon, LLC // https://www.iana.org/domains/root/db/technology.html technology // temasek : Temasek Holdings (Private) Limited // https://www.iana.org/domains/root/db/temasek.html temasek // tennis : Binky Moon, LLC // https://www.iana.org/domains/root/db/tennis.html tennis // teva : Teva Pharmaceutical Industries Limited // https://www.iana.org/domains/root/db/teva.html teva // thd : Home Depot Product Authority, LLC // https://www.iana.org/domains/root/db/thd.html thd // theater : Binky Moon, LLC // https://www.iana.org/domains/root/db/theater.html theater // theatre : XYZ.COM LLC // https://www.iana.org/domains/root/db/theatre.html theatre // tiaa : Teachers Insurance and Annuity Association of America // https://www.iana.org/domains/root/db/tiaa.html tiaa // tickets : XYZ.COM LLC // https://www.iana.org/domains/root/db/tickets.html tickets // tienda : Binky Moon, LLC // https://www.iana.org/domains/root/db/tienda.html tienda // tips : Binky Moon, LLC // https://www.iana.org/domains/root/db/tips.html tips // tires : Binky Moon, LLC // https://www.iana.org/domains/root/db/tires.html tires // tirol : punkt Tirol GmbH // https://www.iana.org/domains/root/db/tirol.html tirol // tjmaxx : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/tjmaxx.html tjmaxx // tjx : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/tjx.html tjx // tkmaxx : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/tkmaxx.html tkmaxx // tmall : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/tmall.html tmall // today : Binky Moon, LLC // https://www.iana.org/domains/root/db/today.html today // tokyo : GMO Registry, Inc. // https://www.iana.org/domains/root/db/tokyo.html tokyo // tools : Binky Moon, LLC // https://www.iana.org/domains/root/db/tools.html tools // top : .TOP Registry // https://www.iana.org/domains/root/db/top.html top // toray : Toray Industries, Inc. // https://www.iana.org/domains/root/db/toray.html toray // toshiba : TOSHIBA Corporation // https://www.iana.org/domains/root/db/toshiba.html toshiba // total : TotalEnergies SE // https://www.iana.org/domains/root/db/total.html total // tours : Binky Moon, LLC // https://www.iana.org/domains/root/db/tours.html tours // town : Binky Moon, LLC // https://www.iana.org/domains/root/db/town.html town // toyota : TOYOTA MOTOR CORPORATION // https://www.iana.org/domains/root/db/toyota.html toyota // toys : Binky Moon, LLC // https://www.iana.org/domains/root/db/toys.html toys // trade : Elite Registry Limited // https://www.iana.org/domains/root/db/trade.html trade // trading : Dog Beach, LLC // https://www.iana.org/domains/root/db/trading.html trading // training : Binky Moon, LLC // https://www.iana.org/domains/root/db/training.html training // travel : Dog Beach, LLC // https://www.iana.org/domains/root/db/travel.html travel // travelers : Travelers TLD, LLC // https://www.iana.org/domains/root/db/travelers.html travelers // travelersinsurance : Travelers TLD, LLC // https://www.iana.org/domains/root/db/travelersinsurance.html travelersinsurance // trust : Internet Naming Company LLC // https://www.iana.org/domains/root/db/trust.html trust // trv : Travelers TLD, LLC // https://www.iana.org/domains/root/db/trv.html trv // tube : Latin American Telecom LLC // https://www.iana.org/domains/root/db/tube.html tube // tui : TUI AG // https://www.iana.org/domains/root/db/tui.html tui // tunes : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/tunes.html tunes // tushu : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/tushu.html tushu // tvs : T V SUNDRAM IYENGAR & SONS LIMITED // https://www.iana.org/domains/root/db/tvs.html tvs // ubank : National Australia Bank Limited // https://www.iana.org/domains/root/db/ubank.html ubank // ubs : UBS AG // https://www.iana.org/domains/root/db/ubs.html ubs // unicom : China United Network Communications Corporation Limited // https://www.iana.org/domains/root/db/unicom.html unicom // university : Binky Moon, LLC // https://www.iana.org/domains/root/db/university.html university // uno : Radix FZC DMCC // https://www.iana.org/domains/root/db/uno.html uno // uol : UBN INTERNET LTDA. // https://www.iana.org/domains/root/db/uol.html uol // ups : UPS Market Driver, Inc. // https://www.iana.org/domains/root/db/ups.html ups // vacations : Binky Moon, LLC // https://www.iana.org/domains/root/db/vacations.html vacations // vana : Internet Naming Company LLC // https://www.iana.org/domains/root/db/vana.html vana // vanguard : The Vanguard Group, Inc. // https://www.iana.org/domains/root/db/vanguard.html vanguard // vegas : Dot Vegas, Inc. // https://www.iana.org/domains/root/db/vegas.html vegas // ventures : Binky Moon, LLC // https://www.iana.org/domains/root/db/ventures.html ventures // verisign : VeriSign, Inc. // https://www.iana.org/domains/root/db/verisign.html verisign // versicherung : tldbox GmbH // https://www.iana.org/domains/root/db/versicherung.html versicherung // vet : Dog Beach, LLC // https://www.iana.org/domains/root/db/vet.html vet // viajes : Binky Moon, LLC // https://www.iana.org/domains/root/db/viajes.html viajes // video : Dog Beach, LLC // https://www.iana.org/domains/root/db/video.html video // vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe // https://www.iana.org/domains/root/db/vig.html vig // viking : Viking River Cruises (Bermuda) Ltd. // https://www.iana.org/domains/root/db/viking.html viking // villas : Binky Moon, LLC // https://www.iana.org/domains/root/db/villas.html villas // vin : Binky Moon, LLC // https://www.iana.org/domains/root/db/vin.html vin // vip : Registry Services, LLC // https://www.iana.org/domains/root/db/vip.html vip // virgin : Virgin Enterprises Limited // https://www.iana.org/domains/root/db/virgin.html virgin // visa : Visa Worldwide Pte. Limited // https://www.iana.org/domains/root/db/visa.html visa // vision : Binky Moon, LLC // https://www.iana.org/domains/root/db/vision.html vision // viva : Saudi Telecom Company // https://www.iana.org/domains/root/db/viva.html viva // vivo : Telefonica Brasil S.A. // https://www.iana.org/domains/root/db/vivo.html vivo // vlaanderen : DNS.be vzw // https://www.iana.org/domains/root/db/vlaanderen.html vlaanderen // vodka : Registry Services, LLC // https://www.iana.org/domains/root/db/vodka.html vodka // volvo : Volvo Holding Sverige Aktiebolag // https://www.iana.org/domains/root/db/volvo.html volvo // vote : Monolith Registry LLC // https://www.iana.org/domains/root/db/vote.html vote // voting : Valuetainment Corp. // https://www.iana.org/domains/root/db/voting.html voting // voto : Monolith Registry LLC // https://www.iana.org/domains/root/db/voto.html voto // voyage : Binky Moon, LLC // https://www.iana.org/domains/root/db/voyage.html voyage // wales : Nominet UK // https://www.iana.org/domains/root/db/wales.html wales // walmart : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/walmart.html walmart // walter : Sandvik AB // https://www.iana.org/domains/root/db/walter.html walter // wang : Zodiac Wang Limited // https://www.iana.org/domains/root/db/wang.html wang // wanggou : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/wanggou.html wanggou // watch : Binky Moon, LLC // https://www.iana.org/domains/root/db/watch.html watch // watches : Identity Digital Limited // https://www.iana.org/domains/root/db/watches.html watches // weather : International Business Machines Corporation // https://www.iana.org/domains/root/db/weather.html weather // weatherchannel : International Business Machines Corporation // https://www.iana.org/domains/root/db/weatherchannel.html weatherchannel // webcam : dot Webcam Limited // https://www.iana.org/domains/root/db/webcam.html webcam // weber : Saint-Gobain Weber SA // https://www.iana.org/domains/root/db/weber.html weber // website : Radix FZC DMCC // https://www.iana.org/domains/root/db/website.html website // wed // https://www.iana.org/domains/root/db/wed.html wed // wedding : Registry Services, LLC // https://www.iana.org/domains/root/db/wedding.html wedding // weibo : Sina Corporation // https://www.iana.org/domains/root/db/weibo.html weibo // weir : Weir Group IP Limited // https://www.iana.org/domains/root/db/weir.html weir // whoswho : Who's Who Registry // https://www.iana.org/domains/root/db/whoswho.html whoswho // wien : punkt.wien GmbH // https://www.iana.org/domains/root/db/wien.html wien // wiki : Registry Services, LLC // https://www.iana.org/domains/root/db/wiki.html wiki // williamhill : William Hill Organization Limited // https://www.iana.org/domains/root/db/williamhill.html williamhill // win : First Registry Limited // https://www.iana.org/domains/root/db/win.html win // windows : Microsoft Corporation // https://www.iana.org/domains/root/db/windows.html windows // wine : Binky Moon, LLC // https://www.iana.org/domains/root/db/wine.html wine // winners : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/winners.html winners // wme : William Morris Endeavor Entertainment, LLC // https://www.iana.org/domains/root/db/wme.html wme // wolterskluwer : Wolters Kluwer N.V. // https://www.iana.org/domains/root/db/wolterskluwer.html wolterskluwer // woodside : Woodside Petroleum Limited // https://www.iana.org/domains/root/db/woodside.html woodside // work : Registry Services, LLC // https://www.iana.org/domains/root/db/work.html work // works : Binky Moon, LLC // https://www.iana.org/domains/root/db/works.html works // world : Binky Moon, LLC // https://www.iana.org/domains/root/db/world.html world // wow : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/wow.html wow // wtc : World Trade Centers Association, Inc. // https://www.iana.org/domains/root/db/wtc.html wtc // wtf : Binky Moon, LLC // https://www.iana.org/domains/root/db/wtf.html wtf // xbox : Microsoft Corporation // https://www.iana.org/domains/root/db/xbox.html xbox // xerox : Xerox DNHC LLC // https://www.iana.org/domains/root/db/xerox.html xerox // xfinity : Comcast IP Holdings I, LLC // https://www.iana.org/domains/root/db/xfinity.html xfinity // xihuan : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/xihuan.html xihuan // xin : Elegant Leader Limited // https://www.iana.org/domains/root/db/xin.html xin // xn--11b4c3d : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--11b4c3d.html xn--11b4c3d // xn--1ck2e1b : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--1ck2e1b.html xn--1ck2e1b // xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--1qqw23a.html xn--1qqw23a // xn--30rr7y : Excellent First Limited // https://www.iana.org/domains/root/db/xn--30rr7y.html xn--30rr7y // xn--3bst00m : Eagle Horizon Limited // https://www.iana.org/domains/root/db/xn--3bst00m.html xn--3bst00m // xn--3ds443g : TLD REGISTRY LIMITED OY // https://www.iana.org/domains/root/db/xn--3ds443g.html xn--3ds443g // xn--3pxu8k : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--3pxu8k.html xn--3pxu8k // xn--42c2d9a : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--42c2d9a.html xn--42c2d9a // xn--45q11c : Zodiac Gemini Ltd // https://www.iana.org/domains/root/db/xn--45q11c.html xn--45q11c // xn--4gbrim : Helium TLDs Ltd // https://www.iana.org/domains/root/db/xn--4gbrim.html xn--4gbrim // xn--55qw42g : China Organizational Name Administration Center // https://www.iana.org/domains/root/db/xn--55qw42g.html xn--55qw42g // xn--55qx5d : China Internet Network Information Center (CNNIC) // https://www.iana.org/domains/root/db/xn--55qx5d.html xn--55qx5d // xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited // https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html xn--5su34j936bgsg // xn--5tzm5g : Global Website TLD Asia Limited // https://www.iana.org/domains/root/db/xn--5tzm5g.html xn--5tzm5g // xn--6frz82g : Identity Digital Limited // https://www.iana.org/domains/root/db/xn--6frz82g.html xn--6frz82g // xn--6qq986b3xl : Tycoon Treasure Limited // https://www.iana.org/domains/root/db/xn--6qq986b3xl.html xn--6qq986b3xl // xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) // https://www.iana.org/domains/root/db/xn--80adxhks.html xn--80adxhks // xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/xn--80aqecdr1a.html xn--80aqecdr1a // xn--80asehdb : CORE Association // https://www.iana.org/domains/root/db/xn--80asehdb.html xn--80asehdb // xn--80aswg : CORE Association // https://www.iana.org/domains/root/db/xn--80aswg.html xn--80aswg // xn--8y0a063a : China United Network Communications Corporation Limited // https://www.iana.org/domains/root/db/xn--8y0a063a.html xn--8y0a063a // xn--9dbq2a : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--9dbq2a.html xn--9dbq2a // xn--9et52u : RISE VICTORY LIMITED // https://www.iana.org/domains/root/db/xn--9et52u.html xn--9et52u // xn--9krt00a : Sina Corporation // https://www.iana.org/domains/root/db/xn--9krt00a.html xn--9krt00a // xn--b4w605ferd : Temasek Holdings (Private) Limited // https://www.iana.org/domains/root/db/xn--b4w605ferd.html xn--b4w605ferd // xn--bck1b9a5dre4c : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html xn--bck1b9a5dre4c // xn--c1avg : Public Interest Registry // https://www.iana.org/domains/root/db/xn--c1avg.html xn--c1avg // xn--c2br7g : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--c2br7g.html xn--c2br7g // xn--cck2b3b : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--cck2b3b.html xn--cck2b3b // xn--cckwcxetd : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--cckwcxetd.html xn--cckwcxetd // xn--cg4bki : SAMSUNG SDS CO., LTD // https://www.iana.org/domains/root/db/xn--cg4bki.html xn--cg4bki // xn--czr694b : Internet DotTrademark Organisation Limited // https://www.iana.org/domains/root/db/xn--czr694b.html xn--czr694b // xn--czrs0t : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--czrs0t.html xn--czrs0t // xn--czru2d : Zodiac Aquarius Limited // https://www.iana.org/domains/root/db/xn--czru2d.html xn--czru2d // xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet” // https://www.iana.org/domains/root/db/xn--d1acj3b.html xn--d1acj3b // xn--eckvdtc9d : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--eckvdtc9d.html xn--eckvdtc9d // xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--efvy88h.html xn--efvy88h // xn--fct429k : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--fct429k.html xn--fct429k // xn--fhbei : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--fhbei.html xn--fhbei // xn--fiq228c5hs : TLD REGISTRY LIMITED OY // https://www.iana.org/domains/root/db/xn--fiq228c5hs.html xn--fiq228c5hs // xn--fiq64b : CITIC Group Corporation // https://www.iana.org/domains/root/db/xn--fiq64b.html xn--fiq64b // xn--fjq720a : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--fjq720a.html xn--fjq720a // xn--flw351e : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/xn--flw351e.html xn--flw351e // xn--fzys8d69uvgm : PCCW Enterprises Limited // https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html xn--fzys8d69uvgm // xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. // https://www.iana.org/domains/root/db/xn--g2xx48c.html xn--g2xx48c // xn--gckr3f0f : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--gckr3f0f.html xn--gckr3f0f // xn--gk3at1e : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--gk3at1e.html xn--gk3at1e // xn--hxt814e : Zodiac Taurus Limited // https://www.iana.org/domains/root/db/xn--hxt814e.html xn--hxt814e // xn--i1b6b1a6a2e : Public Interest Registry // https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html xn--i1b6b1a6a2e // xn--imr513n : Internet DotTrademark Organisation Limited // https://www.iana.org/domains/root/db/xn--imr513n.html xn--imr513n // xn--io0a7i : China Internet Network Information Center (CNNIC) // https://www.iana.org/domains/root/db/xn--io0a7i.html xn--io0a7i // xn--j1aef : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--j1aef.html xn--j1aef // xn--jlq480n2rg : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--jlq480n2rg.html xn--jlq480n2rg // xn--jvr189m : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--jvr189m.html xn--jvr189m // xn--kcrx77d1x4a : Koninklijke Philips N.V. // https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html xn--kcrx77d1x4a // xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd // https://www.iana.org/domains/root/db/xn--kput3i.html xn--kput3i // xn--mgba3a3ejt : Aramco Services Company // https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html xn--mgba3a3ejt // xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl // https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html xn--mgba7c0bbn0a // xn--mgbab2bd : CORE Association // https://www.iana.org/domains/root/db/xn--mgbab2bd.html xn--mgbab2bd // xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre // https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html xn--mgbca7dzdo // xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html xn--mgbi4ecexp // xn--mgbt3dhd : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. // https://www.iana.org/domains/root/db/xn--mgbt3dhd.html xn--mgbt3dhd // xn--mk1bu44c : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--mk1bu44c.html xn--mk1bu44c // xn--mxtq1m : Net-Chinese Co., Ltd. // https://www.iana.org/domains/root/db/xn--mxtq1m.html xn--mxtq1m // xn--ngbc5azd : International Domain Registry Pty. Ltd. // https://www.iana.org/domains/root/db/xn--ngbc5azd.html xn--ngbc5azd // xn--ngbe9e0a : Kuwait Finance House // https://www.iana.org/domains/root/db/xn--ngbe9e0a.html xn--ngbe9e0a // xn--ngbrx : League of Arab States // https://www.iana.org/domains/root/db/xn--ngbrx.html xn--ngbrx // xn--nqv7f : Public Interest Registry // https://www.iana.org/domains/root/db/xn--nqv7f.html xn--nqv7f // xn--nqv7fs00ema : Public Interest Registry // https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html xn--nqv7fs00ema // xn--nyqy26a : Stable Tone Limited // https://www.iana.org/domains/root/db/xn--nyqy26a.html xn--nyqy26a // xn--otu796d : Jiang Yu Liang Cai Technology Company Limited // https://www.iana.org/domains/root/db/xn--otu796d.html xn--otu796d // xn--p1acf : Rusnames Limited // https://www.iana.org/domains/root/db/xn--p1acf.html xn--p1acf // xn--pssy2u : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--pssy2u.html xn--pssy2u // xn--q9jyb4c : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/xn--q9jyb4c.html xn--q9jyb4c // xn--qcka1pmc : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/xn--qcka1pmc.html xn--qcka1pmc // xn--rhqv96g : Stable Tone Limited // https://www.iana.org/domains/root/db/xn--rhqv96g.html xn--rhqv96g // xn--rovu88b : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--rovu88b.html xn--rovu88b // xn--ses554g : KNET Co., Ltd. // https://www.iana.org/domains/root/db/xn--ses554g.html xn--ses554g // xn--t60b56a : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--t60b56a.html xn--t60b56a // xn--tckwe : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--tckwe.html xn--tckwe // xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/xn--tiq49xqyj.html xn--tiq49xqyj // xn--unup4y : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--unup4y.html xn--unup4y // xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html xn--vermgensberater-ctb // xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html xn--vermgensberatung-pwb // xn--vhquv : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--vhquv.html xn--vhquv // xn--vuq861b : Beijing Tele-info Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--vuq861b.html xn--vuq861b // xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html xn--w4r85el8fhu5dnra // xn--w4rs40l : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/xn--w4rs40l.html xn--w4rs40l // xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--xhq521b.html xn--xhq521b // xn--zfr164b : China Organizational Name Administration Center // https://www.iana.org/domains/root/db/xn--zfr164b.html xn--zfr164b // xyz : XYZ.COM LLC // https://www.iana.org/domains/root/db/xyz.html xyz // yachts : XYZ.COM LLC // https://www.iana.org/domains/root/db/yachts.html yachts // yahoo : Oath Inc. // https://www.iana.org/domains/root/db/yahoo.html yahoo // yamaxun : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/yamaxun.html yamaxun // yandex : Yandex Europe B.V. // https://www.iana.org/domains/root/db/yandex.html yandex // yodobashi : YODOBASHI CAMERA CO.,LTD. // https://www.iana.org/domains/root/db/yodobashi.html yodobashi // yoga : Registry Services, LLC // https://www.iana.org/domains/root/db/yoga.html yoga // yokohama : GMO Registry, Inc. // https://www.iana.org/domains/root/db/yokohama.html yokohama // you : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/you.html you // youtube : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/youtube.html youtube // yun : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/yun.html yun // zappos : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/zappos.html zappos // zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) // https://www.iana.org/domains/root/db/zara.html zara // zero : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/zero.html zero // zip : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/zip.html zip // zone : Binky Moon, LLC // https://www.iana.org/domains/root/db/zone.html zone // zuerich : Kanton Zürich (Canton of Zurich) // https://www.iana.org/domains/root/db/zuerich.html zuerich // ===END ICANN DOMAINS=== // ===BEGIN PRIVATE DOMAINS=== // (Note: these are in alphabetical order by company name) // 1GB LLC : https://www.1gb.ua/ // Submitted by 1GB LLC cc.ua inf.ua ltd.ua // 611coin : https://611project.org/ 611.to // Aaron Marais' Gitlab pages: https://lab.aaronleem.co.za // Submitted by Aaron Marais graphox.us // accesso Technology Group, plc. : https://accesso.com/ // Submitted by accesso Team *.devcdnaccesso.com // Acorn Labs : https://acorn.io // Submitted by Craig Jellick *.on-acorn.io // ActiveTrail: https://www.activetrail.biz/ // Submitted by Ofer Kalaora activetrail.biz // Adobe : https://www.adobe.com/ // Submitted by Ian Boston and Lars Trieloff adobeaemcloud.com *.dev.adobeaemcloud.com hlx.live adobeaemcloud.net hlx.page hlx3.page // Adobe Developer Platform : https://developer.adobe.com // Submitted by Jesse MacFadyen adobeio-static.net adobeioruntime.net // Agnat sp. z o.o. : https://domena.pl // Submitted by Przemyslaw Plewa beep.pl // Airkit : https://www.airkit.com/ // Submitted by Grant Cooksey airkitapps.com airkitapps-au.com airkitapps.eu // Aiven: https://aiven.io/ // Submitted by Etienne Stalmans aivencloud.com // Akamai : https://www.akamai.com/ // Submitted by Akamai Team akadns.net akamai.net akamai-staging.net akamaiedge.net akamaiedge-staging.net akamaihd.net akamaihd-staging.net akamaiorigin.net akamaiorigin-staging.net akamaized.net akamaized-staging.net edgekey.net edgekey-staging.net edgesuite.net edgesuite-staging.net // alboto.ca : http://alboto.ca // Submitted by Anton Avramov barsy.ca // Alces Software Ltd : http://alces-software.com // Submitted by Mark J. Titorenko *.compute.estate *.alces.network // all-inkl.com : https://all-inkl.com // Submitted by Werner Kaltofen kasserver.com // Altervista: https://www.altervista.org // Submitted by Carlo Cannas altervista.org // alwaysdata : https://www.alwaysdata.com // Submitted by Cyril alwaysdata.net // Amaze Software : https://amaze.co // Submitted by Domain Admin myamaze.net // Amazon : https://www.amazon.com/ // Submitted by AWS Security // Subsections of Amazon/subsidiaries will appear until "concludes" tag // Amazon API Gateway // Submitted by AWS Security // Reference: 4d863337-ff98-4501-a6f2-361eba8445d6 execute-api.cn-north-1.amazonaws.com.cn execute-api.cn-northwest-1.amazonaws.com.cn execute-api.af-south-1.amazonaws.com execute-api.ap-east-1.amazonaws.com execute-api.ap-northeast-1.amazonaws.com execute-api.ap-northeast-2.amazonaws.com execute-api.ap-northeast-3.amazonaws.com execute-api.ap-south-1.amazonaws.com execute-api.ap-south-2.amazonaws.com execute-api.ap-southeast-1.amazonaws.com execute-api.ap-southeast-2.amazonaws.com execute-api.ap-southeast-3.amazonaws.com execute-api.ap-southeast-4.amazonaws.com execute-api.ca-central-1.amazonaws.com execute-api.eu-central-1.amazonaws.com execute-api.eu-central-2.amazonaws.com execute-api.eu-north-1.amazonaws.com execute-api.eu-south-1.amazonaws.com execute-api.eu-south-2.amazonaws.com execute-api.eu-west-1.amazonaws.com execute-api.eu-west-2.amazonaws.com execute-api.eu-west-3.amazonaws.com execute-api.il-central-1.amazonaws.com execute-api.me-central-1.amazonaws.com execute-api.me-south-1.amazonaws.com execute-api.sa-east-1.amazonaws.com execute-api.us-east-1.amazonaws.com execute-api.us-east-2.amazonaws.com execute-api.us-gov-east-1.amazonaws.com execute-api.us-gov-west-1.amazonaws.com execute-api.us-west-1.amazonaws.com execute-api.us-west-2.amazonaws.com // Amazon CloudFront // Submitted by Donavan Miller // Reference: 54144616-fd49-4435-8535-19c6a601bdb3 cloudfront.net // Amazon Cognito // Submitted by AWS Security // Reference: 7bee1013-f456-47df-bfe8-03c78d946d61 auth.af-south-1.amazoncognito.com auth.ap-northeast-1.amazoncognito.com auth.ap-northeast-2.amazoncognito.com auth.ap-northeast-3.amazoncognito.com auth.ap-south-1.amazoncognito.com auth.ap-southeast-1.amazoncognito.com auth.ap-southeast-2.amazoncognito.com auth.ap-southeast-3.amazoncognito.com auth.ca-central-1.amazoncognito.com auth.eu-central-1.amazoncognito.com auth.eu-north-1.amazoncognito.com auth.eu-south-1.amazoncognito.com auth.eu-west-1.amazoncognito.com auth.eu-west-2.amazoncognito.com auth.eu-west-3.amazoncognito.com auth.il-central-1.amazoncognito.com auth.me-south-1.amazoncognito.com auth.sa-east-1.amazoncognito.com auth.us-east-1.amazoncognito.com auth-fips.us-east-1.amazoncognito.com auth.us-east-2.amazoncognito.com auth-fips.us-east-2.amazoncognito.com auth-fips.us-gov-west-1.amazoncognito.com auth.us-west-1.amazoncognito.com auth-fips.us-west-1.amazoncognito.com auth.us-west-2.amazoncognito.com auth-fips.us-west-2.amazoncognito.com // Amazon EC2 // Submitted by Luke Wells // Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 *.compute.amazonaws.com *.compute-1.amazonaws.com *.compute.amazonaws.com.cn us-east-1.amazonaws.com // Amazon EMR // Submitted by AWS Security // Reference: 597f3f8e-9283-4e48-8e32-7ee25a1ff6ab emrappui-prod.cn-north-1.amazonaws.com.cn emrnotebooks-prod.cn-north-1.amazonaws.com.cn emrstudio-prod.cn-north-1.amazonaws.com.cn emrappui-prod.cn-northwest-1.amazonaws.com.cn emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn emrstudio-prod.cn-northwest-1.amazonaws.com.cn emrappui-prod.af-south-1.amazonaws.com emrnotebooks-prod.af-south-1.amazonaws.com emrstudio-prod.af-south-1.amazonaws.com emrappui-prod.ap-east-1.amazonaws.com emrnotebooks-prod.ap-east-1.amazonaws.com emrstudio-prod.ap-east-1.amazonaws.com emrappui-prod.ap-northeast-1.amazonaws.com emrnotebooks-prod.ap-northeast-1.amazonaws.com emrstudio-prod.ap-northeast-1.amazonaws.com emrappui-prod.ap-northeast-2.amazonaws.com emrnotebooks-prod.ap-northeast-2.amazonaws.com emrstudio-prod.ap-northeast-2.amazonaws.com emrappui-prod.ap-northeast-3.amazonaws.com emrnotebooks-prod.ap-northeast-3.amazonaws.com emrstudio-prod.ap-northeast-3.amazonaws.com emrappui-prod.ap-south-1.amazonaws.com emrnotebooks-prod.ap-south-1.amazonaws.com emrstudio-prod.ap-south-1.amazonaws.com emrappui-prod.ap-southeast-1.amazonaws.com emrnotebooks-prod.ap-southeast-1.amazonaws.com emrstudio-prod.ap-southeast-1.amazonaws.com emrappui-prod.ap-southeast-2.amazonaws.com emrnotebooks-prod.ap-southeast-2.amazonaws.com emrstudio-prod.ap-southeast-2.amazonaws.com emrappui-prod.ap-southeast-3.amazonaws.com emrnotebooks-prod.ap-southeast-3.amazonaws.com emrstudio-prod.ap-southeast-3.amazonaws.com emrappui-prod.ca-central-1.amazonaws.com emrnotebooks-prod.ca-central-1.amazonaws.com emrstudio-prod.ca-central-1.amazonaws.com emrappui-prod.eu-central-1.amazonaws.com emrnotebooks-prod.eu-central-1.amazonaws.com emrstudio-prod.eu-central-1.amazonaws.com emrappui-prod.eu-north-1.amazonaws.com emrnotebooks-prod.eu-north-1.amazonaws.com emrstudio-prod.eu-north-1.amazonaws.com emrappui-prod.eu-south-1.amazonaws.com emrnotebooks-prod.eu-south-1.amazonaws.com emrstudio-prod.eu-south-1.amazonaws.com emrappui-prod.eu-west-1.amazonaws.com emrnotebooks-prod.eu-west-1.amazonaws.com emrstudio-prod.eu-west-1.amazonaws.com emrappui-prod.eu-west-2.amazonaws.com emrnotebooks-prod.eu-west-2.amazonaws.com emrstudio-prod.eu-west-2.amazonaws.com emrappui-prod.eu-west-3.amazonaws.com emrnotebooks-prod.eu-west-3.amazonaws.com emrstudio-prod.eu-west-3.amazonaws.com emrappui-prod.me-central-1.amazonaws.com emrnotebooks-prod.me-central-1.amazonaws.com emrstudio-prod.me-central-1.amazonaws.com emrappui-prod.me-south-1.amazonaws.com emrnotebooks-prod.me-south-1.amazonaws.com emrstudio-prod.me-south-1.amazonaws.com emrappui-prod.sa-east-1.amazonaws.com emrnotebooks-prod.sa-east-1.amazonaws.com emrstudio-prod.sa-east-1.amazonaws.com emrappui-prod.us-east-1.amazonaws.com emrnotebooks-prod.us-east-1.amazonaws.com emrstudio-prod.us-east-1.amazonaws.com emrappui-prod.us-east-2.amazonaws.com emrnotebooks-prod.us-east-2.amazonaws.com emrstudio-prod.us-east-2.amazonaws.com emrappui-prod.us-gov-east-1.amazonaws.com emrnotebooks-prod.us-gov-east-1.amazonaws.com emrstudio-prod.us-gov-east-1.amazonaws.com emrappui-prod.us-gov-west-1.amazonaws.com emrnotebooks-prod.us-gov-west-1.amazonaws.com emrstudio-prod.us-gov-west-1.amazonaws.com emrappui-prod.us-west-1.amazonaws.com emrnotebooks-prod.us-west-1.amazonaws.com emrstudio-prod.us-west-1.amazonaws.com emrappui-prod.us-west-2.amazonaws.com emrnotebooks-prod.us-west-2.amazonaws.com emrstudio-prod.us-west-2.amazonaws.com // Amazon Managed Workflows for Apache Airflow // Submitted by AWS Security // Reference: 4ab55e6f-90c0-4a8d-b6a0-52ca5dbb1c2e *.cn-north-1.airflow.amazonaws.com.cn *.cn-northwest-1.airflow.amazonaws.com.cn *.ap-northeast-1.airflow.amazonaws.com *.ap-northeast-2.airflow.amazonaws.com *.ap-south-1.airflow.amazonaws.com *.ap-southeast-1.airflow.amazonaws.com *.ap-southeast-2.airflow.amazonaws.com *.ca-central-1.airflow.amazonaws.com *.eu-central-1.airflow.amazonaws.com *.eu-north-1.airflow.amazonaws.com *.eu-west-1.airflow.amazonaws.com *.eu-west-2.airflow.amazonaws.com *.eu-west-3.airflow.amazonaws.com *.sa-east-1.airflow.amazonaws.com *.us-east-1.airflow.amazonaws.com *.us-east-2.airflow.amazonaws.com *.us-west-2.airflow.amazonaws.com // Amazon S3 // Submitted by AWS Security // Reference: 0e801048-08f2-4064-9cb8-e7373e0b57f4 s3.dualstack.cn-north-1.amazonaws.com.cn s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn s3-website.dualstack.cn-north-1.amazonaws.com.cn s3.cn-north-1.amazonaws.com.cn s3-accesspoint.cn-north-1.amazonaws.com.cn s3-deprecated.cn-north-1.amazonaws.com.cn s3-object-lambda.cn-north-1.amazonaws.com.cn s3-website.cn-north-1.amazonaws.com.cn s3.dualstack.cn-northwest-1.amazonaws.com.cn s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn s3.cn-northwest-1.amazonaws.com.cn s3-accesspoint.cn-northwest-1.amazonaws.com.cn s3-object-lambda.cn-northwest-1.amazonaws.com.cn s3-website.cn-northwest-1.amazonaws.com.cn s3.dualstack.af-south-1.amazonaws.com s3-accesspoint.dualstack.af-south-1.amazonaws.com s3-website.dualstack.af-south-1.amazonaws.com s3.af-south-1.amazonaws.com s3-accesspoint.af-south-1.amazonaws.com s3-object-lambda.af-south-1.amazonaws.com s3-website.af-south-1.amazonaws.com s3.dualstack.ap-east-1.amazonaws.com s3-accesspoint.dualstack.ap-east-1.amazonaws.com s3.ap-east-1.amazonaws.com s3-accesspoint.ap-east-1.amazonaws.com s3-object-lambda.ap-east-1.amazonaws.com s3-website.ap-east-1.amazonaws.com s3.dualstack.ap-northeast-1.amazonaws.com s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com s3-website.dualstack.ap-northeast-1.amazonaws.com s3.ap-northeast-1.amazonaws.com s3-accesspoint.ap-northeast-1.amazonaws.com s3-object-lambda.ap-northeast-1.amazonaws.com s3-website.ap-northeast-1.amazonaws.com s3.dualstack.ap-northeast-2.amazonaws.com s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com s3-website.dualstack.ap-northeast-2.amazonaws.com s3.ap-northeast-2.amazonaws.com s3-accesspoint.ap-northeast-2.amazonaws.com s3-object-lambda.ap-northeast-2.amazonaws.com s3-website.ap-northeast-2.amazonaws.com s3.dualstack.ap-northeast-3.amazonaws.com s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com s3-website.dualstack.ap-northeast-3.amazonaws.com s3.ap-northeast-3.amazonaws.com s3-accesspoint.ap-northeast-3.amazonaws.com s3-object-lambda.ap-northeast-3.amazonaws.com s3-website.ap-northeast-3.amazonaws.com s3.dualstack.ap-south-1.amazonaws.com s3-accesspoint.dualstack.ap-south-1.amazonaws.com s3-website.dualstack.ap-south-1.amazonaws.com s3.ap-south-1.amazonaws.com s3-accesspoint.ap-south-1.amazonaws.com s3-object-lambda.ap-south-1.amazonaws.com s3-website.ap-south-1.amazonaws.com s3.dualstack.ap-south-2.amazonaws.com s3-accesspoint.dualstack.ap-south-2.amazonaws.com s3.ap-south-2.amazonaws.com s3-accesspoint.ap-south-2.amazonaws.com s3-object-lambda.ap-south-2.amazonaws.com s3-website.ap-south-2.amazonaws.com s3.dualstack.ap-southeast-1.amazonaws.com s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com s3-website.dualstack.ap-southeast-1.amazonaws.com s3.ap-southeast-1.amazonaws.com s3-accesspoint.ap-southeast-1.amazonaws.com s3-object-lambda.ap-southeast-1.amazonaws.com s3-website.ap-southeast-1.amazonaws.com s3.dualstack.ap-southeast-2.amazonaws.com s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com s3-website.dualstack.ap-southeast-2.amazonaws.com s3.ap-southeast-2.amazonaws.com s3-accesspoint.ap-southeast-2.amazonaws.com s3-object-lambda.ap-southeast-2.amazonaws.com s3-website.ap-southeast-2.amazonaws.com s3.dualstack.ap-southeast-3.amazonaws.com s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com s3.ap-southeast-3.amazonaws.com s3-accesspoint.ap-southeast-3.amazonaws.com s3-object-lambda.ap-southeast-3.amazonaws.com s3-website.ap-southeast-3.amazonaws.com s3.dualstack.ap-southeast-4.amazonaws.com s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com s3.ap-southeast-4.amazonaws.com s3-accesspoint.ap-southeast-4.amazonaws.com s3-object-lambda.ap-southeast-4.amazonaws.com s3-website.ap-southeast-4.amazonaws.com s3.dualstack.ca-central-1.amazonaws.com s3-accesspoint.dualstack.ca-central-1.amazonaws.com s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com s3-fips.dualstack.ca-central-1.amazonaws.com s3-website.dualstack.ca-central-1.amazonaws.com s3.ca-central-1.amazonaws.com s3-accesspoint.ca-central-1.amazonaws.com s3-accesspoint-fips.ca-central-1.amazonaws.com s3-fips.ca-central-1.amazonaws.com s3-object-lambda.ca-central-1.amazonaws.com s3-website.ca-central-1.amazonaws.com s3.dualstack.eu-central-1.amazonaws.com s3-accesspoint.dualstack.eu-central-1.amazonaws.com s3-website.dualstack.eu-central-1.amazonaws.com s3.eu-central-1.amazonaws.com s3-accesspoint.eu-central-1.amazonaws.com s3-object-lambda.eu-central-1.amazonaws.com s3-website.eu-central-1.amazonaws.com s3.dualstack.eu-central-2.amazonaws.com s3-accesspoint.dualstack.eu-central-2.amazonaws.com s3.eu-central-2.amazonaws.com s3-accesspoint.eu-central-2.amazonaws.com s3-object-lambda.eu-central-2.amazonaws.com s3-website.eu-central-2.amazonaws.com s3.dualstack.eu-north-1.amazonaws.com s3-accesspoint.dualstack.eu-north-1.amazonaws.com s3.eu-north-1.amazonaws.com s3-accesspoint.eu-north-1.amazonaws.com s3-object-lambda.eu-north-1.amazonaws.com s3-website.eu-north-1.amazonaws.com s3.dualstack.eu-south-1.amazonaws.com s3-accesspoint.dualstack.eu-south-1.amazonaws.com s3-website.dualstack.eu-south-1.amazonaws.com s3.eu-south-1.amazonaws.com s3-accesspoint.eu-south-1.amazonaws.com s3-object-lambda.eu-south-1.amazonaws.com s3-website.eu-south-1.amazonaws.com s3.dualstack.eu-south-2.amazonaws.com s3-accesspoint.dualstack.eu-south-2.amazonaws.com s3.eu-south-2.amazonaws.com s3-accesspoint.eu-south-2.amazonaws.com s3-object-lambda.eu-south-2.amazonaws.com s3-website.eu-south-2.amazonaws.com s3.dualstack.eu-west-1.amazonaws.com s3-accesspoint.dualstack.eu-west-1.amazonaws.com s3-website.dualstack.eu-west-1.amazonaws.com s3.eu-west-1.amazonaws.com s3-accesspoint.eu-west-1.amazonaws.com s3-deprecated.eu-west-1.amazonaws.com s3-object-lambda.eu-west-1.amazonaws.com s3-website.eu-west-1.amazonaws.com s3.dualstack.eu-west-2.amazonaws.com s3-accesspoint.dualstack.eu-west-2.amazonaws.com s3.eu-west-2.amazonaws.com s3-accesspoint.eu-west-2.amazonaws.com s3-object-lambda.eu-west-2.amazonaws.com s3-website.eu-west-2.amazonaws.com s3.dualstack.eu-west-3.amazonaws.com s3-accesspoint.dualstack.eu-west-3.amazonaws.com s3-website.dualstack.eu-west-3.amazonaws.com s3.eu-west-3.amazonaws.com s3-accesspoint.eu-west-3.amazonaws.com s3-object-lambda.eu-west-3.amazonaws.com s3-website.eu-west-3.amazonaws.com s3.dualstack.il-central-1.amazonaws.com s3-accesspoint.dualstack.il-central-1.amazonaws.com s3.il-central-1.amazonaws.com s3-accesspoint.il-central-1.amazonaws.com s3-object-lambda.il-central-1.amazonaws.com s3-website.il-central-1.amazonaws.com s3.dualstack.me-central-1.amazonaws.com s3-accesspoint.dualstack.me-central-1.amazonaws.com s3.me-central-1.amazonaws.com s3-accesspoint.me-central-1.amazonaws.com s3-object-lambda.me-central-1.amazonaws.com s3-website.me-central-1.amazonaws.com s3.dualstack.me-south-1.amazonaws.com s3-accesspoint.dualstack.me-south-1.amazonaws.com s3.me-south-1.amazonaws.com s3-accesspoint.me-south-1.amazonaws.com s3-object-lambda.me-south-1.amazonaws.com s3-website.me-south-1.amazonaws.com s3.amazonaws.com s3-1.amazonaws.com s3-ap-east-1.amazonaws.com s3-ap-northeast-1.amazonaws.com s3-ap-northeast-2.amazonaws.com s3-ap-northeast-3.amazonaws.com s3-ap-south-1.amazonaws.com s3-ap-southeast-1.amazonaws.com s3-ap-southeast-2.amazonaws.com s3-ca-central-1.amazonaws.com s3-eu-central-1.amazonaws.com s3-eu-north-1.amazonaws.com s3-eu-west-1.amazonaws.com s3-eu-west-2.amazonaws.com s3-eu-west-3.amazonaws.com s3-external-1.amazonaws.com s3-fips-us-gov-east-1.amazonaws.com s3-fips-us-gov-west-1.amazonaws.com mrap.accesspoint.s3-global.amazonaws.com s3-me-south-1.amazonaws.com s3-sa-east-1.amazonaws.com s3-us-east-2.amazonaws.com s3-us-gov-east-1.amazonaws.com s3-us-gov-west-1.amazonaws.com s3-us-west-1.amazonaws.com s3-us-west-2.amazonaws.com s3-website-ap-northeast-1.amazonaws.com s3-website-ap-southeast-1.amazonaws.com s3-website-ap-southeast-2.amazonaws.com s3-website-eu-west-1.amazonaws.com s3-website-sa-east-1.amazonaws.com s3-website-us-east-1.amazonaws.com s3-website-us-gov-west-1.amazonaws.com s3-website-us-west-1.amazonaws.com s3-website-us-west-2.amazonaws.com s3.dualstack.sa-east-1.amazonaws.com s3-accesspoint.dualstack.sa-east-1.amazonaws.com s3-website.dualstack.sa-east-1.amazonaws.com s3.sa-east-1.amazonaws.com s3-accesspoint.sa-east-1.amazonaws.com s3-object-lambda.sa-east-1.amazonaws.com s3-website.sa-east-1.amazonaws.com s3.dualstack.us-east-1.amazonaws.com s3-accesspoint.dualstack.us-east-1.amazonaws.com s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com s3-fips.dualstack.us-east-1.amazonaws.com s3-website.dualstack.us-east-1.amazonaws.com s3.us-east-1.amazonaws.com s3-accesspoint.us-east-1.amazonaws.com s3-accesspoint-fips.us-east-1.amazonaws.com s3-deprecated.us-east-1.amazonaws.com s3-fips.us-east-1.amazonaws.com s3-object-lambda.us-east-1.amazonaws.com s3-website.us-east-1.amazonaws.com s3.dualstack.us-east-2.amazonaws.com s3-accesspoint.dualstack.us-east-2.amazonaws.com s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com s3-fips.dualstack.us-east-2.amazonaws.com s3.us-east-2.amazonaws.com s3-accesspoint.us-east-2.amazonaws.com s3-accesspoint-fips.us-east-2.amazonaws.com s3-deprecated.us-east-2.amazonaws.com s3-fips.us-east-2.amazonaws.com s3-object-lambda.us-east-2.amazonaws.com s3-website.us-east-2.amazonaws.com s3.dualstack.us-gov-east-1.amazonaws.com s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com s3-fips.dualstack.us-gov-east-1.amazonaws.com s3.us-gov-east-1.amazonaws.com s3-accesspoint.us-gov-east-1.amazonaws.com s3-accesspoint-fips.us-gov-east-1.amazonaws.com s3-fips.us-gov-east-1.amazonaws.com s3-object-lambda.us-gov-east-1.amazonaws.com s3-website.us-gov-east-1.amazonaws.com s3.dualstack.us-gov-west-1.amazonaws.com s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com s3-fips.dualstack.us-gov-west-1.amazonaws.com s3.us-gov-west-1.amazonaws.com s3-accesspoint.us-gov-west-1.amazonaws.com s3-accesspoint-fips.us-gov-west-1.amazonaws.com s3-fips.us-gov-west-1.amazonaws.com s3-object-lambda.us-gov-west-1.amazonaws.com s3-website.us-gov-west-1.amazonaws.com s3.dualstack.us-west-1.amazonaws.com s3-accesspoint.dualstack.us-west-1.amazonaws.com s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com s3-fips.dualstack.us-west-1.amazonaws.com s3-website.dualstack.us-west-1.amazonaws.com s3.us-west-1.amazonaws.com s3-accesspoint.us-west-1.amazonaws.com s3-accesspoint-fips.us-west-1.amazonaws.com s3-fips.us-west-1.amazonaws.com s3-object-lambda.us-west-1.amazonaws.com s3-website.us-west-1.amazonaws.com s3.dualstack.us-west-2.amazonaws.com s3-accesspoint.dualstack.us-west-2.amazonaws.com s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com s3-fips.dualstack.us-west-2.amazonaws.com s3-website.dualstack.us-west-2.amazonaws.com s3.us-west-2.amazonaws.com s3-accesspoint.us-west-2.amazonaws.com s3-accesspoint-fips.us-west-2.amazonaws.com s3-deprecated.us-west-2.amazonaws.com s3-fips.us-west-2.amazonaws.com s3-object-lambda.us-west-2.amazonaws.com s3-website.us-west-2.amazonaws.com // Amazon SageMaker Notebook Instances // Submitted by AWS Security // Reference: fe8c9e94-5a22-486d-8750-991a3a9b13c6 notebook.af-south-1.sagemaker.aws notebook.ap-east-1.sagemaker.aws notebook.ap-northeast-1.sagemaker.aws notebook.ap-northeast-2.sagemaker.aws notebook.ap-northeast-3.sagemaker.aws notebook.ap-south-1.sagemaker.aws notebook.ap-south-2.sagemaker.aws notebook.ap-southeast-1.sagemaker.aws notebook.ap-southeast-2.sagemaker.aws notebook.ap-southeast-3.sagemaker.aws notebook.ap-southeast-4.sagemaker.aws notebook.ca-central-1.sagemaker.aws notebook.eu-central-1.sagemaker.aws notebook.eu-central-2.sagemaker.aws notebook.eu-north-1.sagemaker.aws notebook.eu-south-1.sagemaker.aws notebook.eu-south-2.sagemaker.aws notebook.eu-west-1.sagemaker.aws notebook.eu-west-2.sagemaker.aws notebook.eu-west-3.sagemaker.aws notebook.il-central-1.sagemaker.aws notebook.me-central-1.sagemaker.aws notebook.me-south-1.sagemaker.aws notebook.sa-east-1.sagemaker.aws notebook.us-east-1.sagemaker.aws notebook-fips.us-east-1.sagemaker.aws notebook.us-east-2.sagemaker.aws notebook-fips.us-east-2.sagemaker.aws notebook.us-gov-east-1.sagemaker.aws notebook-fips.us-gov-east-1.sagemaker.aws notebook.us-gov-west-1.sagemaker.aws notebook-fips.us-gov-west-1.sagemaker.aws notebook.us-west-1.sagemaker.aws notebook.us-west-2.sagemaker.aws notebook-fips.us-west-2.sagemaker.aws notebook.cn-north-1.sagemaker.com.cn notebook.cn-northwest-1.sagemaker.com.cn // Amazon SageMaker Studio // Submitted by AWS Security // Reference: 057ee397-6bf8-4f20-b807-d7bc145ac980 studio.af-south-1.sagemaker.aws studio.ap-east-1.sagemaker.aws studio.ap-northeast-1.sagemaker.aws studio.ap-northeast-2.sagemaker.aws studio.ap-northeast-3.sagemaker.aws studio.ap-south-1.sagemaker.aws studio.ap-southeast-1.sagemaker.aws studio.ap-southeast-2.sagemaker.aws studio.ap-southeast-3.sagemaker.aws studio.ca-central-1.sagemaker.aws studio.eu-central-1.sagemaker.aws studio.eu-north-1.sagemaker.aws studio.eu-south-1.sagemaker.aws studio.eu-west-1.sagemaker.aws studio.eu-west-2.sagemaker.aws studio.eu-west-3.sagemaker.aws studio.il-central-1.sagemaker.aws studio.me-central-1.sagemaker.aws studio.me-south-1.sagemaker.aws studio.sa-east-1.sagemaker.aws studio.us-east-1.sagemaker.aws studio.us-east-2.sagemaker.aws studio.us-gov-east-1.sagemaker.aws studio-fips.us-gov-east-1.sagemaker.aws studio.us-gov-west-1.sagemaker.aws studio-fips.us-gov-west-1.sagemaker.aws studio.us-west-1.sagemaker.aws studio.us-west-2.sagemaker.aws studio.cn-north-1.sagemaker.com.cn studio.cn-northwest-1.sagemaker.com.cn // Analytics on AWS // Submitted by AWS Security // Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd analytics-gateway.ap-northeast-1.amazonaws.com analytics-gateway.ap-northeast-2.amazonaws.com analytics-gateway.ap-south-1.amazonaws.com analytics-gateway.ap-southeast-1.amazonaws.com analytics-gateway.ap-southeast-2.amazonaws.com analytics-gateway.eu-central-1.amazonaws.com analytics-gateway.eu-west-1.amazonaws.com analytics-gateway.us-east-1.amazonaws.com analytics-gateway.us-east-2.amazonaws.com analytics-gateway.us-west-2.amazonaws.com // AWS Amplify // Submitted by AWS Security // Reference: 5ecce854-c033-4fc4-a755-1a9916d9a9bb *.amplifyapp.com // AWS App Runner // Submitted by AWS Security // Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 *.awsapprunner.com // AWS Cloud9 // Submitted by: AWS Security // Reference: 05c44955-977c-4b57-938a-f2af92733f9f webview-assets.aws-cloud9.af-south-1.amazonaws.com vfs.cloud9.af-south-1.amazonaws.com webview-assets.cloud9.af-south-1.amazonaws.com webview-assets.aws-cloud9.ap-east-1.amazonaws.com vfs.cloud9.ap-east-1.amazonaws.com webview-assets.cloud9.ap-east-1.amazonaws.com webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com vfs.cloud9.ap-northeast-1.amazonaws.com webview-assets.cloud9.ap-northeast-1.amazonaws.com webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com vfs.cloud9.ap-northeast-2.amazonaws.com webview-assets.cloud9.ap-northeast-2.amazonaws.com webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com vfs.cloud9.ap-northeast-3.amazonaws.com webview-assets.cloud9.ap-northeast-3.amazonaws.com webview-assets.aws-cloud9.ap-south-1.amazonaws.com vfs.cloud9.ap-south-1.amazonaws.com webview-assets.cloud9.ap-south-1.amazonaws.com webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com vfs.cloud9.ap-southeast-1.amazonaws.com webview-assets.cloud9.ap-southeast-1.amazonaws.com webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com vfs.cloud9.ap-southeast-2.amazonaws.com webview-assets.cloud9.ap-southeast-2.amazonaws.com webview-assets.aws-cloud9.ca-central-1.amazonaws.com vfs.cloud9.ca-central-1.amazonaws.com webview-assets.cloud9.ca-central-1.amazonaws.com webview-assets.aws-cloud9.eu-central-1.amazonaws.com vfs.cloud9.eu-central-1.amazonaws.com webview-assets.cloud9.eu-central-1.amazonaws.com webview-assets.aws-cloud9.eu-north-1.amazonaws.com vfs.cloud9.eu-north-1.amazonaws.com webview-assets.cloud9.eu-north-1.amazonaws.com webview-assets.aws-cloud9.eu-south-1.amazonaws.com vfs.cloud9.eu-south-1.amazonaws.com webview-assets.cloud9.eu-south-1.amazonaws.com webview-assets.aws-cloud9.eu-west-1.amazonaws.com vfs.cloud9.eu-west-1.amazonaws.com webview-assets.cloud9.eu-west-1.amazonaws.com webview-assets.aws-cloud9.eu-west-2.amazonaws.com vfs.cloud9.eu-west-2.amazonaws.com webview-assets.cloud9.eu-west-2.amazonaws.com webview-assets.aws-cloud9.eu-west-3.amazonaws.com vfs.cloud9.eu-west-3.amazonaws.com webview-assets.cloud9.eu-west-3.amazonaws.com webview-assets.aws-cloud9.me-south-1.amazonaws.com vfs.cloud9.me-south-1.amazonaws.com webview-assets.cloud9.me-south-1.amazonaws.com webview-assets.aws-cloud9.sa-east-1.amazonaws.com vfs.cloud9.sa-east-1.amazonaws.com webview-assets.cloud9.sa-east-1.amazonaws.com webview-assets.aws-cloud9.us-east-1.amazonaws.com vfs.cloud9.us-east-1.amazonaws.com webview-assets.cloud9.us-east-1.amazonaws.com webview-assets.aws-cloud9.us-east-2.amazonaws.com vfs.cloud9.us-east-2.amazonaws.com webview-assets.cloud9.us-east-2.amazonaws.com webview-assets.aws-cloud9.us-west-1.amazonaws.com vfs.cloud9.us-west-1.amazonaws.com webview-assets.cloud9.us-west-1.amazonaws.com webview-assets.aws-cloud9.us-west-2.amazonaws.com vfs.cloud9.us-west-2.amazonaws.com webview-assets.cloud9.us-west-2.amazonaws.com // AWS Elastic Beanstalk // Submitted by AWS Security // Reference: bb5a965c-dec3-4967-aa22-e306ad064797 cn-north-1.eb.amazonaws.com.cn cn-northwest-1.eb.amazonaws.com.cn elasticbeanstalk.com af-south-1.elasticbeanstalk.com ap-east-1.elasticbeanstalk.com ap-northeast-1.elasticbeanstalk.com ap-northeast-2.elasticbeanstalk.com ap-northeast-3.elasticbeanstalk.com ap-south-1.elasticbeanstalk.com ap-southeast-1.elasticbeanstalk.com ap-southeast-2.elasticbeanstalk.com ap-southeast-3.elasticbeanstalk.com ca-central-1.elasticbeanstalk.com eu-central-1.elasticbeanstalk.com eu-north-1.elasticbeanstalk.com eu-south-1.elasticbeanstalk.com eu-west-1.elasticbeanstalk.com eu-west-2.elasticbeanstalk.com eu-west-3.elasticbeanstalk.com il-central-1.elasticbeanstalk.com me-south-1.elasticbeanstalk.com sa-east-1.elasticbeanstalk.com us-east-1.elasticbeanstalk.com us-east-2.elasticbeanstalk.com us-gov-east-1.elasticbeanstalk.com us-gov-west-1.elasticbeanstalk.com us-west-1.elasticbeanstalk.com us-west-2.elasticbeanstalk.com // (AWS) Elastic Load Balancing // Submitted by Luke Wells // Reference: 12a3d528-1bac-4433-a359-a395867ffed2 *.elb.amazonaws.com.cn *.elb.amazonaws.com // AWS Global Accelerator // Submitted by Daniel Massaguer // Reference: d916759d-a08b-4241-b536-4db887383a6a awsglobalaccelerator.com // eero // Submitted by Yue Kang // Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 eero.online eero-stage.online // concludes Amazon // Amune : https://amune.org/ // Submitted by Team Amune t3l3p0rt.net tele.amune.org // Apigee : https://apigee.com/ // Submitted by Apigee Security Team apigee.io // Apphud : https://apphud.com // Submitted by Alexander Selivanov siiites.com // Appspace : https://www.appspace.com // Submitted by Appspace Security Team appspacehosted.com appspaceusercontent.com // Appudo UG (haftungsbeschränkt) : https://www.appudo.com // Submitted by Alexander Hochbaum appudo.net // Aptible : https://www.aptible.com/ // Submitted by Thomas Orozco on-aptible.com // ASEINet : https://www.aseinet.com/ // Submitted by Asei SEKIGUCHI user.aseinet.ne.jp gv.vc d.gv.vc // Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ // Submitted by Hector Martin user.party.eus // Association potager.org : https://potager.org/ // Submitted by Lunar pimienta.org poivron.org potager.org sweetpepper.org // ASUSTOR Inc. : http://www.asustor.com // Submitted by Vincent Tseng myasustor.com // Atlassian : https://atlassian.com // Submitted by Sam Smyth cdn.prod.atlassian-dev.net // Authentick UG (haftungsbeschränkt) : https://authentick.net // Submitted by Lukas Reschke translated.page // Autocode : https://autocode.com // Submitted by Jacob Lee autocode.dev // AVM : https://avm.de // Submitted by Andreas Weise myfritz.net // AVStack Pte. Ltd. : https://avstack.io // Submitted by Jasper Hugo onavstack.net // AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com // Submitted by James Kennedy *.awdev.ca *.advisor.ws // AZ.pl sp. z.o.o: https://az.pl // Submitted by Krzysztof Wolski ecommerce-shop.pl // b-data GmbH : https://www.b-data.io // Submitted by Olivier Benz b-data.io // backplane : https://www.backplane.io // Submitted by Anthony Voutas backplaneapp.io // Balena : https://www.balena.io // Submitted by Petros Angelatos balena-devices.com // University of Banja Luka : https://unibl.org // Domains for Republic of Srpska administrative entity. // Submitted by Marko Ivanovic rs.ba // Banzai Cloud // Submitted by Janos Matyas *.banzai.cloud app.banzaicloud.io *.backyards.banzaicloud.io // BASE, Inc. : https://binc.jp // Submitted by Yuya NAGASAWA base.ec official.ec buyshop.jp fashionstore.jp handcrafted.jp kawaiishop.jp supersale.jp theshop.jp shopselect.net base.shop // BeagleBoard.org Foundation : https://beagleboard.org // Submitted by Jason Kridner beagleboard.io // Beget Ltd // Submitted by Lev Nekrasov *.beget.app // BetaInABox // Submitted by Adrian betainabox.com // BinaryLane : http://www.binarylane.com // Submitted by Nathan O'Sullivan bnr.la // Bitbucket : http://bitbucket.org // Submitted by Andy Ortlieb bitbucket.io // Blackbaud, Inc. : https://www.blackbaud.com // Submitted by Paul Crowder blackbaudcdn.net // Blatech : http://www.blatech.net // Submitted by Luke Bratch of.je // Blue Bite, LLC : https://bluebite.com // Submitted by Joshua Weiss bluebite.io // Boomla : https://boomla.com // Submitted by Tibor Halter boomla.net // Boutir : https://www.boutir.com // Submitted by Eric Ng Ka Ka boutir.com // Boxfuse : https://boxfuse.com // Submitted by Axel Fontaine boxfuse.io // bplaced : https://www.bplaced.net/ // Submitted by Miroslav Bozic square7.ch bplaced.com bplaced.de square7.de bplaced.net square7.net // Brendly : https://brendly.rs // Submitted by Dusan Radovanovic shop.brendly.rs // BrowserSafetyMark // Submitted by Dave Tharp browsersafetymark.io // Bytemark Hosting : https://www.bytemark.co.uk // Submitted by Paul Cammish uk0.bigv.io dh.bytemark.co.uk vm.bytemark.co.uk // Caf.js Labs LLC : https://www.cafjs.com // Submitted by Antonio Lain cafjs.com // callidomus : https://www.callidomus.com/ // Submitted by Marcus Popp mycd.eu // Canva Pty Ltd : https://canva.com/ // Submitted by Joel Aquilina canva-apps.cn canva-apps.com // Carrd : https://carrd.co // Submitted by AJ drr.ac uwu.ai carrd.co crd.co ju.mp // CentralNic : http://www.centralnic.com/names/domains // Submitted by registry ae.org br.com cn.com com.de com.se de.com eu.com gb.net hu.net jp.net jpn.com mex.com ru.com sa.com se.net uk.com uk.net us.com za.bz za.com // No longer operated by CentralNic, these entries should be adopted and/or removed by current operators // Submitted by Gavin Brown ar.com hu.com kr.com no.com qc.com uy.com // Africa.com Web Solutions Ltd : https://registry.africa.com // Submitted by Gavin Brown africa.com // iDOT Services Limited : http://www.domain.gr.com // Submitted by Gavin Brown gr.com // Radix FZC : http://domains.in.net // Submitted by Gavin Brown in.net web.in // US REGISTRY LLC : http://us.org // Submitted by Gavin Brown us.org // co.com Registry, LLC : https://registry.co.com // Submitted by Gavin Brown co.com // Roar Domains LLC : https://roar.basketball/ // Submitted by Gavin Brown aus.basketball nz.basketball // BRS Media : https://brsmedia.com/ // Submitted by Gavin Brown radio.am radio.fm // c.la : http://www.c.la/ c.la // certmgr.org : https://certmgr.org // Submitted by B. Blechschmidt certmgr.org // Cityhost LLC : https://cityhost.ua // Submitted by Maksym Rivtin cx.ua // Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ // Submitted by Rishabh Nambiar & Michael Brown discourse.group discourse.team // Clever Cloud : https://www.clever-cloud.com/ // Submitted by Quentin Adam cleverapps.io // Clerk : https://www.clerk.dev // Submitted by Colin Sidoti clerk.app clerkstage.app *.lcl.dev *.lclstage.dev *.stg.dev *.stgstage.dev // ClickRising : https://clickrising.com/ // Submitted by Umut Gumeli clickrising.net // Cloud66 : https://www.cloud66.com/ // Submitted by Khash Sajadi c66.me cloud66.ws cloud66.zone // CloudAccess.net : https://www.cloudaccess.net/ // Submitted by Pawel Panek jdevcloud.com wpdevcloud.com cloudaccess.host freesite.host cloudaccess.net // cloudControl : https://www.cloudcontrol.com/ // Submitted by Tobias Wilken cloudcontrolled.com cloudcontrolapp.com // Cloudera, Inc. : https://www.cloudera.com/ // Submitted by Kedarnath Waikar *.cloudera.site // Cloudflare, Inc. : https://www.cloudflare.com/ // Submitted by Cloudflare Team cf-ipfs.com cloudflare-ipfs.com trycloudflare.com pages.dev r2.dev workers.dev // Clovyr : https://clovyr.io // Submitted by Patrick Nielsen wnext.app // co.ca : http://registry.co.ca/ co.ca // Co & Co : https://co-co.nl/ // Submitted by Govert Versluis *.otap.co // i-registry s.r.o. : http://www.i-registry.cz/ // Submitted by Martin Semrad co.cz // CDN77.com : http://www.cdn77.com // Submitted by Jan Krpes c.cdn77.org cdn77-ssl.net r.cdn77.net rsc.cdn77.org ssl.origin.cdn77-secure.org // Cloud DNS Ltd : http://www.cloudns.net // Submitted by Aleksander Hristov cloudns.asia cloudns.biz cloudns.club cloudns.cc cloudns.eu cloudns.in cloudns.info cloudns.org cloudns.pro cloudns.pw cloudns.us // CNPY : https://cnpy.gdn // Submitted by Angelo Gladding cnpy.gdn // Codeberg e. V. : https://codeberg.org // Submitted by Moritz Marquardt codeberg.page // CoDNS B.V. co.nl co.no // Combell.com : https://www.combell.com // Submitted by Thomas Wouters webhosting.be hosting-cluster.nl // Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ // Submitted by George Georgievsky ac.ru edu.ru gov.ru int.ru mil.ru test.ru // COSIMO GmbH : http://www.cosimo.de // Submitted by Rene Marticke dyn.cosidns.de dynamisches-dns.de dnsupdater.de internet-dns.de l-o-g-i-n.de dynamic-dns.info feste-ip.net knx-server.net static-access.net // Craynic, s.r.o. : http://www.craynic.com/ // Submitted by Ales Krajnik realm.cz // Cryptonomic : https://cryptonomic.net/ // Submitted by Andrew Cady *.cryptonomic.net // Cupcake : https://cupcake.io/ // Submitted by Jonathan Rudenberg cupcake.is // Curv UG : https://curv-labs.de/ // Submitted by Marvin Wiesner curv.dev // Customer OCI - Oracle Dyn https://cloud.oracle.com/home https://dyn.com/dns/ // Submitted by Gregory Drake // Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label *.customer-oci.com *.oci.customer-oci.com *.ocp.customer-oci.com *.ocs.customer-oci.com // cyon GmbH : https://www.cyon.ch/ // Submitted by Dominic Luechinger cyon.link cyon.site // Danger Science Group: https://dangerscience.com/ // Submitted by Skylar MacDonald fnwk.site folionetwork.site platform0.app // Daplie, Inc : https://daplie.com // Submitted by AJ ONeal daplie.me localhost.daplie.me // Datto, Inc. : https://www.datto.com/ // Submitted by Philipp Heckel dattolocal.com dattorelay.com dattoweb.com mydatto.com dattolocal.net mydatto.net // Dansk.net : http://www.dansk.net/ // Submitted by Anani Voule biz.dk co.dk firm.dk reg.dk store.dk // dappnode.io : https://dappnode.io/ // Submitted by Abel Boldu / DAppNode Team dyndns.dappnode.io // dapps.earth : https://dapps.earth/ // Submitted by Daniil Burdakov *.dapps.earth *.bzz.dapps.earth // Dark, Inc. : https://darklang.com // Submitted by Paul Biggar builtwithdark.com // DataDetect, LLC. : https://datadetect.com // Submitted by Andrew Banchich demo.datadetect.com instance.datadetect.com // Datawire, Inc : https://www.datawire.io // Submitted by Richard Li edgestack.me // DDNS5 : https://ddns5.com // Submitted by Cameron Elliott ddns5.com // Debian : https://www.debian.org/ // Submitted by Peter Palfrader / Debian Sysadmin Team debian.net // Deno Land Inc : https://deno.com/ // Submitted by Luca Casonato deno.dev deno-staging.dev // deSEC : https://desec.io/ // Submitted by Peter Thomassen dedyn.io // Deta: https://www.deta.sh/ // Submitted by Aavash Shrestha deta.app deta.dev // Diher Solutions : https://diher.solutions // Submitted by Didi Hermawan *.rss.my.id *.diher.solutions // Discord Inc : https://discord.com // Submitted by Sahn Lam discordsays.com discordsez.com // DNS Africa Ltd https://dns.business // Submitted by Calvin Browne jozi.biz // DNShome : https://www.dnshome.de/ // Submitted by Norbert Auler dnshome.de // DotArai : https://www.dotarai.com/ // Submitted by Atsadawat Netcharadsang online.th shop.th // DrayTek Corp. : https://www.draytek.com/ // Submitted by Paul Fang drayddns.com // DreamCommerce : https://shoper.pl/ // Submitted by Konrad Kotarba shoparena.pl // DreamHost : http://www.dreamhost.com/ // Submitted by Andrew Farmer dreamhosters.com // Drobo : http://www.drobo.com/ // Submitted by Ricardo Padilha mydrobo.com // Drud Holdings, LLC. : https://www.drud.com/ // Submitted by Kevin Bridges drud.io drud.us // DuckDNS : http://www.duckdns.org/ // Submitted by Richard Harper duckdns.org // Bip : https://bip.sh // Submitted by Joel Kennedy bip.sh // bitbridge.net : Submitted by Craig Welch, abeliidev@gmail.com bitbridge.net // dy.fi : http://dy.fi/ // Submitted by Heikki Hannikainen dy.fi tunk.org // DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ dyndns-at-home.com dyndns-at-work.com dyndns-blog.com dyndns-free.com dyndns-home.com dyndns-ip.com dyndns-mail.com dyndns-office.com dyndns-pics.com dyndns-remote.com dyndns-server.com dyndns-web.com dyndns-wiki.com dyndns-work.com dyndns.biz dyndns.info dyndns.org dyndns.tv at-band-camp.net ath.cx barrel-of-knowledge.info barrell-of-knowledge.info better-than.tv blogdns.com blogdns.net blogdns.org blogsite.org boldlygoingnowhere.org broke-it.net buyshouses.net cechire.com dnsalias.com dnsalias.net dnsalias.org dnsdojo.com dnsdojo.net dnsdojo.org does-it.net doesntexist.com doesntexist.org dontexist.com dontexist.net dontexist.org doomdns.com doomdns.org dvrdns.org dyn-o-saur.com dynalias.com dynalias.net dynalias.org dynathome.net dyndns.ws endofinternet.net endofinternet.org endoftheinternet.org est-a-la-maison.com est-a-la-masion.com est-le-patron.com est-mon-blogueur.com for-better.biz for-more.biz for-our.info for-some.biz for-the.biz forgot.her.name forgot.his.name from-ak.com from-al.com from-ar.com from-az.net from-ca.com from-co.net from-ct.com from-dc.com from-de.com from-fl.com from-ga.com from-hi.com from-ia.com from-id.com from-il.com from-in.com from-ks.com from-ky.com from-la.net from-ma.com from-md.com from-me.org from-mi.com from-mn.com from-mo.com from-ms.com from-mt.com from-nc.com from-nd.com from-ne.com from-nh.com from-nj.com from-nm.com from-nv.com from-ny.net from-oh.com from-ok.com from-or.com from-pa.com from-pr.com from-ri.com from-sc.com from-sd.com from-tn.com from-tx.com from-ut.com from-va.com from-vt.com from-wa.com from-wi.com from-wv.com from-wy.com ftpaccess.cc fuettertdasnetz.de game-host.org game-server.cc getmyip.com gets-it.net go.dyndns.org gotdns.com gotdns.org groks-the.info groks-this.info ham-radio-op.net here-for-more.info hobby-site.com hobby-site.org home.dyndns.org homedns.org homeftp.net homeftp.org homeip.net homelinux.com homelinux.net homelinux.org homeunix.com homeunix.net homeunix.org iamallama.com in-the-band.net is-a-anarchist.com is-a-blogger.com is-a-bookkeeper.com is-a-bruinsfan.org is-a-bulls-fan.com is-a-candidate.org is-a-caterer.com is-a-celticsfan.org is-a-chef.com is-a-chef.net is-a-chef.org is-a-conservative.com is-a-cpa.com is-a-cubicle-slave.com is-a-democrat.com is-a-designer.com is-a-doctor.com is-a-financialadvisor.com is-a-geek.com is-a-geek.net is-a-geek.org is-a-green.com is-a-guru.com is-a-hard-worker.com is-a-hunter.com is-a-knight.org is-a-landscaper.com is-a-lawyer.com is-a-liberal.com is-a-libertarian.com is-a-linux-user.org is-a-llama.com is-a-musician.com is-a-nascarfan.com is-a-nurse.com is-a-painter.com is-a-patsfan.org is-a-personaltrainer.com is-a-photographer.com is-a-player.com is-a-republican.com is-a-rockstar.com is-a-socialist.com is-a-soxfan.org is-a-student.com is-a-teacher.com is-a-techie.com is-a-therapist.com is-an-accountant.com is-an-actor.com is-an-actress.com is-an-anarchist.com is-an-artist.com is-an-engineer.com is-an-entertainer.com is-by.us is-certified.com is-found.org is-gone.com is-into-anime.com is-into-cars.com is-into-cartoons.com is-into-games.com is-leet.com is-lost.org is-not-certified.com is-saved.org is-slick.com is-uberleet.com is-very-bad.org is-very-evil.org is-very-good.org is-very-nice.org is-very-sweet.org is-with-theband.com isa-geek.com isa-geek.net isa-geek.org isa-hockeynut.com issmarterthanyou.com isteingeek.de istmein.de kicks-ass.net kicks-ass.org knowsitall.info land-4-sale.us lebtimnetz.de leitungsen.de likes-pie.com likescandy.com merseine.nu mine.nu misconfused.org mypets.ws myphotos.cc neat-url.com office-on-the.net on-the-web.tv podzone.net podzone.org readmyblog.org saves-the-whales.com scrapper-site.net scrapping.cc selfip.biz selfip.com selfip.info selfip.net selfip.org sells-for-less.com sells-for-u.com sells-it.net sellsyourhome.org servebbs.com servebbs.net servebbs.org serveftp.net serveftp.org servegame.org shacknet.nu simple-url.com space-to-rent.com stuff-4-sale.org stuff-4-sale.us teaches-yoga.com thruhere.net traeumtgerade.de webhop.biz webhop.info webhop.net webhop.org worse-than.tv writesthisblog.com // ddnss.de : https://www.ddnss.de/ // Submitted by Robert Niedziela ddnss.de dyn.ddnss.de dyndns.ddnss.de dyndns1.de dyn-ip24.de home-webserver.de dyn.home-webserver.de myhome-server.de ddnss.org // Definima : http://www.definima.com/ // Submitted by Maxence Bitterli definima.net definima.io // DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ // Submitted by Braxton Huggins ondigitalocean.app // DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ // Submitted by Robin H. Johnson *.digitaloceanspaces.com // dnstrace.pro : https://dnstrace.pro/ // Submitted by Chris Partridge bci.dnstrace.pro // Dynu.com : https://www.dynu.com/ // Submitted by Sue Ye ddnsfree.com ddnsgeek.com giize.com gleeze.com kozow.com loseyourip.com ooguy.com theworkpc.com casacam.net dynu.net accesscam.org camdvr.org freeddns.org mywire.org webredirect.org myddns.rocks blogsite.xyz // dynv6 : https://dynv6.com // Submitted by Dominik Menke dynv6.net // E4YOU spol. s.r.o. : https://e4you.cz/ // Submitted by Vladimir Dudr e4.cz // Easypanel : https://easypanel.io // Submitted by Andrei Canta easypanel.app easypanel.host // Elementor : Elementor Ltd. // Submitted by Anton Barkan elementor.cloud elementor.cool // En root‽ : https://en-root.org // Submitted by Emmanuel Raviart en-root.fr // Enalean SAS: https://www.enalean.com // Submitted by Thomas Cottier mytuleap.com tuleap-partners.com // Encoretivity AB: https://encore.dev // Submitted by André Eriksson encr.app encoreapi.com // ECG Robotics, Inc: https://ecgrobotics.org // Submitted by onred.one staging.onred.one // encoway GmbH : https://www.encoway.de // Submitted by Marcel Daus eu.encoway.cloud // EU.org https://eu.org/ // Submitted by Pierre Beyssac eu.org al.eu.org asso.eu.org at.eu.org au.eu.org be.eu.org bg.eu.org ca.eu.org cd.eu.org ch.eu.org cn.eu.org cy.eu.org cz.eu.org de.eu.org dk.eu.org edu.eu.org ee.eu.org es.eu.org fi.eu.org fr.eu.org gr.eu.org hr.eu.org hu.eu.org ie.eu.org il.eu.org in.eu.org int.eu.org is.eu.org it.eu.org jp.eu.org kr.eu.org lt.eu.org lu.eu.org lv.eu.org mc.eu.org me.eu.org mk.eu.org mt.eu.org my.eu.org net.eu.org ng.eu.org nl.eu.org no.eu.org nz.eu.org paris.eu.org pl.eu.org pt.eu.org q-a.eu.org ro.eu.org ru.eu.org se.eu.org si.eu.org sk.eu.org tr.eu.org uk.eu.org us.eu.org // Eurobyte : https://eurobyte.ru // Submitted by Evgeniy Subbotin eurodir.ru // Evennode : http://www.evennode.com/ // Submitted by Michal Kralik eu-1.evennode.com eu-2.evennode.com eu-3.evennode.com eu-4.evennode.com us-1.evennode.com us-2.evennode.com us-3.evennode.com us-4.evennode.com // eDirect Corp. : https://hosting.url.com.tw/ // Submitted by C.S. chang twmail.cc twmail.net twmail.org mymailer.com.tw url.tw // Fabrica Technologies, Inc. : https://www.fabrica.dev/ // Submitted by Eric Jiang onfabrica.com // Facebook, Inc. // Submitted by Peter Ruibal apps.fbsbx.com // FAITID : https://faitid.org/ // Submitted by Maxim Alzoba // https://www.flexireg.net/stat_info ru.net adygeya.ru bashkiria.ru bir.ru cbg.ru com.ru dagestan.ru grozny.ru kalmykia.ru kustanai.ru marine.ru mordovia.ru msk.ru mytis.ru nalchik.ru nov.ru pyatigorsk.ru spb.ru vladikavkaz.ru vladimir.ru abkhazia.su adygeya.su aktyubinsk.su arkhangelsk.su armenia.su ashgabad.su azerbaijan.su balashov.su bashkiria.su bryansk.su bukhara.su chimkent.su dagestan.su east-kazakhstan.su exnet.su georgia.su grozny.su ivanovo.su jambyl.su kalmykia.su kaluga.su karacol.su karaganda.su karelia.su khakassia.su krasnodar.su kurgan.su kustanai.su lenug.su mangyshlak.su mordovia.su msk.su murmansk.su nalchik.su navoi.su north-kazakhstan.su nov.su obninsk.su penza.su pokrovsk.su sochi.su spb.su tashkent.su termez.su togliatti.su troitsk.su tselinograd.su tula.su tuva.su vladikavkaz.su vladimir.su vologda.su // Fancy Bits, LLC : http://getchannels.com // Submitted by Aman Gupta channelsdvr.net u.channelsdvr.net // Fastly Inc. : http://www.fastly.com/ // Submitted by Fastly Security edgecompute.app fastly-edge.com fastly-terrarium.com fastlylb.net map.fastlylb.net freetls.fastly.net map.fastly.net a.prod.fastly.net global.prod.fastly.net a.ssl.fastly.net b.ssl.fastly.net global.ssl.fastly.net // Fastmail : https://www.fastmail.com/ // Submitted by Marc Bradshaw *.user.fm // FASTVPS EESTI OU : https://fastvps.ru/ // Submitted by Likhachev Vasiliy fastvps-server.com fastvps.host myfast.host fastvps.site myfast.space // Fedora : https://fedoraproject.org/ // submitted by Patrick Uiterwijk fedorainfracloud.org fedorapeople.org cloud.fedoraproject.org app.os.fedoraproject.org app.os.stg.fedoraproject.org // FearWorks Media Ltd. : https://fearworksmedia.co.uk // submitted by Keith Fairley conn.uk copro.uk hosp.uk // Fermax : https://fermax.com/ // submitted by Koen Van Isterdael mydobiss.com // FH Muenster : https://www.fh-muenster.de // Submitted by Robin Naundorf fh-muenster.io // Filegear Inc. : https://www.filegear.com // Submitted by Jason Zhu filegear.me filegear-au.me filegear-de.me filegear-gb.me filegear-ie.me filegear-jp.me filegear-sg.me // Firebase, Inc. // Submitted by Chris Raynor firebaseapp.com // Firewebkit : https://www.firewebkit.com // Submitted by Majid Qureshi fireweb.app // FLAP : https://www.flap.cloud // Submitted by Louis Chemineau flap.id // FlashDrive : https://flashdrive.io // Submitted by Eric Chan onflashdrive.app fldrv.com // fly.io: https://fly.io // Submitted by Kurt Mackey fly.dev edgeapp.net shw.io // Flynn : https://flynn.io // Submitted by Jonathan Rudenberg flynnhosting.net // Forgerock : https://www.forgerock.com // Submitted by Roderick Parr forgeblocks.com id.forgerock.io // Framer : https://www.framer.com // Submitted by Koen Rouwhorst framer.app framercanvas.com framer.media framer.photos framer.website framer.wiki // Frusky MEDIA&PR : https://www.frusky.de // Submitted by Victor Pupynin *.frusky.de // RavPage : https://www.ravpage.co.il // Submitted by Roni Horowitz ravpage.co.il // Frederik Braun https://frederik-braun.com // Submitted by Frederik Braun 0e.vc // Freebox : http://www.freebox.fr // Submitted by Romain Fliedel freebox-os.com freeboxos.com fbx-os.fr fbxos.fr freebox-os.fr freeboxos.fr // freedesktop.org : https://www.freedesktop.org // Submitted by Daniel Stone freedesktop.org // freemyip.com : https://freemyip.com // Submitted by Cadence freemyip.com // FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at // Submitted by Daniel A. Maierhofer wien.funkfeuer.at // Futureweb GmbH : https://www.futureweb.at // Submitted by Andreas Schnederle-Wagner *.futurecms.at *.ex.futurecms.at *.in.futurecms.at futurehosting.at futuremailing.at *.ex.ortsinfo.at *.kunden.ortsinfo.at *.statics.cloud // GDS : https://www.gov.uk/service-manual/technology/managing-domain-names // Submitted by Stephen Ford independent-commission.uk independent-inquest.uk independent-inquiry.uk independent-panel.uk independent-review.uk public-inquiry.uk royal-commission.uk campaign.gov.uk service.gov.uk // CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk // Submitted by Jamie Tanna api.gov.uk // Gehirn Inc. : https://www.gehirn.co.jp/ // Submitted by Kohei YOSHIDA gehirn.ne.jp usercontent.jp // Gentlent, Inc. : https://www.gentlent.com // Submitted by Tom Klein gentapps.com gentlentapis.com lab.ms cdn-edges.net // Ghost Foundation : https://ghost.org // Submitted by Matt Hanley ghost.io // GignoSystemJapan: http://gsj.bz // Submitted by GignoSystemJapan gsj.bz // GitHub, Inc. // Submitted by Patrick Toomey githubusercontent.com githubpreview.dev github.io // GitLab, Inc. // Submitted by Alex Hanselka gitlab.io // Gitplac.si - https://gitplac.si // Submitted by Aljaž Starc gitapp.si gitpage.si // Glitch, Inc : https://glitch.com // Submitted by Mads Hartmann glitch.me // Global NOG Alliance : https://nogalliance.org/ // Submitted by Sander Steffann nog.community // Globe Hosting SRL : https://www.globehosting.com/ // Submitted by Gavin Brown co.ro shop.ro // GMO Pepabo, Inc. : https://pepabo.com/ // Submitted by Hosting Div lolipop.io angry.jp babyblue.jp babymilk.jp backdrop.jp bambina.jp bitter.jp blush.jp boo.jp boy.jp boyfriend.jp but.jp candypop.jp capoo.jp catfood.jp cheap.jp chicappa.jp chillout.jp chips.jp chowder.jp chu.jp ciao.jp cocotte.jp coolblog.jp cranky.jp cutegirl.jp daa.jp deca.jp deci.jp digick.jp egoism.jp fakefur.jp fem.jp flier.jp floppy.jp fool.jp frenchkiss.jp girlfriend.jp girly.jp gloomy.jp gonna.jp greater.jp hacca.jp heavy.jp her.jp hiho.jp hippy.jp holy.jp hungry.jp icurus.jp itigo.jp jellybean.jp kikirara.jp kill.jp kilo.jp kuron.jp littlestar.jp lolipopmc.jp lolitapunk.jp lomo.jp lovepop.jp lovesick.jp main.jp mods.jp mond.jp mongolian.jp moo.jp namaste.jp nikita.jp nobushi.jp noor.jp oops.jp parallel.jp parasite.jp pecori.jp peewee.jp penne.jp pepper.jp perma.jp pigboat.jp pinoko.jp punyu.jp pupu.jp pussycat.jp pya.jp raindrop.jp readymade.jp sadist.jp schoolbus.jp secret.jp staba.jp stripper.jp sub.jp sunnyday.jp thick.jp tonkotsu.jp under.jp upper.jp velvet.jp verse.jp versus.jp vivian.jp watson.jp weblike.jp whitesnow.jp zombie.jp heteml.net // GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ // Submitted by Tom Whitwell cloudapps.digital london.cloudapps.digital // GOV.UK Pay : https://www.payments.service.gov.uk/ // Submitted by Richard Baker pymnt.uk // GlobeHosting, Inc. // Submitted by Zoltan Egresi ro.im // GoIP DNS Services : http://www.goip.de // Submitted by Christian Poulter goip.de // Google, Inc. // Submitted by Eduardo Vela run.app a.run.app web.app *.0emm.com appspot.com *.r.appspot.com codespot.com googleapis.com googlecode.com pagespeedmobilizer.com publishproxy.com withgoogle.com withyoutube.com *.gateway.dev cloud.goog translate.goog *.usercontent.goog cloudfunctions.net blogspot.ae blogspot.al blogspot.am blogspot.ba blogspot.be blogspot.bg blogspot.bj blogspot.ca blogspot.cf blogspot.ch blogspot.cl blogspot.co.at blogspot.co.id blogspot.co.il blogspot.co.ke blogspot.co.nz blogspot.co.uk blogspot.co.za blogspot.com blogspot.com.ar blogspot.com.au blogspot.com.br blogspot.com.by blogspot.com.co blogspot.com.cy blogspot.com.ee blogspot.com.eg blogspot.com.es blogspot.com.mt blogspot.com.ng blogspot.com.tr blogspot.com.uy blogspot.cv blogspot.cz blogspot.de blogspot.dk blogspot.fi blogspot.fr blogspot.gr blogspot.hk blogspot.hr blogspot.hu blogspot.ie blogspot.in blogspot.is blogspot.it blogspot.jp blogspot.kr blogspot.li blogspot.lt blogspot.lu blogspot.md blogspot.mk blogspot.mr blogspot.mx blogspot.my blogspot.nl blogspot.no blogspot.pe blogspot.pt blogspot.qa blogspot.re blogspot.ro blogspot.rs blogspot.ru blogspot.se blogspot.sg blogspot.si blogspot.sk blogspot.sn blogspot.td blogspot.tw blogspot.ug blogspot.vn // Goupile : https://goupile.fr // Submitted by Niels Martignene goupile.fr // Government of the Netherlands: https://www.government.nl // Submitted by gov.nl // Group 53, LLC : https://www.group53.com // Submitted by Tyler Todd awsmppl.com // GünstigBestellen : https://günstigbestellen.de // Submitted by Furkan Akkoc xn--gnstigbestellen-zvb.de xn--gnstigliefern-wob.de // Hakaran group: http://hakaran.cz // Submitted by Arseniy Sokolov fin.ci free.hr caa.li ua.rs conf.se // Handshake : https://handshake.org // Submitted by Mike Damm hs.zone hs.run // Hashbang : https://hashbang.sh hashbang.sh // Hasura : https://hasura.io // Submitted by Shahidh K Muhammed hasura.app hasura-app.io // Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages): https://www.hs-heilbronn.de // Submitted by Richard Zowalla pages.it.hs-heilbronn.de // Hepforge : https://www.hepforge.org // Submitted by David Grellscheid hepforge.org // Heroku : https://www.heroku.com/ // Submitted by Tom Maher herokuapp.com herokussl.com // Hibernating Rhinos // Submitted by Oren Eini ravendb.cloud ravendb.community ravendb.me development.run ravendb.run // home.pl S.A.: https://home.pl // Submitted by Krzysztof Wolski homesklep.pl // Hong Kong Productivity Council: https://www.hkpc.org/ // Submitted by SECaaS Team secaas.hk // Hoplix : https://www.hoplix.com // Submitted by Danilo De Franco hoplix.shop // HOSTBIP REGISTRY : https://www.hostbip.com/ // Submitted by Atanunu Igbunuroghene orx.biz biz.gl col.ng firm.ng gen.ng ltd.ng ngo.ng edu.scot sch.so // HostFly : https://www.ie.ua // Submitted by Bohdan Dub ie.ua // HostyHosting (hostyhosting.com) hostyhosting.io // Häkkinen.fi // Submitted by Eero Häkkinen xn--hkkinen-5wa.fi // Ici la Lune : http://www.icilalune.com/ // Submitted by Simon Morvan *.moonscale.io moonscale.net // iki.fi // Submitted by Hannu Aronsson iki.fi // iliad italia: https://www.iliad.it // Submitted by Marios Makassikis ibxos.it iliadboxos.it // Impertrix Solutions : // Submitted by Zhixiang Zhao impertrixcdn.com impertrix.com // Incsub, LLC: https://incsub.com/ // Submitted by Aaron Edwards smushcdn.com wphostedmail.com wpmucdn.com tempurl.host wpmudev.host // Individual Network Berlin e.V. : https://www.in-berlin.de/ // Submitted by Christian Seitz dyn-berlin.de in-berlin.de in-brb.de in-butter.de in-dsl.de in-dsl.net in-dsl.org in-vpn.de in-vpn.net in-vpn.org // info.at : http://www.info.at/ biz.at info.at // info.cx : http://info.cx // Submitted by Jacob Slater info.cx // Interlegis : http://www.interlegis.leg.br // Submitted by Gabriel Ferreira ac.leg.br al.leg.br am.leg.br ap.leg.br ba.leg.br ce.leg.br df.leg.br es.leg.br go.leg.br ma.leg.br mg.leg.br ms.leg.br mt.leg.br pa.leg.br pb.leg.br pe.leg.br pi.leg.br pr.leg.br rj.leg.br rn.leg.br ro.leg.br rr.leg.br rs.leg.br sc.leg.br se.leg.br sp.leg.br to.leg.br // intermetrics GmbH : https://pixolino.com/ // Submitted by Wolfgang Schwarz pixolino.com // Internet-Pro, LLP: https://netangels.ru/ // Submitted by Vasiliy Sheredeko na4u.ru // iopsys software solutions AB : https://iopsys.eu/ // Submitted by Roman Azarenko iopsys.se // IPiFony Systems, Inc. : https://www.ipifony.com/ // Submitted by Matthew Hardeman ipifony.net // IServ GmbH : https://iserv.de // Submitted by Mario Hoberg iservschule.de mein-iserv.de schulplattform.de schulserver.de test-iserv.de iserv.dev // I-O DATA DEVICE, INC. : http://www.iodata.com/ // Submitted by Yuji Minagawa iobb.net // Jelastic, Inc. : https://jelastic.com/ // Submitted by Ihor Kolodyuk mel.cloudlets.com.au cloud.interhostsolutions.be mycloud.by alp1.ae.flow.ch appengine.flow.ch es-1.axarnet.cloud diadem.cloud vip.jelastic.cloud jele.cloud it1.eur.aruba.jenv-aruba.cloud it1.jenv-aruba.cloud keliweb.cloud cs.keliweb.cloud oxa.cloud tn.oxa.cloud uk.oxa.cloud primetel.cloud uk.primetel.cloud ca.reclaim.cloud uk.reclaim.cloud us.reclaim.cloud ch.trendhosting.cloud de.trendhosting.cloud jele.club amscompute.com dopaas.com paas.hosted-by-previder.com rag-cloud.hosteur.com rag-cloud-ch.hosteur.com jcloud.ik-server.com jcloud-ver-jpc.ik-server.com demo.jelastic.com kilatiron.com paas.massivegrid.com jed.wafaicloud.com lon.wafaicloud.com ryd.wafaicloud.com j.scaleforce.com.cy jelastic.dogado.eu fi.cloudplatform.fi demo.datacenter.fi paas.datacenter.fi jele.host mircloud.host paas.beebyte.io sekd1.beebyteapp.io jele.io cloud-fr1.unispace.io jc.neen.it cloud.jelastic.open.tim.it jcloud.kz upaas.kazteleport.kz cloudjiffy.net fra1-de.cloudjiffy.net west1-us.cloudjiffy.net jls-sto1.elastx.net jls-sto2.elastx.net jls-sto3.elastx.net faststacks.net fr-1.paas.massivegrid.net lon-1.paas.massivegrid.net lon-2.paas.massivegrid.net ny-1.paas.massivegrid.net ny-2.paas.massivegrid.net sg-1.paas.massivegrid.net jelastic.saveincloud.net nordeste-idc.saveincloud.net j.scaleforce.net jelastic.tsukaeru.net sdscloud.pl unicloud.pl mircloud.ru jelastic.regruhosting.ru enscaled.sg jele.site jelastic.team orangecloud.tn j.layershift.co.uk phx.enscaled.us mircloud.us // Jino : https://www.jino.ru // Submitted by Sergey Ulyashin myjino.ru *.hosting.myjino.ru *.landing.myjino.ru *.spectrum.myjino.ru *.vps.myjino.ru // Jotelulu S.L. : https://jotelulu.com // Submitted by Daniel Fariña jotelulu.cloud // Joyent : https://www.joyent.com/ // Submitted by Brian Bennett *.triton.zone *.cns.joyent.com // JS.ORG : http://dns.js.org // Submitted by Stefan Keim js.org // KaasHosting : http://www.kaashosting.nl/ // Submitted by Wouter Bakker kaas.gg khplay.nl // Kakao : https://www.kakaocorp.com/ // Submitted by JaeYoong Lee ktistory.com // Kapsi : https://kapsi.fi // Submitted by Tomi Juntunen kapsi.fi // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl keymachine.de // KingHost : https://king.host // Submitted by Felipe Keller Braz kinghost.net uni5.net // KnightPoint Systems, LLC : http://www.knightpoint.com/ // Submitted by Roy Keene knightpoint.systems // KoobinEvent, SL: https://www.koobin.com // Submitted by Iván Oliva koobin.events // KUROKU LTD : https://kuroku.ltd/ // Submitted by DisposaBoy oya.to // Katholieke Universiteit Leuven: https://www.kuleuven.be // Submitted by Abuse KU Leuven kuleuven.cloud ezproxy.kuleuven.be // .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf co.krd edu.krd // Krellian Ltd. : https://krellian.com // Submitted by Ben Francis krellian.net webthings.io // LCube - Professional hosting e.K. : https://www.lcube-webhosting.de // Submitted by Lars Laehn git-repos.de lcube-server.de svn-repos.de // Leadpages : https://www.leadpages.net // Submitted by Greg Dallavalle leadpages.co lpages.co lpusercontent.com // Lelux.fi : https://lelux.fi/ // Submitted by Lelux Admin lelux.site // Lifetime Hosting : https://Lifetime.Hosting/ // Submitted by Mike Fillator co.business co.education co.events co.financial co.network co.place co.technology // Lightmaker Property Manager, Inc. : https://app.lmpm.com/ // Submitted by Greg Holland app.lmpm.com // linkyard ldt: https://www.linkyard.ch/ // Submitted by Mario Siegenthaler linkyard.cloud linkyard-cloud.ch // Linode : https://linode.com // Submitted by members.linode.com *.nodebalancer.linode.com *.linodeobjects.com ip.linodeusercontent.com // LiquidNet Ltd : http://www.liquidnetlimited.com/ // Submitted by Victor Velchev we.bs // Localcert : https://localcert.dev // Submitted by Lann Martin *.user.localcert.dev // localzone.xyz // Submitted by Kenny Niehage localzone.xyz // Log'in Line : https://www.loginline.com/ // Submitted by Rémi Mach loginline.app loginline.dev loginline.io loginline.services loginline.site // Lokalized : https://lokalized.nl // Submitted by Noah Taheij servers.run // Lõhmus Family, The // Submitted by Heiki Lõhmus lohmus.me // LubMAN UMCS Sp. z o.o : https://lubman.pl/ // Submitted by Ireneusz Maliszewski krasnik.pl leczna.pl lubartow.pl lublin.pl poniatowa.pl swidnik.pl // Lug.org.uk : https://lug.org.uk // Submitted by Jon Spriggs glug.org.uk lug.org.uk lugs.org.uk // Lukanet Ltd : https://lukanet.com // Submitted by Anton Avramov barsy.bg barsy.co.uk barsyonline.co.uk barsycenter.com barsyonline.com barsy.club barsy.de barsy.eu barsy.in barsy.info barsy.io barsy.me barsy.menu barsy.mobi barsy.net barsy.online barsy.org barsy.pro barsy.pub barsy.ro barsy.shop barsy.site barsy.support barsy.uk // Magento Commerce // Submitted by Damien Tournoud *.magentosite.cloud // May First - People Link : https://mayfirst.org/ // Submitted by Jamie McClelland mayfirst.info mayfirst.org // Mail.Ru Group : https://hb.cldmail.ru // Submitted by Ilya Zaretskiy hb.cldmail.ru // Mail Transfer Platform : https://www.neupeer.com // Submitted by Li Hui cn.vu // Maze Play: https://www.mazeplay.com // Submitted by Adam Humpherys mazeplay.com // mcpe.me : https://mcpe.me // Submitted by Noa Heyl mcpe.me // McHost : https://mchost.ru // Submitted by Evgeniy Subbotin mcdir.me mcdir.ru mcpre.ru vps.mcdir.ru // Mediatech : https://mediatech.by // Submitted by Evgeniy Kozhuhovskiy mediatech.by mediatech.dev // Medicom Health : https://medicomhealth.com // Submitted by Michael Olson hra.health // Memset hosting : https://www.memset.com // Submitted by Tom Whitwell miniserver.com memset.net // Messerli Informatik AG : https://www.messerli.ch/ // Submitted by Ruben Schmidmeister messerli.app // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Zdeněk Šustr *.cloud.metacentrum.cz custom.metacentrum.cz // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Radim Janča flt.cloud.muni.cz usr.cloud.muni.cz // Meteor Development Group : https://www.meteor.com/hosting // Submitted by Pierre Carrier meteorapp.com eu.meteorapp.com // Michau Enterprises Limited : http://www.co.pl/ co.pl // Microsoft Corporation : http://microsoft.com // Submitted by Public Suffix List Admin *.azurecontainer.io azurewebsites.net azure-mobile.net cloudapp.net azurestaticapps.net 1.azurestaticapps.net 2.azurestaticapps.net 3.azurestaticapps.net 4.azurestaticapps.net 5.azurestaticapps.net 6.azurestaticapps.net 7.azurestaticapps.net centralus.azurestaticapps.net eastasia.azurestaticapps.net eastus2.azurestaticapps.net westeurope.azurestaticapps.net westus2.azurestaticapps.net // minion.systems : http://minion.systems // Submitted by Robert Böttinger csx.cc // Mintere : https://mintere.com/ // Submitted by Ben Aubin mintere.site // MobileEducation, LLC : https://joinforte.com // Submitted by Grayson Martin forte.id // Mozilla Corporation : https://mozilla.com // Submitted by Ben Francis mozilla-iot.org // Mozilla Foundation : https://mozilla.org/ // Submitted by glob bmoattachments.org // MSK-IX : https://www.msk-ix.ru/ // Submitted by Khannanov Roman net.ru org.ru pp.ru // Mythic Beasts : https://www.mythic-beasts.com // Submitted by Paul Cammish hostedpi.com customer.mythic-beasts.com caracal.mythic-beasts.com fentiger.mythic-beasts.com lynx.mythic-beasts.com ocelot.mythic-beasts.com oncilla.mythic-beasts.com onza.mythic-beasts.com sphinx.mythic-beasts.com vs.mythic-beasts.com x.mythic-beasts.com yali.mythic-beasts.com cust.retrosnub.co.uk // Nabu Casa : https://www.nabucasa.com // Submitted by Paulus Schoutsen ui.nabu.casa // Net at Work Gmbh : https://www.netatwork.de // Submitted by Jan Jaeschke cloud.nospamproxy.com // Netlify : https://www.netlify.com // Submitted by Jessica Parsons netlify.app // Neustar Inc. // Submitted by Trung Tran 4u.com // ngrok : https://ngrok.com/ // Submitted by Alan Shreve ngrok.app ngrok-free.app ngrok.dev ngrok-free.dev ngrok.io ap.ngrok.io au.ngrok.io eu.ngrok.io in.ngrok.io jp.ngrok.io sa.ngrok.io us.ngrok.io ngrok.pizza // Nicolaus Copernicus University in Torun - MSK TORMAN (https://www.man.torun.pl) torun.pl // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ // Submitted by Nicholas Ford nh-serv.co.uk // NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ // Submitted by Jeff Wheelhouse nfshost.com // Noop : https://noop.app // Submitted by Nathaniel Schweinberg *.developer.app noop.app // Northflank Ltd. : https://northflank.com/ // Submitted by Marco Suter *.northflank.app *.build.run *.code.run *.database.run *.migration.run // Noticeable : https://noticeable.io // Submitted by Laurent Pellegrino noticeable.news // Now-DNS : https://now-dns.com // Submitted by Steve Russell dnsking.ch mypi.co n4t.co 001www.com ddnslive.com myiphost.com forumz.info 16-b.it 32-b.it 64-b.it soundcast.me tcp4.me dnsup.net hicam.net now-dns.net ownip.net vpndns.net dynserv.org now-dns.org x443.pw now-dns.top ntdll.top freeddns.us crafting.xyz zapto.xyz // nsupdate.info : https://www.nsupdate.info/ // Submitted by Thomas Waldmann nsupdate.info nerdpol.ovh // No-IP.com : https://noip.com/ // Submitted by Deven Reza blogsyte.com brasilia.me cable-modem.org ciscofreak.com collegefan.org couchpotatofries.org damnserver.com ddns.me ditchyourip.com dnsfor.me dnsiskinky.com dvrcam.info dynns.com eating-organic.net fantasyleague.cc geekgalaxy.com golffan.us health-carereform.com homesecuritymac.com homesecuritypc.com hopto.me ilovecollege.info loginto.me mlbfan.org mmafan.biz myactivedirectory.com mydissent.net myeffect.net mymediapc.net mypsx.net mysecuritycamera.com mysecuritycamera.net mysecuritycamera.org net-freaks.com nflfan.org nhlfan.net no-ip.ca no-ip.co.uk no-ip.net noip.us onthewifi.com pgafan.net point2this.com pointto.us privatizehealthinsurance.net quicksytes.com read-books.org securitytactics.com serveexchange.com servehumour.com servep2p.com servesarcasm.com stufftoread.com ufcfan.org unusualperson.com workisboring.com 3utilities.com bounceme.net ddns.net ddnsking.com gotdns.ch hopto.org myftp.biz myftp.org myvnc.com no-ip.biz no-ip.info no-ip.org noip.me redirectme.net servebeer.com serveblog.net servecounterstrike.com serveftp.com servegame.com servehalflife.com servehttp.com serveirc.com serveminecraft.net servemp3.com servepics.com servequake.com sytes.net webhop.me zapto.org // NodeArt : https://nodeart.io // Submitted by Konstantin Nosov stage.nodeart.io // Nucleos Inc. : https://nucleos.com // Submitted by Piotr Zduniak pcloud.host // NYC.mn : http://www.information.nyc.mn // Submitted by Matthew Brown nyc.mn // Observable, Inc. : https://observablehq.com // Submitted by Mike Bostock static.observableusercontent.com // Octopodal Solutions, LLC. : https://ulterius.io/ // Submitted by Andrew Sampson cya.gg // OMG.LOL : // Submitted by Adam Newbold omg.lol // Omnibond Systems, LLC. : https://www.omnibond.com // Submitted by Cole Estep cloudycluster.net // OmniWe Limited: https://omniwe.com // Submitted by Vicary Archangel omniwe.site // One.com: https://www.one.com/ // Submitted by Jacob Bunk Nielsen 123hjemmeside.dk 123hjemmeside.no 123homepage.it 123kotisivu.fi 123minsida.se 123miweb.es 123paginaweb.pt 123sait.ru 123siteweb.fr 123webseite.at 123webseite.de 123website.be 123website.ch 123website.lu 123website.nl service.one simplesite.com simplesite.com.br simplesite.gr simplesite.pl // One Fold Media : http://www.onefoldmedia.com/ // Submitted by Eddie Jones nid.io // Open Social : https://www.getopensocial.com/ // Submitted by Alexander Varwijk opensocial.site // OpenCraft GmbH : http://opencraft.com/ // Submitted by Sven Marnach opencraft.hosting // OpenResearch GmbH: https://openresearch.com/ // Submitted by Philipp Schmid orsites.com // Opera Software, A.S.A. // Submitted by Yngve Pettersen operaunite.com // Orange : https://www.orange.com // Submitted by Alexandre Linte tech.orange // Oursky Limited : https://authgear.com/, https://skygear.io/ // Submitted by Authgear Team , Skygear Developer authgear-staging.com authgearapps.com skygearapp.com // OutSystems // Submitted by Duarte Santos outsystemscloud.com // OVHcloud: https://ovhcloud.com // Submitted by Vincent Cassé *.webpaas.ovh.net *.hosting.ovh.net // OwnProvider GmbH: http://www.ownprovider.com // Submitted by Jan Moennich ownprovider.com own.pm // OwO : https://whats-th.is/ // Submitted by Dean Sheather *.owo.codes // OX : http://www.ox.rs // Submitted by Adam Grand ox.rs // oy.lc // Submitted by Charly Coste oy.lc // Pagefog : https://pagefog.com/ // Submitted by Derek Myers pgfog.com // Pagefront : https://www.pagefronthq.com/ // Submitted by Jason Kriss pagefrontapp.com // PageXL : https://pagexl.com // Submitted by Yann Guichard pagexl.com // Paywhirl, Inc : https://paywhirl.com/ // Submitted by Daniel Netzer *.paywhirl.com // pcarrier.ca Software Inc: https://pcarrier.ca/ // Submitted by Pierre Carrier bar0.net bar1.net bar2.net rdv.to // .pl domains (grandfathered) art.pl gliwice.pl krakow.pl poznan.pl wroc.pl zakopane.pl // Pantheon Systems, Inc. : https://pantheon.io/ // Submitted by Gary Dylina pantheonsite.io gotpantheon.com // Peplink | Pepwave : http://peplink.com/ // Submitted by Steve Leung mypep.link // Perspecta : https://perspecta.com/ // Submitted by Kenneth Van Alstyne perspecta.cloud // PE Ulyanov Kirill Sergeevich : https://airy.host // Submitted by Kirill Ulyanov lk3.ru // Planet-Work : https://www.planet-work.com/ // Submitted by Frédéric VANNIÈRE on-web.fr // Platform.sh : https://platform.sh // Submitted by Nikola Kotur bc.platform.sh ent.platform.sh eu.platform.sh us.platform.sh *.platformsh.site *.tst.site // Platter: https://platter.dev // Submitted by Patrick Flor platter-app.com platter-app.dev platterp.us // Plesk : https://www.plesk.com/ // Submitted by Anton Akhtyamov pdns.page plesk.page pleskns.com // Port53 : https://port53.io/ // Submitted by Maximilian Schieder dyn53.io // Porter : https://porter.run/ // Submitted by Rudraksh MK onporter.run // Positive Codes Technology Company : http://co.bn/faq.html // Submitted by Zulfais co.bn // Postman, Inc : https://postman.com // Submitted by Rahul Dhawan postman-echo.com pstmn.io mock.pstmn.io httpbin.org //prequalifyme.today : https://prequalifyme.today //Submitted by DeepakTiwari deepak@ivylead.io prequalifyme.today // prgmr.com : https://prgmr.com/ // Submitted by Sarah Newman xen.prgmr.com // priv.at : http://www.nic.priv.at/ // Submitted by registry priv.at // privacytools.io : https://www.privacytools.io/ // Submitted by Jonah Aragon prvcy.page // Protocol Labs : https://protocol.ai/ // Submitted by Michael Burns *.dweb.link // Protonet GmbH : http://protonet.io // Submitted by Martin Meier protonet.io // Publication Presse Communication SARL : https://ppcom.fr // Submitted by Yaacov Akiba Slama chirurgiens-dentistes-en-france.fr byen.site // pubtls.org: https://www.pubtls.org // Submitted by Kor Nielsen pubtls.org // PythonAnywhere LLP: https://www.pythonanywhere.com // Submitted by Giles Thomas pythonanywhere.com eu.pythonanywhere.com // QOTO, Org. // Submitted by Jeffrey Phillips Freeman qoto.io // Qualifio : https://qualifio.com/ // Submitted by Xavier De Cock qualifioapp.com // Quality Unit: https://qualityunit.com // Submitted by Vasyl Tsalko ladesk.com // QuickBackend: https://www.quickbackend.com // Submitted by Dani Biro qbuser.com // Rad Web Hosting: https://radwebhosting.com // Submitted by Scott Claeys cloudsite.builders // Redgate Software: https://red-gate.com // Submitted by Andrew Farries instances.spawn.cc // Redstar Consultants : https://www.redstarconsultants.com/ // Submitted by Jons Slemmer instantcloud.cn // Russian Academy of Sciences // Submitted by Tech Support ras.ru // QA2 // Submitted by Daniel Dent (https://www.danieldent.com/) qa2.com // QCX // Submitted by Cassandra Beelen qcx.io *.sys.qcx.io // QNAP System Inc : https://www.qnap.com // Submitted by Nick Chang dev-myqnapcloud.com alpha-myqnapcloud.com myqnapcloud.com // Quip : https://quip.com // Submitted by Patrick Linehan *.quipelements.com // Qutheory LLC : http://qutheory.io // Submitted by Jonas Schwartz vapor.cloud vaporcloud.io // Rackmaze LLC : https://www.rackmaze.com // Submitted by Kirill Pertsev rackmaze.com rackmaze.net // Rakuten Games, Inc : https://dev.viberplay.io // Submitted by Joshua Zhang g.vbrplsbx.io // Rancher Labs, Inc : https://rancher.com // Submitted by Vincent Fiduccia *.on-k3s.io *.on-rancher.cloud *.on-rio.io // Read The Docs, Inc : https://www.readthedocs.org // Submitted by David Fischer readthedocs.io // Red Hat, Inc. OpenShift : https://openshift.redhat.com/ // Submitted by Tim Kramer rhcloud.com // Render : https://render.com // Submitted by Anurag Goel app.render.com onrender.com // Repl.it : https://repl.it // Submitted by Lincoln Bergeson firewalledreplit.co id.firewalledreplit.co repl.co id.repl.co repl.run // Resin.io : https://resin.io // Submitted by Tim Perry resindevice.io devices.resinstaging.io // RethinkDB : https://www.rethinkdb.com/ // Submitted by Chris Kastorff hzc.io // Revitalised Limited : http://www.revitalised.co.uk // Submitted by Jack Price wellbeingzone.eu wellbeingzone.co.uk // Rico Developments Limited : https://adimo.co // Submitted by Colin Brown adimo.co.uk // Riseup Networks : https://riseup.net // Submitted by Micah Anderson itcouldbewor.se // Rochester Institute of Technology : http://www.rit.edu/ // Submitted by Jennifer Herting git-pages.rit.edu // Rocky Enterprise Software Foundation : https://resf.org // Submitted by Neil Hanlon rocky.page // Rusnames Limited: http://rusnames.ru/ // Submitted by Sergey Zotov xn--90amc.xn--p1acf xn--j1aef.xn--p1acf xn--j1ael8b.xn--p1acf xn--h1ahn.xn--p1acf xn--j1adp.xn--p1acf xn--c1avg.xn--p1acf xn--80aaa0cvac.xn--p1acf xn--h1aliz.xn--p1acf xn--90a1af.xn--p1acf xn--41a.xn--p1acf // SAKURA Internet Inc. : https://www.sakura.ad.jp/ // Submitted by Internet Service Department 180r.com dojin.com sakuratan.com sakuraweb.com x0.com 2-d.jp bona.jp crap.jp daynight.jp eek.jp flop.jp halfmoon.jp jeez.jp matrix.jp mimoza.jp ivory.ne.jp mail-box.ne.jp mints.ne.jp mokuren.ne.jp opal.ne.jp sakura.ne.jp sumomo.ne.jp topaz.ne.jp netgamers.jp nyanta.jp o0o0.jp rdy.jp rgr.jp rulez.jp s3.isk01.sakurastorage.jp s3.isk02.sakurastorage.jp saloon.jp sblo.jp skr.jp tank.jp uh-oh.jp undo.jp rs.webaccel.jp user.webaccel.jp websozai.jp xii.jp squares.net jpn.org kirara.st x0.to from.tv sakura.tv // Salesforce.com, Inc. https://salesforce.com/ // Submitted by Michael Biven *.builder.code.com *.dev-builder.code.com *.stg-builder.code.com // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia sandcats.io // SBE network solutions GmbH : https://www.sbe.de/ // Submitted by Norman Meilick logoip.de logoip.com // Scaleway : https://www.scaleway.com/ // Submitted by Rémy Léone fr-par-1.baremetal.scw.cloud fr-par-2.baremetal.scw.cloud nl-ams-1.baremetal.scw.cloud fnc.fr-par.scw.cloud functions.fnc.fr-par.scw.cloud k8s.fr-par.scw.cloud nodes.k8s.fr-par.scw.cloud s3.fr-par.scw.cloud s3-website.fr-par.scw.cloud whm.fr-par.scw.cloud priv.instances.scw.cloud pub.instances.scw.cloud k8s.scw.cloud k8s.nl-ams.scw.cloud nodes.k8s.nl-ams.scw.cloud s3.nl-ams.scw.cloud s3-website.nl-ams.scw.cloud whm.nl-ams.scw.cloud k8s.pl-waw.scw.cloud nodes.k8s.pl-waw.scw.cloud s3.pl-waw.scw.cloud s3-website.pl-waw.scw.cloud scalebook.scw.cloud smartlabeling.scw.cloud dedibox.fr // schokokeks.org GbR : https://schokokeks.org/ // Submitted by Hanno Böck schokokeks.net // Scottish Government: https://www.gov.scot // Submitted by Martin Ellis gov.scot service.gov.scot // Scry Security : http://www.scrysec.com // Submitted by Shante Adam scrysec.com // Securepoint GmbH : https://www.securepoint.de // Submitted by Erik Anders firewall-gateway.com firewall-gateway.de my-gateway.de my-router.de spdns.de spdns.eu firewall-gateway.net my-firewall.org myfirewall.org spdns.org // Seidat : https://www.seidat.com // Submitted by Artem Kondratev seidat.net // Sellfy : https://sellfy.com // Submitted by Yuriy Romadin sellfy.store // Senseering GmbH : https://www.senseering.de // Submitted by Felix Mönckemeyer senseering.net // Sendmsg: https://www.sendmsg.co.il // Submitted by Assaf Stern minisite.ms // Service Magnet : https://myservicemagnet.com // Submitted by Dave Sanders magnet.page // Service Online LLC : http://drs.ua/ // Submitted by Serhii Bulakh biz.ua co.ua pp.ua // Shift Crypto AG : https://shiftcrypto.ch // Submitted by alex shiftcrypto.dev shiftcrypto.io // ShiftEdit : https://shiftedit.net/ // Submitted by Adam Jimenez shiftedit.io // Shopblocks : http://www.shopblocks.com/ // Submitted by Alex Bowers myshopblocks.com // Shopify : https://www.shopify.com // Submitted by Alex Richter myshopify.com // Shopit : https://www.shopitcommerce.com/ // Submitted by Craig McMahon shopitsite.com // shopware AG : https://shopware.com // Submitted by Jens Küper shopware.store // Siemens Mobility GmbH // Submitted by Oliver Graebner mo-siemens.io // SinaAppEngine : http://sae.sina.com.cn/ // Submitted by SinaAppEngine 1kapp.com appchizi.com applinzi.com sinaapp.com vipsinaapp.com // Siteleaf : https://www.siteleaf.com/ // Submitted by Skylar Challand siteleaf.net // Skyhat : http://www.skyhat.io // Submitted by Shante Adam bounty-full.com alpha.bounty-full.com beta.bounty-full.com // Smallregistry by Promopixel SARL: https://www.smallregistry.net // Former AFNIC's SLDs // Submitted by Jérôme Lipowicz aeroport.fr avocat.fr chambagri.fr chirurgiens-dentistes.fr experts-comptables.fr medecin.fr notaires.fr pharmacien.fr port.fr veterinaire.fr // Small Technology Foundation : https://small-tech.org // Submitted by Aral Balkan small-web.org // Smoove.io : https://www.smoove.io/ // Submitted by Dan Kozak vp4.me // Snowflake Inc : https://www.snowflake.com/ // Submitted by Faith Olapade snowflake.app privatelink.snowflake.app streamlit.app streamlitapp.com // Snowplow Analytics : https://snowplowanalytics.com/ // Submitted by Ian Streeter try-snowplow.com // SourceHut : https://sourcehut.org // Submitted by Drew DeVault srht.site // Stackhero : https://www.stackhero.io // Submitted by Adrien Gillon stackhero-network.com // Staclar : https://staclar.com // Submitted by Q Misell musician.io // Submitted by Matthias Merkel novecore.site // staticland : https://static.land // Submitted by Seth Vincent static.land dev.static.land sites.static.land // Storebase : https://www.storebase.io // Submitted by Tony Schirmer storebase.store // Strategic System Consulting (eApps Hosting): https://www.eapps.com/ // Submitted by Alex Oancea vps-host.net atl.jelastic.vps-host.net njs.jelastic.vps-host.net ric.jelastic.vps-host.net // Sony Interactive Entertainment LLC : https://sie.com/ // Submitted by David Coles playstation-cloud.com // SourceLair PC : https://www.sourcelair.com // Submitted by Antonis Kalipetis apps.lair.io *.stolos.io // SpaceKit : https://www.spacekit.io/ // Submitted by Reza Akhavan spacekit.io // SpeedPartner GmbH: https://www.speedpartner.de/ // Submitted by Stefan Neufeind customer.speedpartner.de // Spreadshop (sprd.net AG) : https://www.spreadshop.com/ // Submitted by Martin Breest myspreadshop.at myspreadshop.com.au myspreadshop.be myspreadshop.ca myspreadshop.ch myspreadshop.com myspreadshop.de myspreadshop.dk myspreadshop.es myspreadshop.fi myspreadshop.fr myspreadshop.ie myspreadshop.it myspreadshop.net myspreadshop.nl myspreadshop.no myspreadshop.pl myspreadshop.se myspreadshop.co.uk // Standard Library : https://stdlib.com // Submitted by Jacob Lee api.stdlib.com // Storipress : https://storipress.com // Submitted by Benno Liu storipress.app // Storj Labs Inc. : https://storj.io/ // Submitted by Philip Hutchins storj.farm // Studenten Net Twente : http://www.snt.utwente.nl/ // Submitted by Silke Hofstra utwente.io // Student-Run Computing Facility : https://www.srcf.net/ // Submitted by Edwin Balani soc.srcf.net user.srcf.net // Sub 6 Limited: http://www.sub6.com // Submitted by Dan Miller temp-dns.com // Supabase : https://supabase.io // Submitted by Inian Parameshwaran supabase.co supabase.in supabase.net su.paba.se // Symfony, SAS : https://symfony.com/ // Submitted by Fabien Potencier *.s5y.io *.sensiosite.cloud // Syncloud : https://syncloud.org // Submitted by Boris Rybalkin syncloud.it // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng dscloud.biz direct.quickconnect.cn dsmynas.com familyds.com diskstation.me dscloud.me i234.me myds.me synology.me dscloud.mobi dsmynas.net familyds.net dsmynas.org familyds.org vpnplus.to direct.quickconnect.to // Tabit Technologies Ltd. : https://tabit.cloud/ // Submitted by Oren Agiv tabitorder.co.il mytabit.co.il mytabit.com // TAIFUN Software AG : http://taifun-software.de // Submitted by Bjoern Henke taifun-dns.de // Tailscale Inc. : https://www.tailscale.com // Submitted by David Anderson beta.tailscale.net ts.net // TASK geographical domains (www.task.gda.pl/uslugi/dns) gda.pl gdansk.pl gdynia.pl med.pl sopot.pl // team.blue https://team.blue // Submitted by Cedric Dubois site.tb-hosting.com // Teckids e.V. : https://www.teckids.org // Submitted by Dominik George edugit.io s3.teckids.org // Telebit : https://telebit.cloud // Submitted by AJ ONeal telebit.app telebit.io *.telebit.xyz // Thingdust AG : https://thingdust.com/ // Submitted by Adrian Imboden *.firenet.ch *.svc.firenet.ch reservd.com thingdustdata.com cust.dev.thingdust.io cust.disrec.thingdust.io cust.prod.thingdust.io cust.testing.thingdust.io reservd.dev.thingdust.io reservd.disrec.thingdust.io reservd.testing.thingdust.io // ticket i/O GmbH : https://ticket.io // Submitted by Christian Franke tickets.io // Tlon.io : https://tlon.io // Submitted by Mark Staarink arvo.network azimuth.network tlon.network // Tor Project, Inc. : https://torproject.org // Submitted by Antoine Beaupré bloxcms.com townnews-staging.com // TrafficPlex GmbH : https://www.trafficplex.de/ // Submitted by Phillipp Röll 12hp.at 2ix.at 4lima.at lima-city.at 12hp.ch 2ix.ch 4lima.ch lima-city.ch trafficplex.cloud de.cool 12hp.de 2ix.de 4lima.de lima-city.de 1337.pictures clan.rip lima-city.rocks webspace.rocks lima.zone // TransIP : https://www.transip.nl // Submitted by Rory Breuk *.transurl.be *.transurl.eu *.transurl.nl // TransIP: https://www.transip.nl // Submitted by Cedric Dubois site.transip.me // TuxFamily : http://tuxfamily.org // Submitted by TuxFamily administrators tuxfamily.org // TwoDNS : https://www.twodns.de/ // Submitted by TwoDNS-Support dd-dns.de diskstation.eu diskstation.org dray-dns.de draydns.de dyn-vpn.de dynvpn.de mein-vigor.de my-vigor.de my-wan.de syno-ds.de synology-diskstation.de synology-ds.de // Typedream : https://typedream.com // Submitted by Putri Karunia typedream.app // Typeform : https://www.typeform.com // Submitted by Sergi Ferriz pro.typeform.com // Uberspace : https://uberspace.de // Submitted by Moritz Werner uber.space *.uberspace.de // UDR Limited : http://www.udr.hk.com // Submitted by registry hk.com hk.org ltd.hk inc.hk // UK Intis Telecom LTD : https://it.com // Submitted by ITComdomains it.com // UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ // see also: whois -h whois.udr.org.yt help // Submitted by Atanunu Igbunuroghene name.pm sch.tf biz.wf sch.wf org.yt // United Gameserver GmbH : https://united-gameserver.de // Submitted by Stefan Schwarz virtualuser.de virtual-user.de // Upli : https://upli.io // Submitted by Lenny Bakkalian upli.io // urown.net : https://urown.net // Submitted by Hostmaster urown.cloud dnsupdate.info // .US // Submitted by Ed Moore lib.de.us // VeryPositive SIA : http://very.lv // Submitted by Danko Aleksejevs 2038.io // Vercel, Inc : https://vercel.com/ // Submitted by Connor Davis vercel.app vercel.dev now.sh // Viprinet Europe GmbH : http://www.viprinet.com // Submitted by Simon Kissel router.management // Virtual-Info : https://www.virtual-info.info/ // Submitted by Adnan RIHAN v-info.info // Voorloper.com: https://voorloper.com // Submitted by Nathan van Bakel voorloper.cloud // Voxel.sh DNS : https://voxel.sh/dns/ // Submitted by Mia Rehlinger neko.am nyaa.am be.ax cat.ax es.ax eu.ax gg.ax mc.ax us.ax xy.ax nl.ci xx.gl app.gp blog.gt de.gt to.gt be.gy cc.hn blog.kg io.kg jp.kg tv.kg uk.kg us.kg de.ls at.md de.md jp.md to.md indie.porn vxl.sh ch.tc me.tc we.tc nyan.to at.vg blog.vu dev.vu me.vu // V.UA Domain Administrator : https://domain.v.ua/ // Submitted by Serhii Rostilo v.ua // Vultr Objects : https://www.vultr.com/products/object-storage/ // Submitted by Niels Maumenee *.vultrobjects.com // Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com // Submitted by Masayuki Note wafflecell.com // WebHare bv: https://www.webhare.com/ // Submitted by Arnold Hendriks *.webhare.dev // WebHotelier Technologies Ltd: https://www.webhotelier.net/ // Submitted by Apostolos Tsakpinis reserve-online.net reserve-online.com bookonline.app hotelwithflight.com // WeDeploy by Liferay, Inc. : https://www.wedeploy.com // Submitted by Henrique Vicente wedeploy.io wedeploy.me wedeploy.sh // Western Digital Technologies, Inc : https://www.wdc.com // Submitted by Jung Jin remotewd.com // WIARD Enterprises : https://wiardweb.com // Submitted by Kidd Hustle pages.wiardweb.com // Wikimedia Labs : https://wikitech.wikimedia.org // Submitted by Arturo Borrero Gonzalez wmflabs.org toolforge.org wmcloud.org // WISP : https://wisp.gg // Submitted by Stepan Fedotov panel.gg daemon.panel.gg // Wizard Zines : https://wizardzines.com // Submitted by Julia Evans messwithdns.com // WoltLab GmbH : https://www.woltlab.com // Submitted by Tim Düsterhus woltlab-demo.com myforum.community community-pro.de diskussionsbereich.de community-pro.net meinforum.net // Woods Valldata : https://www.woodsvalldata.co.uk/ // Submitted by Chris Whittle affinitylottery.org.uk raffleentry.org.uk weeklylottery.org.uk // WP Engine : https://wpengine.com/ // Submitted by Michael Smith // Submitted by Brandon DuRette wpenginepowered.com js.wpenginepowered.com // Wix.com, Inc. : https://www.wix.com // Submitted by Shahar Talmi wixsite.com editorx.io wixstudio.io wix.run // XenonCloud GbR: https://xenoncloud.net // Submitted by Julian Uphoff half.host // XnBay Technology : http://www.xnbay.com/ // Submitted by XnBay Developer xnbay.com u2.xnbay.com u2-local.xnbay.com // XS4ALL Internet bv : https://www.xs4all.nl/ // Submitted by Daniel Mostertman cistron.nl demon.nl xs4all.space // Yandex.Cloud LLC: https://cloud.yandex.com // Submitted by Alexander Lodin yandexcloud.net storage.yandexcloud.net website.yandexcloud.net // YesCourse Pty Ltd : https://yescourse.com // Submitted by Atul Bhouraskar official.academy // Yola : https://www.yola.com/ // Submitted by Stefano Rivera yolasite.com // Yombo : https://yombo.net // Submitted by Mitch Schwenk ybo.faith yombo.me homelink.one ybo.party ybo.review ybo.science ybo.trade // Yunohost : https://yunohost.org // Submitted by Valentin Grimaud ynh.fr nohost.me noho.st // ZaNiC : http://www.za.net/ // Submitted by registry za.net za.org // Zine EOOD : https://zine.bg/ // Submitted by Martin Angelov bss.design // Zitcom A/S : https://www.zitcom.dk // Submitted by Emil Stahl basicserver.io virtualserver.io enterprisecloud.nu // ===END PRIVATE DOMAINS=== END_BUILTIN_DATA 1; IO-Socket-SSL-2.085/lib/IO/Socket/SSL/Intercept.pm0000644000175000017500000002622314521466373021053 0ustar steffensteffen package IO::Socket::SSL::Intercept; use strict; use warnings; use Carp 'croak'; use IO::Socket::SSL::Utils; use Net::SSLeay; our $VERSION = '2.056'; sub new { my ($class,%args) = @_; my $cacert = delete $args{proxy_cert}; if ( ! $cacert ) { if ( my $f = delete $args{proxy_cert_file} ) { $cacert = PEM_file2cert($f); } else { croak "no proxy_cert or proxy_cert_file given"; } } my $cakey = delete $args{proxy_key}; if ( ! $cakey ) { if ( my $f = delete $args{proxy_key_file} ) { $cakey = PEM_file2key($f); } else { croak "no proxy_cert or proxy_cert_file given"; } } my $certkey = delete $args{cert_key}; if ( ! $certkey ) { if ( my $f = delete $args{cert_key_file} ) { $certkey = PEM_file2key($f); } } my $cache = delete $args{cache} || {}; if (ref($cache) eq 'CODE') { # check cache type my $type = $cache->('type'); if (!$type) { # old cache interface - change into new interface # get: $cache->(fp) # set: $cache->(fp,cert,key) my $oc = $cache; $cache = sub { my ($fp,$create_cb) = @_; my @ck = $oc->($fp); $oc->($fp, @ck = &$create_cb) if !@ck; return @ck; }; } elsif ($type == 1) { # current interface: # get/set: $cache->(fp,cb_create) } else { die "invalid type of cache: $type"; } } my $self = bless { cacert => $cacert, cakey => $cakey, certkey => $certkey, cache => $cache, serial => delete $args{serial}, }; return $self; } sub DESTROY { # call various ssl _free routines my $self = shift or return; for ( \$self->{cacert}, map { \$_->{cert} } ref($self->{cache}) ne 'CODE' ? values %{$self->{cache}} :()) { $$_ or next; CERT_free($$_); $$_ = undef; } for ( \$self->{cakey}, \$self->{pubkey} ) { $$_ or next; KEY_free($$_); $$_ = undef; } } sub clone_cert { my ($self,$old_cert,$clone_key) = @_; my $hash = CERT_asHash($old_cert); my $create_cb = sub { # if not in cache create new certificate based on original # copy most but not all extensions if (my $ext = $hash->{ext}) { @$ext = grep { defined($_->{sn}) && $_->{sn} !~m{^(?: authorityInfoAccess | subjectKeyIdentifier | authorityKeyIdentifier | certificatePolicies | crlDistributionPoints )$}x } @$ext; } my ($clone,$key) = CERT_create( %$hash, ignore_invalid_args => 1, issuer_cert => $self->{cacert}, issuer_key => $self->{cakey}, key => $self->{certkey}, serial => ! defined($self->{serial}) ? (unpack('L',$hash->{x509_digest_sha256}))[0] : ref($self->{serial}) eq 'CODE' ? $self->{serial}($old_cert,$hash) : ++$self->{serial}, ); return ($clone,$key); }; $clone_key ||= substr(unpack("H*", $hash->{x509_digest_sha256}),0,32); my $c = $self->{cache}; return $c->($clone_key,$create_cb) if ref($c) eq 'CODE'; my $e = $c->{$clone_key} ||= do { my ($cert,$key) = &$create_cb; { cert => $cert, key => $key }; }; $e->{atime} = time(); return ($e->{cert},$e->{key}); } sub STORABLE_freeze { my $self = shift; $self->serialize() } sub STORABLE_thaw { my ($class,undef,$data) = @_; $class->unserialize($data) } sub serialize { my $self = shift; my $data = pack("N",2); # version $data .= pack("N/a", PEM_cert2string($self->{cacert})); $data .= pack("N/a", PEM_key2string($self->{cakey})); if ( $self->{certkey} ) { $data .= pack("N/a", PEM_key2string($self->{certkey})); } else { $data .= pack("N/a", ''); } $data .= pack("N",$self->{serial}); if ( ref($self->{cache}) eq 'HASH' ) { while ( my($k,$v) = each %{ $self->{cache}} ) { $data .= pack("N/aN/aN/aN", $k, PEM_cert2string($k->{cert}), $k->{key} ? PEM_key2string($k->{key}) : '', $k->{atime}); } } return $data; } sub unserialize { my ($class,$data) = @_; unpack("N",substr($data,0,4,'')) == 2 or croak("serialized with wrong version"); ( my $cacert,my $cakey,my $certkey,my $serial,$data) = unpack("N/aN/aN/aNa*",$data); my $self = bless { serial => $serial, cacert => PEM_string2cert($cacert), cakey => PEM_string2key($cakey), $certkey ? ( certkey => PEM_string2key($certkey)):(), }, ref($class)||$class; $self->{cache} = {} if $data ne ''; while ( $data ne '' ) { (my $key,my $cert,my $certkey, my $atime,$data) = unpack("N/aN/aNa*",$data); $self->{cache}{$key} = { cert => PEM_string2cert($cert), $key ? ( key => PEM_string2key($certkey)):(), atime => $atime }; } return $self; } 1; __END__ =head1 NAME IO::Socket::SSL::Intercept -- SSL interception (man in the middle) =head1 SYNOPSIS use IO::Socket::SSL::Intercept; # create interceptor with proxy certificates my $mitm = IO::Socket::SSL::Intercept->new( proxy_cert_file => 'proxy_cert.pem', proxy_key_file => 'proxy_key.pem', ... ); my $listen = IO::Socket::INET->new( LocalAddr => .., Listen => .. ); while (1) { # TCP accept new client my $client = $listen->accept or next; # SSL connect to server my $server = IO::Socket::SSL->new( PeerAddr => .., SSL_verify_mode => ..., ... ) or die "ssl connect failed: $!,$SSL_ERROR"; # clone server certificate my ($cert,$key) = $mitm->clone_cert( $server->peer_certificate ); # and upgrade client side to SSL with cloned certificate IO::Socket::SSL->start_SSL($client, SSL_server => 1, SSL_cert => $cert, SSL_key => $key ) or die "upgrade failed: $SSL_ERROR"; # now transfer data between $client and $server and analyze # the unencrypted data ... } =head1 DESCRIPTION This module provides functionality to clone certificates and sign them with a proxy certificate, thus making it easy to intercept SSL connections (man in the middle). It also manages a cache of the generated certificates. =head1 How Intercepting SSL Works Intercepting SSL connections is useful for analyzing encrypted traffic for security reasons or for testing. It does not break the end-to-end security of SSL, e.g. a properly written client will notice the interception unless you explicitly configure the client to trust your interceptor. Intercepting SSL works the following way: =over 4 =item * Create a new CA certificate, which will be used to sign the cloned certificates. This proxy CA certificate should be trusted by the client, or (a properly written client) will throw error messages or deny the connections because it detected a man in the middle attack. Due to the way the interception works there no support for client side certificates is possible. Using openssl such a proxy CA certificate and private key can be created with: openssl genrsa -out proxy_key.pem 1024 openssl req -new -x509 -extensions v3_ca -key proxy_key.pem -out proxy_cert.pem # export as PKCS12 for import into browser openssl pkcs12 -export -in proxy_cert.pem -inkey proxy_key.pem -out proxy_cert.p12 =item * Configure client to connect to use intercepting proxy or somehow redirect connections from client to the proxy (e.g. packet filter redirects, ARP or DNS spoofing etc). =item * Accept the TCP connection from the client, e.g. don't do any SSL handshakes with the client yet. =item * Establish the SSL connection to the server and verify the servers certificate as usually. Then create a new certificate based on the original servers certificate, but signed by your proxy CA. This is the step where IO::Socket::SSL::Intercept helps. =item * Upgrade the TCP connection to the client to SSL using the cloned certificate from the server. If the client trusts your proxy CA it will accept the upgrade to SSL. =item * Transfer data between client and server. While the connections to client and server are both encrypted with SSL you will read/write the unencrypted data in your proxy application. =back =head1 METHODS IO::Socket::SSL::Intercept helps creating the cloned certificate with the following methods: =over 4 =item B<< $mitm = IO::Socket::SSL::Intercept->new(%args) >> This creates a new interceptor object. C<%args> should be =over 8 =item proxy_cert X509 | proxy_cert_file filename This is the proxy certificate. It can be either given by an X509 object from Ls internal representation, or using a file in PEM format. =item proxy_key EVP_PKEY | proxy_key_file filename This is the key for the proxy certificate. It can be either given by an EVP_PKEY object from Ls internal representation, or using a file in PEM format. The key should not have a passphrase. =item pubkey EVP_PKEY | pubkey_file filename This optional argument specifies the public key used for the cloned certificate. It can be either given by an EVP_PKEY object from Ls internal representation, or using a file in PEM format. If not given it will create a new public key on each call of C. =item serial INTEGER|CODE This optional argument gives the starting point for the serial numbers of the newly created certificates. If not set the serial number will be created based on the digest of the original certificate. If the value is code it will be called with C<< serial(original_cert,CERT_asHash(original_cert)) >> and should return the new serial number. =item cache HASH | SUBROUTINE This optional argument gives a way to cache created certificates, so that they don't get recreated on future accesses to the same host. If the argument ist not given an internal HASH ist used. If the argument is a hash it will store for each generated certificate a hash reference with C and C in the hash, where C is the time of last access (to expire unused entries) and C is the certificate. Please note, that the certificate is in Ls internal X509 format and can thus not be simply dumped and restored. The key for the hash is an C either given to C or generated from the original certificate. If the argument is a subroutine it will be called as C<< $cache->(ident,sub) >>. This call should return either an existing (cached) C<< (cert,key) >> or call C without arguments to create a new C<< (cert,key) >>, store it and return it. If called with C<< $cache->('type') >> the function should just return 1 to signal that it supports the current type of cache. If it reutrns nothing instead the older cache interface is assumed for compatibility reasons. =back =item B<< ($clone_cert,$key) = $mitm->clone_cert($original_cert,[ $ident ]) >> This clones the given certificate. An ident as the key into the cache can be given (like C), if not it will be created from the properties of the original certificate. It returns the cloned certificate and its key (which is the same for alle created certificates). =item B<< $string = $mitm->serialize >> This creates a serialized version of the object (e.g. a string) which can then be used to persistantly store created certificates over restarts of the application. The cache will only be serialized if it is a HASH. To work together with L the C function is defined to call C. =item B<< $mitm = IO::Socket::SSL::Intercept->unserialize($string) >> This restores an Intercept object from a serialized string. To work together with L the C function is defined to call C. =back =head1 AUTHOR Steffen Ullrich IO-Socket-SSL-2.085/lib/IO/Socket/SSL.pod0000644000175000017500000025370414521466373017272 0ustar steffensteffen =head1 NAME IO::Socket::SSL - SSL sockets with IO::Socket interface =head1 SYNOPSIS use strict; use IO::Socket::SSL; # simple client my $cl = IO::Socket::SSL->new('www.google.com:443'); print $cl "GET / HTTP/1.0\r\n\r\n"; print <$cl>; # simple server my $srv = IO::Socket::SSL->new( LocalAddr => '0.0.0.0:1234', Listen => 10, SSL_cert_file => 'server-cert.pem', SSL_key_file => 'server-key.pem', ); $srv->accept; =head1 DESCRIPTION IO::Socket::SSL makes using SSL/TLS much easier by wrapping the necessary functionality into the familiar L interface and providing secure defaults whenever possible. This way, existing applications can be made SSL-aware without much effort, at least if you do blocking I/O and don't use select or poll. But, under the hood, SSL is a complex beast. So there are lots of methods to make it do what you need if the default behavior is not adequate. Because it is easy to inadvertently introduce critical security bugs or just hard to debug problems, I would recommend studying the following documentation carefully. The documentation consists of the following parts: =over 4 =item * L =item * L =item * L =item * L =item * L =item * L =item * L =item * L =item * L =back Additional documentation can be found in =over 4 =item * L - Doing Man-In-The-Middle with SSL =item * L - Useful functions for certificates etc =back =head1 Essential Information About SSL/TLS SSL (Secure Socket Layer) or its successor TLS (Transport Layer Security) are protocols to facilitate end-to-end security. These protocols are used when accessing web sites (https), delivering or retrieving email, and in lots of other use cases. In the following documentation we will refer to both SSL and TLS as simply 'SSL'. SSL enables end-to-end security by providing two essential functions: =over 4 =item Encryption This part encrypts the data for transit between the communicating parties, so that nobody in between can read them. It also provides tamper resistance so that nobody in between can manipulate the data. =item Identification This part makes sure that you talk to the right peer. If the identification is done incorrectly it is easy to mount man-in-the-middle attacks, e.g. if Alice wants to talk to Bob it would be possible for Mallory to put itself in the middle, so that Alice talks to Mallory and Mallory to Bob. All the data would still be encrypted, but not end-to-end between Alice and Bob, but only between Alice and Mallory and then between Mallory and Bob. Thus Mallory would be able to read and modify all traffic between Alice and Bob. =back Identification is the part which is the hardest to understand and the easiest to get wrong. With SSL, the Identification is usually done with B inside a B (Public Key Infrastructure). These Certificates are comparable to an identity card, which contains information about the owner of the card. The card then is somehow B by the B of the card, the B (Certificate Agency). To verify the identity of the peer the following must be done inside SSL: =over 4 =item * Get the certificate from the peer. If the peer does not present a certificate we cannot verify it. =item * Check if we trust the certificate, e.g. make sure it's not a forgery. We believe that a certificate is not a fake if we either know the certificate already or if we B the issuer (the CA) and can verify the issuers signature on the certificate. In reality there is often a hierarchy of certificate agencies and we only directly trust the root of this hierarchy. In this case the peer not only sends his own certificate, but also all B. Verification will be done by building a B from the trusted root up to the peers certificate and checking in each step if the we can verify the issuer's signature. This step often causes problems because the client does not know the necessary trusted root certificates. These are usually stored in a system dependent CA store, but often the browsers have their own CA store. =item * Check if the certificate is still valid. Each certificate has a lifetime and should not be used after that time because it might be compromised or the underlying cryptography got broken in the mean time. =item * Check if the subject of the certificate matches the peer. This is like comparing the picture on the identity card against the person representing the identity card. When connecting to a server this is usually done by comparing the hostname used for connecting against the names represented in the certificate. A certificate might contain multiple names or wildcards, so that it can be used for multiple hosts (e.g. *.example.com and *.example.org). Although nobody sane would accept an identity card where the picture does not match the person we see, it is a common implementation error with SSL to omit this check or get it wrong. =item * Check if the certificate was revoked by the issuer. This might be the case if the certificate was compromised somehow and now somebody else might use it to claim the wrong identity. Such revocations happened a lot after the heartbleed attack. For SSL there are two ways to verify a revocation, CRL and OCSP. With CRLs (Certificate Revocation List) the CA provides a list of serial numbers for revoked certificates. The client somehow has to download the list (which can be huge) and keep it up to date. With OCSP (Online Certificate Status Protocol) the client can check a single certificate directly by asking the issuer. Revocation is the hardest part of the verification and none of today's browsers get it fully correct. But, they are still better than most other implementations which don't implement revocation checks or leave the hard parts to the developer. =back When accessing a web site with SSL or delivering mail in a secure way the identity is usually only checked one way, e.g. the client wants to make sure it talks to the right server, but the server usually does not care which client it talks to. But, sometimes the server wants to identify the client too and will request a certificate from the client which the server must verify in a similar way. =head1 Basic SSL Client A basic SSL client is simple: my $client = IO::Socket::SSL->new('www.example.com:443') or die "error=$!, ssl_error=$SSL_ERROR"; This will take the OpenSSL default CA store as the store for the trusted CA. This usually works on UNIX systems. If there are no certificates in the store it will try use L which provides the default CAs of Firefox. In the default settings, L will use a safer cipher set and SSL version, do a proper hostname check against the certificate, and use SNI (server name indication) to send the hostname inside the SSL handshake. This is necessary to work with servers which have different certificates behind the same IP address. It will also check the revocation of the certificate with OCSP, but currently only if the server provides OCSP stapling (for deeper checks see C method). Lots of options can be used to change ciphers, SSL version, location of CA and much more. See documentation of methods for details. With protocols like SMTP it is necessary to upgrade an existing socket to SSL. This can be done like this: my $client = IO::Socket::INET->new('mx.example.com:25') or die $!; # .. read greeting from server # .. send EHLO and read response # .. send STARTTLS command and read response # .. if response was successful we can upgrade the socket to SSL now: IO::Socket::SSL->start_SSL($client, # explicitly set hostname we should use for SNI SSL_hostname => 'mx.example.com' ) or die $SSL_ERROR; A more complete example for a simple HTTP client: my $client = IO::Socket::SSL->new( # where to connect PeerHost => "www.example.com", PeerPort => "https", # certificate verification - VERIFY_PEER is default SSL_verify_mode => SSL_VERIFY_PEER, # location of CA store # need only be given if default store should not be used SSL_ca_path => '/etc/ssl/certs', # typical CA path on Linux SSL_ca_file => '/etc/ssl/cert.pem', # typical CA file on BSD # or just use default path on system: IO::Socket::SSL::default_ca(), # either explicitly # or implicitly by not giving SSL_ca_* # easy hostname verification # It will use PeerHost as default name a verification # scheme as default, which is safe enough for most purposes. SSL_verifycn_name => 'foo.bar', SSL_verifycn_scheme => 'http', # SNI support - defaults to PeerHost SSL_hostname => 'foo.bar', ) or die "failed connect or ssl handshake: $!,$SSL_ERROR"; # send and receive over SSL connection print $client "GET / HTTP/1.0\r\n\r\n"; print <$client>; And to do revocation checks with OCSP (only available with OpenSSL 1.0.0 or higher and L 1.59 or higher): # default will try OCSP stapling and check only leaf certificate my $client = IO::Socket::SSL->new($dst); # better yet: require checking of full chain my $client = IO::Socket::SSL->new( PeerAddr => $dst, SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN, ); # even better: make OCSP errors fatal # (this will probably fail with lots of sites because of bad OCSP setups) # also use common OCSP response cache my $ocsp_cache = IO::Socket::SSL::OCSP_Cache->new; my $client = IO::Socket::SSL->new( PeerAddr => $dst, SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN|SSL_OCSP_FAIL_HARD, SSL_ocsp_cache => $ocsp_cache, ); # disable OCSP stapling in case server has problems with it my $client = IO::Socket::SSL->new( PeerAddr => $dst, SSL_ocsp_mode => SSL_OCSP_NO_STAPLE, ); # check any certificates which are not yet checked by OCSP stapling or # where we have already cached results. For your own resolving combine # $ocsp->requests with $ocsp->add_response(uri,response). my $ocsp = $client->ocsp_resolver(); my $errors = $ocsp->resolve_blocking(); if ($errors) { warn "OCSP verification failed: $errors"; close($client); } =head1 Basic SSL Server A basic SSL server looks similar to other L servers, only that it also contains settings for certificate and key: # simple server my $server = IO::Socket::SSL->new( # where to listen LocalAddr => '127.0.0.1', LocalPort => 8080, Listen => 10, # which certificate to offer # with SNI support there can be different certificates per hostname SSL_cert_file => 'cert.pem', SSL_key_file => 'key.pem', ) or die "failed to listen: $!"; # accept client my $client = $server->accept or die "failed to accept or ssl handshake: $!,$SSL_ERROR"; This will automatically use a secure set of ciphers and SSL version and also supports Forward Secrecy with (Elliptic-Curve) Diffie-Hellmann Key Exchange. If you are doing a forking or threading server, we recommend that you do the SSL handshake inside the new process/thread so that the master is free for new connections. We recommend this because a client with improper or slow SSL handshake could make the server block in the handshake which would be bad to do on the listening socket: # inet server my $server = IO::Socket::INET->new( # where to listen LocalAddr => '127.0.0.1', LocalPort => 8080, Listen => 10, ); # accept client my $client = $server->accept or die; # SSL upgrade client (in new process/thread) IO::Socket::SSL->start_SSL($client, SSL_server => 1, SSL_cert_file => 'cert.pem', SSL_key_file => 'key.pem', ) or die "failed to ssl handshake: $SSL_ERROR"; Like with normal sockets, neither forking nor threading servers scale well. It is recommended to use non-blocking sockets instead, see L =head1 Common Usage Errors This is a list of typical errors seen with the use of L: =over 4 =item * Disabling verification with C. As described in L, a proper identification of the peer is essential and failing to verify makes Man-In-The-Middle attacks possible. Nevertheless, lots of scripts and even public modules or applications disable verification, because it is probably the easiest way to make the thing work and usually nobody notices any security problems anyway. If the verification does not succeed with the default settings, one can do the following: =over 8 =item * Make sure the needed CAs are in the store, maybe use C or C to specify a different CA store. =item * If the validation fails because the certificate is self-signed and that's what you expect, you can use the C option to accept specific leaf certificates by their certificate or pubkey fingerprint. =item * If the validation failed because the hostname does not match and you cannot access the host with the name given in the certificate, you can use C to specify the hostname you expect in the certificate. =back A common error pattern is also to disable verification if they found no CA store (different modules look at different "default" places). Because L is now able to provide a usable CA store on most platforms (UNIX, Mac OSX and Windows) it is better to use the defaults provided by L. If necessary these can be checked with the C method. =item * Polling of SSL sockets (e.g. select, poll and other event loops). If you sysread one byte on a normal socket it will result in a syscall to read one byte. Thus, if more than one byte is available on the socket it will be kept in the network stack of your OS and the next select or poll call will return the socket as readable. But, with SSL you don't deliver single bytes. Multiple data bytes are packaged and encrypted together in an SSL frame. Decryption can only be done on the whole frame, so a sysread for one byte actually reads the complete SSL frame from the socket, decrypts it and returns the first decrypted byte. Further sysreads will return more bytes from the same frame until all bytes are returned and the next SSL frame will be read from the socket. Thus, in order to decide if you can read more data (e.g. if sysread will block) you must check if there are still data in the current SSL frame by calling C and if there are no data pending you might check the underlying socket with select or poll. Another way might be if you try to sysread at least 16kByte all the time. 16kByte is the maximum size of an SSL frame and because sysread returns data from only a single SSL frame you can guarantee that there are no pending data. Additionally, contrary to plain sockets the data delivered on the socket are not necessarily application payload. It might be a TLS handshake, it might just be the beginning of a TLS record or it might be TLS session tickets which are send after the TLS handshake in TLS 1.3. In such situations select will return that data are available for read since it only looks at the plain socket. A sysread on the IO::Socket::SSL socket will not return any data though since it is an abstraction which only returns application data. This causes the sysread to hang in case the socket was blocking or to return an error with EAGAIN on non-blocking sockets. Applications using select or similar should therefore set the socket to non-blocking and also expect that the sysread might temporarily fail with EAGAIN. See also L. =item * Expecting exactly the same behavior as plain sockets. IO::Socket::SSL tries to emulate the usual socket behavior as good as possible, but full emulation can not be done. Specifically a read on the SSL socket might also result in a write on the TCP socket or a write on the SSL socket might result in a read on the TCP socket. Also C and B on the SSL socket will result in writing and reading data to the TCP socket too. Especially the hidden writes might result in a connection reset if the underlying TCP socket is already closed by the peer. Unless signal PIPE is explicitly handled by the application this will usually result in the application crashing. It is thus recommended to explicitly IGNORE signal PIPE so that the errors get propagated as EPIPE instead of causing a crash of the application. =item * Set 'SSL_version' or 'SSL_cipher_list' to a "better" value. L tries to set these values to reasonable, secure values which are compatible with the rest of the world. But, there are some scripts or modules out there which tried to be smart and get more secure or compatible settings. Unfortunately, they did this years ago and never updated these values, so they are still forced to do only 'TLSv1' (instead of also using TLSv12 or TLSv11). Or they set 'HIGH' as the cipher list and thought they were secure, but did not notice that 'HIGH' includes anonymous ciphers, e.g. without identification of the peer. So it is recommended to leave the settings at the secure defaults which L sets and which get updated from time to time to better fit the real world. =item * Make SSL settings inaccessible by the user, together with bad builtin settings. Some modules use L, but don't make the SSL settings available to the user. This is often combined with bad builtin settings or defaults (like switching verification off). Thus the user needs to hack around these restrictions by using C or similar. =item * Use of constants as strings. Constants like C or C should be used as constants and not be put inside quotes, because they represent numerical values. =item * Forking and handling the socket in parent and child. A B of the process will duplicate the internal user space SSL state of the socket. If both master and child interact with the socket by using their own SSL state strange error messages will happen. Such interaction includes explicit or implicit B of the SSL socket. To avoid this the socket should be explicitly closed with B. =item * Forking and executing a new process. Since the SSL state is stored in user space it will be duplicated by a B but it will be lost when doing B. This means it is not possible to simply redirect stdin and stdout for the new process to the SSL socket by duplicating the relevant file handles. Instead explicitly exchanging plain data between child-process and SSL socket are needed. =back =head1 Common Problems with SSL SSL is a complex protocol with multiple implementations and each of these has their own quirks. While most of these implementations work together, it often gets problematic with older versions, minimal versions in load balancers, or plain wrong setups. Unfortunately these problems are hard to debug. Helpful for debugging are a knowledge of SSL internals, wireshark and the use of the debug settings of L and L, which can both be set with C<$IO::Socket::SSL::DEBUG>. The following debugs levels are defined, but used not in any consistent way: =over 4 =item * 0 - No debugging (default). =item * 1 - Print out errors from L and ciphers from L. =item * 2 - Print also information about call flow from L, progress information from L and state information from OpenSSL. =item * 3 - Print also some data dumps from L and from L. =back Also, C from the ssl-tools repository at L might be a helpful tool when debugging SSL problems, as do the C command line tool and a check with a different SSL implementation (e.g. a web browser). The following problems are not uncommon: =over 4 =item * Bad server setup: missing intermediate certificates. It is a regular problem that administrators fail to include all necessary certificates into their server setup, e.g. everything needed to build the trust chain from the trusted root. If they check the setup with the browser everything looks ok, because browsers work around these problems by caching any intermediate certificates and apply them to new connections if certificates are missing. But, fresh browser profiles which have never seen these intermediates cannot fill in the missing certificates and fail to verify; the same is true with L. =item * Old versions of servers or load balancers which do not understand specific TLS versions or croak on specific data. From time to time one encounters an SSL peer, which just closes the connection inside the SSL handshake. This can usually be worked around by downgrading the SSL version, e.g. by setting C. Modern Browsers usually deal with such servers by automatically downgrading the SSL version and repeat the connection attempt until they succeed. Worse servers do not close the underlying TCP connection but instead just drop the relevant packet. This is harder to detect because it looks like a stalled connection. But downgrading the SSL version often works here too. A cause of such problems are often load balancers or security devices, which have hardware acceleration and only a minimal (and less robust) SSL stack. They can often be detected because they support much fewer ciphers than other implementations. =item * Bad or old OpenSSL versions. L uses OpenSSL with the help of the L library. It is recommend to have a recent version of this library, because it has more features and usually fewer known bugs. =item * Validation of client certificates fail. Make sure that the purpose of the certificate allows use as ssl client (check with C<< openssl x509 -purpose >>, that the necessary root certificate is in the path specified by C (or the default path) and that any intermediate certificates needed to build the trust chain are sent by the client. =item * Validation of self-signed certificate fails even if it is given with C argument. The C arguments do not give a general trust store for arbitrary certificates but only specify a store for CA certificates which then can be used to verify other certificates. This especially means that certificates which are not a CA get simply ignored, notably self-signed certificates which do not also have the CA-flag set. This behavior of OpenSSL differs from the more general trust-store concept which can be found in browsers and where it is possible to simply added arbitrary certificates (CA or not) as trusted. =back =head1 Using Non-Blocking Sockets If you have a non-blocking socket, the expected behavior on read, write, accept or connect is to set C<$!> to EWOULDBLOCK if the operation cannot be completed immediately. Note that EWOULDBLOCK is the same as EAGAIN on UNIX systems, but is different on Windows. With SSL, handshakes might occur at any time, even within an established connection. In these cases it is necessary to finish the handshake before you can read or write data. This might result in situations where you want to read but must first finish the write of a handshake or where you want to write but must first finish a read. In these cases C<$!> is set to EAGAIN like expected, and additionally C<$SSL_ERROR> is set to either SSL_WANT_READ or SSL_WANT_WRITE. Thus if you get EWOULDBLOCK on a SSL socket you must check C<$SSL_ERROR> for SSL_WANT_* and adapt your event mask accordingly. Using readline on non-blocking sockets does not make much sense and I would advise against using it. And, while the behavior is not documented for other L classes, it will try to emulate the behavior seen there, e.g. to return the received data instead of blocking, even if the line is not complete. If an unrecoverable error occurs it will return nothing, even if it already received some data. Also, I would advise against using C with a non-blocking SSL object because it might block and this is not what most would expect. The reason for this is that C on a non-blocking TCP socket (e.g. L, L..) results in a new TCP socket which does not inherit the non-blocking behavior of the master socket. And thus, the initial SSL handshake on the new socket inside C will be done in a blocking way. To work around this you are safer by doing a TCP accept and later upgrade the TCP socket in a non-blocking way with C and C. my $cl = IO::Socket::SSL->new($dst); $cl->blocking(0); my $sel = IO::Select->new($cl); while (1) { # with SSL a call for reading n bytes does not result in reading of n # bytes from the socket, but instead it must read at least one full SSL # frame. If the socket has no new bytes, but there are unprocessed data # from the SSL frame can_read will block! # wait for data on socket $sel->can_read(); # new data on socket or eof READ: # this does not read only 1 byte from socket, but reads the complete SSL # frame and then just returns one byte. On subsequent calls it than # returns more byte of the same SSL frame until it needs to read the # next frame. my $n = sysread( $cl,my $buf,1); if ( ! defined $n ) { die $! if not $!{EWOULDBLOCK}; next if $SSL_ERROR == SSL_WANT_READ; if ( $SSL_ERROR == SSL_WANT_WRITE ) { # need to write data on renegotiation $sel->can_write; next; } die "something went wrong: $SSL_ERROR"; } elsif ( ! $n ) { last; # eof } else { # read next bytes # we might have still data within the current SSL frame # thus first process these data instead of waiting on the underlying # socket object goto READ if $cl->pending; # goto sysread next; # goto $sel->can_read } } Additionally there are differences to plain sockets when using select, poll, kqueue or similar technologies to get notified if data are available. Relying only on these calls is not sufficient in all cases since unread data might be internally buffered in the SSL stack. To detect such buffering B need to be used. Alternatively the buffering can be avoided by using B with the maximum size of an SSL frame. See L for details. =head1 Advanced Usage =head2 SNI Support Newer extensions to SSL can distinguish between multiple hostnames on the same IP address using Server Name Indication (SNI). Support for SNI on the client side was added somewhere in the OpenSSL 0.9.8 series, but with 1.0 a bug was fixed when the server could not decide about its hostname. Therefore client side SNI is only supported with OpenSSL 1.0 or higher in L. With a supported version, SNI is used automatically on the client side, if it can determine the hostname from C or C (which are synonyms in the underlying IO::Socket:: classes and thus should never be set both or at least not to different values). On unsupported OpenSSL versions it will silently not use SNI. The hostname can also be given explicitly given with C, but in this case it will throw in error, if SNI is not supported. To check for support you might call C<< IO::Socket::SSL->can_client_sni() >>. On the server side, earlier versions of OpenSSL are supported, but only together with L version >= 1.50. To check for support you might call C<< IO::Socket::SSL->can_server_sni() >>. If server side SNI is supported, you might specify different certificates per host with C and C, and check the requested name using C. =head2 Talk Plain and SSL With The Same Socket It is often required to first exchange some plain data and then upgrade the socket to SSL after some kind of STARTTLS command. Protocols like FTPS even need a way to downgrade the socket again back to plain. The common way to do this would be to create a normal socket and use C to upgrade and stop_SSL to downgrade: my $sock = IO::Socket::INET->new(...) or die $!; ... exchange plain data on $sock until starttls command ... IO::Socket::SSL->start_SSL($sock,%sslargs) or die $SSL_ERROR; ... now $sock is an IO::Socket::SSL object ... ... exchange data with SSL on $sock until stoptls command ... $sock->stop_SSL or die $SSL_ERROR; ... now $sock is again an IO::Socket::INET object ... But, lots of modules just derive directly from L. While this base class can be replaced with L, these modules cannot easily support different base classes for SSL and plain data and switch between these classes on a starttls command. To help in this case, L can be reduced to a plain socket on startup, and connect_SSL/accept_SSL/start_SSL can be used to enable SSL and C to talk plain again: my $sock = IO::Socket::SSL->new( PeerAddr => ... SSL_startHandshake => 0, %sslargs ) or die $!; ... exchange plain data on $sock until starttls command ... $sock->connect_SSL or die $SSL_ERROR; ... now $sock is an IO::Socket::SSL object ... ... exchange data with SSL on $sock until stoptls command ... $sock->stop_SSL or die $SSL_ERROR; ... $sock is still an IO::Socket::SSL object ... ... but data exchanged again in plain ... =head1 Integration Into Own Modules L behaves similarly to other L modules and thus could be integrated in the same way, but you have to take special care when using non-blocking I/O (like for handling timeouts) or using select or poll. Please study the documentation on how to deal with these differences. Also, it is recommended to not set or touch most of the C options, so that they keep their secure defaults. It is also recommended to let the user override these SSL specific settings without the need of global settings or hacks like C. The notable exception is C. This should be set to the hostname verification scheme required by the module or protocol. =head1 Description Of Methods L inherits from another L module. The choice of the super class depends on the installed modules: =over 4 =item * If L with at least version 0.20 is installed it will use this module as super class, transparently providing IPv6 and IPv4 support. =item * If L is installed it will use this module as super class, transparently providing IPv6 and IPv4 support. =item * Otherwise it will fall back to L, which is a perl core module. With L you only get IPv4 support. =back Please be aware that with the IPv6 capable super classes, it will look first for the IPv6 address of a given hostname. If the resolver provides an IPv6 address, but the host cannot be reached by IPv6, there will be no automatic fallback to IPv4. To avoid these problems you can enforce IPv4 for a specific socket by using the C or C option with the value AF_INET as described in L. Alternatively you can enforce IPv4 globally by loading L with the option 'inet4', in which case it will use the IPv4 only class L as the super class. L will provide all of the methods of its super class, but sometimes it will override them to match the behavior expected from SSL or to provide additional arguments. The new or changed methods are described below, but please also read the section about SSL specific error handling. =over 4 =item Error Handling If an SSL specific error occurs, the global variable C<$SSL_ERROR> will be set. If the error occurred on an existing SSL socket, the method C will give access to the latest socket specific error. Both C<$SSL_ERROR> and the C method give a dualvar similar to C<$!>, e.g. providing an error number in numeric context or an error description in string context. =item B Creates a new L object. You may use all the friendly options that came bundled with the super class (e.g. L, L, ...) plus (optionally) the ones described below. If you don't specify any SSL related options it will do its best in using secure defaults, e.g. choosing good ciphers, enabling proper verification, etc. =over 2 =item SSL_server Set this option to a true value if the socket should be used as a server. If this is not explicitly set it is assumed if the C parameter is given when creating the socket. =item SSL_hostname This can be given to specify the hostname used for SNI, which is needed if you have multiple SSL hostnames on the same IP address. If not given it will try to determine the hostname from C, which will fail if only an IP was given or if this argument is used within C. If you want to disable SNI, set this argument to ''. Currently only supported for the client side and will be ignored for the server side. See section "SNI Support" for details of SNI the support. =item SSL_startHandshake If this option is set to false (defaults to true) it will not start the SSL handshake yet. This has to be done later with C or C. Before the handshake is started read/write/etc. can be used to exchange plain data. =item SSL_keepSocketOnError If this option is set to true (defaults to false) it will not close the underlying TCP socket on errors. In most cases there is no real use for this behavior since both sides of the TCP connection will probably have a different idea of the current state of the connection. =item SSL_ca | SSL_ca_file | SSL_ca_path Usually you want to verify that the peer certificate has been signed by a trusted certificate authority. In this case you should use this option to specify the file (C) or directory (C) containing the certificateZ<>(s) of the trusted certificate authorities. C can also be an array or a string containing multiple path, where the path are separated by the platform specific separator. This separator is C<;> on DOS, Windows, Netware, C<,> on VMS and C<:> for all the other systems. If multiple path are given at least one of these must be accessible. You can also give a list of X509* certificate handles (like you get from L or L) with C. These will be added to the CA store before path and file and thus take precedence. If neither SSL_ca, nor SSL_ca_file or SSL_ca_path are set it will use C to determine the user-set or system defaults. If you really don't want to set a CA set SSL_ca_file or SSL_ca_path to C<\undef> or SSL_ca to an empty list. (unfortunately C<''> is used by some modules using L when CA is not explicitly given). =item SSL_client_ca | SSL_client_ca_file If verify_mode is VERIFY_PEER on the server side these options can be used to set the list of acceptable CAs for the client. This way the client can select they required certificate from a list of certificates. The value for these options is similar to C and C. =item SSL_fingerprint Sometimes you have a self-signed certificate or a certificate issued by an unknown CA and you really want to accept it, but don't want to disable verification at all. In this case you can specify the fingerprint of the certificate as C<'algo$hex_fingerprint'>. C is a fingerprint algorithm supported by OpenSSL, e.g. 'sha1','sha256'... and C is the hexadecimal representation of the binary fingerprint. Any colons inside the hex string will be ignored. If you want to use the fingerprint of the pubkey inside the certificate instead of the certificate use the syntax C<'algo$pub$hex_fingerprint'> instead. To get the fingerprint of an established connection you can use C. It is also possible to skip C, i.e. only specify the fingerprint. In this case the likely algorithms will be automatically detected based on the length of the digest string. You can specify a list of fingerprints in case you have several acceptable certificates. If a fingerprint matches the topmost (i.e. leaf) certificate no additional validations can make the verification fail. =item SSL_cert_file | SSL_cert | SSL_key_file | SSL_key If you create a server you usually need to specify a server certificate which should be verified by the client. Same is true for client certificates, which should be verified by the server. The certificate can be given as a file with SSL_cert_file or as an internal representation of an X509* object (like you get from L or L) with SSL_cert. If given as a file it will automatically detect the format. Supported file formats are PEM, DER and PKCS#12, where PEM and PKCS#12 can contain the certificate and the chain to use, while DER can only contain a single certificate. If given as a list of X509* please note, that the all the chain certificates (e.g. all except the first) will be "consumed" by openssl and will be freed if the SSL context gets destroyed - so you should never free them yourself. But the servers certificate (e.g. the first) will not be consumed by openssl and thus must be freed by the application. For each certificate a key is need, which can either be given as a file with SSL_key_file or as an internal representation of an EVP_PKEY* object with SSL_key (like you get from L or L). If a key was already given within the PKCS#12 file specified by SSL_cert_file it will ignore any SSL_key or SSL_key_file. If no SSL_key or SSL_key_file was given it will try to use the PEM file given with SSL_cert_file again, maybe it contains the key too. If your SSL server should be able to use different certificates on the same IP address, depending on the name given by SNI, you can use a hash reference instead of a file with C< cert_file>>. If your SSL server should be able to use both RSA and ECDSA certificates for the same domain/IP a similar hash reference like with SNI is given. The domain names used to specify the additional certificates should be C, i.e. C or similar. This needs at least OpenSSL 1.0.2. To let the server pick the certificate based on the clients cipher preference C should be set to false. In case certs and keys are needed but not given it might fall back to builtin defaults, see "Defaults for Cert, Key and CA". Examples: SSL_cert_file => 'mycert.pem', SSL_key_file => 'mykey.pem', SSL_cert_file => { "foo.example.org" => 'foo-cert.pem', "foo.example.org%ecc" => 'foo-ecc-cert.pem', "bar.example.org" => 'bar-cert.pem', # used when nothing matches or client does not support SNI '' => 'default-cert.pem', '%ecc' => 'default-ecc-cert.pem', }, SSL_key_file => { "foo.example.org" => 'foo-key.pem', "foo.example.org%ecc" => 'foo-ecc-key.pem', "bar.example.org" => 'bar-key.pem', # used when nothing matches or client does not support SNI '' => 'default-key.pem', '%ecc' => 'default-ecc-key.pem', } =item SSL_passwd_cb If your private key is encrypted, you might not want the default password prompt from Net::SSLeay. This option takes a reference to a subroutine that should return the password required to decrypt your private key. =item SSL_use_cert If this is true, it forces IO::Socket::SSL to use a certificate and key, even if you are setting up an SSL client. If this is set to 0 (the default), then you will only need a certificate and key if you are setting up a server. SSL_use_cert will implicitly be set if SSL_server is set. For convenience it is also set if it was not given but a cert was given for use (SSL_cert_file or similar). =item SSL_version Sets the version of the SSL protocol used to transmit data. 'SSLv23' uses a handshake compatible with SSL2.0, SSL3.0 and TLS1.x, while 'SSLv2', 'SSLv3', 'TLSv1', 'TLSv1_1', 'TLSv1_2', or 'TLSv1_3' restrict handshake and protocol to the specified version. All values are case-insensitive. Instead of 'TLSv1_1', 'TLSv1_2', and 'TLSv1_3' one can also use 'TLSv11', 'TLSv12', and 'TLSv13'. Which protocol versions are actually supported depend on the versions of OpenSSL and Net::SSLeay installed, but modern protocols like TLS 1.3 are supported by these for many years now. Independent from the handshake format you can limit to set of accepted SSL versions by adding !version separated by ':'. The default SSL_version is 'SSLv23:!TLSv1:!TLSv1_1:!SSLv3:!SSLv2'. This means, that the handshake format is compatible to SSL2.0 and higher, but that the successful handshake is limited to TLS1.2 and higher, that is no SSL2.0, SSL3.0, TLS 1.0 or TLS 1.1 because these versions have serious security issues and should not be used anymore. You can also use !TLSv1_1 and !TLSv1_2 to disable TLS versions 1.1 and 1.2 while still allowing TLS version 1.0. Setting the version instead to 'TLSv1' might break interaction with very old or broken clients, which expect a SSL2.0 compatible handshake. On the other side some broken clients just close the connection when they receive a TLS version 1.1 request. In this case setting the version to 'SSLv23:!SSLv2:!SSLv3:!TLSv1_1:!TLSv1_2' might help. =item SSL_cipher_list If this option is set the cipher list for the connection will be set to the given value, e.g. something like 'ALL:!LOW:!EXP:!aNULL'. This will only affect ciphers for TLS 1.2 and lower. See the OpenSSL documentation (L) for more details. Unless you fail to contact your peer because of no shared ciphers it is recommended to leave this option at the default setting, which uses the system default but disables some insecure ciphers which might still be enabled on older systems. In case different cipher lists are needed for different SNI hosts a hash can be given with the host as key and the cipher suite as value, similar to B. =item SSL_ciphersuites If this option is set the TLS 1.3 ciphersuites for the connection will be set to the given value. This is similar to SSL_cipher_list, but only for TLS 1.3 ciphers. See argument C<-ciphersuites> in the OpenSSL documentation (L) for details. Unless you fail to contact your peer because of no shared ciphers it is recommended to leave this option at the default setting, which uses the system default. In case different cipher lists are needed for different SNI hosts a hash can be given with the host as key and the cipher suite as value, similar to B. =item SSL_honor_cipher_order If this option is true the cipher order the server specified is used instead of the order proposed by the client. This option defaults to true to make use of our secure cipher list setting. =item SSL_dh_file To create a server which provides forward secrecy you need to either give the DH parameters or (better, because faster) the ECDH curve. This setting cares about DH parameters. To support non-elliptic Diffie-Hellman key exchange a suitable file needs to be given here or the SSL_dh should be used with an appropriate value. See dhparam command in openssl for more information. If neither C nor C are set a builtin DH parameter with a length of 2048 bit is used to offer DH key exchange by default. If you don't want this (e.g. disable DH key exchange) explicitly set this or the C parameter to undef. =item SSL_dh Like SSL_dh_file, but instead of giving a file you use a preloaded or generated DH*. =item SSL_ecdh_curve To create a server which provides forward secrecy you need to either give the DH parameters or (better, because faster) the ECDH curve. This setting cares about the ECDH curve(s). To support Elliptic Curve Diffie-Hellmann key exchange the OID or NID of at least one suitable curve needs to be provided here. With OpenSSL 1.1.0+ this parameter defaults to C, which means that it lets OpenSSL pick the best settings. If support for CTX_set_ecdh_auto is implemented in Net::SSLeay (needs at least version 1.86) it will use this to implement the same default. Otherwise it will default to C (builtin of OpenSSL) in order to offer ECDH key exchange by default. If setting groups or curves is supported by Net::SSLeay (needs at least version 1.86) then multiple curves can be given here in the order of the preference, i.e. C. When used at the client side this will include the supported curves as extension in the TLS handshake. If you don't want to have ECDH key exchange this could be set to undef or set C to exclude all of these ciphers. You can check if ECDH support is available by calling C<< IO::Socket::SSL->can_ecdh >>. =item SSL_verify_mode This option sets the verification mode for the peer certificate. You may combine SSL_VERIFY_PEER (verify_peer), SSL_VERIFY_FAIL_IF_NO_PEER_CERT (fail verification if no peer certificate exists; ignored for clients), SSL_VERIFY_CLIENT_ONCE (verify client once; ignored for clients). See OpenSSL man page for SSL_CTX_set_verify for more information. The default is SSL_VERIFY_NONE for server (e.g. no check for client certificate) and SSL_VERIFY_PEER for client (check server certificate). =item SSL_verify_callback If you want to verify certificates yourself, you can pass a sub reference along with this parameter to do so. When the callback is called, it will be passed: =over 4 =item 1. a true/false value that indicates what OpenSSL thinks of the certificate, =item 2. a C-style memory address of the certificate store, =item 3. a string containing the certificate's issuer attributes and owner attributes, and =item 4. a string containing any errors encountered (0 if no errors). =item 5. a C-style memory address of the peer's own certificate (convertible to PEM form with Net::SSLeay::PEM_get_string_X509()). =item 6. The depth of the certificate in the chain. Depth 0 is the leaf certificate. =back The function should return 1 or 0, depending on whether it thinks the certificate is valid or invalid. The default is to let OpenSSL do all of the busy work. The callback will be called for each element in the certificate chain. See the OpenSSL documentation for SSL_CTX_set_verify for more information. =item SSL_verifycn_scheme The scheme is used to correctly verify the identity inside the certificate by using the hostname of the peer. See the information about the verification schemes in B. If you don't specify a scheme it will use 'default', but only complain loudly if the name verification fails instead of letting the whole certificate verification fail. THIS WILL CHANGE, e.g. it will let the certificate verification fail in the future if the hostname does not match the certificate !!!! To override the name used in verification use B. The scheme 'default' is a superset of the usual schemes, which will accept the hostname in common name and subjectAltName and allow wildcards everywhere. While using this scheme is way more secure than no name verification at all you better should use the scheme specific to your application protocol, e.g. 'http', 'ftp'... If you are really sure, that you don't want to verify the identity using the hostname you can use 'none' as a scheme. In this case you'd better have alternative forms of verification, like a certificate fingerprint or do a manual verification later by calling B yourself. =item SSL_verifycn_publicsuffix This option is used to specify the behavior when checking wildcards certificates for public suffixes, e.g. no wildcard certificates for *.com or *.co.uk should be accepted, while *.example.com or *.example.co.uk is ok. If not specified it will simply use the builtin default of L, you can create another object with from_string or from_file of this module. To disable verification of public suffix set this option to C<''>. =item SSL_verifycn_name Set the name which is used in verification of hostname. If SSL_verifycn_scheme is set and no SSL_verifycn_name is given it will try to use SSL_hostname or PeerHost and PeerAddr settings and fail if no name can be determined. If SSL_verifycn_scheme is not set it will use a default scheme and warn if it cannot determine a hostname, but it will not fail. Using PeerHost or PeerAddr works only if you create the connection directly with C<< IO::Socket::SSL->new >>, if an IO::Socket::INET object is upgraded with B the name has to be given in B or B. =item SSL_check_crl If you want to verify that the peer certificate has not been revoked by the signing authority, set this value to true. OpenSSL will search for the CRL in your SSL_ca_path, or use the file specified by SSL_crl_file. See the Net::SSLeay documentation for more details. Note that this functionality appears to be broken with OpenSSL < v0.9.7b, so its use with lower versions will result in an error. =item SSL_crl_file If you want to specify the CRL file to be used, set this value to the pathname to be used. This must be used in addition to setting SSL_check_crl. =item SSL_ocsp_mode Defines how certificate revocation is done using OCSP (Online Status Revocation Protocol). The default is to send a request for OCSP stapling to the server and if the server sends an OCSP response back the result will be used. Any other OCSP checking needs to be done manually with C. The following flags can be combined with C<|>: =over 8 =item SSL_OCSP_NO_STAPLE Don't ask for OCSP stapling. This is the default if SSL_verify_mode is VERIFY_NONE. =item SSL_OCSP_TRY_STAPLE Try OCSP stapling, but don't complain if it gets no stapled response back. This is the default if SSL_verify_mode is VERIFY_PEER (the default). =item SSL_OCSP_MUST_STAPLE Consider it a hard error, if the server does not send a stapled OCSP response back. Most servers currently send no stapled OCSP response back. =item SSL_OCSP_FAIL_HARD Fail hard on response errors, default is to fail soft like the browsers do. Soft errors mean, that the OCSP response is not usable, e.g. no response, error response, no valid signature etc. Certificate revocations inside a verified response are considered hard errors in any case. Soft errors inside a stapled response are never considered hard, e.g. it is expected that in this case an OCSP request will be send to the responsible OCSP responder. =item SSL_OCSP_FULL_CHAIN This will set up the C so that all certificates from the peer chain will be checked, otherwise only the leaf certificate will be checked against revocation. =back =item SSL_ocsp_staple_callback If this callback is defined, it will be called with the SSL object and the OCSP response handle obtained from the peer, e.g. C<<$cb->($ssl,$resp)>>. If the peer did not provide a stapled OCSP response the function will be called with C<$resp=undef>. Because the OCSP response handle is no longer valid after leaving this function it should not by copied or freed. If access to the response is necessary after leaving this function it can be serialized with C. If no such callback is provided, it will use the default one, which verifies the response and uses it to check if the certificate(s) of the connection got revoked. =item SSL_ocsp_cache With this option a cache can be given for caching OCSP responses, which could be shared between different SSL contexts. If not given a cache specific to the SSL context only will be used. You can either create a new cache with C<< IO::Socket::SSL::OCSP_Cache->new([size]) >> or implement your own cache, which needs to have methods C and C (returning C<\%entry>) where entry is the hash representation of the OCSP response with fields like C. The default implementation of the cache will consider responses valid as long as C is less then the current time. =item SSL_reuse_ctx If you have already set the above options for a previous instance of IO::Socket::SSL, then you can reuse the SSL context of that instance by passing it as the value for the SSL_reuse_ctx parameter. You may also create a new instance of the IO::Socket::SSL::SSL_Context class, using any context options that you desire without specifying connection options, and pass that here instead. If you use this option, all other context-related options that you pass in the same call to new() will be ignored unless the context supplied was invalid. Note that, contrary to versions of IO::Socket::SSL below v0.90, a global SSL context will not be implicitly used unless you use the set_default_context() function. =item SSL_create_ctx_callback With this callback you can make individual settings to the context after it got created and the default setup was done. The callback will be called with the CTX object from Net::SSLeay as the single argument. Example for limiting the server session cache size: SSL_create_ctx_callback => sub { my $ctx = shift; Net::SSLeay::CTX_sess_set_cache_size($ctx,128); } =item SSL_session_cache_size If you make repeated connections to the same host/port and the SSL renegotiation time is an issue, you can turn on client-side session caching with this option by specifying a positive cache size. For successive connections, pass the SSL_reuse_ctx option to the new() calls (or use set_default_context()) to make use of the cached sessions. The session cache size refers to the number of unique host/port pairs that can be stored at one time; the oldest sessions in the cache will be removed if new ones are added. This option does not effect the session cache a server has for it's clients, e.g. it does not affect SSL objects with SSL_server set. Note that session caching with TLS 1.3 needs at least Net::SSLeay 1.86. =item SSL_session_cache Specifies session cache object which should be used instead of creating a new. Overrules SSL_session_cache_size. This option is useful if you want to reuse the cache, but not the rest of the context. A session cache object can be created using C<< IO::Socket::SSL::Session_Cache->new( cachesize ) >>. Use set_default_session_cache() to set a global cache object. =item SSL_session_key Specifies a key to use for lookups and inserts into client-side session cache. Per default ip:port of destination will be used, but sometimes you want to share the same session over multiple ports on the same server (like with FTPS). =item SSL_session_id_context This gives an id for the servers session cache. It's necessary if you want clients to connect with a client certificate. If not given but SSL_verify_mode specifies the need for client certificate a context unique id will be picked. =item SSL_error_trap When using the accept() or connect() methods, it may be the case that the actual socket connection works but the SSL negotiation fails, as in the case of an HTTP client connecting to an HTTPS server. Passing a subroutine ref attached to this parameter allows you to gain control of the orphaned socket instead of having it be closed forcibly. The subroutine, if called, will be passed two parameters: a reference to the socket on which the SSL negotiation failed and the full text of the error message. =item SSL_npn_protocols If used on the server side it specifies list of protocols advertised by SSL server as an array ref, e.g. ['spdy/2','http1.1']. On the client side it specifies the protocols offered by the client for NPN as an array ref. See also method C. Next Protocol Negotiation (NPN) is available with Net::SSLeay 1.46+ and openssl-1.0.1+. NPN is unavailable in TLSv1.3 protocol. To check support you might call C<< IO::Socket::SSL->can_npn() >>. If you use this option with an unsupported Net::SSLeay/OpenSSL it will throw an error. =item SSL_alpn_protocols If used on the server side it specifies list of protocols supported by the SSL server as an array ref, e.g. ['http/2.0', 'spdy/3.1','http/1.1']. On the client side it specifies the protocols advertised by the client for ALPN as an array ref. See also method C. Application-Layer Protocol Negotiation (ALPN) is available with Net::SSLeay 1.56+ and openssl-1.0.2+. More details about the extension are in RFC7301. To check support you might call C<< IO::Socket::SSL->can_alpn() >>. If you use this option with an unsupported Net::SSLeay/OpenSSL it will throw an error. Note that some client implementations may encounter problems if both NPN and ALPN are specified. Since ALPN is intended as a replacement for NPN, try providing ALPN protocols then fall back to NPN if that fails. =item SSL_ticket_keycb => [$sub,$data] | $sub This is a callback used for stateless session reuse (Session Tickets, RFC 5077). This callback will be called as C<< $sub->($data,[$key_name]) >> where C<$data> is the argument given to SSL_ticket_keycb (or undef) and C<$key_name> depends on the mode: =over 8 =item encrypt ticket If a ticket needs to be encrypted the callback will be called without C<$key_name>. In this case it should return C<($current_key,$current_key_name>) where C<$current_key> is the current key (32 byte random data) and C<$current_key_name> the name associated with this key (exactly 16 byte). This C<$current_key_name> will be incorporated into the ticket. =item decrypt ticket If a ticket needs to be decrypted the callback will be called with C<$key_name> as found in the ticket. It should return C<($key,$current_key_name>) where C<$key> is the key associated with the given C<$key_name> and C<$current_key_name> the name associated with the currently active key. If C<$current_key_name> is different from the given C<$key_name> the callback will be called again to re-encrypt the ticket with the currently active key. If no key can be found which matches the given C<$key_name> then this function should return nothing (empty list). This mechanism should be used to limit the life time for each key encrypting the ticket. Compromise of a ticket encryption key might lead to decryption of SSL sessions which used session tickets protected by this key. =back Example: Net::SSLeay::RAND_bytes(my $oldkey,32); Net::SSLeay::RAND_bytes(my $newkey,32); my $oldkey_name = pack("a16",'oldsecret'); my $newkey_name = pack("a16",'newsecret'); my @keys = ( [ $newkey_name, $newkey ], # current active key [ $oldkey_name, $oldkey ], # already expired ); my $keycb = [ sub { my ($mykeys,$name) = @_; # return (current_key, current_key_name) if no name given return ($mykeys->[0][1],$mykeys->[0][0]) if ! $name; # return (matching_key, current_key_name) if we find a key matching # the given name for(my $i = 0; $i<@$mykeys; $i++) { next if $name ne $mykeys->[$i][0]; return ($mykeys->[$i][1],$mykeys->[0][0]); } # no matching key found return; },\@keys ]; my $srv = IO::Socket::SSL->new(..., SSL_ticket_keycb => $keycb); =item SSL_mode_release_buffers 1|0 This enables or disables the SSL_MODE_RELEASE_BUFFERS option on the SSL object. With this option the read buffer will be released after each SSL_read but will need to be reallocated for each new SSL_read. If memory usage is a concern this might save lots of memory in the mean time though, about 34k per idle SSL connection according to the documentation in SSL_CTX_set_mode(3ssl). =back =item B This behaves similar to the accept function of the underlying socket class, but additionally does the initial SSL handshake. But because the underlying socket class does return a blocking file handle even when accept is called on a non-blocking socket, the SSL handshake on the new file object will be done in a blocking way. Please see the section about non-blocking I/O for details. If you don't like this behavior you should do accept on the TCP socket and then upgrade it with C later. =item B This behaves similar to the connect function but also does an SSL handshake. Because you cannot give SSL specific arguments to this function, you should better either use C to create a connect SSL socket or C to upgrade an established TCP socket to SSL. =item B Contrary to a close for a simple INET socket a close in SSL also mandates a proper shutdown of the SSL part. This is done by sending a close notify message by both peers. A naive implementation would thus wait until it receives the close notify message from the peer - which conflicts with the commonly expected semantic that a close will not block. The default behavior is thus to only send a close notify but not wait for the close notify of the peer. If this is required C need to be explicitly set to false. There are also cases where a SSL shutdown should not be done at all. This is true for example when forking to let a child deal with the socket and closing the socket in the parent process. A naive explicit C or an implicit close when destroying the socket in the parent would send a close notify to the peer which would make the SSL socket in the client process unusable. In this case an explicit C with C set to true should be done in the parent process. For more details and other arguments see C which gets called from C to shutdown the SSL state of the socket. =item B This function behaves from the outside the same as B in other L objects, e.g. it returns at most LEN bytes of data. But in reality it reads not only LEN bytes from the underlying socket, but at a single SSL frame. It then returns up to LEN bytes it decrypted from this SSL frame. If the frame contained more data than requested it will return only LEN data, buffer the rest and return it on further read calls. This means, that it might be possible to read data, even if the underlying socket is not readable, so using poll or select might not be sufficient. sysread will only return data from a single SSL frame, e.g. either the pending data from the already buffered frame or it will read a frame from the underlying socket and return the decrypted data. It will not return data spanning several SSL frames in a single call. Also, calls to sysread might fail, because it must first finish an SSL handshake. To understand these behaviors is essential, if you write applications which use event loops and/or non-blocking sockets. Please read the specific sections in this documentation. =item B This functions behaves from the outside the same as B in other L objects, e.g. it will write at most LEN bytes to the socket, but there is no guarantee, that all LEN bytes are written. It will return the number of bytes written. Because it basically just calls SSL_write from OpenSSL syswrite will write at most a single SSL frame. This means, that no more than 16.384 bytes, which is the maximum size of an SSL frame, will be written at once. For non-blocking sockets SSL specific behavior applies. Pease read the specific section in this documentation. =item B This function has exactly the same syntax as B, and performs nearly the same task but will not advance the read position so that successive calls to peek() with the same arguments will return the same results. This function requires OpenSSL 0.9.6a or later to work. =item B This function gives you the number of bytes available without reading from the underlying socket object. This function is essential if you work with event loops, please see the section about polling SSL sockets. =item B This methods returns the fingerprint of the given certificate in the form C, where C is the used algorithm, default 'sha256'. If no certificate is given the peer certificate of the connection is used. If C is true it will not return the fingerprint of the certificate but instead the fingerprint of the pubkey inside the certificate as C. =item B This methods returns the binary fingerprint of the given certificate by using the algorithm C, default 'sha256'. If no certificate is given the peer certificate of the connection is used. If C is true it will not return the fingerprint of the certificate but instead the fingerprint of the pubkey inside the certificate. =item B Returns the string form of the cipher that the IO::Socket::SSL object is using. =item B Returns the string representation of the SSL version of an established connection. =item B Returns the integer representation of the SSL version of an established connection. =item B This returns true if the session got reused and false otherwise. Note that with a reused session no certificates are send within the handshake and no ciphers are offered and thus functions which rely on this might not work. =item B Returns a parsable string with select fields from the peer SSL certificate. This method directly returns the result of the dump_peer_certificate() method of Net::SSLeay. =item B If a peer certificate exists, this function can retrieve values from it. If no field is given the internal representation of certificate from Net::SSLeay is returned. If refresh is true it will not used a cached version, but check again in case the certificate of the connection has changed due to renegotiation. The following fields can be queried: =over 8 =item authority (alias issuer) The certificate authority which signed the certificate. =item owner (alias subject) The owner of the certificate. =item commonName (alias cn) - only for Net::SSLeay version >=1.30 The common name, usually the server name for SSL certificates. =item subjectAltNames - only for Net::SSLeay version >=1.33 Alternative names for the subject, usually different names for the same server, like example.org, example.com, *.example.com. It returns a list of (typ,value) with typ GEN_DNS, GEN_IPADD etc (these constants are exported from IO::Socket::SSL). See Net::SSLeay::X509_get_subjectAltNames. =back =item B This is similar to C but will return the sites own certificate. The same arguments for B<$field> can be used. If no B<$field> is given the certificate handle from the underlying OpenSSL will be returned. This handle will only be valid as long as the SSL connection exists and if used afterwards it might result in strange crashes of the application. =item B This returns all the certificates send by the peer, e.g. first the peers own certificate and then the rest of the chain. You might use B from L to inspect each of the certificates. This function depends on a version of Net::SSLeay >= 1.58 . =item B This gives the name requested by the client if Server Name Indication (SNI) was used. =item B This verifies the given hostname against the peer certificate using the given scheme. Hostname is usually what you specify within the PeerAddr. See the C parameter for an explanation of suffix checking and for the possible values. Verification of hostname against a certificate is different between various applications and RFCs. Some scheme allow wildcards for hostnames, some only in subjectAltNames, and even their different wildcard schemes are possible. RFC 6125 provides a good overview. To ease the verification the following schemes are predefined (both protocol name and rfcXXXX name can be used): =over 8 =item rfc2818, xmpp (rfc3920), ftp (rfc4217) Extended wildcards in subjectAltNames and common name are possible, e.g. *.example.org or even www*.example.org. The common name will be only checked if no DNS names are given in subjectAltNames. =item http (alias www) While name checking is defined in rfc2818 the current browsers usually accept also an IP address (w/o wildcards) within the common name as long as no subjectAltNames are defined. Thus this is rfc2818 extended with this feature. =item smtp (rfc2595), imap, pop3, acap (rfc4642), netconf (rfc5538), syslog (rfc5425), snmp (rfc5953) Simple wildcards in subjectAltNames are possible, e.g. *.example.org matches www.example.org but not lala.www.example.org. If nothing from subjectAltNames match it checks against the common name, where wildcards are also allowed to match the full leftmost label. =item ldap (rfc4513) Simple wildcards are allowed in subjectAltNames, but not in common name. Common name will be checked even if subjectAltNames exist. =item sip (rfc5922) No wildcards are allowed and common name is checked even if subjectAltNames exist. =item gist (rfc5971) Simple wildcards are allowed in subjectAltNames and common name, but common name will only be checked if there are no DNS names in subjectAltNames. =item default This is a superset of all the rules and is automatically used if no scheme is given but a hostname (instead of IP) is known. Extended wildcards are allowed in subjectAltNames and common name and common name is checked always. =item none No verification will be done. Actually is does not make any sense to call verify_hostname in this case. =back The scheme can be given either by specifying the name for one of the above predefined schemes, or by using a hash which can have the following keys and values: =over 8 =item check_cn: 0|'always'|'when_only' Determines if the common name gets checked. If 'always' it will always be checked (like in ldap), if 'when_only' it will only be checked if no names are given in subjectAltNames (like in http), for any other values the common name will not be checked. =item wildcards_in_alt: 0|'full_label'|'anywhere' Determines if and where wildcards in subjectAltNames are possible. If 'full_label' only cases like *.example.org will be possible (like in ldap), for 'anywhere' www*.example.org is possible too (like http), dangerous things like but www.*.org or even '*' will not be allowed. For compatibility with older versions 'leftmost' can be given instead of 'full_label'. =item wildcards_in_cn: 0|'full_label'|'anywhere' Similar to wildcards_in_alt, but checks the common name. There is no predefined scheme which allows wildcards in common names. =item ip_in_cn: 0|1|4|6 Determines if an IP address is allowed in the common name (no wildcards are allowed). If set to 4 or 6 it only allows IPv4 or IPv6 addresses, any other true value allows both. =item callback: \&coderef If you give a subroutine for verification it will be called with the arguments ($hostname,$commonName,@subjectAltNames), where hostname is the name given for verification, commonName is the result from peer_certificate('cn') and subjectAltNames is the result from peer_certificate('subjectAltNames'). All other arguments for the verification scheme will be ignored in this case. =back =item B This method returns the name of negotiated protocol - e.g. 'http/1.1'. It works for both client and server side of SSL connection. NPN support is available with Net::SSLeay 1.46+ and openssl-1.0.1+. To check support you might call C<< IO::Socket::SSL->can_npn() >>. =item B Returns the protocol negotiated via ALPN as a string, e.g. 'http/1.1', 'http/2.0' or 'spdy/3.1'. ALPN support is available with Net::SSLeay 1.56+ and openssl-1.0.2+. To check support, use C<< IO::Socket::SSL->can_alpn() >>. =item B Returns the last error (in string form) that occurred. If you do not have a real object to perform this method on, call IO::Socket::SSL::errstr() instead. For read and write errors on non-blocking sockets, this method may include the string C or C meaning that the other side is expecting to read from or write to the socket and wants to be satisfied before you get to do anything. But with version 0.98 you are better comparing the global exported variable $SSL_ERROR against the exported symbols SSL_WANT_READ and SSL_WANT_WRITE. =item B This returns false if the socket could not be opened, 1 if the socket could be opened and the SSL handshake was successful done and -1 if the underlying IO::Handle is open, but the SSL handshake failed. =item B<< IO::Socket::SSL->start_SSL($socket, ... ) >> This will convert a glob reference or a socket that you provide to an IO::Socket::SSL object. You may also pass parameters to specify context or connection options as with a call to new(). If you are using this function on an accept()ed socket, you must set the parameter "SSL_server" to 1, i.e. IO::Socket::SSL->start_SSL($socket, SSL_server => 1). If you have a class that inherits from IO::Socket::SSL and you want the $socket to be blessed into your own class instead, use MyClass->start_SSL($socket) to achieve the desired effect. Note that if start_SSL() fails in SSL negotiation, $socket will remain blessed in its original class. For non-blocking sockets you better just upgrade the socket to IO::Socket::SSL and call accept_SSL or connect_SSL and the upgraded object. To just upgrade the socket set B explicitly to 0. If you call start_SSL w/o this parameter it will revert to blocking behavior for accept_SSL and connect_SSL. If given the parameter "Timeout" it will stop if after the timeout no SSL connection was established. This parameter is only used for blocking sockets, if it is not given the default Timeout from the underlying IO::Socket will be used. =item B This is the opposite of start_SSL(), connect_SSL() and accept_SSL(), e.g. it will shutdown the SSL connection and return to the class before start_SSL(). It gets the same arguments as close(), in fact close() calls stop_SSL() (but without downgrading the class). Will return true if it succeeded and undef if failed. This might be the case for non-blocking sockets. In this case $! is set to EWOULDBLOCK and the ssl error to SSL_WANT_READ or SSL_WANT_WRITE. In this case the call should be retried again with the same arguments once the socket is ready. For calling from C C default to false, e.g. it waits for the close_notify of the peer. This is necessary in case you want to downgrade the socket and continue to use it as a plain socket. After stop_SSL the socket can again be used to exchange plain data. =item B, B These functions should be used to do the relevant handshake, if the socket got created with C or upgraded with C and C was set to false. They will return undef until the handshake succeeded or an error got thrown. As long as the function returns undef and $! is set to EWOULDBLOCK one could retry the call after the socket got readable (SSL_WANT_READ) or writeable (SSL_WANT_WRITE). =item B This will add/remove a user defined callback for each message, internally using openssl SSL_set_msg_callback API. To make sure that the callback is active before the handshake starts, combine it with C<< SSL_startHandshake => 0 >> in the preceding setup of the SSL object. To remove callback explicitly call it with an empty callback function. Example: $sock = IO::Socket::SSL->new( .... , SSL_startHandshake => 0); # set callback $sock->set_msg_callback(\&cb, $cbarg1, $cbarg2); $sock->connect_SSL(); sub cb { my ($sock, # see SSL_set_msg_callback for the following args $direction, $ssl_ver, $content_type, $buf, $len, $ssl, $cbarg1, $cbarg2) = @_; ... if (no_longer_need_cb) { # disable callback $sock->set_msg_callback(undef); } } =item B This will create an OCSP resolver object, which can be used to create OCSP requests for the certificates of the SSL connection. Which certificates are verified depends on the setting of C: by default only the leaf certificate will be checked, but with SSL_OCSP_FULL_CHAIN all chain certificates will be checked. Because to create an OCSP request the certificate and its issuer certificate need to be known it is not possible to check certificates when the trust chain is incomplete or if the certificate is self-signed. The OCSP resolver gets created by calling C<< $ssl->ocsp_resolver >> and provides the following methods: =over 8 =item hard_error This returns the hard error when checking the OCSP response. Hard errors are certificate revocations. With the C of SSL_OCSP_FAIL_HARD any soft error (e.g. failures to get signed information about the certificates) will be considered a hard error too. The OCSP resolving will stop on the first hard error. The method will return undef as long as no hard errors occurred and still requests to be resolved. If all requests got resolved and no hard errors occurred the method will return C<''>. =item soft_error This returns the soft error(s) which occurred when asking the OCSP responders. =item requests This will return a hash consisting of C<(url,request)>-tuples, e.g. which contain the OCSP request string and the URL where it should be sent too. The usual way to send such a request is as HTTP POST request with a content-type of C or as a GET request with the base64 and url-encoded request is added to the path of the URL. After you've handled all these requests and added the response with C you should better call this method again to make sure, that no more requests are outstanding. IO::Socket::SSL will combine multiple OCSP requests for the same server inside a single request, but some server don't give a response to all these requests, so that one has to ask again with the remaining requests. =item add_response($uri,$response) This method takes the HTTP body of the response which got received when sending the OCSP request to C<$uri>. If no response was received or an error occurred one should either retry or consider C<$response> as empty which will trigger a soft error. The method returns the current value of C, e.g. a defined value when no more requests need to be done. =item resolve_blocking(%args) This combines C and C which L to do all necessary requests in a blocking way. C<%args> will be given to L so that you can put proxy settings etc here. L will be called with C of false, because the OCSP responses have their own signatures so no extra SSL verification is needed. If you don't want to use blocking requests you need to roll your own user agent with C and C. =back =item B<< IO::Socket::SSL->new_from_fd($fd, [mode], %sslargs) >> This will convert a socket identified via a file descriptor into an SSL socket. Note that the argument list does not include a "MODE" argument; if you supply one, it will be thoughtfully ignored (for compatibility with IO::Socket::INET). Instead, a mode of '+<' is assumed, and the file descriptor passed must be able to handle such I/O because the initial SSL handshake requires bidirectional communication. Internally the given $fd will be upgraded to a socket object using the C method of the super class (L or similar) and then C will be called using the given C<%sslargs>. If C<$fd> is already an IO::Socket object you should better call C directly. =item B ..., SSL_ca_path => ... ])> Determines or sets the default CA path. If existing path or dir or a hash is given it will set the default CA path to this value and never try to detect it automatically. If C is given it will forget any stored defaults and continue with detection of system defaults. If no arguments are given it will start detection of system defaults, unless it has already stored user-set or previously detected values. The detection of system defaults works similar to OpenSSL, e.g. it will check the directory specified in environment variable SSL_CERT_DIR or the path OPENSSLDIR/certs (SSLCERTS: on VMS) and the file specified in environment variable SSL_CERT_FILE or the path OPENSSLDIR/cert.pem (SSLCERTS:cert.pem on VMS). Contrary to OpenSSL it will check if the SSL_ca_path contains PEM files with the hash as file name and if the SSL_ca_file looks like PEM. If no usable system default can be found it will try to load and use L and if not available give up detection. The result of the detection will be saved to speed up future calls. The function returns the saved default CA as hash with SSL_ca_file and SSL_ca_path. =item B You may use this to make IO::Socket::SSL automatically re-use a given context (unless specifically overridden in a call to new()). It accepts one argument, which should be either an IO::Socket::SSL object or an IO::Socket::SSL::SSL_Context object. See the SSL_reuse_ctx option of new() for more details. Note that this sets the default context globally, so use with caution (esp. in mod_perl scripts). =item B You may use this to make IO::Socket::SSL automatically re-use a given session cache (unless specifically overridden in a call to new()). It accepts one argument, which should be an IO::Socket::SSL::Session_Cache object or similar (e.g. something which implements get_session, add_session and del_session like IO::Socket::SSL::Session_Cache does). See the SSL_session_cache option of new() for more details. Note that this sets the default cache globally, so use with caution. =item B With this function one can set defaults for all SSL_* parameter used for creation of the context, like the SSL_verify* parameter. Any SSL_* parameter can be given or the following short versions: =over 8 =item mode - SSL_verify_mode =item callback - SSL_verify_callback =item scheme - SSL_verifycn_scheme =item name - SSL_verifycn_name =back =item B Similar to C, but only sets the defaults for client mode. =item B Similar to C, but only sets the defaults for server mode. =item B Sometimes one has to use code which uses unwanted or invalid arguments for SSL, typically disabling SSL verification or setting wrong ciphers or SSL versions. With this hack it is possible to override these settings and restore sanity. Example: IO::Socket::SSL::set_args_filter_hack( sub { my ($is_server,$args) = @_; if ( ! $is_server ) { # client settings - enable verification with default CA # and fallback hostname verification etc delete @{$args}{qw( SSL_verify_mode SSL_ca_file SSL_ca_path SSL_verifycn_scheme SSL_version )}; # and add some fingerprints for known certs which are signed by # unknown CAs or are self-signed $args->{SSL_fingerprint} = ... } }); With the short setting C it will prefer the default settings in all cases. These default settings can be modified with C, C and C. =back The following methods are unsupported (not to mention futile!) and IO::Socket::SSL will emit a large CROAK() if you are silly enough to use them: =over 4 =item truncate =item stat =item ungetc =item setbuf =item setvbuf =item fdopen =item send/recv Note that send() and recv() cannot be reliably trapped by a tied filehandle (such as that used by IO::Socket::SSL) and so may send unencrypted data over the socket. Object-oriented calls to these functions will fail, telling you to use the print/printf/syswrite and read/sysread families instead. =back =head1 DEPRECATIONS The following functions are deprecated and are only retained for compatibility: =over 2 =item context_init() use the SSL_reuse_ctx option if you want to re-use a context =item socketToSSL() and socket_to_SSL() use IO::Socket::SSL->start_SSL() instead =item kill_socket() use close() instead =item get_peer_certificate() use the peer_certificate() function instead. Used to return X509_Certificate with methods subject_name and issuer_name. Now simply returns $self which has these methods (although deprecated). =item issuer_name() use peer_certificate( 'issuer' ) instead =item subject_name() use peer_certificate( 'subject' ) instead =back =head1 EXAMPLES See the 'example' directory, the tests in 't' and also the tools in 'util'. =head1 BUGS If you use IO::Socket::SSL together with threads you should load it (e.g. use or require) inside the main thread before creating any other threads which use it. This way it is much faster because it will be initialized only once. Also there are reports that it might crash the other way. Creating an IO::Socket::SSL object in one thread and closing it in another thread will not work. IO::Socket::SSL does not work together with Storable::fd_retrieve/fd_store. See BUGS file for more information and how to work around the problem. Non-blocking and timeouts (which are based on non-blocking) are not supported on Win32, because the underlying IO::Socket::INET does not support non-blocking on this platform. If you have a server and it looks like you have a memory leak you might check the size of your session cache. Default for Net::SSLeay seems to be 20480, see the example for SSL_create_ctx_callback for how to limit it. TLS 1.3 support regarding session reuse is incomplete. =head1 SEE ALSO IO::Socket::INET, IO::Socket::INET6, IO::Socket::IP, Net::SSLeay. =head1 THANKS Many thanks to all who added patches or reported bugs or helped IO::Socket::SSL another way. Please keep reporting bugs and help with patches, even if they just fix the documentation. Special thanks to the team of Net::SSLeay for the good cooperation. =head1 AUTHORS Steffen Ullrich, is the current maintainer. Peter Behroozi, (Note the lack of an "i" at the end of "behrooz") Marko Asplund, , was the original author of IO::Socket::SSL. Patches incorporated from various people, see file Changes. =head1 COPYRIGHT The original versions of this module are Copyright (C) 1999-2002 Marko Asplund. The rewrite of this module is Copyright (C) 2002-2005 Peter Behroozi. Versions 0.98 and newer are Copyright (C) 2006-2014 Steffen Ullrich. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. IO-Socket-SSL-2.085/lib/IO/Socket/SSL.pm0000644000175000017500000034252414553534157017124 0ustar steffensteffen#vim: set sts=4 sw=4 ts=8 ai: # # IO::Socket::SSL: # provide an interface to SSL connections similar to IO::Socket modules # # Current Code Shepherd: Steffen Ullrich # Code Shepherd before: Peter Behroozi, # # The original version of this module was written by # Marko Asplund, , who drew from # Crypt::SSLeay (Net::SSL) by Gisle Aas. # package IO::Socket::SSL; our $VERSION = '2.085'; use IO::Socket; use Net::SSLeay 1.46; use IO::Socket::SSL::PublicSuffix; use Exporter (); use Errno qw( EWOULDBLOCK EAGAIN ETIMEDOUT EINTR EPIPE ); use Carp; use strict; my $use_threads; BEGIN { die "no support for weaken - please install Scalar::Util" if ! do { local $SIG{__DIE__}; eval { require Scalar::Util; Scalar::Util->import("weaken"); 1 } || eval { require WeakRef; WeakRef->import("weaken"); 1 } }; require Config; $use_threads = $Config::Config{usethreads}; } # results from commonly used constant functions from Net::SSLeay for fast access my $Net_SSLeay_ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ(); my $Net_SSLeay_ERROR_WANT_WRITE = Net::SSLeay::ERROR_WANT_WRITE(); my $Net_SSLeay_ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL(); my $Net_SSLeay_ERROR_SSL = Net::SSLeay::ERROR_SSL(); my $Net_SSLeay_VERIFY_NONE = Net::SSLeay::VERIFY_NONE(); my $Net_SSLeay_VERIFY_PEER = Net::SSLeay::VERIFY_PEER(); use constant SSL_VERIFY_NONE => &Net::SSLeay::VERIFY_NONE; use constant SSL_VERIFY_PEER => &Net::SSLeay::VERIFY_PEER; use constant SSL_VERIFY_FAIL_IF_NO_PEER_CERT => Net::SSLeay::VERIFY_FAIL_IF_NO_PEER_CERT(); use constant SSL_VERIFY_CLIENT_ONCE => Net::SSLeay::VERIFY_CLIENT_ONCE(); # from openssl/ssl.h; should be better in Net::SSLeay use constant SSL_SENT_SHUTDOWN => 1; use constant SSL_RECEIVED_SHUTDOWN => 2; use constant SSL_OCSP_NO_STAPLE => 0b00001; use constant SSL_OCSP_MUST_STAPLE => 0b00010; use constant SSL_OCSP_FAIL_HARD => 0b00100; use constant SSL_OCSP_FULL_CHAIN => 0b01000; use constant SSL_OCSP_TRY_STAPLE => 0b10000; # capabilities of underlying Net::SSLeay/openssl my $can_client_sni; # do we support SNI on the client side my $can_server_sni; # do we support SNI on the server side my $can_multi_cert; # RSA and ECC certificate in same context my $can_npn; # do we support NPN (obsolete) my $can_alpn; # do we support ALPN my $can_ecdh; # do we support ECDH key exchange my $set_groups_list; # SSL_CTX_set1_groups_list || SSL_CTX_set1_curves_list || undef my $can_ocsp; # do we support OCSP my $can_ocsp_staple; # do we support OCSP stapling my $can_tckt_keycb; # TLS ticket key callback my $can_pha; # do we support PHA my $session_upref; # SSL_SESSION_up_ref is implemented my %sess_cb; # SSL_CTX_sess_set_(new|remove)_cb my $check_partial_chain; # use X509_V_FLAG_PARTIAL_CHAIN if available my $auto_retry; # (clear|set)_mode SSL_MODE_AUTO_RETRY with OpenSSL 1.1.1+ with non-blocking my $ssl_mode_release_buffers = 0; # SSL_MODE_RELEASE_BUFFERS if available my $can_ciphersuites; # support for SSL_CTX_set_ciphersuites (TLS 1.3) my $openssl_version; my $netssleay_version; BEGIN { $openssl_version = Net::SSLeay::OPENSSL_VERSION_NUMBER(); $netssleay_version = do { no warnings; $Net::SSLeay::VERSION + 0.0; }; $can_client_sni = $openssl_version >= 0x10000000; $can_server_sni = defined &Net::SSLeay::get_servername; $can_npn = defined &Net::SSLeay::P_next_proto_negotiated && ! Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER"); # LibreSSL 2.6.1 disabled NPN by keeping the relevant functions # available but removed the actual functionality from these functions. $can_alpn = defined &Net::SSLeay::CTX_set_alpn_protos; $can_ecdh = ($openssl_version >= 0x1010000f) ? 'auto' : defined(&Net::SSLeay::CTX_set_ecdh_auto) ? 'can_auto' : (defined &Net::SSLeay::CTX_set_tmp_ecdh && # There is a regression with elliptic curves on 1.0.1d with 64bit # http://rt.openssl.org/Ticket/Display.html?id=2975 ( $openssl_version != 0x1000104f || length(pack("P",0)) == 4 )) ? 'tmp_ecdh' : ''; $set_groups_list = defined &Net::SSLeay::CTX_set1_groups_list ? \&Net::SSLeay::CTX_set1_groups_list : defined &Net::SSLeay::CTX_set1_curves_list ? \&Net::SSLeay::CTX_set1_curves_list : undef; $can_multi_cert = $can_ecdh && $openssl_version >= 0x10002000; $can_ocsp = defined &Net::SSLeay::OCSP_cert2ids # OCSP got broken in 1.75..1.77 && ($netssleay_version < 1.75 || $netssleay_version > 1.77); $can_ocsp_staple = $can_ocsp && defined &Net::SSLeay::set_tlsext_status_type; $can_tckt_keycb = defined &Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb && $netssleay_version >= 1.80; $can_pha = defined &Net::SSLeay::CTX_set_post_handshake_auth; $can_ciphersuites = defined &Net::SSLeay::CTX_set_ciphersuites; if (defined &Net::SSLeay::SESSION_up_ref) { $session_upref = 1; } if ($session_upref && defined &Net::SSLeay::CTX_sess_set_new_cb && defined &Net::SSLeay::CTX_sess_set_remove_cb) { %sess_cb = ( new => \&Net::SSLeay::CTX_sess_set_new_cb, remove => \&Net::SSLeay::CTX_sess_set_remove_cb, ); } if (my $c = defined &Net::SSLeay::CTX_get0_param && eval { Net::SSLeay::X509_V_FLAG_PARTIAL_CHAIN() }) { $check_partial_chain = sub { my $ctx = shift; my $param = Net::SSLeay::CTX_get0_param($ctx); Net::SSLeay::X509_VERIFY_PARAM_set_flags($param, $c); }; } if (!defined &Net::SSLeay::clear_mode) { # assume SSL_CTRL_CLEAR_MODE being 78 since it was always this way *Net::SSLeay::clear_mode = sub { my ($ctx,$opt) = @_; Net::SSLeay::ctrl($ctx,78,$opt,0); }; } if ($openssl_version >= 0x10101000) { # openssl 1.1.1 enabled SSL_MODE_AUTO_RETRY by default, which is bad for # non-blocking sockets my $mode_auto_retry = # was always 0x00000004 eval { Net::SSLeay::MODE_AUTO_RETRY() } || 0x00000004; $auto_retry = sub { my ($ssl,$on) = @_; if ($on) { Net::SSLeay::set_mode($ssl, $mode_auto_retry); } else { Net::SSLeay::clear_mode($ssl, $mode_auto_retry); } } } if ($openssl_version >= 0x10000000) { # ssl/ssl.h:#define SSL_MODE_RELEASE_BUFFERS 0x00000010L $ssl_mode_release_buffers = 0x00000010; } } my $algo2digest = do { my %digest; sub { my $digest_name = shift; return $digest{$digest_name} ||= do { Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::EVP_get_digestbyname($digest_name) or die "Digest algorithm $digest_name is not available"; }; } }; my $CTX_tlsv1_3_new; if ( defined &Net::SSLeay::CTX_set_min_proto_version and defined &Net::SSLeay::CTX_set_max_proto_version and my $tls13 = eval { Net::SSLeay::TLS1_3_VERSION() } ) { $CTX_tlsv1_3_new = sub { my $ctx = Net::SSLeay::CTX_new(); return $ctx if Net::SSLeay::CTX_set_min_proto_version($ctx,$tls13) && Net::SSLeay::CTX_set_max_proto_version($ctx,$tls13); Net::SSLeay::CTX_free($ctx); return; }; } # global defaults my %DEFAULT_SSL_ARGS = ( SSL_check_crl => 0, # TLS 1.1 and lower are deprecated with RFC 8996 SSL_version => 'SSLv23:!TLSv1:!TLSv1_1:!SSLv3:!SSLv2', SSL_verify_callback => undef, SSL_verifycn_scheme => undef, # fallback cn verification SSL_verifycn_publicsuffix => undef, # fallback default list verification #SSL_verifycn_name => undef, # use from PeerAddr/PeerHost - do not override in set_args_filter_hack 'use_defaults' SSL_npn_protocols => undef, # meaning depends whether on server or client side SSL_alpn_protocols => undef, # list of protocols we'll accept/send, for example ['http/1.1','spdy/3.1'] # rely on system default but be sure to disable some definitely bad ones SSL_cipher_list => 'DEFAULT !EXP !MEDIUM !LOW !eNULL !aNULL !RC4 !DES !MD5 !PSK !SRP', ); my %DEFAULT_SSL_CLIENT_ARGS = ( %DEFAULT_SSL_ARGS, SSL_verify_mode => SSL_VERIFY_PEER, SSL_ca_file => undef, SSL_ca_path => undef, ); # set values inside _init to work with perlcc, RT#95452 my %DEFAULT_SSL_SERVER_ARGS; # Initialization of OpenSSL internals # This will be called once during compilation - perlcc users might need to # call it again by hand, see RT#95452 { sub init { # library_init returns false if the library was already initialized. # This way we can find out if the library needs to be re-initialized # inside code compiled with perlcc Net::SSLeay::library_init() or return; Net::SSLeay::load_error_strings(); Net::SSLeay::OpenSSL_add_all_digests(); Net::SSLeay::randomize(); %DEFAULT_SSL_SERVER_ARGS = ( %DEFAULT_SSL_ARGS, SSL_verify_mode => SSL_VERIFY_NONE, SSL_honor_cipher_order => 1, # trust server to know the best cipher SSL_dh => do { my $bio = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()); # generated with: openssl dhparam 2048 Net::SSLeay::BIO_write($bio,<<'DH'); -----BEGIN DH PARAMETERS----- MIIBCAKCAQEAr8wskArj5+1VCVsnWt/RUR7tXkHJ7mGW7XxrLSPOaFyKyWf8lZht iSY2Lc4oa4Zw8wibGQ3faeQu/s8fvPq/aqTxYmyHPKCMoze77QJHtrYtJAosB9SY CN7s5Hexxb5/vQ4qlQuOkVrZDiZO9GC4KaH9mJYnCoAsXDhDft6JT0oRVSgtZQnU gWFKShIm+JVjN94kGs0TcBEesPTK2g8XVHK9H8AtSUb9BwW2qD/T5RmgNABysApO Ps2vlkxjAHjJcqc3O+OiImKik/X2rtBTZjpKmzN3WWTB0RJZCOWaLlDO81D01o1E aZecz3Np9KIYey900f+X7zC2bJxEHp95ywIBAg== -----END DH PARAMETERS----- DH my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio); Net::SSLeay::BIO_free($bio); $dh or die "no DH"; $dh; }, ( $can_ecdh eq 'auto' ? () : # automatically enabled by openssl $can_ecdh eq 'can_auto' ? (SSL_ecdh_curve => 'auto') : $can_ecdh eq 'tmp_ecdh' ? ( SSL_ecdh_curve => 'prime256v1' ) : (), ) ); } # Call it once at compile time and try it at INIT. # This should catch all cases of including the module, e.g. 'use' (INIT) or # 'require' (compile time) and works also with perlcc { no warnings; INIT { init() } init(); } } # global defaults which can be changed using set_defaults # either key/value can be set or it can just be set to an external hash my $GLOBAL_SSL_ARGS = {}; my $GLOBAL_SSL_CLIENT_ARGS = {}; my $GLOBAL_SSL_SERVER_ARGS = {}; # hack which is used to filter bad settings from used modules my $FILTER_SSL_ARGS = undef; # non-XS Versions of Scalar::Util will fail BEGIN{ die "You need the XS Version of Scalar::Util for dualvar() support" if !do { local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent eval { use Scalar::Util 'dualvar'; dualvar(0,''); 1 }; }; } # get constants for SSL_OP_NO_* now, instead calling the related functions # every time we setup a connection my %SSL_OP_NO; for(qw( SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv11:TLSv1_1 TLSv1_2 TLSv12:TLSv1_2 TLSv1_3 TLSv13:TLSv1_3 )) { my ($k,$op) = m{:} ? split(m{:},$_,2) : ($_,$_); my $sub = "Net::SSLeay::OP_NO_$op"; local $SIG{__DIE__}; $SSL_OP_NO{$k} = eval { no strict 'refs'; &$sub } || 0; } # Make SSL_CTX_clear_options accessible through SSL_CTX_ctrl unless it is # already implemented in Net::SSLeay if (!defined &Net::SSLeay::CTX_clear_options) { *Net::SSLeay::CTX_clear_options = sub { my ($ctx,$opt) = @_; # 77 = SSL_CTRL_CLEAR_OPTIONS Net::SSLeay::CTX_ctrl($ctx,77,$opt,0); }; } # Try to work around problems with alternative trust path by default, RT#104759 my $DEFAULT_X509_STORE_flags = 0; { local $SIG{__DIE__}; eval { $DEFAULT_X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_TRUSTED_FIRST() }; } our $DEBUG; use vars qw(@ISA $SSL_ERROR @EXPORT); { # These constants will be used in $! at return from SSL_connect, # SSL_accept, _generic_(read|write), thus notifying the caller # the usual way of problems. Like with EWOULDBLOCK, EINPROGRESS.. # these are especially important for non-blocking sockets my $x = $Net_SSLeay_ERROR_WANT_READ; use constant SSL_WANT_READ => dualvar( \$x, 'SSL wants a read first' ); my $y = $Net_SSLeay_ERROR_WANT_WRITE; use constant SSL_WANT_WRITE => dualvar( \$y, 'SSL wants a write first' ); @EXPORT = qw( SSL_WANT_READ SSL_WANT_WRITE SSL_VERIFY_NONE SSL_VERIFY_PEER SSL_VERIFY_FAIL_IF_NO_PEER_CERT SSL_VERIFY_CLIENT_ONCE SSL_OCSP_NO_STAPLE SSL_OCSP_TRY_STAPLE SSL_OCSP_MUST_STAPLE SSL_OCSP_FAIL_HARD SSL_OCSP_FULL_CHAIN $SSL_ERROR GEN_DNS GEN_IPADD ); } my @caller_force_inet4; # in case inet4 gets forced we store here who forced it my $IOCLASS; my $family_key; # 'Domain'||'Family' BEGIN { # declare @ISA depending of the installed socket class # try to load inet_pton from Socket or Socket6 and make sure it is usable local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent my $ip6 = eval { require Socket; Socket->VERSION(1.95); Socket::inet_pton( AF_INET6(),'::1') && AF_INET6() or die; Socket->import( qw/inet_pton NI_NUMERICHOST NI_NUMERICSERV/ ); # behavior different to Socket6::getnameinfo - wrap *_getnameinfo = sub { my ($err,$host,$port) = Socket::getnameinfo(@_) or return; return if $err; return ($host,$port); }; 'Socket'; } || eval { require Socket6; Socket6::inet_pton( AF_INET6(),'::1') && AF_INET6() or die; Socket6->import( qw/inet_pton NI_NUMERICHOST NI_NUMERICSERV/ ); # behavior different to Socket::getnameinfo - wrap *_getnameinfo = sub { return Socket6::getnameinfo(@_); }; 'Socket6'; } || undef; # try IO::Socket::IP or IO::Socket::INET6 for IPv6 support $family_key = 'Domain'; # traditional if ($ip6) { # if we have IO::Socket::IP >= 0.31 we will use this in preference # because it can handle both IPv4 and IPv6 if ( eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.31) }) { @ISA = qw(IO::Socket::IP); constant->import( CAN_IPV6 => "IO::Socket::IP" ); $family_key = 'Family'; $IOCLASS = "IO::Socket::IP"; # if we have IO::Socket::INET6 we will use this not IO::Socket::INET # because it can handle both IPv4 and IPv6 # require at least 2.62 because of several problems before that version } elsif( eval { require IO::Socket::INET6; IO::Socket::INET6->VERSION(2.62) } ) { @ISA = qw(IO::Socket::INET6); constant->import( CAN_IPV6 => "IO::Socket::INET6" ); $IOCLASS = "IO::Socket::INET6"; } else { $ip6 = '' } } # fall back to IO::Socket::INET for IPv4 only if (!$ip6) { @ISA = qw(IO::Socket::INET); $IOCLASS = "IO::Socket::INET"; constant->import(CAN_IPV6 => ''); if (!defined $ip6) { constant->import(NI_NUMERICHOST => 1); constant->import(NI_NUMERICSERV => 2); } } #Make $DEBUG another name for $Net::SSLeay::trace *DEBUG = \$Net::SSLeay::trace; #Compatibility *ERROR = \$SSL_ERROR; } sub DEBUG { $DEBUG or return; my (undef,$file,$line,$sub) = caller(1); if ($sub =~m{^IO::Socket::SSL::(?:error|(_internal_error))$}) { (undef,$file,$line) = caller(2) if $1; } else { (undef,$file,$line) = caller; } my $msg = shift; $file = '...'.substr( $file,-17 ) if length($file)>20; $msg = sprintf $msg,@_ if @_; print STDERR "DEBUG: $file:$line: $msg\n"; } BEGIN { # import some constants from Net::SSLeay or use hard-coded defaults # if Net::SSLeay isn't recent enough to provide the constants my %const = ( NID_CommonName => 13, GEN_DNS => 2, GEN_IPADD => 7, ); while ( my ($name,$value) = each %const ) { no strict 'refs'; *{$name} = UNIVERSAL::can( 'Net::SSLeay', $name ) || sub { $value }; } *idn_to_ascii = \&IO::Socket::SSL::PublicSuffix::idn_to_ascii; *idn_to_unicode = \&IO::Socket::SSL::PublicSuffix::idn_to_unicode; } my $OPENSSL_LIST_SEPARATOR = $^O =~m{^(?:(dos|os2|mswin32|netware)|vms)$}i ? $1 ? ';' : ',' : ':'; my $CHECK_SSL_PATH = sub { my %args = (@_ == 1) ? ('',@_) : @_; for my $type (keys %args) { my $path = $args{$type}; if (!$type) { delete $args{$type}; $type = (ref($path) || -d $path) ? 'SSL_ca_path' : 'SSL_ca_file'; $args{$type} = $path; } next if ref($path) eq 'SCALAR' && ! $$path; if ($type eq 'SSL_ca_file') { die "SSL_ca_file $path can't be used: $!" if ! open(my $fh,'<',$path); } elsif ($type eq 'SSL_ca_path') { $path = [ split($OPENSSL_LIST_SEPARATOR,$path) ] if !ref($path); my @err; for my $d (ref($path) ? @$path : $path) { if (! -d $d) { push @err, "SSL_ca_path $d does not exist"; } elsif (! opendir(my $dh,$d)) { push @err, "SSL_ca_path $d is not accessible: $!" } else { @err = (); last } } die "@err" if @err; } } return %args; }; { my %default_ca; my $ca_detected; # 0: never detect, undef: need to (re)detect my $openssldir; sub default_ca { if (@_) { # user defined default CA or reset if ( @_ > 1 ) { %default_ca = @_; $ca_detected = 0; } elsif ( my $path = shift ) { %default_ca = $CHECK_SSL_PATH->($path); $ca_detected = 0; } else { $ca_detected = undef; } } return %default_ca if defined $ca_detected; # SSLEAY_DIR was 5 up to OpenSSL 1.1, then switched to 4 and got # renamed to OPENSSL_DIR. Unfortunately it is not exported as constant # by Net::SSLeay so we use the fixed number. $openssldir ||= Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} ? $1 : Net::SSLeay::SSLeay_version(4) =~m{^OPENSSLDIR: "(.+)"$} ? $1 : 'cannot-determine-openssldir-from-ssleay-version'; # (re)detect according to openssl crypto/cryptlib.h my $dir = $ENV{SSL_CERT_DIR} || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" ); if ( opendir(my $dh,$dir)) { FILES: for my $f ( grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) { open( my $fh,'<',"$dir/$f") or next; while (my $line = <$fh>) { $line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next; $default_ca{SSL_ca_path} = $dir; last FILES; } } } my $file = $ENV{SSL_CERT_FILE} || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" ); if ( open(my $fh,'<',$file)) { while (my $line = <$fh>) { $line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next; $default_ca{SSL_ca_file} = $file; last; } } $default_ca{SSL_ca_file} = Mozilla::CA::SSL_ca_file() if ! %default_ca && do { local $SIG{__DIE__}; eval { require Mozilla::CA; 1 }; }; $ca_detected = 1; return %default_ca; } } # Export some stuff # inet4|inet6|debug will be handled by myself, everything # else will be handled the Exporter way sub import { my $class = shift; my @export; foreach (@_) { if ( /^inet4$/i ) { # explicitly fall back to inet4 @ISA = 'IO::Socket::INET'; @caller_force_inet4 = caller(); # save for warnings for 'inet6' case } elsif ( /^inet6$/i ) { # check if we have already ipv6 as base if ( ! UNIVERSAL::isa( $class, 'IO::Socket::INET6') and ! UNIVERSAL::isa( $class, 'IO::Socket::IP' )) { # either we don't support it or we disabled it by explicitly # loading it with 'inet4'. In this case re-enable but warn # because this is probably an error if ( CAN_IPV6 ) { @ISA = ( CAN_IPV6 ); warn "IPv6 support re-enabled in __PACKAGE__, got disabled in file $caller_force_inet4[1] line $caller_force_inet4[2]"; } else { die "INET6 is not supported, install IO::Socket::IP"; } } } elsif ( /^:?debug(\d+)/ ) { $DEBUG=$1; } else { push @export,$_ } } @_ = ( $class,@export ); goto &Exporter::import; } my %SSL_OBJECT; my %CREATED_IN_THIS_THREAD; sub CLONE { %CREATED_IN_THIS_THREAD = (); } # all keys used internally, these should be cleaned up at end my @all_my_keys = qw( _SSL_arguments _SSL_certificate _SSL_ctx _SSL_fileno _SSL_in_DESTROY _SSL_ioclass_downgrade _SSL_ioclass_upgraded _SSL_last_err _SSL_object _SSL_ocsp_verify _SSL_opened _SSL_opening _SSL_servername _SSL_msg_callback ); # we have callbacks associated with contexts, but have no way to access the # current SSL object from these callbacks. To work around this # CURRENT_SSL_OBJECT will be set before calling Net::SSLeay::{connect,accept} # and reset afterwards, so we have access to it inside _internal_error. my $CURRENT_SSL_OBJECT; # You might be expecting to find a new() subroutine here, but that is # not how IO::Socket::INET works. All configuration gets performed in # the calls to configure() and either connect() or accept(). #Call to configure occurs when a new socket is made using #IO::Socket::INET. Returns false (empty list) on failure. sub configure { my ($self, $arg_hash) = @_; return _invalid_object() unless($self); # force initial blocking # otherwise IO::Socket::SSL->new might return undef if the # socket is nonblocking and it fails to connect immediately # for real nonblocking behavior one should create a nonblocking # socket and later call connect explicitly my $blocking = delete $arg_hash->{Blocking}; # because Net::HTTPS simple redefines blocking() to {} (e.g. # return undef) and IO::Socket::INET does not like this we # set Blocking only explicitly if it was set $arg_hash->{Blocking} = 1 if defined ($blocking); $self->configure_SSL($arg_hash) || return; if ($arg_hash->{$family_key} ||= $arg_hash->{Domain} || $arg_hash->{Family}) { # Hack to work around the problem that IO::Socket::IP defaults to # AI_ADDRCONFIG which creates problems if we have only the loopback # interface. If we already know the family this flag is more harmful # then useful. $arg_hash->{GetAddrInfoFlags} = 0 if $IOCLASS eq 'IO::Socket::IP' && ! defined $arg_hash->{GetAddrInfoFlags}; } return $self->_internal_error("@ISA configuration failed",0) if ! $self->SUPER::configure($arg_hash); $self->blocking(0) if defined $blocking && !$blocking; return $self; } sub configure_SSL { my ($self, $arg_hash) = @_; $arg_hash->{Proto} ||= 'tcp'; my $is_server = $arg_hash->{SSL_server}; if ( ! defined $is_server ) { $is_server = $arg_hash->{SSL_server} = $arg_hash->{Listen} || 0; } # add user defined defaults, maybe after filtering $FILTER_SSL_ARGS->($is_server,$arg_hash) if $FILTER_SSL_ARGS; delete @{*$self}{@all_my_keys}; ${*$self}{_SSL_opened} = $is_server; ${*$self}{_SSL_arguments} = $arg_hash; # this adds defaults to $arg_hash as a side effect! ${*$self}{'_SSL_ctx'} = IO::Socket::SSL::SSL_Context->new($arg_hash) or return; return $self; } sub _skip_rw_error { my ($self,$ssl,$rv) = @_; my $err = Net::SSLeay::get_error($ssl,$rv); if ( $err == $Net_SSLeay_ERROR_WANT_READ) { $SSL_ERROR = SSL_WANT_READ; } elsif ( $err == $Net_SSLeay_ERROR_WANT_WRITE) { $SSL_ERROR = SSL_WANT_WRITE; } else { return $err; } $! ||= EWOULDBLOCK; ${*$self}{_SSL_last_err} = [$SSL_ERROR,4] if ref($self); Net::SSLeay::ERR_clear_error(); return 0; } # Call to connect occurs when a new client socket is made using IO::Socket::* sub connect { my $self = shift || return _invalid_object(); return $self if ${*$self}{'_SSL_opened'}; # already connected if ( ! ${*$self}{'_SSL_opening'} ) { # call SUPER::connect if the underlying socket is not connected # if this fails this might not be an error (e.g. if $! = EINPROGRESS # and socket is nonblocking this is normal), so keep any error # handling to the client $DEBUG>=2 && DEBUG('socket not yet connected' ); $self->SUPER::connect(@_) || return; $DEBUG>=2 && DEBUG('socket connected' ); # IO::Socket works around systems, which return EISCONN or similar # on non-blocking re-connect by returning true, even if $! is set # but it does not clear $!, so do it here $! = undef; # don't continue with connect_SSL if SSL_startHandshake is set to 0 my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake}; return $self if defined $sh && ! $sh; } return $self->connect_SSL; } sub connect_SSL { my $self = shift; my $args = @_>1 ? {@_}: $_[0]||{}; return $self if ${*$self}{'_SSL_opened'}; # already connected my ($ssl,$ctx); if ( ! ${*$self}{'_SSL_opening'} ) { # start ssl connection $DEBUG>=2 && DEBUG('ssl handshake not started' ); ${*$self}{'_SSL_opening'} = 1; my $arg_hash = ${*$self}{'_SSL_arguments'}; my $fileno = ${*$self}{'_SSL_fileno'} = fileno($self); return $self->_internal_error("Socket has no fileno",9) if ! defined $fileno; $ctx = ${*$self}{'_SSL_ctx'}; # Reference to real context $ssl = ${*$self}{'_SSL_object'} = Net::SSLeay::new($ctx->{context}) || return $self->error("SSL structure creation failed"); $CREATED_IN_THIS_THREAD{$ssl} = 1 if $use_threads; $SSL_OBJECT{$ssl} = [$self,0]; weaken($SSL_OBJECT{$ssl}[0]); if ($ctx->{session_cache}) { $arg_hash->{SSL_session_key} ||= do { my $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} || $self->_update_peer; my $port = $arg_hash->{PeerPort} || $arg_hash->{PeerService}; $port ? "$host:$port" : $host; } } Net::SSLeay::set_fd($ssl, $fileno) || return $self->error("SSL filehandle association failed"); set_msg_callback($self) if $DEBUG>=2 || ${*$self}{_SSL_msg_callback}; if ( $can_client_sni ) { my $host; if ( exists $arg_hash->{SSL_hostname} ) { # explicitly given # can be set to undef/'' to not use extension $host = $arg_hash->{SSL_hostname} } elsif ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) { # implicitly given $host =~s{:[a-zA-Z0-9_\-]+$}{}; # should be hostname, not IPv4/6 $host = undef if $host !~m{[a-z_]}i or $host =~m{:}; } # define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 # define TLSEXT_NAMETYPE_host_name 0 if ($host) { $DEBUG>=2 && DEBUG("using SNI with hostname $host"); Net::SSLeay::ctrl($ssl,55,0,$host); } else { $DEBUG>=2 && DEBUG("not using SNI because hostname is unknown"); } } elsif ( $arg_hash->{SSL_hostname} ) { return $self->_internal_error( "Client side SNI not supported for this openssl",9); } else { $DEBUG>=2 && DEBUG("not using SNI because openssl is too old"); } $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} || $self->_update_peer; if ( $ctx->{verify_name_ref} ) { # need target name for update my $host = $arg_hash->{SSL_verifycn_name} || $arg_hash->{SSL_hostname}; if ( ! defined $host ) { if ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) { $host =~s{^ ( (?:[^:\[]+) | # ipv4|host (?:\[(?:.*)\]) # [ipv6|host] ) (:[\w\-]+)? # optional :port $}{$1}x; # ipv4|host|ipv6 } } ${$ctx->{verify_name_ref}} = $host; } my $ocsp = $ctx->{ocsp_mode}; if ( $ocsp & SSL_OCSP_NO_STAPLE ) { # don't try stapling } elsif ( ! $can_ocsp_staple ) { croak("OCSP stapling not support") if $ocsp & SSL_OCSP_MUST_STAPLE; } elsif ( $ocsp & (SSL_OCSP_TRY_STAPLE|SSL_OCSP_MUST_STAPLE)) { # staple by default if verification enabled ${*$self}{_SSL_ocsp_verify} = undef; Net::SSLeay::set_tlsext_status_type($ssl, Net::SSLeay::TLSEXT_STATUSTYPE_ocsp()); $DEBUG>=2 && DEBUG("request OCSP stapling"); } if ($ctx->{session_cache} and my $session = $ctx->{session_cache}->get_session($arg_hash->{SSL_session_key}) ) { Net::SSLeay::set_session($ssl, $session); } } $ssl ||= ${*$self}{'_SSL_object'}; $SSL_ERROR = $! = undef; my $timeout = exists $args->{Timeout} ? $args->{Timeout} : ${*$self}{io_socket_timeout}; # from IO::Socket if ( defined($timeout) && $timeout>0 && $self->blocking(0) ) { $DEBUG>=2 && DEBUG( "set socket to non-blocking to enforce timeout=$timeout" ); # timeout was given and socket was blocking # enforce timeout with now non-blocking socket } else { # timeout does not apply because invalid or socket non-blocking $timeout = undef; $auto_retry && $auto_retry->($ssl,$self->blocking); } my $start = defined($timeout) && time(); { $SSL_ERROR = undef; $CURRENT_SSL_OBJECT = $self; $DEBUG>=3 && DEBUG("call Net::SSLeay::connect" ); my $rv = Net::SSLeay::connect($ssl); $CURRENT_SSL_OBJECT = undef; $DEBUG>=3 && DEBUG("done Net::SSLeay::connect -> $rv" ); if ( $rv < 0 ) { if ( my $err = $self->_skip_rw_error( $ssl,$rv )) { $self->error("SSL connect attempt failed"); delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'} = -1; $DEBUG>=1 && DEBUG( "fatal SSL error: $SSL_ERROR" ); return $self->fatal_ssl_error(); } $DEBUG>=2 && DEBUG('ssl handshake in progress' ); # connect failed because handshake needs to be completed # if socket was non-blocking or no timeout was given return with this error return if ! defined($timeout); # wait until socket is readable or writable my $rv; if ( $timeout>0 ) { my $vec = ''; vec($vec,$self->fileno,1) = 1; $DEBUG>=2 && DEBUG( "waiting for fd to become ready: $SSL_ERROR" ); $rv = $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,undef,$timeout) : $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec,undef,$timeout) : undef; } else { $DEBUG>=2 && DEBUG("handshake failed because no more time" ); $! = ETIMEDOUT } if ( ! $rv ) { $DEBUG>=2 && DEBUG("handshake failed because socket did not became ready" ); # failed because of timeout, return $! ||= ETIMEDOUT; delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'} = -1; $self->blocking(1); # was blocking before return } # socket is ready, try non-blocking connect again after recomputing timeout $DEBUG>=2 && DEBUG("socket ready, retrying connect" ); my $now = time(); $timeout -= $now - $start; $start = $now; redo; } elsif ( $rv == 0 ) { delete ${*$self}{'_SSL_opening'}; $DEBUG>=2 && DEBUG("connection failed - connect returned 0" ); $self->error("SSL connect attempt failed because of handshake problems" ); ${*$self}{'_SSL_opened'} = -1; return $self->fatal_ssl_error(); } } $DEBUG>=2 && DEBUG('ssl handshake done' ); # ssl connect successful delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'}=1; if (defined($timeout)) { $self->blocking(1); # reset back to blocking $! = undef; # reset errors from non-blocking } $ctx ||= ${*$self}{'_SSL_ctx'}; if ( my $ocsp_result = ${*$self}{_SSL_ocsp_verify} ) { # got result from OCSP stapling if ( $ocsp_result->[0] > 0 ) { $DEBUG>=3 && DEBUG("got OCSP success with stapling"); # successful validated } elsif ( $ocsp_result->[0] < 0 ) { # Permanent problem with validation because certificate # is either self-signed or the issuer cannot be found. # Ignore here, because this will cause other errors too. $DEBUG>=3 && DEBUG("got OCSP failure with stapling: %s", $ocsp_result->[1]); } else { # definitely revoked $DEBUG>=3 && DEBUG("got OCSP revocation with stapling: %s", $ocsp_result->[1]); $self->_internal_error($ocsp_result->[1],5); return $self->fatal_ssl_error(); } } elsif ( $ctx->{ocsp_mode} & SSL_OCSP_MUST_STAPLE ) { $self->_internal_error("did not receive the required stapled OCSP response",5); return $self->fatal_ssl_error(); } if (!%sess_cb and $ctx->{session_cache} and my $session = Net::SSLeay::get1_session($ssl)) { $ctx->{session_cache}->add_session( ${*$self}{_SSL_arguments}{SSL_session_key}, $session ); } tie *{$self}, "IO::Socket::SSL::SSL_HANDLE", $self; return $self; } # called if PeerAddr is not set in ${*$self}{'_SSL_arguments'} # this can be the case if start_SSL is called with a normal IO::Socket::INET # so that PeerAddr|PeerPort are not set from args # returns PeerAddr sub _update_peer { my $self = shift; my $arg_hash = ${*$self}{'_SSL_arguments'}; eval { my $sockaddr = getpeername( $self ); my $af = sockaddr_family($sockaddr); if( CAN_IPV6 && $af == AF_INET6 ) { my (undef, $host, $port) = _getnameinfo($sockaddr, NI_NUMERICHOST | NI_NUMERICSERV); $arg_hash->{PeerPort} = $port; $arg_hash->{PeerAddr} = $host; } else { my ($port,$addr) = sockaddr_in( $sockaddr); $arg_hash->{PeerPort} = $port; $arg_hash->{PeerAddr} = inet_ntoa( $addr ); } } } #Call to accept occurs when a new client connects to a server using #IO::Socket::SSL sub accept { my $self = shift || return _invalid_object(); my $class = shift || 'IO::Socket::SSL'; my $socket = ${*$self}{'_SSL_opening'}; if ( ! $socket ) { # underlying socket not done $DEBUG>=2 && DEBUG('no socket yet' ); $socket = $self->SUPER::accept($class) || return; $DEBUG>=2 && DEBUG('accept created normal socket '.$socket ); # don't continue with accept_SSL if SSL_startHandshake is set to 0 my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake}; if (defined $sh && ! $sh) { ${*$socket}{_SSL_ctx} = ${*$self}{_SSL_ctx}; ${*$socket}{_SSL_arguments} = { %{${*$self}{_SSL_arguments}}, SSL_server => 0, }; $DEBUG>=2 && DEBUG('will not start SSL handshake yet'); return wantarray ? ($socket, getpeername($socket) ) : $socket } } $self->accept_SSL($socket) || return; $DEBUG>=2 && DEBUG('accept_SSL ok' ); return wantarray ? ($socket, getpeername($socket) ) : $socket; } sub accept_SSL { my $self = shift; my $socket = ( @_ && UNIVERSAL::isa( $_[0], 'IO::Handle' )) ? shift : $self; my $args = @_>1 ? {@_}: $_[0]||{}; my $ssl; if ( ! ${*$self}{'_SSL_opening'} ) { $DEBUG>=2 && DEBUG('starting sslifying' ); ${*$self}{'_SSL_opening'} = $socket; if ($socket != $self) { ${*$socket}{_SSL_ctx} = ${*$self}{_SSL_ctx}; ${*$socket}{_SSL_arguments} = { %{${*$self}{_SSL_arguments}}, SSL_server => 0 }; } my $fileno = ${*$socket}{'_SSL_fileno'} = fileno($socket); return $socket->_internal_error("Socket has no fileno",9) if ! defined $fileno; $ssl = ${*$socket}{_SSL_object} = Net::SSLeay::new(${*$socket}{_SSL_ctx}{context}) || return $socket->error("SSL structure creation failed"); $CREATED_IN_THIS_THREAD{$ssl} = 1 if $use_threads; $SSL_OBJECT{$ssl} = [$socket,1]; weaken($SSL_OBJECT{$ssl}[0]); Net::SSLeay::set_fd($ssl, $fileno) || return $socket->error("SSL filehandle association failed"); set_msg_callback($self) if $DEBUG>=2 || ${*$self}{_SSL_msg_callback}; } $ssl ||= ${*$socket}{'_SSL_object'}; $SSL_ERROR = $! = undef; #$DEBUG>=2 && DEBUG('calling ssleay::accept' ); my $timeout = exists $args->{Timeout} ? $args->{Timeout} : ${*$self}{io_socket_timeout}; # from IO::Socket if ( defined($timeout) && $timeout>0 && $socket->blocking(0) ) { # timeout was given and socket was blocking # enforce timeout with now non-blocking socket } else { # timeout does not apply because invalid or socket non-blocking $timeout = undef; $auto_retry && $auto_retry->($ssl,$socket->blocking); } my $start = defined($timeout) && time(); { $SSL_ERROR = undef; $CURRENT_SSL_OBJECT = $self; my $rv = Net::SSLeay::accept($ssl); $CURRENT_SSL_OBJECT = undef; $DEBUG>=3 && DEBUG( "Net::SSLeay::accept -> $rv" ); if ( $rv < 0 ) { if ( my $err = $socket->_skip_rw_error( $ssl,$rv )) { $socket->error("SSL accept attempt failed"); delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = -1; return $socket->fatal_ssl_error(); } # accept failed because handshake needs to be completed # if socket was non-blocking or no timeout was given return with this error return if ! defined($timeout); # wait until socket is readable or writable my $rv; if ( $timeout>0 ) { my $vec = ''; vec($vec,$socket->fileno,1) = 1; $rv = $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,undef,$timeout) : $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec,undef,$timeout) : undef; } else { $! = ETIMEDOUT } if ( ! $rv ) { # failed because of timeout, return $! ||= ETIMEDOUT; delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = -1; $socket->blocking(1); # was blocking before return } # socket is ready, try non-blocking accept again after recomputing timeout my $now = time(); $timeout -= $now - $start; $start = $now; redo; } elsif ( $rv == 0 ) { $socket->error("SSL accept attempt failed because of handshake problems" ); delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = -1; return $socket->fatal_ssl_error(); } } $DEBUG>=2 && DEBUG('handshake done, socket ready' ); # socket opened delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = 1; if (defined($timeout)) { $socket->blocking(1); # reset back to blocking $! = undef; # reset errors from non-blocking } tie *{$socket}, "IO::Socket::SSL::SSL_HANDLE", $socket; return $socket; } # support user defined message callback but also internal debugging sub _msg_callback { ## my ($direction, $ssl_ver, $content_type, $buf, $len, $ssl, $userp) = @_; IO::Socket::SSL::Trace::ossl_trace(@_) if $DEBUG>=2; my $self = ($SSL_OBJECT{$_[5]} || return)->[0] || return; if (my $cb = ${*$self}{_SSL_msg_callback}) { my ($sub,@arg) = @$cb; $sub->($self, @_[0..5], @arg); } } my $ssleay_set_msg_callback = defined &Net::SSLeay::set_msg_callback && \&Net::SSLeay::set_msg_callback; sub set_msg_callback { my $self = shift; if (@_) { if ($_[0]) { # enable user defined callback: ($cb,@arg) die "no support for msg callback with this version of Net::SSLeay/OpenSSL" if !$ssleay_set_msg_callback; ${*$self}{_SSL_msg_callback} = [@_]; } else { # disable user defined callback delete ${*$self}{_SSL_msg_callback}; } } # activate user set callback and/or internal for debugging if ($ssleay_set_msg_callback and my $ssl = ${*$self}{_SSL_object}) { $ssleay_set_msg_callback->($ssl, ($DEBUG>=2 || ${*$self}{_SSL_msg_callback})? \&_msg_callback : undef) } } ####### I/O subroutines ######################## if ($auto_retry) { *blocking = sub { my $self = shift; { @_ && $auto_retry->(${*$self}{_SSL_object} || last, @_); } return $self->SUPER::blocking(@_); }; } sub _generic_read { my ($self, $read_func, undef, $length, $offset) = @_; my $ssl = ${*$self}{_SSL_object} || return; my $buffer=\$_[2]; $SSL_ERROR = $! = undef; my ($data,$rwerr) = $read_func->($ssl, $length); while ( ! defined($data)) { if ( my $err = $self->_skip_rw_error( $ssl, defined($rwerr) ? $rwerr:-1 )) { # OpenSSL 1.1.0c+ : EOF can now result in SSL_read returning -1 and SSL_ERROR_SYSCALL # OpenSSL 3.0 : EOF can now result in SSL_read returning -1 and SSL_ERROR_SSL if (not $! and $err == $Net_SSLeay_ERROR_SSL || $err == $Net_SSLeay_ERROR_SYSCALL) { # treat as EOF $data = ''; # clear the "unexpected eof while reading" error (OpenSSL 3.0+) Net::SSLeay::ERR_clear_error(); last; } $self->error("SSL read error"); } return; } $length = length($data); $$buffer = '' if !defined $$buffer; $offset ||= 0; if ($offset>length($$buffer)) { $$buffer.="\0" x ($offset-length($$buffer)); #mimic behavior of read } substr($$buffer, $offset, length($$buffer), $data); return $length; } sub read { my $self = shift; ${*$self}{_SSL_object} && return _generic_read($self, $self->blocking ? \&Net::SSLeay::ssl_read_all : \&Net::SSLeay::read, @_ ); # fall back to plain read if we are not required to use SSL yet return $self->SUPER::read(@_); } # contrary to the behavior of read sysread can read partial data sub sysread { my $self = shift; ${*$self}{_SSL_object} && return _generic_read( $self, \&Net::SSLeay::read, @_ ); # fall back to plain sysread if we are not required to use SSL yet my $rv = $self->SUPER::sysread(@_); return $rv; } sub peek { my $self = shift; ${*$self}{_SSL_object} && return _generic_read( $self, \&Net::SSLeay::peek, @_ ); # fall back to plain peek if we are not required to use SSL yet # emulate peek with recv(...,MS_PEEK) - peek(buf,len,offset) return if ! defined recv($self,my $buf,$_[1],MSG_PEEK); $_[0] = $_[2] ? substr($_[0],0,$_[2]).$buf : $buf; return length($buf); } sub _generic_write { my ($self, $write_all, undef, $length, $offset) = @_; my $ssl = ${*$self}{_SSL_object} || return; my $buffer = \$_[2]; my $buf_len = length($$buffer); $length ||= $buf_len; $offset ||= 0; return $self->_internal_error("Invalid offset for SSL write",9) if $offset>$buf_len; return 0 if ($offset == $buf_len); $SSL_ERROR = $! = undef; my $written; if ( $write_all ) { my $data = $length < $buf_len-$offset ? substr($$buffer, $offset, $length) : $$buffer; ($written, my $errs) = Net::SSLeay::ssl_write_all($ssl, $data); # ssl_write_all returns number of bytes written $written = undef if ! $written && $errs; } else { $written = Net::SSLeay::write_partial( $ssl,$offset,$length,$$buffer ); # write_partial does SSL_write which returns -1 on error $written = undef if $written <= 0; } if ( !defined($written) ) { if ( my $err = $self->_skip_rw_error( $ssl,-1 )) { # if $! is not set with ERROR_SYSCALL then report as EPIPE $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL; $self->error("SSL write error ($err)"); } return; } return $written; } # if socket is blocking write() should return only on error or # if all data are written sub write { my $self = shift; ${*$self}{_SSL_object} && return _generic_write( $self, scalar($self->blocking),@_ ); # fall back to plain write if we are not required to use SSL yet return $self->SUPER::write(@_); } # contrary to write syswrite() returns already if only # a part of the data is written sub syswrite { my $self = shift; ${*$self}{_SSL_object} && return _generic_write($self,0,@_); # fall back to plain syswrite if we are not required to use SSL yet return $self->SUPER::syswrite(@_); } sub print { my $self = shift; my $string = join(($, or ''), @_, ($\ or '')); return $self->write( $string ); } sub printf { my ($self,$format) = (shift,shift); return $self->write(sprintf($format, @_)); } sub getc { my ($self, $buffer) = (shift, undef); return $buffer if $self->read($buffer, 1, 0); } sub readline { my $self = shift; ${*$self}{_SSL_object} or return $self->SUPER::getline; if ( not defined $/ or wantarray) { # read all and split my $buf = ''; while (1) { my $rv = $self->sysread($buf,2**16,length($buf)); if ( ! defined $rv ) { next if $! == EINTR; # retry last if $! == EWOULDBLOCK || $! == EAGAIN; # use everything so far return; # return error } elsif ( ! $rv ) { last } } if ( ! defined $/ ) { return $buf } elsif ( ref($/)) { my $size = ${$/}; die "bad value in ref \$/: $size" unless $size>0; return $buf=~m{\G(.{1,$size})}g; } elsif ( $/ eq '' ) { return $buf =~m{\G(.*\n\n+|.+)}g; } else { return $buf =~m{\G(.*$/|.+)}g; } } # read only one line if ( ref($/) ) { my $size = ${$/}; # read record of $size bytes die "bad value in ref \$/: $size" unless $size>0; my $buf = ''; while ( $size>length($buf)) { my $rv = $self->sysread($buf,$size-length($buf),length($buf)); if ( ! defined $rv ) { next if $! == EINTR; # retry last if $! == EWOULDBLOCK || $! == EAGAIN; # use everything so far return; # return error } elsif ( ! $rv ) { last } } return $buf; } my ($delim0,$delim1) = $/ eq '' ? ("\n\n","\n"):($/,''); # find first occurrence of $delim0 followed by as much as possible $delim1 my $buf = ''; my $eod = 0; # pointer into $buf after $delim0 $delim1* my $ssl = $self->_get_ssl_object or return; while (1) { # wait until we have more data or eof my $poke = Net::SSLeay::peek($ssl,1); if ( ! defined $poke or $poke eq '' ) { next if $! == EINTR; } my $skip = 0; # peek into available data w/o reading my $pending = Net::SSLeay::pending($ssl); if ( $pending and ( my $pb = Net::SSLeay::peek( $ssl,$pending )) ne '' ) { $buf .= $pb } else { return $buf eq '' ? ():$buf; } if ( !$eod ) { my $pos = index( $buf,$delim0 ); if ( $pos<0 ) { $skip = $pending } else { $eod = $pos + length($delim0); # pos after delim0 } } if ( $eod ) { if ( $delim1 ne '' ) { # delim0 found, check for as much delim1 as possible while ( index( $buf,$delim1,$eod ) == $eod ) { $eod+= length($delim1); } } $skip = $pending - ( length($buf) - $eod ); } # remove data from $self which I already have in buf while ( $skip>0 ) { if ($self->sysread(my $p,$skip,0)) { $skip -= length($p); next; } $! == EINTR or last; } if ( $eod and ( $delim1 eq '' or $eod < length($buf))) { # delim0 found and there can be no more delim1 pending last } } return substr($buf,0,$eod); } sub close { my $self = shift || return _invalid_object(); my $close_args = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}; return if ! $self->stop_SSL( SSL_fast_shutdown => 1, %$close_args, _SSL_ioclass_downgrade => 0, ); if ( ! $close_args->{_SSL_in_DESTROY} ) { untie( *$self ); undef ${*$self}{_SSL_fileno}; return $self->SUPER::close; } return 1; } sub is_SSL { my $self = pop; return ${*$self}{_SSL_object} && 1 } sub stop_SSL { my $self = shift || return _invalid_object(); my $stop_args = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}; $stop_args->{SSL_no_shutdown} = 1 if ! ${*$self}{_SSL_opened}; if (my $ssl = ${*$self}{'_SSL_object'}) { if (delete ${*$self}{'_SSL_opening'}) { # just destroy the object further below } elsif ( ! $stop_args->{SSL_no_shutdown} ) { my $status = Net::SSLeay::get_shutdown($ssl); my $timeout = not($self->blocking) ? undef : exists $stop_args->{Timeout} ? $stop_args->{Timeout} : ${*$self}{io_socket_timeout}; # from IO::Socket if ($timeout) { $self->blocking(0); $timeout += time(); } while (1) { if ( $status & SSL_SENT_SHUTDOWN and # don't care for received if fast shutdown $status & SSL_RECEIVED_SHUTDOWN || $stop_args->{SSL_fast_shutdown}) { # shutdown complete last; } if ((${*$self}{'_SSL_opened'}||0) <= 0) { # not really open, thus don't expect shutdown to return # something meaningful last; } # initiate or complete shutdown local $SIG{PIPE} = 'IGNORE'; $SSL_ERROR = $! = undef; my $rv = Net::SSLeay::shutdown($ssl); if ( $rv < 0 ) { # non-blocking socket? if ( ! $timeout ) { if ( my $err = $self->_skip_rw_error( $ssl, $rv )) { # if $! is not set with ERROR_SYSCALL then report as EPIPE $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL; $self->error("SSL shutdown error ($err)"); } # need to try again return; } # don't use _skip_rw_error so that existing error does # not get cleared my $wait = $timeout - time(); last if $wait<=0; vec(my $vec = '',fileno($self),1) = 1; my $err = Net::SSLeay::get_error($ssl,$rv); if ( $err == $Net_SSLeay_ERROR_WANT_READ) { select($vec,undef,undef,$wait) } elsif ( $err == $Net_SSLeay_ERROR_WANT_WRITE) { select(undef,$vec,undef,$wait) } else { if ($err) { # if $! is not set with ERROR_SYSCALL then report as EPIPE $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL; $self->error("SSL shutdown error ($err)"); } last; } } $status |= SSL_SENT_SHUTDOWN; $status |= SSL_RECEIVED_SHUTDOWN if $rv>0; } $self->blocking(1) if $timeout; } # destroy allocated objects for SSL and untie # do not destroy CTX unless explicitly specified Net::SSLeay::free($ssl); if (my $cert = delete ${*$self}{'_SSL_certificate'}) { Net::SSLeay::X509_free($cert); } delete ${*$self}{_SSL_object}; ${*$self}{'_SSL_opened'} = 0; delete $SSL_OBJECT{$ssl}; delete $CREATED_IN_THIS_THREAD{$ssl}; untie(*$self); } if ($stop_args->{'SSL_ctx_free'}) { my $ctx = delete ${*$self}{'_SSL_ctx'}; $ctx && $ctx->DESTROY(); } if ( ! $stop_args->{_SSL_in_DESTROY} ) { my $downgrade = $stop_args->{_SSL_ioclass_downgrade}; if ( $downgrade || ! defined $downgrade ) { # rebless to original class from start_SSL if ( my $orig_class = delete ${*$self}{'_SSL_ioclass_upgraded'} ) { bless $self,$orig_class; # FIXME: if original class was tied too we need to restore the tie # remove all _SSL related from *$self my @sslkeys = grep { m{^_?SSL_} } keys %{*$self}; delete @{*$self}{@sslkeys} if @sslkeys; } } } return 1; } sub fileno { my $self = shift; my $fn = ${*$self}{'_SSL_fileno'}; return defined($fn) ? $fn : $self->SUPER::fileno(); } ####### IO::Socket::SSL specific functions ####### # _get_ssl_object is for internal use ONLY! sub _get_ssl_object { my $self = shift; return ${*$self}{'_SSL_object'} || IO::Socket::SSL->_internal_error("Undefined SSL object",9); } # _get_ctx_object is for internal use ONLY! sub _get_ctx_object { my $self = shift; my $ctx_object = ${*$self}{_SSL_ctx}; return $ctx_object && $ctx_object->{context}; } # default error for undefined arguments sub _invalid_object { return IO::Socket::SSL->_internal_error("Undefined IO::Socket::SSL object",9); } sub pending { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::pending($ssl); } sub start_SSL { my ($class,$socket) = (shift,shift); return $class->_internal_error("Not a socket",9) if ! ref($socket); my $arg_hash = @_ == 1 ? $_[0] : {@_}; my %to = exists $arg_hash->{Timeout} ? ( Timeout => delete $arg_hash->{Timeout} ) :(); my $original_class = ref($socket); if ( ! $original_class ) { $socket = ($original_class = $ISA[0])->new_from_fd($socket,'<+') or return $class->_internal_error( "creating $original_class from file handle failed",9); } my $original_fileno = (UNIVERSAL::can($socket, "fileno")) ? $socket->fileno : CORE::fileno($socket); return $class->_internal_error("Socket has no fileno",9) if ! defined $original_fileno; bless $socket, $class; $socket->configure_SSL($arg_hash) or bless($socket, $original_class) && return; ${*$socket}{'_SSL_fileno'} = $original_fileno; ${*$socket}{'_SSL_ioclass_upgraded'} = $original_class if $class ne $original_class; my $start_handshake = $arg_hash->{SSL_startHandshake}; if ( ! defined($start_handshake) || $start_handshake ) { # if we have no callback force blocking mode $DEBUG>=2 && DEBUG( "start handshake" ); my $was_blocking = $socket->blocking(1); my $result = ${*$socket}{'_SSL_arguments'}{SSL_server} ? $socket->accept_SSL(%to) : $socket->connect_SSL(%to); if ( $result ) { $socket->blocking(0) if ! $was_blocking; return $socket; } else { # upgrade to SSL failed, downgrade socket to original class if ( $original_class ) { bless($socket,$original_class); $socket->blocking(0) if ! $was_blocking && $socket->can('blocking'); } return; } } else { $DEBUG>=2 && DEBUG( "don't start handshake: $socket" ); return $socket; # just return upgraded socket } } sub new_from_fd { my ($class, $fd) = (shift,shift); # Check for accidental inclusion of MODE in the argument list if (length($_[0]) < 4) { (my $mode = $_[0]) =~ tr/+<>//d; shift unless length($mode); } my $handle = $ISA[0]->new_from_fd($fd, '+<') || return($class->error("Could not create socket from file descriptor.")); # Annoying workaround for Perl 5.6.1 and below: $handle = $ISA[0]->new_from_fd($handle, '+<'); return $class->start_SSL($handle, @_); } sub dump_peer_certificate { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::dump_peer_certificate($ssl); } if ( defined &Net::SSLeay::get_peer_cert_chain && $netssleay_version >= 1.58 ) { *peer_certificates = sub { my $self = shift; my $ssl = $self->_get_ssl_object || return; my @chain = Net::SSLeay::get_peer_cert_chain($ssl); @chain = () if @chain && !$self->peer_certificate; # work around #96013 if ( ${*$self}{_SSL_arguments}{SSL_server} ) { # in the client case the chain contains the peer certificate, # in the server case not # this one has an increased reference counter, the other not if ( my $peer = Net::SSLeay::get_peer_certificate($ssl)) { Net::SSLeay::X509_free($peer); unshift @chain, $peer; } } return @chain; } } else { *peer_certificates = sub { die "peer_certificates needs Net::SSLeay>=1.58"; } } { my %dispatcher = ( issuer => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name( shift )) }, subject => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name( shift )) }, commonName => sub { my $cn = Net::SSLeay::X509_NAME_get_text_by_NID( Net::SSLeay::X509_get_subject_name( shift ), NID_CommonName); $cn; }, subjectAltNames => sub { Net::SSLeay::X509_get_subjectAltNames( shift ) }, ); # alternative names $dispatcher{authority} = $dispatcher{issuer}; $dispatcher{owner} = $dispatcher{subject}; $dispatcher{cn} = $dispatcher{commonName}; sub peer_certificate { my ($self,$field,$reload) = @_; my $ssl = $self->_get_ssl_object or return; Net::SSLeay::X509_free(delete ${*$self}{_SSL_certificate}) if $reload && ${*$self}{_SSL_certificate}; my $cert = ${*$self}{_SSL_certificate} ||= Net::SSLeay::get_peer_certificate($ssl) or return $self->error("Could not retrieve peer certificate"); if ($field) { my $sub = $dispatcher{$field} or croak "invalid argument for peer_certificate, valid are: ".join( " ",keys %dispatcher ). "\nMaybe you need to upgrade your Net::SSLeay"; return $sub->($cert); } else { return $cert } } sub sock_certificate { my ($self,$field) = @_; my $ssl = $self->_get_ssl_object || return; my $cert = Net::SSLeay::get_certificate( $ssl ) || return; if ($field) { my $sub = $dispatcher{$field} or croak "invalid argument for sock_certificate, valid are: ".join( " ",keys %dispatcher ). "\nMaybe you need to upgrade your Net::SSLeay"; return $sub->($cert); } else { return $cert } } # known schemes, possible attributes are: # - wildcards_in_alt (0, 'full_label', 'anywhere') # - wildcards_in_cn (0, 'full_label', 'anywhere') # - check_cn (0, 'always', 'when_only') # unfortunately there are a lot of different schemes used, see RFC 6125 for a # summary, which references all of the following except RFC4217/ftp my %scheme = ( none => {}, # do not check # default set is a superset of all the others and thus worse than a more # specific set, but much better than not verifying name at all default => { wildcards_in_cn => 'anywhere', wildcards_in_alt => 'anywhere', check_cn => 'always', ip_in_cn => 1, }, ); for(qw( rfc2818 rfc3920 xmpp rfc4217 ftp )) { $scheme{$_} = { wildcards_in_cn => 'anywhere', wildcards_in_alt => 'anywhere', check_cn => 'when_only', } } for(qw(www http)) { $scheme{$_} = { wildcards_in_cn => 'anywhere', wildcards_in_alt => 'anywhere', check_cn => 'when_only', ip_in_cn => 4, } } for(qw( rfc4513 ldap )) { $scheme{$_} = { wildcards_in_cn => 0, wildcards_in_alt => 'full_label', check_cn => 'always', }; } for(qw( rfc2595 smtp rfc4642 imap pop3 acap rfc5539 nntp rfc5538 netconf rfc5425 syslog rfc5953 snmp )) { $scheme{$_} = { wildcards_in_cn => 'full_label', wildcards_in_alt => 'full_label', check_cn => 'always' }; } for(qw( rfc5971 gist )) { $scheme{$_} = { wildcards_in_cn => 'full_label', wildcards_in_alt => 'full_label', check_cn => 'when_only', }; } for(qw( rfc5922 sip )) { $scheme{$_} = { wildcards_in_cn => 0, wildcards_in_alt => 0, check_cn => 'always', }; } # function to verify the hostname # # as every application protocol has its own rules to do this # we provide some default rules as well as a user-defined # callback sub verify_hostname_of_cert { my $identity = shift; my $cert = shift; my $scheme = shift || 'default'; my $publicsuffix = shift; if ( ! ref($scheme) ) { $DEBUG>=3 && DEBUG( "scheme=$scheme cert=$cert" ); $scheme = $scheme{$scheme} || croak("scheme $scheme not defined"); } return 1 if ! %$scheme; # 'none' $identity =~s{\.+$}{}; # ignore absolutism # get data from certificate my $commonName = $dispatcher{cn}->($cert); my @altNames = $dispatcher{subjectAltNames}->($cert); $DEBUG>=3 && DEBUG("identity=$identity cn=$commonName alt=@altNames" ); if ( my $sub = $scheme->{callback} ) { # use custom callback return $sub->($identity,$commonName,@altNames); } # is the given hostname an IP address? Then we have to convert to network byte order [RFC791][RFC2460] my $ipn; if ( CAN_IPV6 and $identity =~m{:} ) { # no IPv4 or hostname have ':' in it, try IPv6. $identity =~m{[^\da-fA-F:\.]} and return; # invalid characters in name $ipn = inet_pton(AF_INET6,$identity) or return; # invalid name } elsif ( my @ip = $identity =~m{^(\d+)(?:\.(\d+)\.(\d+)\.(\d+)|[\d\.]*)$} ) { # check for invalid IP/hostname return if 4 != @ip or 4 != grep { defined($_) && $_<256 } @ip; $ipn = pack("CCCC",@ip); } else { # assume hostname, check for umlauts etc if ( $identity =~m{[^a-zA-Z0-9_.\-]} ) { $identity =~m{\0} and return; # $identity has \\0 byte $identity = idn_to_ascii($identity) or return; # conversation to IDNA failed $identity =~m{[^a-zA-Z0-9_.\-]} and return; # still junk inside } } # do the actual verification my $check_name = sub { my ($name,$identity,$wtyp,$publicsuffix) = @_; $name =~s{\.+$}{}; # ignore absolutism $name eq '' and return; $wtyp ||= ''; my $pattern; ### IMPORTANT! # We accept only a single wildcard and only for a single part of the FQDN # e.g. *.example.org does match www.example.org but not bla.www.example.org # The RFCs are in this regard unspecific but we don't want to have to # deal with certificates like *.com, *.co.uk or even * # see also http://nils.toedtmann.net/pub/subjectAltName.txt . # Also, we fall back to full_label matches if the identity is an IDNA # name, see RFC6125 and the discussion at # http://bugs.python.org/issue17997#msg194950 if ( $wtyp eq 'anywhere' and $name =~m{^([a-zA-Z0-9_\-]*)\*(.+)} ) { return if $1 ne '' and substr($identity,0,4) eq 'xn--'; # IDNA $pattern = qr{^\Q$1\E[a-zA-Z0-9_\-]+\Q$2\E$}i; } elsif ( $wtyp =~ m{^(?:full_label|leftmost)$} and $name =~m{^\*(\..+)$} ) { $pattern = qr{^[a-zA-Z0-9_\-]+\Q$1\E$}i; } else { return lc($identity) eq lc($name); } if ( $identity =~ $pattern ) { $publicsuffix = IO::Socket::SSL::PublicSuffix->default if ! defined $publicsuffix; return 1 if $publicsuffix eq ''; my @labels = split( m{\.+}, $identity ); my $tld = $publicsuffix->public_suffix(\@labels,+1); return 1 if @labels > ( $tld ? 0+@$tld : 1 ); } return; }; my $alt_dnsNames = 0; while (@altNames) { my ($type, $name) = splice (@altNames, 0, 2); if ( $ipn and $type == GEN_IPADD ) { # exact match needed for IP # $name is already packed format (inet_xton) return 1 if $ipn eq $name; } elsif ( ! $ipn and $type == GEN_DNS ) { $name =~s/\s+$//; $name =~s/^\s+//; $alt_dnsNames++; $check_name->($name,$identity,$scheme->{wildcards_in_alt},$publicsuffix) and return 1; } } if ( $scheme->{check_cn} eq 'always' or $scheme->{check_cn} eq 'when_only' and !$alt_dnsNames ) { if ( ! $ipn ) { $check_name->($commonName,$identity,$scheme->{wildcards_in_cn},$publicsuffix) and return 1; } elsif ( $scheme->{ip_in_cn} ) { if ( $identity eq $commonName ) { return 1 if $scheme->{ip_in_cn} == 4 ? length($ipn) == 4 : $scheme->{ip_in_cn} == 6 ? length($ipn) == 16 : 1; } } } return 0; # no match } } sub verify_hostname { my $self = shift; my $host = shift; my $cert = $self->peer_certificate; return verify_hostname_of_cert( $host,$cert,@_ ); } sub get_servername { my $self = shift; return ${*$self}{_SSL_servername} ||= do { my $ssl = $self->_get_ssl_object or return; Net::SSLeay::get_servername($ssl); }; } sub get_fingerprint_bin { my ($self,$algo,$cert,$key_only) = @_; $cert ||= $self->peer_certificate or return; return $key_only ? Net::SSLeay::X509_pubkey_digest($cert, $algo2digest->($algo || 'sha256')) : Net::SSLeay::X509_digest($cert, $algo2digest->($algo || 'sha256')); } sub get_fingerprint { my ($self,$algo,$cert,$key_only) = @_; $algo ||= 'sha256'; my $fp = get_fingerprint_bin($self,$algo,$cert,$key_only) or return; return $algo.'$'.($key_only ? 'pub$':'').unpack('H*',$fp); } sub get_cipher { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::get_cipher($ssl); } sub get_sslversion { my $ssl = shift()->_get_ssl_object || return; my $version = Net::SSLeay::version($ssl) or return; return $version == 0x0304 ? 'TLSv1_3' : $version == 0x0303 ? 'TLSv1_2' : $version == 0x0302 ? 'TLSv1_1' : $version == 0x0301 ? 'TLSv1' : $version == 0x0300 ? 'SSLv3' : $version == 0x0002 ? 'SSLv2' : $version == 0xfeff ? 'DTLS1' : undef; } sub get_sslversion_int { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::version($ssl); } sub get_session_reused { return Net::SSLeay::session_reused( shift()->_get_ssl_object || return); } if ($can_ocsp) { no warnings 'once'; *ocsp_resolver = sub { my $self = shift; my $ssl = $self->_get_ssl_object || return; my $ctx = ${*$self}{_SSL_ctx}; return IO::Socket::SSL::OCSP_Resolver->new( $ssl, $ctx->{ocsp_cache} ||= IO::Socket::SSL::OCSP_Cache->new, $ctx->{ocsp_mode} & SSL_OCSP_FAIL_HARD, @_ ? \@_ : $ctx->{ocsp_mode} & SSL_OCSP_FULL_CHAIN ? [ $self->peer_certificates ]: [ $self->peer_certificate ] ); }; } sub errstr { my $self = shift; my $oe = ref($self) && ${*$self}{_SSL_last_err}; return $oe ? $oe->[0] : $SSL_ERROR || ''; } sub fatal_ssl_error { my $self = shift; my $error_trap = ${*$self}{'_SSL_arguments'}->{'SSL_error_trap'}; $@ = $self->errstr; my $saved_error = $SSL_ERROR; if (defined $error_trap and ref($error_trap) eq 'CODE') { $error_trap->($self, $self->errstr()."\n".$self->get_ssleay_error()); } elsif ( ${*$self}{'_SSL_ioclass_upgraded'} || ${*$self}{_SSL_arguments}{SSL_keepSocketOnError}) { # downgrade only $DEBUG>=3 && DEBUG('downgrading SSL only, not closing socket' ); $self->stop_SSL; } else { # kill socket $self->close } $SSL_ERROR = $saved_error if $saved_error; return; } sub get_ssleay_error { #Net::SSLeay will print out the errors itself unless we explicitly #undefine $Net::SSLeay::trace while running print_errs() local $Net::SSLeay::trace; return Net::SSLeay::print_errs('SSL error: ') || ''; } # internal errors, e.g. unsupported features, hostname check failed etc # _SSL_last_err contains severity so that on error chains we can decide if one # error should replace the previous one or if this is just a less specific # follow-up error, e.g. configuration failed because certificate failed because # hostname check went wrong: # 0 - fallback errors # 4 - errors bubbled up from OpenSSL (sub error, r/w error) # 5 - hostname or OCSP verification failed # 9 - fatal problems, e.g. missing feature, no fileno... # _SSL_last_err and SSL_ERROR are only replaced if the error has a higher # severity than the previous one sub _internal_error { my ($self, $error, $severity) = @_; $error = dualvar( -1, $error ); $self = $CURRENT_SSL_OBJECT if !ref($self) && $CURRENT_SSL_OBJECT; if (ref($self)) { my $oe = ${*$self}{_SSL_last_err}; if (!$oe || $oe->[1] <= $severity) { ${*$self}{_SSL_last_err} = [$error,$severity]; $SSL_ERROR = $error; $DEBUG && DEBUG("local error: $error"); } else { $DEBUG && DEBUG("ignoring less severe local error '$error', keep '$oe->[0]'"); } } else { $SSL_ERROR = $error; $DEBUG && DEBUG("global error: $error"); } return; } # OpenSSL errors sub error { my ($self, $error) = @_; my @err; while ( my $err = Net::SSLeay::ERR_get_error()) { push @err, Net::SSLeay::ERR_error_string($err); $DEBUG>=2 && DEBUG( $error."\n".$self->get_ssleay_error()); } $error .= ' '.join(' ',@err) if @err; return $self->_internal_error($error,4) if $error; return; } sub _errstack { my @err; while (my $err = Net::SSLeay::ERR_get_error()) { push @err, Net::SSLeay::ERR_error_string($err); } return @err; } sub can_client_sni { return $can_client_sni } sub can_server_sni { return $can_server_sni } sub can_multi_cert { return $can_multi_cert } sub can_npn { return $can_npn } sub can_alpn { return $can_alpn } sub can_ecdh { return $can_ecdh } sub can_ipv6 { return CAN_IPV6 } sub can_ocsp { return $can_ocsp } sub can_ticket_keycb { return $can_tckt_keycb } sub can_pha { return $can_pha } sub can_partial_chain { return $check_partial_chain && 1 } sub can_ciphersuites { return $can_ciphersuites } sub DESTROY { my $self = shift or return; if (my $ssl = ${*$self}{_SSL_object}) { delete $SSL_OBJECT{$ssl}; if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) { $self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1); } } delete @{*$self}{@all_my_keys}; } #######Extra Backwards Compatibility Functionality####### sub socket_to_SSL { IO::Socket::SSL->start_SSL(@_); } sub socketToSSL { IO::Socket::SSL->start_SSL(@_); } sub kill_socket { shift->close } sub issuer_name { return(shift()->peer_certificate("issuer")) } sub subject_name { return(shift()->peer_certificate("subject")) } sub get_peer_certificate { return shift() } sub context_init { return($GLOBAL_SSL_ARGS = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}); } sub set_default_context { $GLOBAL_SSL_ARGS->{'SSL_reuse_ctx'} = shift; } sub set_default_session_cache { $GLOBAL_SSL_ARGS->{SSL_session_cache} = shift; } { my $set_defaults = sub { my $args = shift; for(my $i=0;$i<@$args;$i+=2 ) { my ($k,$v) = @{$args}[$i,$i+1]; if ( $k =~m{^SSL_} ) { $_->{$k} = $v for(@_); } elsif ( $k =~m{^(name|scheme)$} ) { $_->{"SSL_verifycn_$k"} = $v for (@_); } elsif ( $k =~m{^(callback|mode)$} ) { $_->{"SSL_verify_$k"} = $v for(@_); } else { $_->{"SSL_$k"} = $v for(@_); } } }; sub set_defaults { my %args = @_; $set_defaults->(\@_, $GLOBAL_SSL_ARGS, $GLOBAL_SSL_CLIENT_ARGS, $GLOBAL_SSL_SERVER_ARGS ); } { # deprecated API no warnings; *set_ctx_defaults = \&set_defaults; } sub set_client_defaults { my %args = @_; $set_defaults->(\@_, $GLOBAL_SSL_CLIENT_ARGS ); } sub set_server_defaults { my %args = @_; $set_defaults->(\@_, $GLOBAL_SSL_SERVER_ARGS ); } } sub set_args_filter_hack { my $sub = shift; if ( ref $sub ) { $FILTER_SSL_ARGS = $sub; } elsif ( $sub eq 'use_defaults' ) { # override args with defaults $FILTER_SSL_ARGS = sub { my ($is_server,$args) = @_; %$args = ( %$args, $is_server ? ( %DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_SERVER_ARGS ) : ( %DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_CLIENT_ARGS ) ); } } } sub next_proto_negotiated { my $self = shift; return $self->_internal_error("NPN not supported in Net::SSLeay",9) if ! $can_npn; my $ssl = $self->_get_ssl_object || return; return Net::SSLeay::P_next_proto_negotiated($ssl); } sub alpn_selected { my $self = shift; return $self->_internal_error("ALPN not supported in Net::SSLeay",9) if ! $can_alpn; my $ssl = $self->_get_ssl_object || return; return Net::SSLeay::P_alpn_selected($ssl); } sub opened { my $self = shift; return IO::Handle::opened($self) && ${*$self}{'_SSL_opened'}; } sub opening { my $self = shift; return ${*$self}{'_SSL_opening'}; } sub want_read { shift->errstr == SSL_WANT_READ } sub want_write { shift->errstr == SSL_WANT_WRITE } #Redundant IO::Handle functionality sub getline { return(scalar shift->readline()) } sub getlines { return(shift->readline()) if wantarray(); croak("Use of getlines() not allowed in scalar context"); } #Useless IO::Handle functionality sub truncate { croak("Use of truncate() not allowed with SSL") } sub stat { croak("Use of stat() not allowed with SSL" ) } sub setbuf { croak("Use of setbuf() not allowed with SSL" ) } sub setvbuf { croak("Use of setvbuf() not allowed with SSL" ) } sub fdopen { croak("Use of fdopen() not allowed with SSL" ) } #Unsupported socket functionality sub ungetc { croak("Use of ungetc() not implemented in IO::Socket::SSL") } sub send { croak("Use of send() not implemented in IO::Socket::SSL; use print/printf/syswrite instead") } sub recv { croak("Use of recv() not implemented in IO::Socket::SSL; use read/sysread instead") } package IO::Socket::SSL::SSL_HANDLE; use strict; use Errno 'EBADF'; *weaken = *IO::Socket::SSL::weaken; sub TIEHANDLE { my ($class, $handle) = @_; weaken($handle); bless \$handle, $class; } sub READ { ${shift()}->sysread(@_) } sub READLINE { ${shift()}->readline(@_) } sub GETC { ${shift()}->getc(@_) } sub PRINT { ${shift()}->print(@_) } sub PRINTF { ${shift()}->printf(@_) } sub WRITE { ${shift()}->syswrite(@_) } sub FILENO { ${shift()}->fileno(@_) } sub TELL { $! = EBADF; return -1 } sub BINMODE { return 0 } # not perfect, but better than not implementing the method sub CLOSE { #<---- Do not change this function! my $ssl = ${$_[0]}; local @_; $ssl->close(); } package IO::Socket::SSL::SSL_Context; use Carp; use strict; my %CTX_CREATED_IN_THIS_THREAD; *DEBUG = *IO::Socket::SSL::DEBUG; *_errstack = \&IO::Socket::SSL::_errstack; use constant SSL_MODE_ENABLE_PARTIAL_WRITE => 1; use constant SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER => 2; use constant FILETYPE_PEM => Net::SSLeay::FILETYPE_PEM(); use constant FILETYPE_ASN1 => Net::SSLeay::FILETYPE_ASN1(); my $DEFAULT_SSL_OP = &Net::SSLeay::OP_ALL | &Net::SSLeay::OP_SINGLE_DH_USE | ($can_ecdh ? &Net::SSLeay::OP_SINGLE_ECDH_USE : 0); # Note that the final object will actually be a reference to the scalar # (C-style pointer) returned by Net::SSLeay::CTX_*_new() so that # it can be blessed. sub new { my $class = shift; #DEBUG( "$class @_" ); my $arg_hash = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}; my $is_server = $arg_hash->{SSL_server}; my %defaults = $is_server ? (%DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_SERVER_ARGS) : (%DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_CLIENT_ARGS); if ( $defaults{SSL_reuse_ctx} ) { # ignore default context if there are args to override it delete $defaults{SSL_reuse_ctx} if grep { m{^SSL_(?!verifycn_name|hostname)$} } keys %$arg_hash; } %$arg_hash = ( %defaults, %$arg_hash ) if %defaults; if (my $ctx = $arg_hash->{'SSL_reuse_ctx'}) { if ($ctx->isa('IO::Socket::SSL::SSL_Context') and $ctx->{context}) { # valid context } elsif ( $ctx = ${*$ctx}{_SSL_ctx} ) { # reuse context from existing SSL object } return $ctx } # common problem forgetting to set SSL_use_cert # if client cert is given by user but SSL_use_cert is undef, assume that it # should be set if ( ! $is_server && ! defined $arg_hash->{SSL_use_cert} && ( grep { $arg_hash->{$_} } qw(SSL_cert SSL_cert_file)) && ( grep { $arg_hash->{$_} } qw(SSL_key SSL_key_file)) ) { $arg_hash->{SSL_use_cert} = 1 } # if any of SSL_ca* is set don't set the other SSL_ca* # from defaults if ( $arg_hash->{SSL_ca} ) { $arg_hash->{SSL_ca_file} ||= undef $arg_hash->{SSL_ca_path} ||= undef } elsif ( $arg_hash->{SSL_ca_path} ) { $arg_hash->{SSL_ca_file} ||= undef } elsif ( $arg_hash->{SSL_ca_file} ) { $arg_hash->{SSL_ca_path} ||= undef; } # add library defaults $arg_hash->{SSL_use_cert} = $is_server if ! defined $arg_hash->{SSL_use_cert}; # Avoid passing undef arguments to Net::SSLeay defined($arg_hash->{$_}) or delete($arg_hash->{$_}) for(keys %$arg_hash); # check SSL CA, cert etc arguments # some apps set keys '' to signal that it is not set, replace with undef for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file SSL_ca SSL_ca_file SSL_ca_path SSL_fingerprint )) { $arg_hash->{$_} = undef if defined $arg_hash->{$_} and $arg_hash->{$_} eq ''; } for(qw(SSL_cert_file SSL_key_file)) { defined( my $file = $arg_hash->{$_} ) or next; for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) { die "$_ $f can't be used: $!" if ! open(my $fh,'<',$f) } } my $verify_mode = $arg_hash->{SSL_verify_mode} || 0; if ( $verify_mode != $Net_SSLeay_VERIFY_NONE) { for (qw(SSL_ca_file SSL_ca_path)) { $CHECK_SSL_PATH->($_ => $arg_hash->{$_} || next); } } elsif ( $verify_mode ne '0' ) { # some users use the string 'SSL_VERIFY_PEER' instead of the constant die "SSL_verify_mode must be a number and not a string"; } my $self = bless {},$class; my $vcn_scheme = delete $arg_hash->{SSL_verifycn_scheme}; my $vcn_publicsuffix = delete $arg_hash->{SSL_verifycn_publicsuffix}; if ( ! $is_server and $verify_mode & 0x01 and ! $vcn_scheme || $vcn_scheme ne 'none' ) { # gets updated during configure_SSL my $verify_name; $self->{verify_name_ref} = \$verify_name; my $vcb = $arg_hash->{SSL_verify_callback}; $arg_hash->{SSL_verify_callback} = sub { my ($ok,$ctx_store,$certname,$error,$cert,$depth) = @_; $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $vcb; $ok or return 0; return $ok if $depth != 0; my $host = $verify_name || ref($vcn_scheme) && $vcn_scheme->{callback} && 'unknown'; if ( ! $host ) { if ( $vcn_scheme ) { IO::Socket::SSL->_internal_error( "Cannot determine peer hostname for verification",8); return 0; } warn "Cannot determine hostname of peer for verification. ". "Disabling default hostname verification for now. ". "Please specify hostname with SSL_verifycn_name and better set SSL_verifycn_scheme too.\n"; return $ok; } # verify name my $rv = IO::Socket::SSL::verify_hostname_of_cert( $host,$cert,$vcn_scheme,$vcn_publicsuffix ); if ( ! $rv ) { IO::Socket::SSL->_internal_error( "hostname verification failed",5); } return $rv; }; } if ($is_server) { if ($arg_hash->{SSL_ticket_keycb} && !$can_tckt_keycb) { warn "Ticket Key Callback is not supported - ignoring option SSL_ticket_keycb\n"; delete $arg_hash->{SSL_ticket_keycb}; } } my $ssl_op = $DEFAULT_SSL_OP; my $ver; for (split(/\s*:\s*/,$arg_hash->{SSL_version})) { m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1(?:_?[123])?))$}i or croak("invalid SSL_version specified"); my $not = $1; ( my $v = lc($2||$3) ) =~s{^(...)}{\U$1}; if ( $not ) { $ssl_op |= $SSL_OP_NO{$v}; } else { croak("cannot set multiple SSL protocols in SSL_version") if $ver && $v ne $ver; $ver = $v; $ver =~s{/}{}; # interpret SSLv2/3 as SSLv23 $ver =~s{(TLSv1)(\d)}{$1\_$2}; # TLSv1_1 } } my $ctx_new_sub = $ver eq 'TLSv1_3' ? $CTX_tlsv1_3_new : UNIVERSAL::can( 'Net::SSLeay', $ver eq 'SSLv2' ? 'CTX_v2_new' : $ver eq 'SSLv3' ? 'CTX_v3_new' : $ver eq 'TLSv1' ? 'CTX_tlsv1_new' : $ver eq 'TLSv1_1' ? 'CTX_tlsv1_1_new' : $ver eq 'TLSv1_2' ? 'CTX_tlsv1_2_new' : 'CTX_new' ) or return IO::Socket::SSL->_internal_error("SSL Version $ver not supported",9); # For SNI in server mode we need a separate context for each certificate. my %ctx; if ($is_server) { my %sni; for my $opt (qw(SSL_key SSL_key_file SSL_cert SSL_cert_file)) { my $val = $arg_hash->{$opt} or next; if ( ref($val) eq 'HASH' ) { while ( my ($host,$v) = each %$val ) { $sni{lc($host)}{$opt} = $v; } } } while (my ($host,$v) = each %sni) { $ctx{$host} = $host =~m{%} ? $v : { %$arg_hash, %$v }; } } $ctx{''} = $arg_hash if ! %ctx; for my $host (sort keys %ctx) { my $arg_hash = delete $ctx{$host}; my $ctx; if ($host =~m{^([^%]*)%}) { $ctx = $ctx{$1} or return IO::Socket::SSL->error( "SSL Context init for $host failed - no config for $1"); if (my @k = grep { !m{^SSL_(?:cert|key)(?:_file)?$} } keys %$arg_hash) { return IO::Socket::SSL->error( "invalid keys @k in configuration '$host' of additional certs"); } $can_multi_cert or return IO::Socket::SSL->error( "no support for both RSA and ECC certificate in same context"); $host = $1; goto just_configure_certs; } $ctx = $ctx_new_sub->() or return IO::Socket::SSL->error("SSL Context init failed"); $CTX_CREATED_IN_THIS_THREAD{$ctx} = 1 if $use_threads; $ctx{$host} = $ctx; # replace value in %ctx with real context # SSL_OP_CIPHER_SERVER_PREFERENCE $ssl_op |= 0x00400000 if $arg_hash->{SSL_honor_cipher_order}; if ($ver eq 'SSLv23' && !($ssl_op & $SSL_OP_NO{SSLv3})) { # At least LibreSSL disables SSLv3 by default in SSL_CTX_new. # If we really want SSL3.0 we need to explicitly allow it with # SSL_CTX_clear_options. Net::SSLeay::CTX_clear_options($ctx,$SSL_OP_NO{SSLv3}); } Net::SSLeay::CTX_set_options($ctx,$ssl_op); # enable X509_V_FLAG_PARTIAL_CHAIN if possible (OpenSSL 1.1.0+) $check_partial_chain && $check_partial_chain->($ctx); # if we don't set session_id_context if client certificate is expected # client session caching will fail # if user does not provide explicit id just use the stringification # of the context if($arg_hash->{SSL_server} and my $id = $arg_hash->{SSL_session_id_context} || ( $arg_hash->{SSL_verify_mode} & 0x01 ) && "$ctx" ) { Net::SSLeay::CTX_set_session_id_context($ctx,$id,length($id)); } # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER makes syswrite return if at least one # buffer was written and not block for the rest # SSL_MODE_ENABLE_PARTIAL_WRITE can be necessary for non-blocking because we # cannot guarantee, that the location of the buffer stays constant Net::SSLeay::CTX_set_mode( $ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | ($arg_hash->{SSL_mode_release_buffers} ? $ssl_mode_release_buffers : 0) ); if ( my $proto_list = $arg_hash->{SSL_npn_protocols} ) { return IO::Socket::SSL->_internal_error("NPN not supported in Net::SSLeay",9) if ! $can_npn; if($arg_hash->{SSL_server}) { # on server side SSL_npn_protocols means a list of advertised protocols Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $proto_list); } else { # on client side SSL_npn_protocols means a list of preferred protocols # negotiation algorithm used is "as-openssl-implements-it" Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $proto_list); } } if ( my $proto_list = $arg_hash->{SSL_alpn_protocols} ) { return IO::Socket::SSL->_internal_error("ALPN not supported in Net::SSLeay",9) if ! $can_alpn; if($arg_hash->{SSL_server}) { Net::SSLeay::CTX_set_alpn_select_cb($ctx, $proto_list); } else { Net::SSLeay::CTX_set_alpn_protos($ctx, $proto_list); } } if ($arg_hash->{SSL_ticket_keycb}) { my $cb = $arg_hash->{SSL_ticket_keycb}; ($cb,my $arg) = ref($cb) eq 'CODE' ? ($cb):@$cb; Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($ctx,$cb,$arg); } # Try to apply SSL_ca even if SSL_verify_mode is 0, so that they can be # used to verify OCSP responses. # If applying fails complain only if verify_mode != VERIFY_NONE. if ( $arg_hash->{SSL_ca} || defined $arg_hash->{SSL_ca_file} || defined $arg_hash->{SSL_ca_path} ) { my $file = $arg_hash->{SSL_ca_file}; $file = undef if ref($file) eq 'SCALAR' && ! $$file; my $dir = $arg_hash->{SSL_ca_path}; $dir = undef if ref($dir) eq 'SCALAR' && ! $$dir; if ( $arg_hash->{SSL_ca} ) { my $store = Net::SSLeay::CTX_get_cert_store($ctx); for (@{$arg_hash->{SSL_ca}}) { Net::SSLeay::X509_STORE_add_cert($store,$_) or return IO::Socket::SSL->error( "Failed to add certificate to CA store"); } } $dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir); if ( $file || $dir and ! Net::SSLeay::CTX_load_verify_locations( $ctx, $file || '', $dir || '')) { return IO::Socket::SSL->error( "Invalid certificate authority locations") if $verify_mode != $Net_SSLeay_VERIFY_NONE; } } elsif ( my %ca = IO::Socket::SSL::default_ca()) { # no CA path given, continue with system defaults my $dir = $ca{SSL_ca_path}; $dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir); if (! Net::SSLeay::CTX_load_verify_locations( $ctx, $ca{SSL_ca_file} || '',$dir || '') && $verify_mode != $Net_SSLeay_VERIFY_NONE) { return IO::Socket::SSL->error( "Invalid default certificate authority locations") } } if ($is_server && ($verify_mode & $Net_SSLeay_VERIFY_PEER)) { if ($arg_hash->{SSL_client_ca}) { for (@{$arg_hash->{SSL_client_ca}}) { return IO::Socket::SSL->error( "Failed to add certificate to client CA list") if ! Net::SSLeay::CTX_add_client_CA($ctx,$_); } } if ($arg_hash->{SSL_client_ca_file}) { my $list = Net::SSLeay::load_client_CA_file( $arg_hash->{SSL_client_ca_file}) or return IO::Socket::SSL->error( "Failed to load certificate to client CA list"); Net::SSLeay::CTX_set_client_CA_list($ctx,$list); } } my $X509_STORE_flags = $DEFAULT_X509_STORE_flags; if ($arg_hash->{'SSL_check_crl'}) { $X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_CRL_CHECK(); if ($arg_hash->{'SSL_crl_file'}) { my $bio = Net::SSLeay::BIO_new_file($arg_hash->{'SSL_crl_file'}, 'r'); my $crl = Net::SSLeay::PEM_read_bio_X509_CRL($bio); Net::SSLeay::BIO_free($bio); if ( $crl ) { Net::SSLeay::X509_STORE_add_crl(Net::SSLeay::CTX_get_cert_store($ctx), $crl); Net::SSLeay::X509_CRL_free($crl); } else { return IO::Socket::SSL->error("Invalid certificate revocation list"); } } } Net::SSLeay::X509_STORE_set_flags( Net::SSLeay::CTX_get_cert_store($ctx), $X509_STORE_flags ) if $X509_STORE_flags; Net::SSLeay::CTX_set_default_passwd_cb($ctx,$arg_hash->{SSL_passwd_cb}) if $arg_hash->{SSL_passwd_cb}; just_configure_certs: my ($havekey,$havecert); if ( my $x509 = $arg_hash->{SSL_cert} ) { # binary, e.g. X509* # we have either a single certificate or a list with # a chain of certificates my @x509 = ref($x509) eq 'ARRAY' ? @$x509: ($x509); my $cert = shift @x509; Net::SSLeay::CTX_use_certificate( $ctx,$cert ) || return IO::Socket::SSL->error("Failed to use Certificate"); foreach my $ca (@x509) { Net::SSLeay::CTX_add_extra_chain_cert( $ctx,$ca ) || return IO::Socket::SSL->error("Failed to use Certificate"); } $havecert = 'OBJ'; } elsif ( my $f = $arg_hash->{SSL_cert_file} ) { # try to load chain from PEM or certificate from ASN1 my @err; if (Net::SSLeay::CTX_use_certificate_chain_file($ctx,$f)) { $havecert = 'PEM'; } elsif (do { push @err, [ PEM => _errstack() ]; Net::SSLeay::CTX_use_certificate_file($ctx,$f,FILETYPE_ASN1) }) { $havecert = 'DER'; } else { push @err, [ DER => _errstack() ]; # try to load certificate, key and chain from PKCS12 file my ($key,$cert,@chain) = Net::SSLeay::P_PKCS12_load_file($f,1); if (!$cert and $arg_hash->{SSL_passwd_cb} and defined( my $pw = $arg_hash->{SSL_passwd_cb}->(0))) { ($key,$cert,@chain) = Net::SSLeay::P_PKCS12_load_file($f,1,$pw); } PKCS12: while ($cert) { Net::SSLeay::CTX_use_certificate($ctx,$cert) or last; # Net::SSLeay::P_PKCS12_load_file is implemented using # OpenSSL PKCS12_parse which according to the source code # returns the chain with the last CA certificate first (i.e. # reverse order as in the PKCS12 file). This is not # documented but given the age of this function we'll assume # that this will stay this way in the future. while (my $ca = pop @chain) { Net::SSLeay::CTX_add_extra_chain_cert($ctx,$ca) or last PKCS12; } last if $key && ! Net::SSLeay::CTX_use_PrivateKey($ctx,$key); $havecert = 'PKCS12'; last; } $havekey = 'PKCS12' if $key; Net::SSLeay::X509_free($cert) if $cert; Net::SSLeay::EVP_PKEY_free($key) if $key; # don't free @chain, because CTX_add_extra_chain_cert # did not duplicate the certificates } if (!$havecert) { push @err, [ PKCS12 => _errstack() ]; my $err = "Failed to load certificate from file $f:"; for(@err) { my ($type,@e) = @$_; $err .= " [format:$type] @e **" if @e; } return IO::Socket::SSL->error($err); } } if (!$havecert || $havekey) { # skip SSL_key_* } elsif ( my $pkey = $arg_hash->{SSL_key} ) { # binary, e.g. EVP_PKEY* Net::SSLeay::CTX_use_PrivateKey($ctx, $pkey) || return IO::Socket::SSL->error("Failed to use Private Key"); $havekey = 'MEM'; } elsif ( my $f = $arg_hash->{SSL_key_file} || (($havecert eq 'PEM') ? $arg_hash->{SSL_cert_file}:undef) ) { for my $ft ( FILETYPE_PEM, FILETYPE_ASN1 ) { if (Net::SSLeay::CTX_use_PrivateKey_file($ctx,$f,$ft)) { $havekey = ($ft == FILETYPE_PEM) ? 'PEM':'DER'; last; } } $havekey or return IO::Socket::SSL->error( "Failed to load key from file (no PEM or DER)"); } Net::SSLeay::CTX_set_post_handshake_auth($ctx,1) if (!$is_server && $can_pha && $havecert && $havekey); } if ($arg_hash->{SSL_server}) { if ( my $f = $arg_hash->{SSL_dh_file} ) { my $bio = Net::SSLeay::BIO_new_file( $f,'r' ) || return IO::Socket::SSL->error( "Failed to open DH file $f" ); my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio); Net::SSLeay::BIO_free($bio); $dh || return IO::Socket::SSL->error( "Failed to read PEM for DH from $f - wrong format?" ); my $rv; for (values (%ctx)) { $rv = Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) or last; } Net::SSLeay::DH_free( $dh ); $rv || return IO::Socket::SSL->error( "Failed to set DH from $f" ); } elsif ( my $dh = $arg_hash->{SSL_dh} ) { # binary, e.g. DH* for( values %ctx ) { Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) || return IO::Socket::SSL->error( "Failed to set DH from SSL_dh" ); } } } if ( my $curve = $arg_hash->{SSL_ecdh_curve} ) { return IO::Socket::SSL->_internal_error( "ECDH curve needs Net::SSLeay>=1.56 and OpenSSL>=1.0",9) if ! $can_ecdh; for(values %ctx) { if ($arg_hash->{SSL_server} and $curve eq 'auto') { if ($can_ecdh eq 'can_auto') { Net::SSLeay::CTX_set_ecdh_auto($_,1) or return IO::Socket::SSL->error( "failed to set ECDH curve context"); } elsif ($can_ecdh eq 'auto') { # automatically enabled anyway } else { return IO::Socket::SSL->error( "SSL_CTX_set_ecdh_auto not implemented"); } } elsif ($set_groups_list) { $set_groups_list->($_,$curve) or return IO::Socket::SSL->error( "failed to set ECDH groups/curves on context"); # needed for OpenSSL 1.0.2 if ($can_ecdh eq 'can_auto') { Net::SSLeay::CTX_set_ecdh_auto($_,1) if $can_ecdh eq 'can_auto'; } elsif ($curve =~m{:}) { return IO::Socket::SSL->error( "SSL_CTX_groups_list or SSL_CTX_curves_list not implemented"); } elsif ($arg_hash->{SSL_server}) { if ( $curve !~ /^\d+$/ ) { # name of curve, find NID $curve = Net::SSLeay::OBJ_txt2nid($curve) || return IO::Socket::SSL->error( "cannot find NID for curve name '$curve'"); } my $ecdh = Net::SSLeay::EC_KEY_new_by_curve_name($curve) or return IO::Socket::SSL->error( "cannot create curve for NID $curve"); for( values %ctx ) { Net::SSLeay::CTX_set_tmp_ecdh($_,$ecdh) or return IO::Socket::SSL->error( "failed to set ECDH curve context"); } Net::SSLeay::EC_KEY_free($ecdh); } } } my $verify_cb = $arg_hash->{SSL_verify_callback}; my @accept_fp; if ( my $fp = $arg_hash->{SSL_fingerprint} ) { for( ref($fp) ? @$fp : $fp) { my ($algo,$pubkey,$digest) = m{^(?:([\w-]+)\$)?(pub\$)?([a-f\d:]+)$}i or return IO::Socket::SSL->_internal_error("invalid fingerprint '$_'",9); ( $digest = lc($digest) ) =~s{:}{}g; $algo ||= length($digest) == 32 ? 'md5' : length($digest) == 40 ? 'sha1' : length($digest) == 64 ? 'sha256' : return IO::Socket::SSL->_internal_error( "cannot detect hash algorithm from fingerprint '$_'",9); $algo = lc($algo); push @accept_fp,[ $algo, $pubkey || '', pack('H*',$digest) ] } } my $verify_fingerprint = @accept_fp && do { my $fail; sub { my ($ok,$cert,$depth) = @_; $fail = 1 if ! $ok; return 1 if $depth>0; # to let us continue with verification # Check fingerprint only from top certificate. my %fp; for(@accept_fp) { my $fp = $fp{$_->[0],$_->[1]} ||= $_->[1] ? Net::SSLeay::X509_pubkey_digest($cert,$algo2digest->($_->[0])) : Net::SSLeay::X509_digest($cert,$algo2digest->($_->[0])); next if $fp ne $_->[2]; return 1; } return ! $fail; } }; my $verify_callback = ( $verify_cb || @accept_fp ) && sub { my ($ok, $ctx_store) = @_; my ($certname,$cert,$error,$depth); if ($ctx_store) { $cert = Net::SSLeay::X509_STORE_CTX_get_current_cert($ctx_store); $error = Net::SSLeay::X509_STORE_CTX_get_error($ctx_store); $depth = Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store); $certname = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)). Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); $error &&= Net::SSLeay::ERR_error_string($error); } $DEBUG>=3 && DEBUG( "ok=$ok [$depth] $certname" ); $ok = $verify_cb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $verify_cb; $ok = $verify_fingerprint->($ok,$cert,$depth) if $verify_fingerprint && $cert; return $ok; }; if ( $^O eq 'darwin' ) { # explicitly set error code to disable use of apples TEA patch # https://hynek.me/articles/apple-openssl-verification-surprises/ my $vcb = $verify_callback; $verify_callback = sub { my $rv = $vcb ? &$vcb : $_[0]; if ( $rv != 1 ) { # 50 - X509_V_ERR_APPLICATION_VERIFICATION: application verification failure Net::SSLeay::X509_STORE_CTX_set_error($_[1], 50); } return $rv; }; } Net::SSLeay::CTX_set_verify($_, $verify_mode, $verify_callback) for (values %ctx); my $staple_callback = $arg_hash->{SSL_ocsp_staple_callback}; if ( !$is_server && $can_ocsp_staple && ! $verify_fingerprint) { $self->{ocsp_cache} = $arg_hash->{SSL_ocsp_cache}; my $status_cb = sub { my ($ssl,$resp) = @_; my $iossl = $SSL_OBJECT{$ssl} or die "no IO::Socket::SSL object found for SSL $ssl"; $iossl->[1] and do { # we must return with 1 or it will be called again # and because we have no SSL object we must make the error global Carp::cluck($IO::Socket::SSL::SSL_ERROR = "OCSP callback on server side"); return 1; }; $iossl = $iossl->[0]; # if we have a callback use this # callback must not free or copy $resp !! if ( $staple_callback ) { $staple_callback->($iossl,$resp); return 1; } # default callback does verification if ( ! $resp ) { $DEBUG>=3 && DEBUG("did not get stapled OCSP response"); return 1; } $DEBUG>=3 && DEBUG("got stapled OCSP response"); my $status = Net::SSLeay::OCSP_response_status($resp); if ($status != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()) { $DEBUG>=3 && DEBUG("bad status of stapled OCSP response: ". Net::SSLeay::OCSP_response_status_str($status)); return 1; } if (!eval { Net::SSLeay::OCSP_response_verify($ssl,$resp) }) { $DEBUG>=3 && DEBUG("verify of stapled OCSP response failed"); return 1; } my (@results,$hard_error); my @chain = $iossl->peer_certificates; for my $cert (@chain) { my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) }; if (!$certid) { $DEBUG>=3 && DEBUG("cannot create OCSP_CERTID: $@"); push @results,[-1,$@]; last; } ($status) = Net::SSLeay::OCSP_response_results($resp,$certid); if ($status && $status->[2]) { my $cache = ${*$iossl}{_SSL_ctx}{ocsp_cache}; if (!$status->[1]) { push @results,[1,$status->[2]{nextUpdate}]; $cache && $cache->put($certid,$status->[2]); } elsif ( $status->[2]{statusType} == Net::SSLeay::V_OCSP_CERTSTATUS_GOOD()) { push @results,[1,$status->[2]{nextUpdate}]; $cache && $cache->put($certid,{ %{$status->[2]}, expire => time()+120, soft_error => $status->[1], }); } else { push @results,($hard_error = [0,$status->[1]]); $cache && $cache->put($certid,{ %{$status->[2]}, hard_error => $status->[1], }); } } } # return result of lead certificate, this should be in chain[0] and # thus result[0], but we better check. But if we had any hard_error # return this instead if ($hard_error) { ${*$iossl}{_SSL_ocsp_verify} = $hard_error; } elsif (@results and $chain[0] == $iossl->peer_certificate) { ${*$iossl}{_SSL_ocsp_verify} = $results[0]; } return 1; }; Net::SSLeay::CTX_set_tlsext_status_cb($_,$status_cb) for (values %ctx); } if ( my $cl = $arg_hash->{SSL_cipher_list} ) { for (keys %ctx) { Net::SSLeay::CTX_set_cipher_list($ctx{$_}, ref($cl) ? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next : $cl ) || return IO::Socket::SSL->error("Failed to set SSL cipher list"); } } if ( my $cl = $arg_hash->{SSL_ciphersuites} ) { return IO::Socket::SSL->error("no support for SSL_ciphersuites in Net::SSLeay") if ! $can_ciphersuites; for (keys %ctx) { Net::SSLeay::CTX_set_ciphersuites($ctx{$_}, ref($cl) ? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next : $cl ) || return IO::Socket::SSL->error("Failed to set SSL cipher list"); } } # Main context is default context or any other if no default context. my $ctx = $ctx{''} || (values %ctx)[0]; if (keys(%ctx) > 1 || ! exists $ctx{''}) { $can_server_sni or return IO::Socket::SSL->_internal_error( "Server side SNI not supported for this openssl/Net::SSLeay",9); Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub { my $ssl = shift; my $host = Net::SSLeay::get_servername($ssl); $host = '' if ! defined $host; my $snictx = $ctx{lc($host)} || $ctx{''} or do { $DEBUG>1 and DEBUG( "cannot get context from servername '$host'"); return 2; # SSL_TLSEXT_ERR_ALERT_FATAL }; $DEBUG>1 and DEBUG("set context from servername $host"); Net::SSLeay::set_SSL_CTX($ssl,$snictx) if $snictx != $ctx; return 0; # SSL_TLSEXT_ERR_OK }); } if ( my $cb = $arg_hash->{SSL_create_ctx_callback} ) { $cb->($_) for values (%ctx); } $self->{context} = $ctx; $self->{verify_mode} = $arg_hash->{SSL_verify_mode}; $self->{ocsp_mode} = defined($arg_hash->{SSL_ocsp_mode}) ? $arg_hash->{SSL_ocsp_mode} : $self->{verify_mode} ? IO::Socket::SSL::SSL_OCSP_TRY_STAPLE() : 0; $DEBUG>=3 && DEBUG( "new ctx $ctx" ); if ( my $cache = $arg_hash->{SSL_session_cache} ) { # use predefined cache $self->{session_cache} = $cache } elsif ( my $size = $arg_hash->{SSL_session_cache_size}) { $self->{session_cache} = IO::Socket::SSL::Session_Cache->new( $size ); } if ($self->{session_cache} and %sess_cb) { Net::SSLeay::CTX_set_session_cache_mode($ctx, Net::SSLeay::SESS_CACHE_CLIENT()); my $cache = $self->{session_cache}; $sess_cb{new}($ctx, sub { my ($ssl,$session) = @_; my $self = ($SSL_OBJECT{$ssl} || do { warn "callback session new: no known SSL object for $ssl"; return; })->[0]; my $args = ${*$self}{_SSL_arguments}; my $key = $args->{SSL_session_key} or do { warn "callback session new: no known SSL_session_key for $ssl"; return; }; $DEBUG>=3 && DEBUG("callback session new <$key> $session"); Net::SSLeay::SESSION_up_ref($session); $cache->add_session($key,$session); }); $sess_cb{remove}($ctx, sub { my ($ctx,$session) = @_; $DEBUG>=3 && DEBUG("callback session remove $session"); $cache->del_session(undef,$session); }); } return $self; } sub has_session_cache { return defined shift->{session_cache}; } sub CLONE { %CTX_CREATED_IN_THIS_THREAD = (); } sub DESTROY { my $self = shift; if ( my $ctx = $self->{context} ) { $DEBUG>=3 && DEBUG("free ctx $ctx open=".join( " ",keys %CTX_CREATED_IN_THIS_THREAD )); if (!$use_threads or delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) { # remove any verify callback for this context if ( $self->{verify_mode}) { $DEBUG>=3 && DEBUG("free ctx $ctx callback" ); Net::SSLeay::CTX_set_verify($ctx, 0,undef); } if ( $self->{ocsp_error_ref}) { $DEBUG>=3 && DEBUG("free ctx $ctx tlsext_status_cb" ); Net::SSLeay::CTX_set_tlsext_status_cb($ctx,undef); } $DEBUG>=3 && DEBUG("OK free ctx $ctx" ); Net::SSLeay::CTX_free($ctx); } } delete(@{$self}{'context','session_cache'}); } package IO::Socket::SSL::Session_Cache; *DEBUG = *IO::Socket::SSL::DEBUG; use constant { SESSION => 0, KEY => 1, GNEXT => 2, GPREV => 3, SNEXT => 4, SPREV => 5, }; sub new { my ($class, $size) = @_; $size>0 or return; return bless { room => $size, ghead => undef, shead => {}, }, $class; } sub add_session { my ($self, $key, $session) = @_; # create new my $v = []; $v->[SESSION] = $session; $v->[KEY] = $key; $DEBUG>=3 && DEBUG("add_session($key,$session)"); _add_entry($self,$v); } sub replace_session { my ($self, $key, $session) = @_; $self->del_session($key); $self->add_session($key, $session); } sub del_session { my ($self, $key, $session) = @_; my ($head,$inext) = $key ? ($self->{shead}{$key},SNEXT) : ($self->{ghead},GNEXT); my $v = $head; my @del; while ($v) { if (!$session) { push @del,$v } elsif ($v->[SESSION] == $session) { push @del, $v; last; } $v = $v->[$inext]; last if $v == $head; } $DEBUG>=3 && DEBUG("del_session(" . ($key ? $key : "undef") . ($session ? ",$session) -> " : ") -> ") . (~~@del || 'none')); for (@del) { _del_entry($self,$_); Net::SSLeay::SESSION_free($_->[SESSION]) if $_->[SESSION]; @$_ = (); } return ~~@del; } sub get_session { my ($self, $key, $session) = @_; my $v = $self->{shead}{$key}; if ($session) { my $shead = $v; while ($v) { $DEBUG>=3 && DEBUG("check $session - $v->[SESSION]"); last if $v->[SESSION] == $session; $v = $v->[SNEXT]; $v = undef if $v == $shead; # session not found } } if ($v) { _del_entry($self, $v); # remove _add_entry($self, $v); # and add back on top } $DEBUG>=3 && DEBUG("get_session($key" . ( $session ? ",$session) -> " : ") -> ") . ($v? $v->[SESSION]:"none")); return $v && $v->[SESSION]; } sub _add_entry { my ($self,$v) = @_; for( [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ], [ GNEXT, GPREV, \$self->{ghead} ], ) { my ($inext,$iprev,$rhead) = @$_; if ($$rhead) { $v->[$inext] = $$rhead; $v->[$iprev] = ${$rhead}->[$iprev]; ${$rhead}->[$iprev][$inext] = $v; ${$rhead}->[$iprev] = $v; } else { $v->[$inext] = $v->[$iprev] = $v; } $$rhead = $v; } $self->{room}--; # drop old entries if necessary if ($self->{room}<0) { my $l = $self->{ghead}[GPREV]; _del_entry($self,$l); Net::SSLeay::SESSION_free($l->[SESSION]) if $l->[SESSION]; @$l = (); } } sub _del_entry { my ($self,$v) = @_; for( [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ], [ GNEXT, GPREV, \$self->{ghead} ], ) { my ($inext,$iprev,$rhead) = @$_; $$rhead or return; $v->[$inext][$iprev] = $v->[$iprev]; $v->[$iprev][$inext] = $v->[$inext]; if ($v != $$rhead) { # not removed from top of list } elsif ($v->[$inext] == $v) { # was only element on list, drop list if ($inext == SNEXT) { delete $self->{shead}{$v->[KEY]}; } else { $$rhead = undef; } } else { # was top element, keep others $$rhead = $v->[$inext]; } } $self->{room}++; } sub _dump { my $self = shift; my %v2i; my $v = $self->{ghead}; while ($v) { exists $v2i{$v} and die; $v2i{$v} = int(keys %v2i); $v = $v->[GNEXT]; last if $v == $self->{ghead}; } my $out = "room: $self->{room}\nghead:\n"; $v = $self->{ghead}; while ($v) { $out .= sprintf(" - [%d] <%d,%d> '%s' <%s>\n", $v2i{$v}, $v2i{$v->[GPREV]}, $v2i{$v->[GNEXT]}, $v->[KEY], $v->[SESSION]); $v = $v->[GNEXT]; last if $v == $self->{ghead}; } $out .= "shead:\n"; for my $key (sort keys %{$self->{shead}}) { $out .= " - '$key'\n"; my $shead = $self->{shead}{$key}; my $v = $shead; while ($v) { $out .= sprintf(" - [%d] <%d,%d> '%s' <%s>\n", $v2i{$v}, $v2i{$v->[SPREV]}, $v2i{$v->[SNEXT]}, $v->[KEY], $v->[SESSION]); $v = $v->[SNEXT]; last if $v == $shead; } } return $out; } sub DESTROY { my $self = shift; delete $self->{shead}; my $v = delete $self->{ghead}; while ($v) { Net::SSLeay::SESSION_free($v->[SESSION]) if $v->[SESSION]; my $next = $v->[GNEXT]; @$v = (); $v = $next; } } package IO::Socket::SSL::OCSP_Cache; sub new { my ($class,$size) = @_; return bless { '' => { _lru => 0, size => $size || 100 } },$class; } sub get { my ($self,$id) = @_; my $e = $self->{$id} or return; $e->{_lru} = $self->{''}{_lru}++; if ( $e->{expire} && time()<$e->{expire}) { delete $self->{$id}; return; } if ( $e->{nextUpdate} && time()<$e->{nextUpdate} ) { delete $self->{$id}; return; } return $e; } sub put { my ($self,$id,$e) = @_; $self->{$id} = $e; $e->{_lru} = $self->{''}{_lru}++; my $del = keys(%$self) - $self->{''}{size}; if ($del>0) { my @k = sort { $self->{$a}{_lru} <=> $self->{$b}{_lru} } keys %$self; delete @{$self}{ splice(@k,0,$del) }; } return $e; } package IO::Socket::SSL::OCSP_Resolver; *DEBUG = *IO::Socket::SSL::DEBUG; # create a new resolver # $ssl - the ssl object # $cache - OCSP_Cache object (put,get) # $failhard - flag if we should fail hard on OCSP problems # $certs - list of certs to verify sub new { my ($class,$ssl,$cache,$failhard,$certs) = @_; my (%todo,$done,$hard_error,@soft_error); for my $cert (@$certs) { # skip entries which have no OCSP uri or where we cannot get a certid # (e.g. self-signed or where we don't have the issuer) my $subj = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); my $uri = Net::SSLeay::P_X509_get_ocsp_uri($cert) or do { $DEBUG>2 && DEBUG("no URI for certificate $subj"); push @soft_error,"no ocsp_uri for $subj"; next; }; my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) } or do { $DEBUG>2 && DEBUG("no OCSP_CERTID for certificate $subj: $@"); push @soft_error,"no certid for $subj: $@"; next; }; if (!($done = $cache->get($certid))) { push @{ $todo{$uri}{ids} }, $certid; push @{ $todo{$uri}{subj} }, $subj; } elsif ( $done->{hard_error} ) { # one error is enough to fail validation $hard_error = $done->{hard_error}; %todo = (); last; } elsif ( $done->{soft_error} ) { push @soft_error,$done->{soft_error}; } } while ( my($uri,$v) = each %todo) { my $ids = $v->{ids}; $v->{req} = Net::SSLeay::i2d_OCSP_REQUEST( Net::SSLeay::OCSP_ids2req(@$ids)); } $hard_error ||= '' if ! %todo; return bless { ssl => $ssl, cache => $cache, failhard => $failhard, hard_error => $hard_error, soft_error => @soft_error ? join("; ",@soft_error) : undef, todo => \%todo, },$class; } # return current result, e.g. '' for no error, else error # if undef we have no final result yet sub hard_error { return shift->{hard_error} } sub soft_error { return shift->{soft_error} } # return hash with uri => ocsp_request_data for open requests sub requests { my $todo = shift()->{todo}; return map { ($_,$todo->{$_}{req}) } keys %$todo; } # add new response sub add_response { my ($self,$uri,$resp) = @_; my $todo = delete $self->{todo}{$uri}; return $self->{error} if ! $todo || $self->{error}; my ($req,@soft_error,@hard_error); # do we have a response if (!$resp) { @soft_error = "http request for OCSP failed; subject: ". join("; ",@{$todo->{subj}}); # is it a valid OCSP_RESPONSE } elsif ( ! eval { $resp = Net::SSLeay::d2i_OCSP_RESPONSE($resp) }) { @soft_error = "invalid response (no OCSP_RESPONSE); subject: ". join("; ",@{$todo->{subj}}); # hopefully short-time error $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+10, }) for (@{$todo->{ids}}); # is the OCSP response status success } elsif ( ( my $status = Net::SSLeay::OCSP_response_status($resp)) != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL() ){ @soft_error = "OCSP response failed: ". Net::SSLeay::OCSP_response_status_str($status). "; subject: ".join("; ",@{$todo->{subj}}); # hopefully short-time error $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+10, }) for (@{$todo->{ids}}); # does nonce match the request and can the signature be verified } elsif ( ! eval { $req = Net::SSLeay::d2i_OCSP_REQUEST($todo->{req}); Net::SSLeay::OCSP_response_verify($self->{ssl},$resp,$req); }) { if ($@) { @soft_error = $@ } else { my @err; while ( my $err = Net::SSLeay::ERR_get_error()) { push @soft_error, Net::SSLeay::ERR_error_string($err); } @soft_error = 'failed to verify OCSP response; subject: '. join("; ",@{$todo->{subj}}) if ! @soft_error; } # configuration problem or we don't know the signer $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+120, }) for (@{$todo->{ids}}); # extract results from response } elsif ( my @result = Net::SSLeay::OCSP_response_results($resp,@{$todo->{ids}})) { my (@found,@miss); for my $rv (@result) { if ($rv->[2]) { push @found,$rv->[0]; if (!$rv->[1]) { # no error $self->{cache}->put($rv->[0],$rv->[2]); } elsif ( $rv->[2]{statusType} == Net::SSLeay::V_OCSP_CERTSTATUS_GOOD()) { # soft error, like response after nextUpdate push @soft_error,$rv->[1]."; subject: ". join("; ",@{$todo->{subj}}); $self->{cache}->put($rv->[0],{ %{$rv->[2]}, soft_error => "@soft_error", expire => time()+120, }); } else { # hard error $self->{cache}->put($rv->[0],$rv->[2]); push @hard_error, $rv->[1]."; subject: ". join("; ",@{$todo->{subj}}); } } else { push @miss,$rv->[0]; } } if (@miss && @found) { # we sent multiple responses, but server answered only to one # try again $self->{todo}{$uri} = $todo; $todo->{ids} = \@miss; $todo->{req} = Net::SSLeay::i2d_OCSP_REQUEST( Net::SSLeay::OCSP_ids2req(@miss)); $DEBUG>=2 && DEBUG("$uri just answered ".@found." of ".(@found+@miss)." requests"); } } else { @soft_error = "no data in response; subject: ". join("; ",@{$todo->{subj}}); # probably configuration problem $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+120, }) for (@{$todo->{ids}}); } Net::SSLeay::OCSP_REQUEST_free($req) if $req; if ($self->{failhard}) { push @hard_error,@soft_error; @soft_error = (); } if (@soft_error) { $self->{soft_error} .= "; " if $self->{soft_error}; $self->{soft_error} .= "$uri: ".join('; ',@soft_error); } if (@hard_error) { $self->{hard_error} = "$uri: ".join('; ',@hard_error); %{$self->{todo}} = (); } elsif ( ! %{$self->{todo}} ) { $self->{hard_error} = '' } return $self->{hard_error}; } # make all necessary requests to get OCSP responses blocking sub resolve_blocking { my ($self,%args) = @_; while ( my %todo = $self->requests ) { eval { require HTTP::Tiny } or die "need HTTP::Tiny installed"; # OCSP responses have their own signature, so we don't need SSL verification my $ua = HTTP::Tiny->new(verify_SSL => 0,%args); while (my ($uri,$reqdata) = each %todo) { $DEBUG && DEBUG("sending OCSP request to $uri"); my $resp = $ua->request('POST',$uri, { headers => { 'Content-type' => 'application/ocsp-request' }, content => $reqdata }); $DEBUG && DEBUG("got OCSP response from $uri code=$resp->{status}"); defined ($self->add_response($uri, $resp->{success} && $resp->{content})) && last; } } $DEBUG>=2 && DEBUG("no more open OCSP requests"); return $self->{hard_error}; } package IO::Socket::SSL::Trace; *DEBUG = *IO::Socket::SSL::DEBUG; # Exhaustive list of constants we need for tracing my %trace_constants = map { $_ => eval { Net::SSLeay->$_ } || -1 } qw( SSL2_VERSION SSL3_VERSION TLS1_VERSION TLS1_1_VERSION TLS1_2_VERSION TLS1_3_VERSION DTLS1_VERSION DTLS1_2_VERSION DTLS1_BAD_VER SSL3_RT_INNER_CONTENT_TYPE SSL3_RT_CHANGE_CIPHER_SPEC SSL3_RT_ALERT SSL3_RT_HEADER SSL3_RT_HANDSHAKE SSL3_RT_APPLICATION_DATA SSL2_MT_ERROR SSL2_MT_CLIENT_HELLO SSL2_MT_CLIENT_MASTER_KEY SSL2_MT_CLIENT_FINISHED SSL2_MT_SERVER_HELLO SSL2_MT_SERVER_VERIFY SSL2_MT_SERVER_FINISHED SSL2_MT_REQUEST_CERTIFICATE SSL2_MT_CLIENT_CERTIFICATE SSL3_MT_HELLO_REQUEST SSL3_MT_CLIENT_HELLO SSL3_MT_SERVER_HELLO SSL3_MT_NEWSESSION_TICKET SSL3_MT_CERTIFICATE SSL3_MT_SERVER_KEY_EXCHANGE SSL3_MT_CLIENT_KEY_EXCHANGE SSL3_MT_CERTIFICATE_REQUEST SSL3_MT_SERVER_DONE SSL3_MT_CERTIFICATE_VERIFY SSL3_MT_FINISHED SSL3_MT_CERTIFICATE_STATUS SSL3_MT_ENCRYPTED_EXTENSIONS SSL3_MT_SUPPLEMENTAL_DATA SSL3_MT_END_OF_EARLY_DATA SSL3_MT_KEY_UPDATE SSL3_MT_NEXT_PROTO SSL3_MT_MESSAGE_HASH ); # # Major versions # $trace_constants{SSL2_VERSION_MAJOR} = $trace_constants{SSL2_VERSION} >> 8; $trace_constants{SSL3_VERSION_MAJOR} = $trace_constants{SSL3_VERSION} >> 8; # # Mapping between trace constant and version string # my %tc_ver2s; for ( [ SSL2_VERSION => "SSLv2" ], [ SSL2_VERSION => "SSLv2" ], [ SSL3_VERSION => "SSLv3" ], [ TLS1_VERSION => "TLSv1.0" ], [ TLS1_1_VERSION => "TLSv1.1" ], [ TLS1_2_VERSION => "TLSv1.2" ], [ TLS1_3_VERSION => "TLSv1.3" ], [ DTLS1_VERSION => "DTLSv1.0" ], [ DTLS1_2_VERSION => "DTLSv1.2" ], [ DTLS1_BAD_VER => "DTLSv1.0 (bad)" ] ) { next if $trace_constants{$_->[0]} == -1; $tc_ver2s{$trace_constants{$_->[0]}} = $_->[1]; } my %tc_type2s; for ( [ SSL3_RT_HEADER => "TLS header" ], [ SSL3_RT_CHANGE_CIPHER_SPEC => "TLS change cipher" ], [ SSL3_RT_ALERT => "TLS alert" ], [ SSL3_RT_HANDSHAKE => "TLS handshake" ], [ SSL3_RT_APPLICATION_DATA => "TLS app data" ] ) { next if $trace_constants{$_->[0]} == -1; $tc_type2s{$trace_constants{$_->[0]}} = $_->[1]; } my %tc_msgtype2s; for( [ SSL2_MT_ERROR => "Error" ], [ SSL2_MT_CLIENT_HELLO => "Client hello" ], [ SSL2_MT_CLIENT_MASTER_KEY => "Client key" ], [ SSL2_MT_CLIENT_FINISHED => "Client finished" ], [ SSL2_MT_SERVER_HELLO => "Server hello" ], [ SSL2_MT_SERVER_VERIFY => "Server verify" ], [ SSL2_MT_SERVER_FINISHED => "Server finished" ], [ SSL2_MT_REQUEST_CERTIFICATE => "Request CERT" ], [ SSL2_MT_REQUEST_CERTIFICATE => "Client CERT" ] ) { next if $trace_constants{$_->[0]} == -1; $tc_msgtype2s{$trace_constants{SSL2_VERSION_MAJOR}, $trace_constants{$_->[0]}} = $_->[1]; } for( [ SSL3_MT_HELLO_REQUEST => "Hello request" ], [ SSL3_MT_CLIENT_HELLO => "Client hello" ], [ SSL3_MT_SERVER_HELLO => "Server hello" ], [ SSL3_MT_NEWSESSION_TICKET => "Newsession Ticket" ], [ SSL3_MT_CERTIFICATE => "Certificate" ], [ SSL3_MT_SERVER_KEY_EXCHANGE => "Server key exchange" ], [ SSL3_MT_CLIENT_KEY_EXCHANGE => "Client key exchange" ], [ SSL3_MT_CERTIFICATE_REQUEST => "Request CERT" ], [ SSL3_MT_SERVER_DONE => "Server finished" ], [ SSL3_MT_CERTIFICATE_VERIFY => "CERT verify" ], [ SSL3_MT_FINISHED => "Finished" ], [ SSL3_MT_CERTIFICATE_STATUS => "Certificate Status" ], [ SSL3_MT_ENCRYPTED_EXTENSIONS => "Encrypted Extensions" ], [ SSL3_MT_SUPPLEMENTAL_DATA => "Supplemental data" ], [ SSL3_MT_END_OF_EARLY_DATA => "End of early data" ], [ SSL3_MT_KEY_UPDATE => "Key update" ], [ SSL3_MT_NEXT_PROTO => "Next protocol" ], [ SSL3_MT_MESSAGE_HASH => "Message hash" ] ) { next if $trace_constants{$_->[0]} == -1; $tc_msgtype2s{$trace_constants{SSL3_VERSION_MAJOR}, $trace_constants{$_->[0]}} = $_->[1]; } # # Translation of curl ossl_trace # sub ossl_trace { $DEBUG>=2 or return; my ($direction, $ssl_ver, $content_type, $buf, $len, $ssl) = @_; # Restore original $! value on return local $!; my $verstr = $tc_ver2s{$ssl_ver} || "(version=$ssl_ver)"; # Log progress for interesting records only (like Handshake or Alert), skip # all raw record headers (content_type == SSL3_RT_HEADER or ssl_ver == 0). # For TLS 1.3, skip notification of the decrypted inner Content-Type. if ($ssl_ver && ($content_type != $trace_constants{SSL3_RT_HEADER}) && ($content_type != $trace_constants{SSL3_RT_INNER_CONTENT_TYPE}) ) { # the info given when the version is zero is not that useful for us $ssl_ver >>= 8; # check the upper 8 bits only below */ # SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL # always pass-up content-type as 0. But the interesting message-type # is at 'buf[0]'. my $tls_rt_name = ($ssl_ver == $trace_constants{SSL3_VERSION_MAJOR} && $content_type) ? $tc_type2s{$content_type} || "TLS Unknown (type=$content_type)" : ""; my $msg_type; my $msg_name; if ($content_type == $trace_constants{SSL3_RT_CHANGE_CIPHER_SPEC}) { $msg_type = unpack('c1', $buf); $msg_name = "Change cipher spec"; } elsif ($content_type == $trace_constants{SSL3_RT_ALERT}) { my @c = unpack('c2', $buf); $msg_type = ($c[0] << 8) + $c[1]; $msg_name = eval { Net::SSLeay::alert_desc_string_long($msg_type) } || "Unknown alert"; } else { $msg_type = unpack('c1', $buf); $msg_name = $tc_msgtype2s{$ssl_ver, $msg_type} || "Unknown (ssl_ver=$ssl_ver, msg=$msg_type)"; } DEBUG(sprintf("* %s (%s), %s, %s (%d)", $verstr, $direction ? "OUT" : "IN", $tls_rt_name, $msg_name, $msg_type)); } # # Here one might want to hexdump $buf (?) # # $DEBUG>=4 && printf STDERR "%s", hexdump($buf); } 1; __END__ IO-Socket-SSL-2.085/README.Win320000644000175000017500000000042514521466373015367 0ustar steffensteffenThe underlying IO::Socket::INET does not support non-blocking sockets on Win32, thus non-blocking IO::Socket::SSL is not supported on Win32, which means also, that timeouts don't work (because they are based on non-blocking). See also http://www.perlmonks.org/?node_id=378675 IO-Socket-SSL-2.085/docs/0000755000175000017500000000000014553536272014536 5ustar steffensteffenIO-Socket-SSL-2.085/docs/debugging.txt0000644000175000017500000000163411136164317017225 0ustar steffensteffen - check that IO::Socket::SSL and Net::SSLeay are properly installed, and that the versions are recently new: perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"' perl -MNet::SSLeay -e 'print "$Net::SSLeay::VERSION\n"' - run the tests in IO::Socket::SSL directory try running the tests with 'make test'. if some of the tests fail run the scripts one by one e.g.: perl -Ilib t/core.t - try running the demos using the DEBUG option - use the OpenSSL client and server for debugging the demo client and server. 'openssl s_client' and 'openssl s_server' against tests/demos testing the demo server: openssl s_client -connect localhost:9000 \ -key certs/client-key.pem -cert certs/client-cert.pem -verify 1 testing the demo client: openssl s_server -accept 9000 \ -key certs/server-key.pem -cert certs/server-cert.pem -verify 1 also, try these commands without the verify argument. IO-Socket-SSL-2.085/BUGS0000644000175000017500000000331114521466373014266 0ustar steffensteffenSee documentation. Following are some common errors to watch out for: It doesn't work together with Storable::fd_retrieve|fd_store, see https://rt.cpan.org/Ticket/Display.html?id=23419. You need to use freeze/nfreeze/thaw and syswrite/sysread the data yourself. See the bug for examples how to do it. --------------------- Note that a random number generator is required for the proper operation of this module. Systems that have /dev/random or /dev/urandom are fine, but those that do not, like most versions of Solaris, will need to fetch one before installing IO::Socket::SSL. If you don't already have a favorite, try EGD (egd.sourceforge.net). --------------------- Versions of perl-ldap below v0.26 do not work with this version of IO::Socket::SSL because they contain a workaround for old versions of IO::Socket::SSL that breaks new versions. --------------------- One user mentioned that the following did not work as it should in IO::Socket::SSL, but worked in IO::Socket::INET: chomp($var = <$socket>); print ord(chop($var)); # Prints "10" for people using ASCII This is due to a bug in Perl that is fixed in 5.8.1. If you need a workaround, try one of the following: chomp($var = $socket->getline()); chomp($var = scalar <$socket>); chomp($var = $var = <$socket>); Any function that returns the value of <$socket> (in scalar context) unchanged will work. --------------------- If you have 384-bit RSA keys you need to use Diffie Hellman Key Exchange. See the parameter SSL_dh_file or SSL_dh for how to use it and http://groups.google.de/group/mailing.openssl.users/msg/d60330cfa7a6034b for an explanation why you need it. -- Steffen Ullrich (sullr at cpan.org) Peter Behroozi (behrooz at fas.harvard.edu) IO-Socket-SSL-2.085/t/0000755000175000017500000000000014553536272014051 5ustar steffensteffenIO-Socket-SSL-2.085/t/testlib.pl0000644000175000017500000001327214521466373016060 0ustar steffensteffenuse strict; use warnings; use IO::Socket; use IO::Socket::SSL; use Config; ############################################################################ # # small test lib for common tasks: # adapted from t/testlib.pl in Net::SIP package # ############################################################################ unless ( $Config::Config{d_fork} || $Config::Config{d_pseudofork} || (($^O eq 'MSWin32' || $^O eq 'NetWare') and $Config::Config{useithreads} and $Config::Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/) ) { print "1..0 # Skipped: fork not implemented on this platform\n"; exit } # let IO errors result in EPIPE instead of crashing the test $SIG{PIPE} = 'IGNORE'; # small implementations if not used from Test::More (09_fdleak.t) if ( ! defined &ok ) { no strict 'refs'; *{'ok'} = sub { my ($bool,$desc) = @_; print $bool ? "ok ":"not ok ", '# ',$desc || '',"\n"; }; *{'diag'} = sub { print "# @_\n"; }; *{'like'} = sub { my ( $data,$rx,$desc ) = @_; ok( $data =~ $rx ? 1:0, $desc ); }; } $SIG{ __DIE__ } = sub { return if $^S; # Ignore from within evals ok( 0,"@_" ); killall(); exit(1); }; ############################################################################ # kill all process collected by fork_sub # Args: ?$signal # $signal: signal to use, default 9 # Returns: NONE ############################################################################ my @pids; sub killall { my $sig = shift || 9; kill $sig, @pids; #diag( "killed @pids with $sig" ); while ( wait() >= 0 ) {} # collect all @pids = (); } ############################################################################ # fork named sub with args and provide fd into subs STDOUT # Args: ($name,@args) # $name: name or ref to sub, if name it will be used for debugging # @args: arguments for sub # Returns: $fh # $fh: file handle to read STDOUT of sub ############################################################################ my %fd2name; # associated sub-name for file descriptor to subs STDOUT sub fork_sub { my ($name,@arg) = @_; my $sub = ref($name) ? $name : UNIVERSAL::can( 'main',$name ) || die; pipe( my $rh, my $wh ) || die $!; defined( my $pid = fork() ) || die $!; if ( ! $pid ) { # CHILD, exec sub $SIG{ __DIE__ } = undef; close($rh); local *STDOUT = local *STDERR = $wh; $wh->autoflush; print "OK\n"; $sub->(@arg); exit(0); } push @pids,$pid; close( $wh ); $fd2name{$rh} = $name; fd_grep_ok( 'OK',10,$rh ) || die 'startup failed'; return $rh; } ############################################################################ # grep within fd's for specified regex or substring # Args: ($pattern,[ $timeout ],@fd) # $pattern: regex or substring # $timeout: how many seconds to wait for pattern, default 10 # @fd: which fds to search, usually fds from fork_sub(..) # Returns: $rv| ($rv,$name) # $rv: matched text if pattern is found, else undef # $name: name for file handle ############################################################################ my %fd2buf; # already read data from fd sub fd_grep { my $pattern = shift; my $timeout = 10; $timeout = shift if !ref($_[0]); my @fd = @_; $pattern = qr{\Q$pattern} if ! UNIVERSAL::isa( $pattern,'Regexp' ); my $name = join( "|", map { $fd2name{$_} || "$_" } @fd ); #diag( "look for $pattern in $name" ); my @bad = wantarray ? ( undef,$name ):(undef); @fd || return @bad; my $rin = ''; map { $_->blocking(0); vec( $rin,fileno($_),1 ) = 1 } @fd; my $end = defined( $timeout ) ? time() + $timeout : undef; while (@fd) { # check existing buf from previous reads foreach my $fd (@fd) { my $buf = \$fd2buf{$fd}; $$buf || next; if ( $$buf =~s{\A(?:.*?)($pattern)}{}s ) { #diag( "found" ); return wantarray ? ( $1,$name ) : $1; } } # if not found try to read new data $timeout = $end - time() if $end; return @bad if $timeout < 0; select( my $rout = $rin,undef,undef,$timeout ); $rout || return @bad; # not found foreach my $fd (@fd) { my $name = $fd2name{$fd} || "$fd"; my $buf = \$fd2buf{$fd}; my $fn = fileno($fd); my $n; if ( defined ($fn)) { vec( $rout,$fn,1 ) || next; my $l = $$buf && length($$buf) || 0; $n = sysread( $fd,$$buf,8192,$l ); } if ( ! $n ) { #diag( "$name >CLOSED<" ); delete $fd2buf{$fd}; @fd = grep { $_ != $fd } @fd; close($fd); next; } diag( "$name >> ".substr( $$buf,-$n ). "<<" ); } } return @bad; } ############################################################################ # like Test::Simple::ok, but based on fd_grep, same as # ok( fd_grep( pattern,... ), "[$subname] $pattern" ) # Args: ($pattern,[ $timeout ],@fd) - see fd_grep # Returns: $rv - like in fd_grep # Comment: if !$rv and wantarray says void it will die() ############################################################################ sub fd_grep_ok { my $pattern = shift; my ($rv,$name) = fd_grep( $pattern, @_ ); local $Test::Builder::Level = $Test::Builder::Level || 0 +1; ok( $rv,"[$name] $pattern" ); die "fatal error" if !$rv && ! defined wantarray; return $rv; } ############################################################################ # create socket on IP # return socket and ip:port ############################################################################ sub create_listen_socket { my ($addr,$port,$proto) = @_; $addr ||= '127.0.0.1'; my $sock = IO::Socket::INET->new( LocalAddr => $addr, $port ? ( LocalPort => $port, Reuse => 1 ) : (), Listen => 10, ) || die $!; ($port,$addr) = unpack_sockaddr_in( getsockname($sock) ); return wantarray ? ( $sock, inet_ntoa($addr).':'.$port ) : $sock; } 1; IO-Socket-SSL-2.085/t/external/0000755000175000017500000000000014553536272015673 5ustar steffensteffenIO-Socket-SSL-2.085/t/external/ocsp.t0000644000175000017500000001316614521466373017032 0ustar steffensteffen#!/usr/bin/perl use strict; use warnings; use Test::More; use IO::Socket::SSL; #$Net::SSLeay::trace=3; plan skip_all => "no OCSP support" if ! IO::Socket::SSL->can_ocsp; my $fingerprints = do './fingerprint.pl' || do './t/external/fingerprint.pl' || die "no fingerprints for sites"; my @tests = grep { $_->{ocsp} } @$fingerprints; plan tests => 0+@tests; my $timeout = 10; my $proxy = ( $ENV{http_proxy} || '' ) =~m{^(?:\w+://)?([\w\-.:\[\]]+:\d+)/?$} && $1; my $have_httptiny = eval { require HTTP::Tiny }; my $ipclass = 'IO::Socket::INET'; for( qw( IO::Socket::IP IO::Socket::INET6 )) { eval { require $_ } or next; $ipclass = $_; last; } TEST: for my $test (@tests) { my $tcp_connect = sub { if ( ! $proxy ) { # direct connection return $ipclass->new( PeerAddr => $test->{host}, PeerPort => $test->{port}, Timeout => $timeout, ) || die "tcp connect to $test->{host}:$test->{port} failed: $!"; } my $cl = $ipclass->new( PeerAddr => $proxy, Timeout => $timeout, ) || die "tcp connect to proxy $proxy failed: $!"; # try to establish tunnel via proxy with CONNECT { local $SIG{ALRM} = sub { die "proxy HTTP tunnel creation timed out" }; alarm($timeout); print $cl "CONNECT $test->{host}:$test->{port} HTTP/1.0\r\n\r\n"; my $reply = ''; while (<$cl>) { $reply .= $_; last if m{\A\r?\n\Z}; } alarm(0); $reply =~m{\AHTTP/1\.[01] 200\b} or die "unexpected response from proxy: $reply"; } return $cl; }; SKIP: { # first check fingerprint in case of SSL interception my $cl = eval { &$tcp_connect } or skip "TCP connect#1 failed: $@",1; diag("tcp connect to $test->{host}:$test->{port} ok"); skip "SSL upgrade w/o validation failed: $SSL_ERROR",1 if ! IO::Socket::SSL->start_SSL($cl, SSL_hostname => $test->{host}, SSL_verify_mode => 0 ); my $pubkey_fp = $test->{fingerprint} =~m{\$pub\$}; skip "fingerprints do not match",1 if $cl->get_fingerprint('sha1',undef,$pubkey_fp) ne $test->{fingerprint}; diag("fingerprint matches"); # then check if we can use the default CA path for successful # validation without OCSP yet $cl = eval { &$tcp_connect } or skip "TCP connect#2 failed: $@",1; skip "SSL upgrade w/o OCSP failed: $SSL_ERROR",1 if ! IO::Socket::SSL->start_SSL($cl, SSL_hostname => $test->{host}, SSL_ocsp_mode => SSL_OCSP_NO_STAPLE ); diag("validation with default CA w/o OCSP ok"); # check with default settings $cl = eval { &$tcp_connect } or skip "TCP connect#3 failed: $@",1; my $ok = IO::Socket::SSL->start_SSL($cl, SSL_hostname => $test->{host}); my $err = !$ok && $SSL_ERROR; if (!$ok && !$test->{ocsp}{revoked}) { fail("SSL upgrade with OCSP stapling failed: $err"); next TEST; } # we got usable stapling if _SSL_ocsp_verify is defined if ($test->{ocsp}{staple}) { if ( ! ${*$cl}{_SSL_ocsp_verify}) { fail("did not get expected OCSP response with stapling"); next TEST; } else { diag("got stapled response as expected"); } } if (!$err && !$${*$cl}{_SSL_ocsp_verify} && $have_httptiny) { # use OCSP resolver to resolve remaining certs, should be at most one my $ocsp_resolver = $cl->ocsp_resolver; my %rq = $ocsp_resolver->requests; if (keys(%rq)>1) { fail("got more open OCSP requests (".keys(%rq). ") than expected(1) in default mode"); next TEST; } $err = $ocsp_resolver->resolve_blocking(timeout => $timeout); } if ($test->{ocsp}{revoked}) { if ($err =~m/revoked/) { my $where = ${*$cl}{_SSL_ocsp_verify} ? 'stapled':'asked OCSP server'; pass("revoked as expected ($where)"); } elsif ($err =~m/OCSP_basic_verify:certificate verify error/) { # badly signed OCSP record pass("maybe revoked, but got OCSP verification error: $SSL_ERROR"); } elsif ($err =~m/response not yet valid or expired/) { pass("maybe revoked, but got not yet valid/expired response from OCSP server"); } elsif ($err) { # some other error pass("maybe revoked, but got error: $err"); } elsif (!$have_httptiny && !$test->{ocsp}{staple}) { # could not check because HTTP::Tiny is missing pass("maybe revoked, but could not check because HTTP::Tiny is missing"); } else { fail("expected revoked but connection ok"); } next TEST; } elsif ($err) { if ($err =~m/revoked/) { fail("expected ok but revoked"); } else { pass("probably ok, but got $err"); } next TEST; } diag("validation with default CA with OCSP defaults ok"); # now check with full chain $cl = eval { &$tcp_connect } or skip "TCP connect#4 failed: $@",1; my $cache = IO::Socket::SSL::OCSP_Cache->new; if (! IO::Socket::SSL->start_SSL($cl, SSL_hostname => $test->{host}, SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN, SSL_ocsp_cache => $cache )) { skip "unexpected fail of SSL connect: $SSL_ERROR",1 } my $chain_size = $cl->peer_certificates; if ( my $ocsp_resolver = $have_httptiny && $cl->ocsp_resolver ) { # there should be no hard error after resolving - unless an # intermediate certificate got revoked which I don't hope $err = $ocsp_resolver->resolve_blocking(timeout => $timeout); if ($err) { fail("fatal error in OCSP resolver: $err"); next TEST; } # we should now either have soft errors or the OCSP cache should # have chain_size entries if ( ! $ocsp_resolver->soft_error ) { my $cache_size = keys(%$cache)-1; if ($cache_size!=$chain_size) { fail("cache_size($cache_size) != chain_size($chain_size)"); next TEST; } } diag("validation with default CA with OCSP full chain ok"); } done: pass("OCSP tests $test->{host}:$test->{port} ok"); } } IO-Socket-SSL-2.085/t/external/fingerprint.pl0000644000175000017500000000725014553534240020554 0ustar steffensteffen# to update fingerprints in this file: # perl -e 'do q[./t/external/fingerprint.pl]; update_fingerprints()' use strict; use warnings; use IO::Socket::SSL; # --- BEGIN-FINGERPRINTS ---- my $fingerprints= [ { _ => 'this should give us OCSP stapling', fingerprint => 'sha1$pub$39d64bbaea90c6035e25ff990ba4ce565350bac5', host => 'www.chksum.de', ocsp => { staple => 1 }, port => 443 }, { _ => 'no OCSP stapling', fingerprint => 'sha1$pub$8facee0f1cd627f8f2eff3caae6ad5579ca1b01d', host => 'www.bild.de', ocsp => { staple => 0 }, port => 443, subject_hash_ca => '3513523f' }, { _ => 'this is revoked', fingerprint => 'sha1$pub$f0f0c49b8a04a2dd2110e10f7806c97d87d0b26f', host => 'revoked.grc.com', ocsp => { revoked => 1 }, port => 443 }, { fingerprint => 'sha1$pub$5e17bd05648fa0391395aaa3cb7dfcf301cd1688', host => 'www.yahoo.com', port => 443, subject_hash_ca => '244b5494' }, { fingerprint => 'sha1$pub$823f1729628d4fd8b7fd3f37488e6f19c5b15178', host => 'www.comdirect.de', port => 443, subject_hash_ca => '062cdee6' }, { fingerprint => 'sha1$pub$89e72d6477cf17c09d5b6e1bc1640938f5037580', host => 'meine.deutsche-bank.de', port => 443, subject_hash_ca => '607986c7' }, { fingerprint => 'sha1$pub$59b067366473a080210fcab6e17a5d4486d1948e', host => 'www.twitter.com', port => 443, subject_hash_ca => '607986c7' }, { fingerprint => 'sha1$pub$a633f0cfcfc39a74ecc4cc780c7673906c531f9b', host => 'www.facebook.com', port => 443, subject_hash_ca => '244b5494' }, { fingerprint => 'sha1$pub$e1fb56045719de063473031c3b4795ee243b794f', host => 'www.live.com', port => 443, subject_hash_ca => '3513523f' } ] ; # --- END-FINGERPRINTS ---- sub update_fingerprints { my $changed; for my $fp (@$fingerprints) { my $cl = IO::Socket::INET->new( PeerHost => $fp->{host}, PeerPort => $fp->{port} || 443, Timeout => 10, ); my $root; if (!$cl) { warn "E $fp->{host}:$fp->{port} - TCP connect failed: $!\n"; } elsif (!IO::Socket::SSL->start_SSL($cl, Timeout => 10, SSL_ocsp_mode => 0, SSL_hostname => $fp->{host}, SSL_verify_callback => sub { my ($cert,$depth) = @_[4,5]; $root ||= $cert; return 1; } )) { warn "E $fp->{host}:$fp->{port} - SSL handshake failed: $SSL_ERROR\n"; } else { my $sha1 = $cl->get_fingerprint('sha1',undef,1); if ($sha1 eq $fp->{fingerprint}) { warn "N $fp->{host}:$fp->{port} - fingerprint as expected\n"; } else { warn "W $fp->{host}:$fp->{port} - fingerprint changed from $fp->{fingerprint} to $sha1\n"; $fp->{fingerprint} = $sha1; $changed++; } if ($root and $fp->{subject_hash_ca}) { my $hash = sprintf("%08x",Net::SSLeay::X509_subject_name_hash($root)); if ($fp->{subject_hash_ca} eq $hash) { warn "N $fp->{host}:$fp->{port} - subject_hash_ca as expected\n"; } else { warn "N $fp->{host}:$fp->{port} - subject_hash_ca changed from $fp->{subject_hash_ca} to $hash\n"; $fp->{subject_hash_ca} = $hash; $changed++; } } } } if ($changed) { require Data::Dumper; open(my $fh,'<',__FILE__) or die $!; my $pl = do { local $/; <$fh> }; my $new = 'my $fingerprints= '.Data::Dumper->new([$fingerprints])->Terse(1)->Quotekeys(0)->Sortkeys(1)->Dump().";\n"; $pl =~ s{^(# --- BEGIN-FINGERPRINTS ----\s*\n)(.*)^(# --- END-FINGERPRINTS ----\s*\n)}{$1$new$3}ms or die "did not find BEGIN and END markers in ".__FILE__; open($fh,'>',__FILE__) or die $!; print $fh $pl; warn __FILE__." updated\n"; } } $fingerprints; IO-Socket-SSL-2.085/t/external/usable_ca.t0000644000175000017500000001052414521466373017777 0ustar steffensteffenuse strict; use warnings; use Test::More; use IO::Socket::SSL; use IO::Socket::SSL::Utils; my $ipclass = 'IO::Socket::INET'; for( qw( IO::Socket::IP IO::Socket::INET6 )) { eval { require $_ } or next; $ipclass = $_; last; } my $fingerprints = do './fingerprint.pl' || do './t/external/fingerprint.pl' || die "no fingerprints for sites"; my @tests = grep { $_->{subject_hash_ca} } @$fingerprints; my %ca = IO::Socket::SSL::default_ca(); plan skip_all => "no default CA store found" if ! %ca; my %have_ca; # some systems seems to have junk in the CA stores # so better wrap it into eval eval { for my $f ( ( $ca{SSL_ca_file} ? ($ca{SSL_ca_file}) : ()), ( $ca{SSL_ca_path} ? glob("$ca{SSL_ca_path}/*") :()), ) { open( my $fh,'<',$f ) or next; my $pem; while (<$fh>) { if ( m{^--+END} ) { my $cert = PEM_string2cert($pem.$_); $pem = undef; $cert or next; my $hash = Net::SSLeay::X509_subject_name_hash($cert); $have_ca{sprintf("%08x",$hash)} = 1; } elsif ( m{^--+BEGIN (TRUSTED |X509 |)CERTIFICATE-+} ) { $pem = $_; } elsif ( $pem ) { $pem .= $_; } } } }; diag( "found ".(0+keys %have_ca)." CA certs"); plan skip_all => "no CA certs found" if ! %have_ca; my $proxy = ( $ENV{https_proxy} || $ENV{http_proxy} || '' ) =~m{^(?:\w+://)?([\w\-.:\[\]]+:\d+)/?$} && $1; my @cap = ('SSL_verifycn_name'); push @cap, 'SSL_hostname' if IO::Socket::SSL->can_client_sni(); plan tests => (1+@cap)*@tests; for my $test (@tests) { my $host = $test->{host}; my $port = $test->{port} || 443; my $fp = $test->{fingerprint}; my $ca_hash = $test->{subject_hash_ca}; SKIP: { # first check if we have the CA in store skip "no root CA $ca_hash for $host in store",1+@cap if ! $have_ca{$ca_hash}; diag("have root CA for $host in store"); # then build inet connections for later SSL upgrades my @cl; for my $cap ('fp','nocn',@cap,'noca') { my $cl; if ( ! $proxy ) { # direct connection $cl = $ipclass->new( PeerAddr => $host, PeerPort => $port, Timeout => 15, ) } elsif ( $cl = $ipclass->new( PeerAddr => $proxy, Timeout => 15 )) { # try to establish tunnel via proxy with CONNECT my $reply = ''; if ( eval { local $SIG{ALRM} = sub { die "timed out" }; alarm(15); print $cl "CONNECT $host:443 HTTP/1.0\r\n\r\n"; while (<$cl>) { $reply .= $_; last if m{\A\r?\n\Z}; } $reply =~m{\AHTTP/1\.[01] 200\b} or die "unexpected response from proxy: $reply"; }) { } else { $cl = undef } } skip "cannot connect to $host:443 with $ipclass: $!",1+@cap if ! $cl; push @cl,$cl; } diag(int(@cl)." connections to $host ok"); # check if we have SSL interception by comparing the fingerprint we get my $cl = shift(@cl); skip "ssl upgrade failed even without verification",1+@cap if ! IO::Socket::SSL->start_SSL($cl, SSL_verify_mode => 0 ); my $pubkey_fp = $test->{fingerprint} =~m{\$pub\$}; my $clfp = $cl->get_fingerprint('sha1',undef,$pubkey_fp); skip "fingerprint mismatch ($clfp) - probably SSL interception or certificate changed",1+@cap if $clfp ne $fp; diag("fingerprint $host matches"); # check if it can verify against builtin CA store $cl = shift(@cl); if ( ! IO::Socket::SSL->start_SSL($cl)) { skip "ssl upgrade failed with builtin CA store",1+@cap; } diag("check $host against builtin CA store ok"); for my $cap (@cap) { my $cl = shift(@cl); # try to upgrade with SSL using default CA path if ( IO::Socket::SSL->start_SSL($cl, SSL_verify_mode => 1, SSL_verifycn_scheme => 'http', $cap => $host, )) { pass("SSL upgrade $host with default CA and $cap"); } elsif ( $SSL_ERROR =~m{verify failed} ) { fail("SSL upgrade $host with default CA and $cap: $SSL_ERROR"); } else { pass("SSL upgrade $host with default CA and $cap failed but not because of verify problem: $SSL_ERROR"); } } # it should fail when we use no default ca, even on OS X # https://hynek.me/articles/apple-openssl-verification-surprises/ $cl = shift(@cl); if ( IO::Socket::SSL->start_SSL($cl, SSL_ca_file => \'' )) { fail("SSL upgrade $host with no CA succeeded"); } elsif ( $SSL_ERROR =~m{verify failed} ) { pass("SSL upgrade $host with no CA failed"); } else { pass("SSL upgrade $host with no CA failed but not because of verify problem: $SSL_ERROR"); } } } IO-Socket-SSL-2.085/t/ecdhe.t0000644000175000017500000000426214521466373015311 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/ecdhe.t' use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; my $can_ecdh = IO::Socket::SSL->can_ecdh; if (! $can_ecdh) { print "1..0 # Skipped: no support for ecdh with this openssl/Net::SSLeay\n"; exit } $|=1; print "1..4\n"; # first create simple ssl-server my $ID = 'server'; my $addr = '127.0.0.1'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, ReuseAddr => 1, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", (defined &Net::SSLeay::CTX_set1_groups_list || defined &Net::SSLeay::CTX_set1_curves_list) ? (SSL_ecdh_curve => 'prime256v1' ) : (), ) || do { notok($!); exit }; ok("Server Initialization"); # add server port to addr $addr.= ':'.(sockaddr_in( getsockname( $server )))[0]; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( !$pid ) { ###### Client $ID = 'client'; close($server); my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, Domain => AF_INET, (defined &Net::SSLeay::CTX_set1_groups_list || defined &Net::SSLeay::CTX_set1_curves_list) ? (SSL_ecdh_curve => 'prime256v1' ) : (), SSL_verify_mode => 0 ) || do { notok( "connect failed: $SSL_ERROR" ); exit }; ok( "client connected" ); my $protocol = $to_server->get_sslversion; if ($protocol eq 'TLSv1_3') { # ok("# SKIP TLSv1.3 doesn't advertize key exchange in a chipher name"); } else { my $cipher = $to_server->get_cipher(); if ( $cipher !~m/^ECDHE-/ ) { notok("bad key exchange: $cipher"); exit; } ok("ecdh key exchange: $cipher"); } } else { ###### Server my $to_client = $server->accept || do { notok( "accept failed: $SSL_ERROR" ); kill(9,$pid); exit; }; ok( "Server accepted" ); wait; } sub ok { print "ok # [$ID] @_\n"; } sub notok { print "not ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/public_suffix_ssl.t0000644000175000017500000000526214521466373017765 0ustar steffensteffenuse strict; use warnings; use IO::Socket::SSL; use IO::Socket::SSL::Utils; use Test::More; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; my @tests = qw( fail:com|* ok:com|com fail:googleapis.com|*.com ok:googleapis.com|googleapis.com ok:ajax.googleapis.com|*.googleapis.com ok:s3.amazonaws.com|s3.amazonaws.com ok:foo.s3.amazonaws.com|*.s3.amazonaws.com fail:google.com|*.com ok:google.com|google.com ok:www.google.com|*.google.com ok:www.bar.com|*.bar.com ok:www.foo.bar.com|*.foo.bar.com ok:www.foo.co.uk|*.foo.co.uk fail:www.co.uk|*.co.uk fail:co.uk|*.uk ok:bl.uk|bl.uk ok:www.bl.uk|*.bl.uk fail:bar.kobe.jp|*.kobe.jp fail:foo.bar.kobe.jp|*.bar.kobe.jp ok:www.foo.bar.kobe.jp|*.foo.bar.kobe.jp fail:city.kobe.jp|*.kobe.jp ok:city.kobe.jp|city.kobe.jp ok:www.city.kobe.jp|*.city.kobe.jp fail:nodomain|* fail:foo.nodomain|*.nodomain ok:www.foo.nodomain|*.foo.nodomain ); $|=1; plan tests => 0+@tests; # create listener my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ) || die "not ok #tcp listen failed: $!\n"; my $saddr = $server->sockhost.':'.$server->sockport; #diag("listen at $saddr"); # create CA - certificates will be created on demand my ($cacert,$cakey) = CERT_create( CA => 1 ); defined( my $pid = fork() ) || die $!; if ( ! $pid ) { while (@tests) { my $cl = $server->accept or next; shift(@tests); # only for counting # client initially sends line with expected CN defined( my $cn = <$cl> ) or do { warn "failed to get expected name from client, remaining ".(0+@tests); next; }; chop($cn); print $cl "ok\n"; my ($cert,$key) = CERT_create( subject => { CN => $cn }, issuer => [ $cacert,$cakey ], key => $cakey, # reuse to speed up ); #diag("created cert for $cn"); <$cl> if IO::Socket::SSL->start_SSL($cl, SSL_server => 1, SSL_cert => $cert, SSL_key => $key, ); } exit(0); } # if anything blocks - this will at least finish the test alarm(60); $SIG{ALRM} = sub { die "test takes too long" }; close($server); for my $test (@tests) { my ($expect,$host,$cn) = $test=~m{^(ok|fail):(\S+)\|(\S+)} or die $test; my $cl = IO::Socket::INET->new($saddr) or die "failed to connect: $!"; print $cl "$cn\n"; <$cl>; my $sslok = IO::Socket::SSL->start_SSL($cl, SSL_verifycn_name => $host, SSL_verifycn_scheme => 'http', SSL_ca => [$cacert], ); if ( ! $sslok ) { is( $sslok?1:0, $expect eq 'ok' ? 1:0, "ssl $host against $cn -> $expect ($SSL_ERROR)"); } else { is( $sslok?1:0, $expect eq 'ok' ? 1:0, "ssl $host against $cn -> $expect"); } } IO-Socket-SSL-2.085/t/startssl-failed.t0000644000175000017500000000327314521466373017343 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use IO::Select; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..9\n"; my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ); print("not ok\n"),exit if !$server; ok("Server Initialization"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { client(); } else { server(); #kill(9,$pid); wait; } sub client { close($server); my $client = IO::Socket::INET->new($saddr) or return fail("client tcp connect"); ok("client tcp connect"); IO::Socket::SSL->start_SSL($client, SSL_verify_mode => 0) and return fail('start ssl should fail'); ok("startssl client failed: $SSL_ERROR"); UNIVERSAL::isa($client,'IO::Socket::INET') or return fail('downgrade socket after error'); ok('downgrade socket after error'); print $client "foo\n" or return fail("send to server: $!"); ok("send to server"); my $l; while (defined($l = <$client>)) { if ( $l =~m{bar\n} ) { return ok('client receive non-ssl data'); } } fail("receive non-ssl data"); } sub server { my $csock = $server->accept or return fail('tcp accept'); ok('tcp accept'); print $csock "This is no SSL handshake\n"; ok('send non-ssl data'); alarm(10); my $l; while (defined( $l = <$csock>)) { if ($l =~m{foo\n} ) { print $csock "bar\n"; return ok("received non-ssl data"); } #warn "XXXXXXXXX $l"; } fail('no data from client'.$!); } sub ok { print "ok #$_[0]\n"; return 1 } sub fail { print "not ok #$_[0]\n"; return } IO-Socket-SSL-2.085/t/certs/0000755000175000017500000000000014553536272015171 5ustar steffensteffenIO-Socket-SSL-2.085/t/certs/client-cert.pem0000644000175000017500000000225014521466373020103 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDQjCCAiqgAwIBAgIFANIO7CcwDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UEAwwX SU86OlNvY2tldDo6U1NMIERlbW8gQ0EwHhcNMjIxMjExMTk1MzQxWhcNMzIxMjA4 MTk1MzQxWjAXMRUwEwYDVQQDDAxjbGllbnQubG9jYWwwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQC0i9404R22VBv1ZHGNN5TNeCHxMmAxKHPzkoof/CMF UzSrmwzvYP0k1EygbRKbrA40eOX775G4Jp/DU6fRs0aAamPO0eT+Y10fXrUkE+/x AFwW36vPFkwuprkatzyqqAOr9GHnSrFlzgM4uV0WbJNC2H6SovSYAOk30C8TiMIy pSdC5VkiZUWC/nekioEB90hmqU+An2b5y1oSHI9uwO0S+TLcilWkFCmUKXPxEUOj l/Wg7fB2W2L6pHpcuztqpZluSd+cZ6m820PUxbQKB3YD5ZrZT+RNjb+cpVTlqByn kWq83PxcPU8vTk8NESCNBuk7CiR/k3qrhCU/3NxiD/hBAgMBAAGjgYkwgYYwHQYD VR0OBBYEFNcCOPQC8C+uv+36vcovBvILRyELMB8GA1UdIwQYMBaAFEnT2LwqEtZv wVkEbtlv/7SmEt9cMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBEGCWCG SAGG+EIBAQQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsF AAOCAQEAM7Qb36dynl4/suJACh6dpBlZ89NQOah7RrJZahL1cA/81MBlkN/MRIYW jlZwmgggoyCzpMCmHdFb+/DHA8qFJs7Q7arHJeFgYOCe5TIFMDZSCoShXqe97Ncc ISfdpBpITvh0l63nABibKvrUAacTsEdmKxPml81gkaxHiNR86z1uIZIZ4h6yX7Pa VNX7mLXK2hxifvoXGTCsFjaSrn8Vr3rEdUHGrhO6jMtn84g6l8p+4uTVk+PYeveQ VLZVyWXshojs6oSBMl7IxxmaddIwNZodEvsRToC9ZVKbCBGmU0DPLBjyCqUJcGt4 pmdA4se0gfWovTvy5YzfsOOCqUkp7w== -----END CERTIFICATE----- IO-Socket-SSL-2.085/t/certs/server.p120000644000175000017500000000464514521466373017033 0ustar steffensteffen0 0 g *H  X T0 P0 *H 00 *H 0 *H  0 2֥()6?Pu_[V!S? 2@*W޾e1x90CCpOjU?wQr?\"/񩗍{}&1ol1냋ZD9N_ H͢B .AtBe:ƿ#TdKur +cR&AܐaP+g'U]` iԣ55%ny~.oW(^R25/m9v}irle8s^ql볘3\zW)n{A͍pA^IeG>~*l7^3CK0-O"ϖ ءɳ(]fi"%'#,ā q2&g@Rg&mϱ,BDYKf i;xSdž@l}J^>>Jj.}Q!ݿaDZ/=*bok`K2ffqxP XJB,fܐF#gY N@ޓbш%ؘԥ )"3{V.1Jap*H=K;f=la&H޲qy|ߠ3r++&J :0Vi >X5HL]M.鉩uP:c%*juE-A3\\Z 7ؼ& !F¯U'6a,Vhh%r~U;۔Oŝ};҇/ȒltlzFPN6kCGe03O7璛ʄniT/T7BVTN??yloo#3vFtiĺ.|0V}e-(͍AV G +P!0A *H 2.0*0& *H  00 *H  0PcWAU[|?Nݮh8-ֶPt< e~ F;]PqZ{'ո/jwR;+%37-NG1C|_O>f Ýۆ'Ti,Jgy,0߮FIN~ gR.v 8"[DO`{I'WgtV؏I ~k~޽[P;-EJu [5 v+TrS-\N#,-: ^\'rl~x{B?*X4=bIRb§ΎIOOn6V߳Ku~u:!RݰGÈֳDy; Tf2E pB Bqh }ǕJ'YW:{6W )%{jfuq= "n?fo<].LGGg2)(i (xpŠvϓ}yǨko]pErtm}\c֚yE{MbfkL (E r( R,4H4q(+WZ/RN%.̴&]kMAJdmC뇀{.j5X_~IR^hGh16S$e=OO}k?ܴDP!YBwNS:3:j+41%0# *H  1~%s8CsJ010!0 +mI˾c'o/=&}FzQh<IO-Socket-SSL-2.085/t/certs/server2-cert.pem0000644000175000017500000000232514521466373020220 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDYzCCAkugAwIBAgIFANn2EaswDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UEAwwX SU86OlNvY2tldDo6U1NMIERlbW8gQ0EwHhcNMjIxMjExMTk1MzQxWhcNMzIxMjA4 MTk1MzQxWjAYMRYwFAYDVQQDDA1zZXJ2ZXIyLmxvY2FsMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA1WJtob8UnSi5DcfD63MxMGb4T45yFJvVq0GkrQD8 noRPEOA2yQP4wxFhqa7eSdApGMHxff1PqhflL7Ovdv8cNcD96B8/dd0DpEbLAyO4 GOlCeWIqnAXwQQLTwIoS1iela9kknvvJ3IbXL5Xc6d05jrjkjfEYdrNOz0yleiyN /I++r5BRkl4m2yw67w3/W05mhKyksqUeF+0kFAGFYYC9MEpLCey+syd3o904W7c+ G8DW5Xq31z5uyq5gMceuYYEGEa3i9qMGYxnqfIGoF2yyIr4uOXmaSABZPRx5eshX G/5ZLaq5+WEtNX3c/9VUIB82NVH4jC/KoZafBDCX4uH7UQIDAQABo4GpMIGmMB0G A1UdDgQWBBSLwPfz2qNRAqULbZicYg2odGJnMzAfBgNVHSMEGDAWgBRJ09i8KhLW b8FZBG7Zb/+0phLfXDAeBgNVHREEFzAVgg1zZXJ2ZXIyLmxvY2FshwR/AAABMAwG A1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBEGCWCGSAGG+EIBAQQEAwIGQDAT BgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAdkFtd3g53oN3 l8lVDQfyOaPmWfakMoWkF/hDENOtCZUhxFYQlBK02erj3/IKbfOLRBa3rHq6CEHp KnBEG3KorZL/AJniDnhUpkNweQ7nh+cvOBZsRO74sqLBVkjYdsrdIjdIQPS5+SvB PWfL42qVFpi1hWZ8B5qgizGPYvHDeZW5HCvuYELC9nxCjTPjbkcftfS1JrdIrarO OH7eFnMso8cuC+Ywo/n19B0fhsOWV4q3S0qx6Ud5vtZMAW4NWlp3pg0lBZxIVAjT t70UzK0kL7EPGe95+y+DMoKyi2JdyRkD5vyFl7rB4Qo2TCW8xyNggP/GlKoWhBmG EFGeaj3Gig== -----END CERTIFICATE----- IO-Socket-SSL-2.085/t/certs/client-key.enc0000644000175000017500000000321714521466373017726 0ustar steffensteffen-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAtIveNOEdtlQb9WRxjTeUzXgh8TJgMShz85KKH/wjBVM0q5sM 72D9JNRMoG0Sm6wONHjl+++RuCafw1On0bNGgGpjztHk/mNdH161JBPv8QBcFt+r zxZMLqa5Grc8qqgDq/Rh50qxZc4DOLldFmyTQth+kqL0mADpN9AvE4jCMqUnQuVZ ImVFgv53pIqBAfdIZqlPgJ9m+ctaEhyPbsDtEvky3IpVpBQplClz8RFDo5f1oO3w dlti+qR6XLs7aqWZbknfnGepvNtD1MW0Cgd2A+Wa2U/kTY2/nKVU5agcp5FqvNz8 XD1PL05PDREgjQbpOwokf5N6q4QlP9zcYg/4QQIDAQABAoIBABXes/jalI1toJHf /AfHxe8COHVVvXRy8qG8fF4NviXC25hWcLGOAXgMvef4cma4R6O4Sd6T2WZRymxA Fc3nbhi32nV29CrS+TinsaBISHo8aYtNRovwJuQHRtibPd5ruf8iPBpG8Fh1RSth u8qPtiJkpGdplSCVCqsbvRocCK8W4WSya/NCq/sq7j4Th0OTPJV/2oUDnn7SYTJV f8fg7X+NIcymeNDkiOz2jwyEtH26sKQpECdLDR6Huk9crVes/2bhbuTocIarCb8r BGImlZ7l0brfpwor7gXrY5DPPVMSYW+UEz3c63qSp97bVnja5CLiZStCol1Q9/6M nhY5zJkCgYEA5r+n17K4+zHNP5uuywbqrxa2jxhpOeFYrYqFtr2F+phhUM/G5taV whcgwrvqc08mmcL8FnG6uDbx3wWkFjHTwFQLbLgn1lytRINMPSMfXmXJ84MB2mtM 5nu40+BMd3TYapJexnd2QVb6ToldA6/QN28/1/0lYYdCAy4fIbyopJkCgYEAyE3P 8cGPtAiIncNIp+GU8Z07LLK2+uJZUZ8SNY6BU7rKJThbb6EfQ6AWXmbhibr2qmwk H45guzlflT0PIiWmVvvx3ETlZu6qsVVX/XDWfAdNDGwm9zK1IEFOnf8zc+G/Miip oR9OLxBqAz89WeHPLTbOZYdJHlbOtrJtImlEEekCgYEAnGtLUfK7Zrypz/avFL4J lMsm0fXQTwYtYObIIcpz6h4lyewvfwfz2PBoqtlL4wLCvfTpgiVyV7IXYAGo68q3 KmdOn1Ju3udQJWOD6OXIO+twbPxf4zpdlNhFwIsKCuhQVF4IlS0iIsTdRSPkw70I vqtRcg8OqgBQhWtcezgycfECgYEAxPzheFxnuyJ5WM3o8lHDbSq4O2k20t0wAjly awFO5s1YZ+pY4huO567U0NpVDGK2mzvm+rHHJ9lwyxBVhbuJLxpv7bRD90rYy7Wm 5zTFewyjFYh3ebyArMwNSQzlyR1GL0oWKMLk3RxDZhYXfAG7AjhYGzlFC3VLrhkj gygLLaECgYEAvMxiWTZ+1knOAt2ajtlEEKuEh5Ez0NVcclhkcZGbE/SFo6Zw0U+B WV8rZ74SyFcRNznk/zd/Kcvbe7sH7w823Te/UI5QiU3IUmlYFUEGHxChaIxGm/1n mQlvAjaIK3TPGVpY/BGptJEWTrFlH9HH11tHAiEkFFZhzkYQLjg9cZM= -----END RSA PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/server-key.der0000644000175000017500000000224614521466373017764 0ustar steffensteffen01K&207?3'W/9ڻ aWye.%ˣZHT-o $(%bAwZR*ڧFVpTL#Lb#yXimnj-BǷyq]|T/T>_}b]ٞ4PeŏE }z3 ںgҎvĨ v vѕnd)Ka8Wn͡a~-⸉w!dl<}hDW@?onW?d > Y/~S \ҌSvF_(Td|ŜcN~TVp9w]QO ElI'OX.׋[f~F-o^;s솥qj;q.܊4.^+o IK~?I4DXQ喣"zpz`Gfm\+m*:g9BHv][εeGi.} g1%=A(% 7I_֚@+.1誕o㱬D"@tsXY[k+Je5Sc y= R=(%Y#Ϩk^nc}[NZ_OSGTCF1tMw2L>pZ&JMH-F]056-V4 8kd*dZXCK1g!rf7V F8%1KE;;%Dn}& ҍK\Loj'h40aȆ M"d/A.cSnH蝛Qmy6x;T+iM҂J/VArH! ?aE<2$feV zq?!k v>^RAu8_χKQD@<_WvY UǧVI]v`}ӻ􎬾&6 ܬn^'q*ޫ('l]}F/d'=0i DxTw8fO" 93]YJ}djL- DHTR|u< _R&AZFB@4QyUa7=wAe'ǹ sz(+*NHHmT{nUIO-Socket-SSL-2.085/t/certs/server-ecc-key.pem0000644000175000017500000000036114521466373020517 0ustar steffensteffen-----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgH78lt7v+KVS5+L3G DTyl9I+VDfgL9KtAt11jxPqffKWhRANCAATzf1JnwwDgcj90cxlYqMkbIadgSXHx AiVjC0ihbZizEw149YEWfBP8LyhZGYrOwmbkgDObqcys4HMEezDxeYnG -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/server2-key.pem0000644000175000017500000000325014521466373020051 0ustar steffensteffen-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVYm2hvxSdKLkN x8PrczEwZvhPjnIUm9WrQaStAPyehE8Q4DbJA/jDEWGprt5J0CkYwfF9/U+qF+Uv s692/xw1wP3oHz913QOkRssDI7gY6UJ5YiqcBfBBAtPAihLWJ6Vr2SSe+8nchtcv ldzp3TmOuOSN8Rh2s07PTKV6LI38j76vkFGSXibbLDrvDf9bTmaErKSypR4X7SQU AYVhgL0wSksJ7L6zJ3ej3Thbtz4bwNblerfXPm7KrmAxx65hgQYRreL2owZjGep8 gagXbLIivi45eZpIAFk9HHl6yFcb/lktqrn5YS01fdz/1VQgHzY1UfiML8qhlp8E MJfi4ftRAgMBAAECggEAPmgWBisbPUdur8AP5al/5lcHIkVXyf01hWuiXNKgD0BE 23unqiyWMX7A4F57Nn1Bt7LpDN7r0KRCbCwSEixUNMhnud6Bsdfcu8vUjeuBaQ+3 WEbEjXMTLABGq9X14logACW2lySuieeJwaoDvQXtUndyqKytafHRB8Gz18J2GDnt ZRjoBq4taYMgyiIhYtjUes2ZZrBljQvKQibwZrh9FDcik+jo8939iqelijyarQMu k5HafSx01IYxHd63dLafbt/Efpg0lUSrRNzQgloTYhvp162eMZZZPXjM6tX9UGVs bYDef7pQ+clPZzZdasoEFirbY0UGVegJ9yYWhDbdHQKBgQDoUEXyhtTg1MwqAxJR niGO+d3cOtbQqt/+I3jUxvBsv4r/BqhwHrz8Vo9w1GFrQHaIXPnHwZMAG2GDLq3a 9fzvJTEpMbzWOsfo5xNZ3j3N6/VdGQJmdHRVqOk8AmiAblVUZc/FEO2PX8Pmmax8 IqDiB0aAnkZ2/2fBsM5Zl59i1wKBgQDrJBP7mYLH+O5+WK176C31o4rj7LdW+7El YR/0r3DqkAZa6vOtR2CsND6ykv5NEl+dlDz0GsJWnfM768vfy6dLdfX4GR1Vd/lQ MRV+n9TwvV8uwoZSz2mfs/X7pFTHD0jsKoA6NLEZeQDUFGwSJDUjVV3Q4Wr0at6i kaL/xOd2FwKBgQDRmUNSqrW8WCIQMY9AljRe5C94eJnB0LmheG2XRBo9c5+7sk0c Q49s98gZG3T9qD6Jj6FIyeyQJyQWkHIJYPEg7uRo71gZzRT6nCmIZoxKkv5gTaUt vRoNAwXTv7R7U5CnQehwO3KqbdO45aOKqE+RPtEsUCDxUkRRq+yxRqxmJwKBgQCa daaSvXJFPeYcJNBA9nFKTFWuBw8gGlFxRm2hY6V+z4D9NB1BlAOS2vbcguZ9ZjZc 4sVvbCyAjVz73ZacucB5N1GN2aGFRTwGS1fdR8yvHxZpNurZdtnhSGurE3WFFStH x1tX4Mj8/JlotsmO2S32udrYnVqOl60LiTNTY9rPnQKBgBB2gXwUt5nIPTHzcLpX ouceUdzALDweFRqLal/y9ZL8cs2Ou891I4nbGfRZz6b60Eldo4vXr2CAVIERaG+u XKECI9Fb/dHLpMicPFWm9A4cwrIGaxdSUcZ3C8vKLAGUmsCLjKBuMyITfacK22/v brhXwJivvezXQKgfN7yNXHZq -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/create-certs.pl0000644000175000017500000000721714521466373020115 0ustar steffensteffenuse strict; use warnings; use IO::Socket::SSL::Utils; use Net::SSLeay; my $dir = "./"; my $now = time(); my $later = $now + 10*365*86400; Net::SSLeay::SSLeay_add_ssl_algorithms(); my $sha256 = Net::SSLeay::EVP_get_digestbyname('sha256') or die; my $printfp = sub { my ($w,$cert) = @_; print $w.' sha256$'.unpack('H*',Net::SSLeay::X509_digest($cert, $sha256))."\n" }; my %time_valid = (not_before => $now, not_after => $later); my @ca = CERT_create( CA => 1, subject => { CN => 'IO::Socket::SSL Demo CA' }, %time_valid, ); save('test-ca.pem',PEM_cert2string($ca[0])); my @server = CERT_create( CA => 0, subject => { CN => 'server.local' }, subjectAltNames => [ [ DNS => 'server.local' ], [ IP => '127.0.0.1' ] ], purpose => 'server', issuer => \@ca, %time_valid, ); save('server-cert.pem',PEM_cert2string($server[0])); save('server-key.pem',PEM_key2string($server[1])); $printfp->(server => $server[0]); @server = CERT_create( CA => 0, subject => { CN => 'server2.local' }, subjectAltNames => [ [ DNS => 'server2.local' ], [ IP => '127.0.0.1' ] ], purpose => 'server', issuer => \@ca, %time_valid, ); save('server2-cert.pem',PEM_cert2string($server[0])); save('server2-key.pem',PEM_key2string($server[1])); $printfp->(server2 => $server[0]); @server = CERT_create( CA => 0, subject => { CN => 'server-ecc.local' }, subjectAltNames => [ [ DNS => 'server-ecc.local' ], [ IP => '127.0.0.1' ] ], purpose => 'server', issuer => \@ca, key => KEY_create_ec(), %time_valid, ); save('server-ecc-cert.pem',PEM_cert2string($server[0])); save('server-ecc-key.pem',PEM_key2string($server[1])); $printfp->('server-ecc' => $server[0]); my @client = CERT_create( CA => 0, subject => { CN => 'client.local' }, purpose => 'client', issuer => \@ca, %time_valid, ); save('client-cert.pem',PEM_cert2string($client[0])); save('client-key.pem',PEM_key2string($client[1])); $printfp->(client => $client[0]); my @swc = CERT_create( CA => 0, subject => { CN => 'server.local' }, purpose => 'server', issuer => \@ca, subjectAltNames => [ [ DNS => '*.server.local' ], [ IP => '127.0.0.1' ], [ DNS => 'www*.other.local' ], [ DNS => 'smtp.mydomain.local' ], [ DNS => 'xn--lwe-sna.idntest.local' ] ], %time_valid, ); save('server-wildcard.pem',PEM_cert2string($swc[0]),PEM_key2string($swc[1])); my @subca = CERT_create( CA => 1, issuer => \@ca, subject => { CN => 'IO::Socket::SSL Demo Sub CA' }, %time_valid, ); save('test-subca.pem',PEM_cert2string($subca[0])); @server = CERT_create( CA => 0, subject => { CN => 'server.local' }, subjectAltNames => [ [ DNS => 'server.local' ], [ IP => '127.0.0.1' ] ], purpose => 'server', issuer => \@subca, %time_valid, ); save('sub-server.pem',PEM_cert2string($server[0]).PEM_key2string($server[1])); my @cap = CERT_create( CA => 1, subject => { CN => 'IO::Socket::SSL::Intercept' }, %time_valid, ); save('proxyca.pem',PEM_cert2string($cap[0]).PEM_key2string($cap[1])); sub save { my $file = shift; open(my $fd,'>',$dir.$file) or die $!; print $fd @_; } system(< Yo#<٬J*(A)iTQl 0v``o^ʪZ0~q9rż : U$eME2$e0趚k |./ha?T@tXh G[la=\A2$ *&F Crآ[|KHjvӌs!/x>,ɫ8XH%J0\^`TR6%\oxoT^^D%=Y+_w(^Z]ПRl7v\:e$2`s)o"~NKq3jDYɺGRx- 46΅b;Br?CyO44r4%HlbY2^7i7rI n P~Ts6joyS"@@Sr(aiOU` #܊DrǴ\i,amV"R &"ShSQzRsPcx :xQȒ,"MjXs?Y:" TU[d>!pqvHuY9}T}|XC'|sp 2U-Qkݙ>9> F+{wϴqHRT40Y)n\$eyX Y##J̛.%r; AVSp2W0Ik?ǯX:M71vKĬ JR@b>[-c9^V@ytg̀^"p-a z\|MT1s:Q *Jo eUTB ڟW|.\9@W\6tZԡQh7ې'Yhl,G7cu8֍F#W;FC0A *H 2.0*0& *H  00 *H  018w ba!hw,s]VztO,3ḁI:&C]P{d舤;Cgo㦞}@GZ2NbH Q@鵇s D\ƙM+/}:^(nq#[㈽oMNe__֤y&qo<(SD:<; C3 .I 3Ƀ;2wCeOTW"y&"RGy{$Z2YLv[,2D&`3bN+ݢ#?[ۉl?P6R8'ÁC$dntyLB`9zjiz 5sXFbMh*KqZx>M n??ƫW爣_@y|&d*21Sn0/d[/,PFr'rRN\@ԪS[ r;MG9ZRN(*F/[B|X՛'mt̙ \3faܬ'>zCn":AmαupMgv5sX|Q`Q h)O"A9a+os+_&Qpc̭y^E?t-i\4.]C-)Lzk<3dȟn8}j:&L1X rtp~FDԭK<4F.WjoEҼA ߇#j7qvΆȲ5JTyJpPՂ;׎vC1ڃ;\"_bJIeJY`)s;)5tWl .CqA F% \&fGv-.e>.W WI!bN"q0q4nxj!Q8O>x}4neݶ!Ee Tr )ݞ tIO-Socket-SSL-2.085/t/certs/server-key.enc0000644000175000017500000000321314521466373017752 0ustar steffensteffen-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEApzHE80smwzIwghU3zz8zpbaWrydXLzkOF/fau40KYdnUxsdX 3nn8HLiiZd3hLsIlf8ujFlpIyVQtbyAkrtgbgYS++owoJdJiiEGzd41aUirap8rU RlbxrwdwD+9UTM0V2iNMYsEbI715wYZYk2mAbW6Vaq8tQse3qLsXr3kccd/uXXwT VNIvVNfBGT5ffWJds9mejr809FCyZfXFj/dFCq19ehuXh/Lx6zMJtNq6Z4vu7tKO zvWu/8UFdvHEqBIKdgp24NGVF25kEuGmA6iJKUthpTi/HlduirzNoWF+4astArK4 yeK4iXfmIZhkbDx9wwRowf5EV/DYQD9vrW5XPwIDAQABAoIBAASVZAraHT6Yr6UW o9MLWS/KflMK8bmaXNKMuZ25U3bfRpVfKFTcZJb8+3wYxcWcY57J8bdOflRWpHA5 d11RELVPnaoMvEUH1tUEHWwXn0matyfbyE9YBC7Xi1uZz2Z+Ri0Ww/n+b+9eOxTy c+yGpeivcWqH/Duqcf8u3Iqzop3/NC5e9ysU8m+2poAMSUt+P0k0h7wRlLtEWFEF l+3F5ZajjZ/s2fn4Inq7cHq7x2B/u65HGwLBtwBmbVydtCttKjpnOUL7SHbtDhr0 XVvOtWWAjYBHFGnjuy77fQqzmcoVHpahsNtnMSXryD1BKCWOIMjWN0lf1pqhvkCj iCuCLjECgYEA6KqVb5Kd0OOxrBug67JE4CL/QKH+/+H7/XRzWFmGlM0DBltrsa+w 8usrr4ZKZcI1U2MZma8HCnk9C+MLrqH4Uj0Sh+4eKNwlWSPUEs+oa5NebvaCr6pj fVuRTo+WWl8XHU9TR1RDRjGJdPBNiXcy4EyTxT5whFomShBNEEi1uC0CgYEAt/ZG pV3gwDA10ew29LotVoH3NIS9Dbg4ph685oLWa2QqGGS475taWENLMWf/Eve6Idxy k2YfN6ZW5g0M00Y4EiUxi6dLrUU7mNk7siVEbq19kiYIIPusi9KNnktcgOLdTG9q J6+PaOA0nhIIETC/YQGNyIYNnE2IsiJk0PL3pJsCgYAvuJ1B7y6TY8BTbq9I6J2b 41G7bf6heTZ4O+RUoLgr2QjfyuyB22lNydKCA+dKi9ToL5FWpkGpckiFIaKJxQrr wz8DxmFFPDIk4GZlHVaMCgP6enE/mpEhayCYnnbWPl69UkHghXXu9cYdyBP/OAWl X8+HS1FEtEDaPBGyX1d2WQKBgAm8Eoj1qssAwhhVs6LHp1aIkhhJXee38+d2gPCB w+7y4fdgfRjQ07sP9I6svia2zTa1f6qlIMnFF5wc3Kzhbl4ncbO+KpcErt6rwCjx J+njbF2rfYqhRsQvZCcYPdDkMGm3C5sGA0S9eItU0PB37+imOGaAEYBP6gfjIgqc kNY5AoGAA94zGQGGsaddWZdKsX3wkwEGZGofrUwPLQtE2EjcVFKtfJ51PILy7iBf GFLfxyZBWowPRkJANK4PilGd4oN59lX8BwjH9Bxh/dI3PcEUEXdBZZGgJ+vHubd/ 3ggKEBZzeuYorfjg0fIrKk6kSEjCbZy+qPdUh3vZbhO21OPX51U= -----END RSA PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/proxyca.pem0000644000175000017500000000545314521466373017367 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDKDCCAhCgAwIBAgIEP4DSWzANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpJ Tzo6U29ja2V0OjpTU0w6OkludGVyY2VwdDAeFw0yMjEyMTExOTUzNDFaFw0zMjEy MDgxOTUzNDFaMCUxIzAhBgNVBAMMGklPOjpTb2NrZXQ6OlNTTDo6SW50ZXJjZXB0 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXK4ahcU/UQcXBt4aIV9 xw3cr3bxzwVDZLJV7YddsvDF4Ln4zB7A1rwiukBkndvR45AmhbalyYWSYzWi5OJH 0aVw/37tn71sPCTLZW5s4uyxnQcEfZ6D8qGGEmAt2k0WtEf++RAxau62pmdSl+7G qIgsHKirFsfp0rFBI01h+uRG+1W/Cvi/1CFtXurjoVz6CH0tR+Y8xgY5ySL98U/h R20blI9tkZ1uB9gmh85sLHAv9+0IRosJ6dniGxc+uKArxlkQUPnr53kG+cOMnLZc BmeNS/KjvBlAHZbKpIvT9aSO+wwqARx+KpY5Rq+UmveXGevbD+MXnIgQ7Thlbp5b gQIDAQABo2AwXjAdBgNVHQ4EFgQUxH7e57Ub+ohnNjvMHKZNk55G23swCQYDVR0j BAIwADAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIChDARBglghkgBhvhC AQEEBAMCAAcwDQYJKoZIhvcNAQELBQADggEBACkB8b1mK8EPAFDs4mFe4fEORYit b6Or+Y/QNCOWC55uGwjr66j4GkNqGWubuROCGX4tjAS7KJdf3ohq9xw+2XyVrFtI 1DVV7BxfFC1/kUiHsbGHpl6TrYfxilhZ2bDbPVOh/Iz5i5WW1xxogkKEm/d9mE6s CCDqywfOXmCU28k+LvZYz5BoM54xW8B1SwR12rue1mF0IKm/ppcWcX6KYjAfDV4f vLCag89YSsvdZH74E2Wxdv2dDlA8ZAJgzecVl5SQwKFD3W7s0QsrL+BwYW9jY0ma 0XpmKc/caAn5FWY7wHxQDQ9rbxdBxhNW1fXiEpTmh2aG6jhBedcdwvnXOVY= -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC9crhqFxT9RBxc G3hohX3HDdyvdvHPBUNkslXth12y8MXgufjMHsDWvCK6QGSd29HjkCaFtqXJhZJj NaLk4kfRpXD/fu2fvWw8JMtlbmzi7LGdBwR9noPyoYYSYC3aTRa0R/75EDFq7ram Z1KX7saoiCwcqKsWx+nSsUEjTWH65Eb7Vb8K+L/UIW1e6uOhXPoIfS1H5jzGBjnJ Iv3xT+FHbRuUj22RnW4H2CaHzmwscC/37QhGiwnp2eIbFz64oCvGWRBQ+evneQb5 w4yctlwGZ41L8qO8GUAdlsqki9P1pI77DCoBHH4qljlGr5Sa95cZ69sP4xeciBDt OGVunluBAgMBAAECggEASQ9G41MHeyybK0JEyzo/6VYFN33NfyLufJTx4mqDzhBg n2vY8Q8jGyzuz5kptF8jsHjVAlgP04m5jJ0Qtug0/jqpOz798M6iQQeHkRRm1ZSm YoJkTvWkuRtlkwyYYkm8acYiJHcEN9LbiYzrI0CoSDJLoLnDUUPDfsdw8WZUVOau Qz94Z1+RuQ82yicKxdmqCboPvpsrmqnFecYlPHdjHIk1xdR0omoEp5rp7cFQSVAg mX85VMeJJAG0MqXvmlHOrB8axi+C56ToD7nXPpEiQpQKRbxSYOCZc8o3jXSrkd4/ UDVSlevOXHFeeQc1RXVweFk36hajxszKXmWCEkPa6QKBgQDeScGQnZWIRa+A3Z2Z T5YuluyXFw5mF86Pkmzr8huj3aUOHKsQBVc7B8CZdZTVOQkvoCmS2gV1dwberu2U Zs3KE+SCHVXIP89vKr4fVjDDEq7DaBg8QNuXDV7vjuiH9aaqF3edmNkS3RHq4GA5 LQblR7cEOzcBtdPw6Nwn8dkizwKBgQDaLfcqU56kjubF+xg0fhi4FUnpdu0rCVLp FCzaUmCCAepjAdi2Xs8H74usqrbigbXd07lNEetbU2AWe1B6H5FX7vfWnGRqunvq DLUs2dqxXaXRjMISwBuqCCN7odx+uHFFg9B72Ar6QsM33mcJIoM4o9v8LFfVgbtt Jbn4FftwrwKBgF4ADqzbFtrzrQ3vqa+lajr1c8NI6rvdoWoxX4I/ddTL6/qVwPkb aRH7a0T55iBs6CeNsUb6j4hm9y7ABpPVDX1BAEbNpPLzmQLHrnKN/jzf76uOn4EL ZFDyRI1Ff6vPA9W16s1oT5OcjPEoRUioc9wNgaV2bQJ6I9AiiMcTjOEdAoGAUMz7 H2rOcuUVZDbktPQKFYqUz+iiVvDiCr3VCpm9cghhlH8nkgq0o5y8Xprulh4xi1CQ 7JD5V94d1NWgbUnpmuY+VPWgXsJnh7tjEZQw4MTs1xlI+oa4+BSBh5TfQvLtyC/T 8zmEf0Bgaf1srT5h2IUewFpvwPuFvRterxj9ALMCgYAPkbzABqm9EQdynBvoiJYB YeOPf0LzGnwl/e1lRMV0mYJlcDZC3jzwe9iTEtlT4CBtyousZyMsT0CFb0cs764p 5a5v/nHcrTPvh98t1yEIjAXqKigXZtfvttzQGPU60zhzPQqidYfKrhZqHloXOhtI m5grczgEd6RbYPixV7HThw== -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/client-key.pem0000644000175000017500000000325414521466373017743 0ustar steffensteffen-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC0i9404R22VBv1 ZHGNN5TNeCHxMmAxKHPzkoof/CMFUzSrmwzvYP0k1EygbRKbrA40eOX775G4Jp/D U6fRs0aAamPO0eT+Y10fXrUkE+/xAFwW36vPFkwuprkatzyqqAOr9GHnSrFlzgM4 uV0WbJNC2H6SovSYAOk30C8TiMIypSdC5VkiZUWC/nekioEB90hmqU+An2b5y1oS HI9uwO0S+TLcilWkFCmUKXPxEUOjl/Wg7fB2W2L6pHpcuztqpZluSd+cZ6m820PU xbQKB3YD5ZrZT+RNjb+cpVTlqBynkWq83PxcPU8vTk8NESCNBuk7CiR/k3qrhCU/ 3NxiD/hBAgMBAAECggEAFd6z+NqUjW2gkd/8B8fF7wI4dVW9dHLyobx8Xg2+JcLb mFZwsY4BeAy95/hyZrhHo7hJ3pPZZlHKbEAVzeduGLfadXb0KtL5OKexoEhIejxp i01Gi/Am5AdG2Js93mu5/yI8GkbwWHVFK2G7yo+2ImSkZ2mVIJUKqxu9GhwIrxbh ZLJr80Kr+yruPhOHQ5M8lX/ahQOeftJhMlV/x+Dtf40hzKZ40OSI7PaPDIS0fbqw pCkQJ0sNHoe6T1ytV6z/ZuFu5OhwhqsJvysEYiaVnuXRut+nCivuBetjkM89UxJh b5QTPdzrepKn3ttWeNrkIuJlK0KiXVD3/oyeFjnMmQKBgQDmv6fXsrj7Mc0/m67L BuqvFraPGGk54VitioW2vYX6mGFQz8bm1pXCFyDCu+pzTyaZwvwWcbq4NvHfBaQW MdPAVAtsuCfWXK1Eg0w9Ix9eZcnzgwHaa0zme7jT4Ex3dNhqkl7Gd3ZBVvpOiV0D r9A3bz/X/SVhh0IDLh8hvKikmQKBgQDITc/xwY+0CIidw0in4ZTxnTsssrb64llR nxI1joFTusolOFtvoR9DoBZeZuGJuvaqbCQfjmC7OV+VPQ8iJaZW+/HcROVm7qqx VVf9cNZ8B00MbCb3MrUgQU6d/zNz4b8yKKmhH04vEGoDPz1Z4c8tNs5lh0keVs62 sm0iaUQR6QKBgQCca0tR8rtmvKnP9q8UvgmUyybR9dBPBi1g5sghynPqHiXJ7C9/ B/PY8Giq2UvjAsK99OmCJXJXshdgAajryrcqZ06fUm7e51AlY4Po5cg763Bs/F/j Ol2U2EXAiwoK6FBUXgiVLSIixN1FI+TDvQi+q1FyDw6qAFCFa1x7ODJx8QKBgQDE /OF4XGe7InlYzejyUcNtKrg7aTbS3TACOXJrAU7mzVhn6ljiG47nrtTQ2lUMYrab O+b6sccn2XDLEFWFu4kvGm/ttEP3StjLtabnNMV7DKMViHd5vICszA1JDOXJHUYv ShYowuTdHENmFhd8AbsCOFgbOUULdUuuGSODKAstoQKBgQC8zGJZNn7WSc4C3ZqO 2UQQq4SHkTPQ1VxyWGRxkZsT9IWjpnDRT4FZXytnvhLIVxE3OeT/N38py9t7uwfv DzbdN79QjlCJTchSaVgVQQYfEKFojEab/WeZCW8CNogrdM8ZWlj8Eam0kRZOsWUf 0cfXW0cCISQUVmHORhAuOD1xkw== -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/sub-server.pem0000644000175000017500000000557514521466373020004 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDZTCCAk2gAwIBAgIFAJEvmBswDQYJKoZIhvcNAQELBQAwJjEkMCIGA1UEAwwb SU86OlNvY2tldDo6U1NMIERlbW8gU3ViIENBMB4XDTIyMTIxMTE5NTM0MVoXDTMy MTIwODE5NTM0MVowFzEVMBMGA1UEAwwMc2VydmVyLmxvY2FsMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx/qAlExE9vnxGXevsrVeKnyaeRpdmRP3tnT1 H5/2DDnEWoNB1eUbPpF/dOgxrPKfAz3umZdXIAnsfQuVRKCW7mAEB+h4UESoRL06 zRJIax1IE9ZkOrc5AxMf9Y/nT65lznWlH1Utl4Jy10VXOgHp4dm+f4KqMMZObjXe ALB7g3oOmOxlYDsQI4O7AmDiMcvKW788scaJK4a/b824HC7/geMFJloCZclYyEh2 3oH8id5bJk0cAogRuMaxjD0KUE6ss2bvbyCz6tHqrE/1d3Dj8w1tbXdUOwdtqvV7 qt1VEXw3ubyqGVpjN4CKJcFonBrdM5e1PLMaUTicNXX+Q5isjwIDAQABo4GoMIGl MB0GA1UdDgQWBBQ9i+Q0MDdSHvLxwp2UJRg28zwlbDAfBgNVHSMEGDAWgBRRH6LP YDjuacDlrTI0dHmqaFoegzAdBgNVHREEFjAUggxzZXJ2ZXIubG9jYWyHBH8AAAEw DAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBaAwEQYJYIZIAYb4QgEBBAQDAgZA MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQCYTBvAFA62 X2FsWfOMdq4wZ77H+hsqCfDYHTkGE+AHvH0j8c53WDNPGmxODOOE/zY7VNEVm12K tF6fG5hoJ2sDejoGfL+UJBHe1uaCjxBVrK5xgNDBcLLJ4yVcrh97aWR+n6BV3nUf wYnTn64h/dFjOjnCukoAal9ca5Ljk3PU/CojXvE4WbL0G66bMHpgU7pgNWtxYin9 Pea3OGIDGcaKPAGgonCH2Y2BzNB4NrVv8DxKz4SNb42vq+BigZJVZdyZa6FadjkY ZDTYzLe5yAjxDyaT5aoEr509ZAAVFXmcg2Dabh68StDtnxy6xXaZ1ieNS9dAQcyD TDkoHKx8q3NM -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDH+oCUTET2+fEZ d6+ytV4qfJp5Gl2ZE/e2dPUfn/YMOcRag0HV5Rs+kX906DGs8p8DPe6Zl1cgCex9 C5VEoJbuYAQH6HhQRKhEvTrNEkhrHUgT1mQ6tzkDEx/1j+dPrmXOdaUfVS2XgnLX RVc6Aenh2b5/gqowxk5uNd4AsHuDeg6Y7GVgOxAjg7sCYOIxy8pbvzyxxokrhr9v zbgcLv+B4wUmWgJlyVjISHbegfyJ3lsmTRwCiBG4xrGMPQpQTqyzZu9vILPq0eqs T/V3cOPzDW1td1Q7B22q9Xuq3VURfDe5vKoZWmM3gIolwWicGt0zl7U8sxpROJw1 df5DmKyPAgMBAAECggEAAa7y1SQF8pim2SWI0t5uQLmUQDh0R4XVAfH2AhmkwOjG TmoFoLe59nxIEECNw5afFIGt0i/8uYp0kn9DyF0Qb3da/mwMUzp4uoMKjVt4FoCQ AkPU+kECgFn8/79ql74qld0b71JcMTVyxcML/G1WslxsA/doHf3PisDHySMQRmG5 tIlCW36hNBgcxp33nRj5RPpuYJVJ5q9rGJQxBJpEuNJcjVqqTolwL3/nYaDkl5vJ j2rHgrr+9EIPdULv7pRxFGaCHE6NtbK0sq9GjncWr0zreTLc5g5rM1/oo7A3zLz4 eJQ993BhzABwlvy9UCJ3Fd+oJe9BNMZjLsurf7+SoQKBgQDc8TcDyMbck9RXgVKT WPF1hEebw88wy44g6wg+fgCX73TM4BDbThQCbHwklagrxZxIxwoHTeBrGwlipYh5 Sd7TyHE9L6YrBvnVpYQd1N4ko5sCyx7Rwo95sLbpW7Scs/UsfvdPC3jyIa9QGvG5 QWrkohTa8TNeu8UXWpmcLazvrwKBgQDntbr/wIxS3Tjos9F5vYTB6Y5T9M66cjcy YOhA/uJXisGdayj5pl62a/Sp0xyTjjDILd/fwkcRHvzdfCb88przH+yp4Ctzfas5 cNyavBHtzrvnAQWMvOoHWhnyyJd2IlJnwrKgHIwDVNvF0Gaho6TWY5CNfy2zrnHU f++hZrFpIQKBgAmVoThVzmKlOxHst0NTGW5qpZyZOvS379t3tqzXVHlC1wNIORL6 aR3NzPjdUSVM9kGl+MZmV3TuAFM6MRhp3vO6/0aTOZcmP1JIUtnkcRqPylqtqxGY ahbyVoz7AHPHzrv2ag4QxldipLNJ5/CMaPGwIk15JyxV4u/na0B+LsFbAoGAMeeH Hfw3fMVes2e/LwwtYqJN4DEysR9WWghbHVyIHTiqWKAy1AoMDhgUOttYJUOTqBmR RR0Pt1VIOt+5efM6gjCXBUNduGMRlK6FJOJqriA/ghJLQrORaAH04sBnNq9Ptj9N v4RGd5U4PFOVNy0KnI4XHRKOIkvpAk6Hquh2P2ECgYAvjhDNoxMHCzCEQAlQPZG1 QhleZkAUBBgGrm/UukRV3GsNUd8EAmiXEcFzS4jvMROsbeLufS0bSQxe+TXwGO/2 tTa4xlOZ80wYt2lyA9Vw4XyXOijbKBemNePhq6DH5NvlVS1j+7+9CQTC6Awt37qn YNPDnMjecnI86C944N29ag== -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/server-cert.der0000644000175000017500000000154514521466373020132 0ustar steffensteffen0a0I0  *H  0"1 0U IO::Socket::SSL Demo CA0 221211195341Z 321208195341Z010U server.local0"0  *H 0 1K&207?3'W/9ڻ aWye.%ˣZHT-o $(%bAwZR*ڧFVpTL#Lb#yXimnj-BǷyq]|T/T>_}b]ٞ4PeŏE }z3 ںgҎvĨ v vѕnd)Ka8Wn͡a~-⸉w!dl<}hDW@?onW?00Uu2_;-)Zb {VV0U#0Iؼ*oYno\0U0 server.local0 U00U0 `HB@0U% 0 +0  *H  9gڄmu#fٝns?M=?㫨=2_YaVdE v.Wh `@.yes:Rۣn$ylɖ-uHc7$]N zpg>3#Ӫ'`cD6#f5xȶǍŚo±l3sd`O/X`,Lde;`?PIO-Socket-SSL-2.085/t/certs/server-cert.pem0000644000175000017500000000232114521466373020132 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDYTCCAkmgAwIBAgIFANkVla8wDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UEAwwX SU86OlNvY2tldDo6U1NMIERlbW8gQ0EwHhcNMjIxMjExMTk1MzQxWhcNMzIxMjA4 MTk1MzQxWjAXMRUwEwYDVQQDDAxzZXJ2ZXIubG9jYWwwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQCnMcTzSybDMjCCFTfPPzOltpavJ1cvOQ4X99q7jQph 2dTGx1feefwcuKJl3eEuwiV/y6MWWkjJVC1vICSu2BuBhL76jCgl0mKIQbN3jVpS KtqnytRGVvGvB3AP71RMzRXaI0xiwRsjvXnBhliTaYBtbpVqry1Cx7eouxeveRxx 3+5dfBNU0i9U18EZPl99Yl2z2Z6OvzT0ULJl9cWP90UKrX16G5eH8vHrMwm02rpn i+7u0o7O9a7/xQV28cSoEgp2Cnbg0ZUXbmQS4aYDqIkpS2GlOL8eV26KvM2hYX7h qy0CsrjJ4riJd+YhmGRsPH3DBGjB/kRX8NhAP2+tblc/AgMBAAGjgagwgaUwHQYD VR0OBBYEFHW7Ml+/HDstKVpiCxHde7b+VttWMB8GA1UdIwQYMBaAFEnT2LwqEtZv wVkEbtlv/7SmEt9cMB0GA1UdEQQWMBSCDHNlcnZlci5sb2NhbIcEfwAAATAMBgNV HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDARBglghkgBhvhCAQEEBAMCBkAwEwYD VR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAKA5/2fl2oRtBnUj Zr+a2Z1uc+oTP03VPT/w46uolz27MqgQyBiSX+a2WWFWZJZFDK6jv3Yd1C7j+KOm V7sbHOhoIGDwQC55vwdlc5r72RYZOuZSFtujvaABEZ+vF8AHnI3PbiShedL/bK2N yZYWtBj4Lbl1Hb9I+AjOY5TJ5zcenyS5hIEYXZgV0NH5Thf4zMIKrRZ6//3XcN5n zT7nMyPTqh0nYIAblmOKvYu6RJQ29BL8FyNmNXjItr3HjaKIxZry7apvwrHBt+a7 bLQzc5e8/cb06gTHZJYdsWDBT6Mv81jNFA/d2OEbpWCNH4ySLPHCBItMmWTxZR87 D7hgP1A= -----END CERTIFICATE----- IO-Socket-SSL-2.085/t/certs/server-key.pem0000644000175000017500000000325014521466373017767 0ustar steffensteffen-----BEGIN PRIVATE KEY----- MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCnMcTzSybDMjCC FTfPPzOltpavJ1cvOQ4X99q7jQph2dTGx1feefwcuKJl3eEuwiV/y6MWWkjJVC1v ICSu2BuBhL76jCgl0mKIQbN3jVpSKtqnytRGVvGvB3AP71RMzRXaI0xiwRsjvXnB hliTaYBtbpVqry1Cx7eouxeveRxx3+5dfBNU0i9U18EZPl99Yl2z2Z6OvzT0ULJl 9cWP90UKrX16G5eH8vHrMwm02rpni+7u0o7O9a7/xQV28cSoEgp2Cnbg0ZUXbmQS 4aYDqIkpS2GlOL8eV26KvM2hYX7hqy0CsrjJ4riJd+YhmGRsPH3DBGjB/kRX8NhA P2+tblc/AgMBAAECggEABJVkCtodPpivpRaj0wtZL8p+UwrxuZpc0oy5nblTdt9G lV8oVNxklvz7fBjFxZxjnsnxt05+VFakcDl3XVEQtU+dqgy8RQfW1QQdbBefSZq3 J9vIT1gELteLW5nPZn5GLRbD+f5v7147FPJz7Ial6K9xaof8O6px/y7cirOinf80 Ll73KxTyb7amgAxJS34/STSHvBGUu0RYUQWX7cXllqONn+zZ+fgiertwervHYH+7 rkcbAsG3AGZtXJ20K20qOmc5QvtIdu0OGvRdW861ZYCNgEcUaeO7Lvt9CrOZyhUe lqGw22cxJevIPUEoJY4gyNY3SV/WmqG+QKOIK4IuMQKBgQDoqpVvkp3Q47GsG6Dr skTgIv9Aof7/4fv9dHNYWYaUzQMGW2uxr7Dy6yuvhkplwjVTYxmZrwcKeT0L4wuu ofhSPRKH7h4o3CVZI9QSz6hrk15u9oKvqmN9W5FOj5ZaXxcdT1NHVENGMYl08E2J dzLgTJPFPnCEWiZKEE0QSLW4LQKBgQC39kalXeDAMDXR7Db0ui1Wgfc0hL0NuDim HrzmgtZrZCoYZLjvm1pYQ0sxZ/8S97oh3HKTZh83plbmDQzTRjgSJTGLp0utRTuY 2TuyJURurX2SJggg+6yL0o2eS1yA4t1Mb2onr49o4DSeEggRML9hAY3Ihg2cTYiy ImTQ8vekmwKBgC+4nUHvLpNjwFNur0jonZvjUbtt/qF5Nng75FSguCvZCN/K7IHb aU3J0oID50qL1OgvkVamQalySIUhoonFCuvDPwPGYUU8MiTgZmUdVowKA/p6cT+a kSFrIJiedtY+Xr1SQeCFde71xh3IE/84BaVfz4dLUUS0QNo8EbJfV3ZZAoGACbwS iPWqywDCGFWzosenVoiSGEld57fz53aA8IHD7vLh92B9GNDTuw/0jqy+JrbNNrV/ qqUgycUXnBzcrOFuXidxs74qlwSu3qvAKPEn6eNsXat9iqFGxC9kJxg90OQwabcL mwYDRL14i1TQ8Hfv6KY4ZoARgE/qB+MiCpyQ1jkCgYAD3jMZAYaxp11Zl0qxffCT AQZkah+tTA8tC0TYSNxUUq18nnU8gvLuIF8YUt/HJkFajA9GQkA0rg+KUZ3ig3n2 VfwHCMf0HGH90jc9wRQRd0FlkaAn68e5t3/eCAoQFnN65iit+ODR8isqTqRISMJt nL6o91SHe9luE7bU49fnVQ== -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/certs/server-ecc-cert.pem0000644000175000017500000000171114521466373020664 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIICnTCCAYWgAwIBAgIEbKmAADANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdJ Tzo6U29ja2V0OjpTU0wgRGVtbyBDQTAeFw0yMjEyMTExOTUzNDFaFw0zMjEyMDgx OTUzNDFaMBsxGTAXBgNVBAMMEHNlcnZlci1lY2MubG9jYWwwWTATBgcqhkjOPQIB BggqhkjOPQMBBwNCAATzf1JnwwDgcj90cxlYqMkbIadgSXHxAiVjC0ihbZizEw14 9YEWfBP8LyhZGYrOwmbkgDObqcys4HMEezDxeYnGo4GsMIGpMB0GA1UdDgQWBBSZ fnCos4XvVIUn6N1Yqcs/VvqVMjAfBgNVHSMEGDAWgBRJ09i8KhLWb8FZBG7Zb/+0 phLfXDAhBgNVHREEGjAYghBzZXJ2ZXItZWNjLmxvY2FshwR/AAABMAwGA1UdEwEB /wQCMAAwDgYDVR0PAQH/BAQDAgWgMBEGCWCGSAGG+EIBAQQEAwIGQDATBgNVHSUE DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAq43znZwQ/Ogvghzgtpol QX/XgaCA/+jKR0HsnIo1i718VUfxdMw+FU5wb/f4jNl2t5lCCVIjHiuobAjPpz96 tqcqcT8Z3IJ+vVvB3xDTn9eojNrvbpGAg9esa8qaErQQo9hJ6+8jYIEAPbm/lgOU 4dkO6zsWYRtERU9g8Qy1TSJQrE3nxNtk555DrnQkXd9DZsCDistxXQryc5TX8eXo UYDLqPw0xgQ0ui4RAmBa/V3RaxQIYfp81BjhjNkWkfdTFg0vrX3B90gNsR8AX4BP nSG9tY6hpiOu+Y1hHKTZN6nexApLdN4a+biyoi/7jvkns4LI+qmfSk9vw27iONfU fw== -----END CERTIFICATE----- IO-Socket-SSL-2.085/t/certs/test-ca.pem0000644000175000017500000000217314521466373017236 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDIjCCAgqgAwIBAgIEPGupAjANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdJ Tzo6U29ja2V0OjpTU0wgRGVtbyBDQTAeFw0yMjEyMTExOTUzNDFaFw0zMjEyMDgx OTUzNDFaMCIxIDAeBgNVBAMMF0lPOjpTb2NrZXQ6OlNTTCBEZW1vIENBMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunYRHBif+Nltt/y4zxgrmg0/XTMh CVj1+ITPtpIImmuNlN/YKFzjdVLCjsfsiy7h1a8IfqopzFp/JciijHXEW9NyqWJY hwGATku0W72e2T4R0H0LikJ33R1oTP5YfKOHz82ZTJJF3xI57py9Q6AJjM1lCMt6 1EAUqPteBLy0xIOabQDp+RpzKv1Uo5aMHiLACl6J52w8IBDIYhz5YXDNULdt6AYK 9Hqyw+m6FiULr+SrKfjgHFHunM9r79aS27iuqwLrAiHvuCfSp0o+qmslz6YIfpF6 /BziErz1dtnDjqinUlGYCDUPRb2nHI5/h6uFGQuF+w3hud3Ip/nZLMLPtQIDAQAB o2AwXjAdBgNVHQ4EFgQUSdPYvCoS1m/BWQRu2W//tKYS31wwCQYDVR0jBAIwADAP BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIChDARBglghkgBhvhCAQEEBAMC AAcwDQYJKoZIhvcNAQELBQADggEBAI1f2QhRUn4pnrESAYowXBPFe0SKpN8d2Pqz WbagBA2/QaZmkW7AhFoSb0Ni2Jhe9RflbBfF6WQIS6uVuSWT414DGMUQjhGjhLXm 5f4YxtIpeKyFqAkcpHiB7XEO+mfT1iV5jw1e4yq7c8fOFCEI4cAQzdDpr35vjEPw pdSXNHCqIbmbDRZigwGK3m0WNATu2K+54QC+rPKzzb6CDb24lRcWKlmzbaeowKEn zP5GqlNz9PTF6OTxBFxe6hxklE6uudViEqBkD3TvFeXDt4ny1xFUbABxtU3qbwHA r//e1FKMu3RDxJyAiTVPKwsN8dL6KgH4AFL96HV/pkCrIds7i3c= -----END CERTIFICATE----- IO-Socket-SSL-2.085/t/certs/server-wildcard.pem0000644000175000017500000000572614521466373021002 0ustar steffensteffen-----BEGIN CERTIFICATE----- MIIDpTCCAo2gAwIBAgIFAJq9WvMwDQYJKoZIhvcNAQELBQAwIjEgMB4GA1UEAwwX SU86OlNvY2tldDo6U1NMIERlbW8gQ0EwHhcNMjIxMjExMTk1MzQxWhcNMzIxMjA4 MTk1MzQxWjAXMRUwEwYDVQQDDAxzZXJ2ZXIubG9jYWwwggEiMA0GCSqGSIb3DQEB AQUAA4IBDwAwggEKAoIBAQCa1OmM4mLIi3TKEVtXxzuXqariYJgt5Ji0KTNrzwaM EQy6E5RVr1YPTzF4JCacqFnLirNI6cDdSVIK8aOllR2DBNUv7l97LBHHZdwGO0bJ R9y3AYp1EZbK0H8fVp0NCQa9jyp0DJ5glGIibIhlLfLeX0WbU4INK2WwQJGHP+qS G5ntMctaUoCottnHA4MqTAOrsA9QFrebBWq3HbXdNuyVwffgGaXf9W3aeoe135QQ B6HojlQZCm6NzZFaoI8I4TnhQFxET/aW2K4NGRHW5vjH9L7Cks2/vk/SAoHY18AS H6snrswKND3Q0+hPqH+RgtS8uVd7FCuJBqcusq55ndIpAgMBAAGjgewwgekwHQYD VR0OBBYEFP/XaXM4BJHBaxOLEc+UYZJ2ogh8MB8GA1UdIwQYMBaAFEnT2LwqEtZv wVkEbtlv/7SmEt9cMGEGA1UdEQRaMFiCDiouc2VydmVyLmxvY2FshwR/AAABghB3 d3cqLm90aGVyLmxvY2FsghNzbXRwLm15ZG9tYWluLmxvY2Fsghl4bi0tbHdlLXNu YS5pZG50ZXN0LmxvY2FsMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBEG CWCGSAGG+EIBAQQEAwIGQDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B AQsFAAOCAQEAp3fbOgFuaQkThrUqp/xoA95kynQghdZiU6rjrjuROQmo+51gEAd4 5OJPFZsP9+UTLi9eHK/BdHK3LUsGKmqiJSLAbvHaUuNneR4UCLbmmUlD5cINQgvH BIKSg8r+tx9q8xVpZLFdszGZHK3Sm01S8pPEzqspEGWbaR7FLZBci0aZ/4vIdrSY 3abnIcG3tA1Ph/9SabXJd/9EDpGE997aoeCLP/G8YkrOMre/47lQCPbiyqSSXoOf O0mf5Y9095J6ZzyM0NwDI+TnXQG2+GI07J/oih/ehJpDvdqn75bLTfrNojoUUKXf 1BhCHnDihzfn+MD260PA3VfG1sNjkT+xMw== -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCa1OmM4mLIi3TK EVtXxzuXqariYJgt5Ji0KTNrzwaMEQy6E5RVr1YPTzF4JCacqFnLirNI6cDdSVIK 8aOllR2DBNUv7l97LBHHZdwGO0bJR9y3AYp1EZbK0H8fVp0NCQa9jyp0DJ5glGIi bIhlLfLeX0WbU4INK2WwQJGHP+qSG5ntMctaUoCottnHA4MqTAOrsA9QFrebBWq3 HbXdNuyVwffgGaXf9W3aeoe135QQB6HojlQZCm6NzZFaoI8I4TnhQFxET/aW2K4N GRHW5vjH9L7Cks2/vk/SAoHY18ASH6snrswKND3Q0+hPqH+RgtS8uVd7FCuJBqcu sq55ndIpAgMBAAECggEAAuxKlXWPqlwRoh/2Qr+45QnXt0reDJ3AcURG233u0HWg 8SFd/0keXY8f7rX2Aaae/Vv6uwFoufTApwK9VWqtgjP052D/bfacxlAquXZkhXfF F7JggAnLODx77eZHdD/LoAgEI+k6EzYx7Rbx80ENEPwo9v/6WE/NrWhmpvBCuCvk NV+e5rPi1zybt0OmxJ+zoIR10M/gyn1uFjHajAyMuqCQZsDatqzKeKPsGPlvJoo4 igF/iIuBXTX0zP1yH/5iHCbCIYZgapVU7taWS4evTib6OmVV/VlzSwVtqCvJeUTT /nlwHdCsROBEqRusqDMa45zsWfhH8j0INjwOJf2+ZQKBgQDHgLPQhd0ZJtEzWugC 2pLNW+In5yWplTDZnCHmci1Lr0Tk/nabfmVb+6eSL5H7Mq6JLpLknwq46z4GQ/NO FzWZ3B7KaSu1enFiJc2LnjTwfBeqxD/GsIQZcVwq89BbNn+K/NG8dXHWpd5wrJUi KOuHhb4IkVS+wLGk5V1pRM8hVQKBgQDGrbRJ6AECGInX5niAM+Z5QPDATJtE4aCD Ue5CYIRSFSNSBuEsGfiHg2RDtNn1xdasxpiTaxfil+Pon4x8frrc/+8Tr3tgNSEz w2RTc9MEWNcneCEvk1omjgVTgwRCp4ZqE0ov9kH/ZF5qQ+EVHpD49QQb+8X1wNYH JTlCF899hQKBgQC0ZRAzMZgnMg5gnYbFbdboknkBE+XeXeT6IFAXDI8grK9jUST2 nWgRsJBpg1JBDib8LHzu9VDAvRYsnCzZI+t34K6G4GqBguIbmYsvADNmcQ8Ffscc ZmhMiVCKFkUE9VaG2uzbuGbjbMCiqauAY/f1Z13aaW9zvNHlBPFeSrXwsQKBgQCd RUef8V1K8W28UB43Ld5VQYjSUFHgttI+4Y4/UPOtnjn1Zqi8JlrLusCVsAWRPehv oE2K9I1Vu3KX5CRrME5vPtFbvd9mCuibdyJlxRvXJxQ5lCiA5p3IQ0gIEYA/2yjV sytYyBD6P9NVPyJfe3C7AgkctbLAlMNXqKmonfyLmQKBgENirwN4QUfe8SPETHga 8cwYI6UQmsbtacvEOaLs3Zlw2Ihc46AggNC53jOTFf4Z+T83Q7iBfH6B8MNyVP/s H1zbfrf6aU85K1d9p2vSDlACkwVr00QKWYgDjvBebjC4IRPm9vq3FOnQOrzpNgiN TirN8xUxB8ae6nrrXVOvHv6G -----END PRIVATE KEY----- IO-Socket-SSL-2.085/t/plain_upgrade_downgrade.t0000644000175000017500000001120314521466373021076 0ustar steffensteffenuse strict; use warnings; use Socket; use IO::Socket::SSL; use IO::Socket::SSL::Utils; use Test::More; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; # create listener IO::Socket::SSL::default_ca('t/certs/test-ca.pem'); my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', # start as plain and upgrade later SSL_startHandshake => 0, ) || die "not ok #tcp listen failed: $!\n"; my $saddr = $server->sockhost.':'.$server->sockport; #diag("listen at $saddr"); # fork child for server defined( my $pid = fork() ) || die $!; if ( ! $pid ) { $SIG{ALRM} = sub { die "server timed out" }; while (1) { alarm(30); my $cl = $server->accept; diag("server accepted new client"); #${*$cl}{_SSL_ctx} or die "accepted socket has no SSL context"; ${*$cl}{_SSL_object} and die "accepted socket is already SSL"; # try to find out if we start with TLS immediately (peek gets data from # client hello) or have some plain data initially (peek gets these # plain data) diag("wait for initial data from client"); my $buf = ''; while (length($buf)<3) { vec(my $rin='',fileno($cl),1) = 1; my $rv = select($rin,undef,undef,10); die "timeout waiting for data from client" if ! $rv; die "something wrong: $!" if $rv<0; $cl->peek($buf,3); $buf eq '' and die "eof from client"; diag("got 0x".unpack("H*",$buf)." from client"); } if ($buf eq "end") { # done diag("client requested end of tests"); exit(0); } if ($buf eq 'foo') { # initial plain dialog diag("server: got plain data at start of connection"); read($cl,$buf,3) or die "failed to read"; $buf eq 'foo' or die "read($buf) different from peek"; print $cl "bar"; # reply } # now we upgrade to TLS diag("server: TLS upgrade"); $cl->accept_SSL or die "failed to SSL upgrade server side: $SSL_ERROR"; ${*$cl}{_SSL_object} or die "no SSL object after accept_SSL"; read($cl,$buf,6) or die "failed to ssl read"; $buf eq 'sslfoo' or die "wrong data received from client '$buf'"; print $cl "sslbar"; # now we downgrade from TLS to plain and try to exchange some data diag("server: TLS downgrade"); $cl->stop_SSL or die "failed to stop SSL"; ${*$cl}{_SSL_object} and die "still SSL object after stop_SSL"; read($cl,$buf,3); $buf eq 'foo' or die "wrong data received from client '$buf'"; print $cl "bar"; # now we upgrade again to TLS diag("server: TLS upgrade#2"); $cl->accept_SSL or die "failed to SSL upgrade server side"; ${*$cl}{_SSL_object} or die "no SSL object after accept_SSL"; read($cl,$buf,6) or die "failed to ssl read"; $buf eq 'sslfoo' or die "wrong data received from client '$buf'"; print $cl "sslbar"; } } # client close($server); # close server in client $SIG{ALRM} = sub { die "client timed out" }; plan tests => 15; for my $test ( [qw(newINET start_SSL stop_SSL start_SSL)], [qw(newSSL stop_SSL connect_SSL)], [qw(newSSL:0 connect_SSL stop_SSL connect_SSL)], [qw(newSSL:0 start_SSL stop_SSL connect_SSL)], ) { my $cl; diag("-- test: @$test"); for my $act (@$test) { if (eval { if ($act =~m{newSSL(?::(.*))?$} ) { $cl = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, defined($1) ? (SSL_startHandshake => $1):(), ) or die "failed to connect: $!|$SSL_ERROR"; if ( ! defined($1) || $1 ) { ${*$cl}{_SSL_object} or die "no SSL object"; } else { ${*$cl}{_SSL_object} and die "have SSL object"; } } elsif ($act eq 'newINET') { $cl = IO::Socket::INET->new($saddr) or die "failed to connect: $!"; } elsif ($act eq 'stop_SSL') { $cl->stop_SSL or die "stop_SSL failed: $SSL_ERROR"; ${*$cl}{_SSL_object} and die "still having SSL object after stop_SSL"; } elsif ($act eq 'connect_SSL') { $cl->connect_SSL or die "connect_SSL failed: $SSL_ERROR"; ${*$cl}{_SSL_object} or die "no SSL object after connect_SSL"; } elsif ($act eq 'start_SSL') { IO::Socket::SSL->start_SSL($cl) or die "start_SSL failed: $SSL_ERROR"; ${*$cl}{_SSL_object} or die "no SSL object after start_SSL"; } else { die "unknown action $act" } if (${*$cl}{_SSL_object}) { print $cl "sslfoo"; read($cl, my $buf,6); $buf eq 'sslbar' or die "wrong response with ssl: $buf"; } else { print $cl "foo"; read($cl, my $buf,3); $buf eq 'bar' or die "wrong response without ssl: $buf"; } }) { pass($act); } else { fail("$act: $@"); last; # slip rest } } } # make server exit alarm(10); my $cl = IO::Socket::INET->new($saddr); print $cl "end" if $cl; wait; IO-Socket-SSL-2.085/t/set_curves.t0000644000175000017500000000350714521466373016424 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; my $set_groups_list = defined &Net::SSLeay::CTX_set1_groups_list ? \&Net::SSLeay::CTX_set1_groups_list : defined &Net::SSLeay::CTX_set1_curves_list ? \&Net::SSLeay::CTX_set1_curves_list : do { print "1..0 # no support for CTX_set1_curves_list or CTX_set1_groups_list\n"; exit; }; print "1..6\n"; my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', Listen => 2, ReuseAddr => 1, SSL_server => 1, SSL_ca_file => "t/certs/test-ca.pem", SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', SSL_cipher_list => 'ECDHE', SSL_ecdh_curve => 'P-521:P-384', ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; print "ok # Server Initialization\n"; my $saddr = $server->sockhost.':'.$server->sockport; my @tests = ( [ 1,'P-521' ], [ 1,'P-384' ], [ 0,'P-256' ], [ 1,'P-384:P-521' ], [ 1,'P-256:P-384:P-521' ], ); defined( my $pid = fork() ) || die $!; if (!$pid) { close($server); for my $t (@tests) { my (undef,$curves) = @$t; my $cl = IO::Socket::SSL->new( PeerAddr => $saddr, SSL_verify_mode => 1, SSL_ca_file => 't/certs/test-ca.pem', SSL_ecdh_curve => $curves, ) or next; <$cl>; } exit; } for my $t (@tests) { my ($expect_ok,$curves) = @$t; my $csock = $server->accept; if ($csock && $expect_ok) { print "ok # expect success $curves\n"; } elsif (!$csock && !$expect_ok) { print "ok # expect fail $curves: $SSL_ERROR\n"; } elsif ($csock) { print "not ok # expect fail $curves\n"; } else { print "not ok # expect success $curves: $SSL_ERROR\n"; } close($csock) if $csock; } wait; IO-Socket-SSL-2.085/t/connectSSL-timeout.t0000644000175000017500000000361014521466373017734 0ustar steffensteffenuse strict; use warnings; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..16\n"; { # first use SSL client my ($server,$saddr) = create_listen_socket(); ok( 1, "listening \@$saddr" ); my $srv = fork_sub( 'server','ssl',$server ); close($server); fd_grep_ok( 'Waiting', $srv ); my $cl = fork_sub( 'client',$saddr ); fd_grep_ok( 'Connect from',$srv ); fd_grep_ok( 'Connected', $cl ); fd_grep_ok( 'Server SSL Handshake OK', $srv ); fd_grep_ok( 'Client SSL Handshake OK', $cl ); fd_grep_ok( 'Hi!', $cl ); } { # then try bad non-SSL client my ($server,$saddr) = create_listen_socket(); ok( 1, "listening \@$saddr" ); my $srv = fork_sub( 'server','nossl',$server ); close($server); fd_grep_ok( 'Waiting', $srv ); my $cl = fork_sub( 'client',$saddr ); fd_grep_ok( 'Connect from',$srv ); fd_grep_ok( 'Connected', $cl ); fd_grep_ok( 'Client SSL Handshake FAILED', $cl ); } sub server { my ($behavior,$server) = @_; print "Waiting\n"; my $client = $server->accept || die "accept failed: $!"; print "Connect from ".$client->peerhost.':'.$client->peerport."\n"; if ( $behavior eq 'ssl' ) { if ( IO::Socket::SSL->start_SSL( $client, SSL_server => 1, Timeout => 30, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', )) { print "Server SSL Handshake OK\n"; print $client "Hi!\n"; } } else { while ( sysread( $client, my $buf,8000 )) {} } } sub client { my $saddr = shift; my $c = IO::Socket::INET->new( $saddr ) || die "connect failed: $!"; print "Connected\n"; if ( IO::Socket::SSL->start_SSL( $c, Timeout => 5, SSL_ca_file => 't/certs/test-ca.pem', )) { print "Client SSL Handshake OK\n"; print <$c> } else { print "Client SSL Handshake FAILED - $SSL_ERROR\n"; } } IO-Socket-SSL-2.085/t/auto_verify_hostname.t0000644000175000017500000000410614521466373020470 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use Test::More; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; plan tests => 1 + 7 + 4 + 7*2 + 4; my @tests = qw( example.com www FAIL server.local ldap OK server.local www FAIL bla.server.local www OK www7.other.local www OK www7.other.local ldap FAIL bla.server.local ldap OK ); my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ReuseAddr => 1, SSL_server => 1, SSL_cert_file => "t/certs/server-wildcard.pem", SSL_key_file => "t/certs/server-wildcard.pem", ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; ok( $server, "Server Initialization"); exit if !$server; my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { while (1) { my $csock = $server->accept || next; print $csock "hallo\n"; } } close($server); IO::Socket::SSL::default_ca('t/certs/test-ca.pem'); for( my $i=0;$i<@tests;$i+=3 ) { my ($name,$scheme,$result) = @tests[$i,$i+1,$i+2]; my $cl = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 1, SSL_verifycn_scheme => $scheme, SSL_verifycn_name => $name, ); if ( $result eq 'FAIL' ) { ok( !$cl, "connection to $name/$scheme failed" ); } else { ok( $cl, "connection to $name/$scheme succeeded" ); } $cl || next; is( <$cl>, "hallo\n", "received hallo" ); } for( my $i=0;$i<@tests;$i+=3 ) { my ($name,$scheme,$result) = @tests[$i,$i+1,$i+2]; my $cl = IO::Socket::INET->new($saddr); ok( $cl, "tcp connect" ); $cl = IO::Socket::SSL->start_SSL( $cl, SSL_verify_mode => 1, SSL_verifycn_scheme => $scheme, SSL_verifycn_name => $name, ); if ( $result eq 'FAIL' ) { ok( !$cl, "ssl upgrade of connection to $name/$scheme failed" ); } else { ok( $cl, "ssl upgrade of connection to $name/$scheme succeeded" ); } $cl || next; is( <$cl>, "hallo\n", "received hallo" ); } kill(9,$pid); wait; IO-Socket-SSL-2.085/t/session_ticket.t0000644000175000017500000001172614521466373017272 0ustar steffensteffenuse strict; use warnings; use IO::Socket::SSL; use IO::Socket::SSL::Utils; use Test::More; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; plan skip_all => 'no support for session ticket key callback' if ! IO::Socket::SSL->can_ticket_keycb; plan tests => 6; # create two servers with the same session ticket callback my (@server,@saddr); for (1,2) { my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ) or die "failed to create listener: $!"; push @server,{ fd => $server }; push @saddr, $server->sockhost.':'.$server->sockport; diag("listen at $saddr[-1]"); } # create some self signed certificate my ($cert,$key) = CERT_create(CA => 1, subject => { CN => 'ca' }, ); my ($client_cert,$client_key) = CERT_create( issuer => [ $cert,$key], subject => { CN => 'client' }, purpose => { client => 1 } ); my ($server_cert,$server_key) = CERT_create( issuer => [ $cert,$key], subject => { CN => 'server' }, subjectAltNames => [ [ DNS => 'server' ], [ IP => $saddr[0]=~m{^(.*):} && $1 ], [ IP => $saddr[1]=~m{^(.*):} && $1 ], ], purpose => { server => 1 } ); defined( my $pid = fork() ) || die $!; exit(_server()) if ! $pid; @server = (); # if anything blocks - this will at least finish the test alarm(60); $SIG{ALRM} = sub { die "test takes too long" }; END{ kill 9,$pid if $pid }; my $clctx = IO::Socket::SSL::SSL_Context->new( SSL_session_cache_size => 10, SSL_cert => $client_cert, SSL_key => $client_key, SSL_ca => [ $cert ], # LibreSSL has currently no support for TLS 1.3 session handling # therefore enforce TLS 1.2 Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") ? (SSL_version => 'TLSv1_2') : # versions of Net::SSLeay with support for SESSION_up_ref have also the # other functionality needed for proper TLS 1.3 session handling defined(&Net::SSLeay::SESSION_up_ref) ? () : (SSL_version => 'SSLv23:!TLSv1_3:!SSLv3:!SSLv2'), ); my $client = sub { my ($i,$expect_reuse,$desc) = @_; my $cl = IO::Socket::SSL->new( PeerAddr => $saddr[$i], SSL_reuse_ctx => $clctx, SSL_session_key => 'server', # single key for both @saddr ); <$cl>; # read something, incl. TLS 1.3 ticket my $reuse = $cl && Net::SSLeay::session_reused($cl->_get_ssl_object); diag("connect to $i: ". ($cl ? "success reuse=$reuse version=".$cl->get_sslversion() : "error: $!,$SSL_ERROR" )); is($reuse,$expect_reuse,$desc); close($cl); }; $client->(0,0,"no initial session -> no reuse"); $client->(0,1,"reuse with the next session and secret[0]"); $client->(1,1,"reuse even though server changed, since they share ticket secret"); $client->(1,0,"reports non-reuse since server1 changed secret to secret[1]"); $client->(0,0,"reports non-reuse on server0 since got ticket with secret[1] in last step"); $client->(0,1,"reuse again since got ticket with secret[0] in last step"); sub _server { # create the secrets for handling session tickets my @secrets; for(qw(key1 key2)) { my $name = pack("a16",$_); Net::SSLeay::RAND_bytes(my $key,32); push @secrets, [ $key,$name ]; } my $get_ticket_key = sub { my (undef,$name) = @_; if (!defined $name) { print "creating new ticket $secrets[0][1]\n"; return @{$secrets[0]}; } for(my $i=0;$i<@secrets;$i++) { next if $secrets[$i][1] ne $name; if ($i == 0) { print "using current ticket secret\n"; return @{$secrets[0]}; } else { print "using non-current ticket secret\n"; return ($secrets[0][0],$secrets[$i][1]); } } print "unknown ticket key name\n"; return; }; # create the SSL context for(@server) { $_->{sslctx} = IO::Socket::SSL::SSL_Context->new( SSL_server => 1, SSL_cert => $server_cert, SSL_key => $server_key, SSL_ca => [ $cert ], SSL_verify_mode => SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, SSL_ticket_keycb => $get_ticket_key, SSL_session_id_context => 'foobar', ) or die "failed to create SSL context: $SSL_ERROR"; } my $rin = ''; vec($rin,fileno($_->{fd}),1) = 1 for @server; while (1) { select(my $rout = $rin,undef,undef,10) or die "select failed or timed out: $!"; for(my $i=0;$i<@server;$i++) { next if ! vec($rout,fileno($server[$i]{fd}),1); alarm(10); local $SIG{ALRM} = sub { die "server[$i] timed out" }; print "access to server[$i]\n"; my $cl = $server[$i]{fd}->accept or do { print "failed to TCP accept: $!\n"; last; }; IO::Socket::SSL->start_SSL($cl, SSL_server => 1, SSL_reuse_ctx => $server[$i]{sslctx} ) or do { print "failed to SSL accept: $SSL_ERROR\n"; last; }; print $cl "hi\n"; my $reuse = Net::SSLeay::session_reused($cl->_get_ssl_object); print "server[$i] reused=$reuse\n"; # after access to server[1] rotate the secrets if ($i == 1) { print "rotate secrets\n"; push @secrets, shift(@secrets); } close($cl); alarm(0); last; } } exit(0); } IO-Socket-SSL-2.085/t/cert_no_file.t0000644000175000017500000000554314521466373016674 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/nonblock.t' # Tests the use if SSL_cert instead of SSL_cert_file # because Net::SSLeay does not implement the necessary functions # to create an X509 from file/string (PEM_read_bio_X509) I just # create a server with SSL_cert_file and get the X509 from it using # Net::SSLeay::get_certificate. # Test should also test if SSL_cert is an array of X509* # and if SSL_key is an EVP_PKEY* but with the current function in # Net::SSLeay I don't see a way to test it use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; use Test::More tests => 9; Test::More->builder->use_numbers(0); Test::More->builder->no_ending(1); my $ID = 'server'; my %server_args = ( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, SSL_server => 1, SSL_verify_mode => 0x00, SSL_ca_file => "t/certs/test-ca.pem", SSL_key_file => "t/certs/client-key.pem", ); my ($x509,@server); foreach my $test ( 1,2,3 ) { my %args = %server_args; my $spec; if ( $test == 1 ) { # 1st test: create server with SSL_cert_file $args{SSL_cert_file} = "t/certs/client-cert.pem"; $spec = 'Using SSL_cert_file'; } elsif ( $test == 2 ) { # 2nd test: use x509 from previous server # with SSL_cert instead of SSL_cert_file $args{SSL_cert} = $x509; $spec = 'Using SSL_cert'; } elsif ( $test == 3 ) { # 3rd test: empty SSL_cert, so that default # SSL_cert_file gets not used # server creation should fail $spec = 'Empty SSL_cert'; $args{SSL_cert} = undef; } # create server my $server = IO::Socket::SSL->new( %args ) || do { fail( "$spec: $!" ); next; }; my $saddr = $server->sockhost.':'.$server->sockport; pass("Server Initialization $spec"); push @server,$server; # then connect to it from a child defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); $ID = 'client'; my $to_server = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 0x00, ); if ( $test == 3 ) { ok( !$to_server, "$spec: connect succeeded" ); exit; } elsif ( ! $to_server ) { fail("connect failed: $!"); exit; } pass( "client connected $spec" ); <$to_server>; # wait for close from parent exit; } my $to_client = $server->accept; if ( $test == 3 ) { ok( !$to_client, "$spec: accept succeeded" ); } elsif ( ! $to_client ) { kill(9,$pid); fail("$spec: accept failed: $!"); exit; } else { pass( "Server accepted $spec" ); # save the X509 certificate from the server $x509 ||= Net::SSLeay::get_certificate($to_client->_get_ssl_object); } close($to_client) if $to_client; wait; } IO-Socket-SSL-2.085/t/session_cache.t0000644000175000017500000000355514521466373017053 0ustar steffensteffenmy $DEBUG = 0; use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; my $numtests = 11; print "1..$numtests\n"; my $ctx = IO::Socket::SSL::SSL_Context->new( SSL_ca_file => "t/certs/test-ca.pem", SSL_session_cache_size => 3, ); my $cache = $ctx->{session_cache} or do { print "not ok \# Context init\n"; exit; }; ok("Context init"); my $dump_cache = $DEBUG ? sub { diag($cache->_dump) } : sub {}; print "not " if $cache->{room} != 3; ok("0 entries in cache, room for 3 more"); &$dump_cache; $cache->add_session("bogus", 0); print "not " if $cache->{ghead}[1] ne 'bogus'; ok("cache head at 'bogus'"); &$dump_cache; $cache->add_session("bogus1", 0); print "not " if $cache->{room} != 1; ok("two entries in cache, room for 1 more"); print "not " if $cache->{ghead}[1] ne 'bogus1'; ok("cache head at 'bogus1'"); &$dump_cache; $cache->get_session("bogus"); print "not " if $cache->{ghead}[1] ne 'bogus'; ok("get_session moves cache head to 'bogus'"); &$dump_cache; $cache->add_session("bogus", 0); print "not " if $cache->{room} != 0; ok("3 entries in cache, room for no more"); &$dump_cache; # add another bogus and bogus1 should be removed to make room print "not " if ! $cache->{shead}{bogus1}; ok("bogus1 still in cache"); &$dump_cache; $cache->add_session("bogus", 0); print "not " if $cache->{room} != 0; ok("still 3 entries in cache, room for no more"); &$dump_cache; print "not " if $cache->{shead}{bogus1}; ok("bogus1 removed from cache to make room"); # when removing 'bogus' the cache should be empty again $cache->del_session('bogus'); print "not " if $cache->{room} != 3; ok("0 entries in cache, room for 3"); &$dump_cache; sub ok { my $line = (caller)[2]; print "ok # $_[0]\n"; } sub diag { my $msg = shift; $msg =~s{^}{ # }mg; print STDERR $msg; } IO-Socket-SSL-2.085/t/verify_hostname.t0000644000175000017500000000766314521466373017453 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; # if we have an IDN library max the IDN tests too my $can_idn = eval { require Encode } && ( eval { require Net::LibIDN } || eval { require Net::IDN::Encode } || eval { require URI; URI->VERSION(1.50) } ); $|=1; my $max = 42; $max+=3 if $can_idn; print "1..$max\n"; my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ReuseAddr => 1, ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; ok("Server Initialization"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); my $client = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 0 ) || print "not "; ok( "client ssl connect" ); my $issuer = $client->peer_certificate( 'issuer' ); print "not " if $issuer !~m{IO::Socket::SSL Demo CA}; ok("issuer"); my $cn = $client->peer_certificate( 'cn' ); print "not " unless $cn eq "server.local"; ok("cn"); my @alt = $client->peer_certificate( 'subjectAltNames' ); my @want = ( GEN_DNS() => '*.server.local', GEN_IPADD() => '127.0.0.1', GEN_DNS() => 'www*.other.local', GEN_DNS() => 'smtp.mydomain.local', GEN_DNS() => 'xn--lwe-sna.idntest.local', ); while (@want) { my ($typ,$text) = splice(@want,0,2); my $data = ($typ == GEN_IPADD() ) ? inet_aton($text):$text; my ($th,$dh) = splice(@alt,0,2); $th == $typ and $dh eq $data or print "not "; ok( $text ); } @alt and print "not "; ok( 'no more altSubjectNames' ); my @tests = ( '127.0.0.1' => [qw( smtp ldap www)], 'server.local' => [qw(smtp ldap)], 'blafasel.server.local' => [qw(smtp ldap www)], 'lala.blafasel.server.local' => [], 'www.other.local' => [qw()], 'www-13.other.local' => [qw(www)], 'www-13.lala.other.local' => [], 'smtp.mydomain.local' => [qw(smtp ldap www)], 'xn--lwe-sna.idntest.local' => [qw(smtp ldap www)], 'smtp.mydomain.localizing.useless.local' => [], ); if ( $can_idn ) { # check IDN handling my $loewe = "l\366we.idntest.local"; push @tests, ( $loewe => [qw(smtp ldap www)] ); } while (@tests) { my ($host,$expect) = splice(@tests,0,2); my %expect = map { $_=>1 } @$expect; for my $typ (qw( smtp ldap www)) { my $is = $client->verify_hostname( $host, $typ ) ? 'pass':'fail'; my $want = $expect{$typ} ? 'pass':'fail'; print "not " if $is ne $want; ok( "$want $host $typ" ); } } exit; } my $accept = sub { my $csock = $server->accept; IO::Socket::SSL->start_SSL($csock, SSL_server => 1, SSL_ca_file => "t/certs/test-ca.pem", SSL_cert_file => "t/certs/server-wildcard.pem", SSL_key_file => "t/certs/server-wildcard.pem", ); }; my $csock = &$accept; wait; # try with implicit checking # Should succeed defined( $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_ca_file => "t/certs/test-ca.pem", SSL_verify_mode => 1, SSL_verifycn_scheme => 'www', SSL_verifycn_name => 'www.server.local' ) || print "not "; ok("implicit hostname check www.server.local"); exit; } $csock = &$accept; wait; # Should fail defined( $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); if (IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_ca_file => "t/certs/test-ca.pem", SSL_verify_mode => 1, SSL_verifycn_scheme => 'www', SSL_verifycn_name => 'does.not.match.server.local' )) { print "not "; } elsif ($SSL_ERROR !~ /hostname verification failed/) { print "# wrong error(should be hostname verification failed): $SSL_ERROR\n"; print "not "; } ok("implicit hostname check does.not.match.server.local"); exit; } $csock = &$accept; wait; sub ok { print "ok #$_[0]\n"; } IO-Socket-SSL-2.085/t/verify_hostname_standalone.t0000644000175000017500000002113714553536035021651 0ustar steffensteffenuse strict; use warnings; use Test::More; use IO::Socket::SSL; use IO::Socket::SSL::Utils; my $libressl = Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER"); my @tests = tests(); plan tests => 0+@tests; my ($ca,$key) = CERT_create( CA => 1); for my $test (@tests) { SKIP: { my ($expect_match,$hostname,$cn,$san_dns,$san_ip) = @$test; my (@san,$ip6); push @san, map { [ "DNS", $_ ] } $san_dns =~m{([^,\s]+)}g if $san_dns; for( ($san_ip||'') =~m{([^,\s]+)}g ) { if ( my @h = m{^x(.{4})(.{4})(.{4})(.{4})(.{4})(.{4})(.{4})(.{4})$}) { $_ = join(':',@h); $ip6 = 1; } push @san, [ "IP", $_ ]; } my $idn = $hostname =~m{[^a-zA-Z0-9_.\-]}; my $diag = "$hostname: cn=$cn san=". join(",", map { "$_->[0]:$_->[1]" } @san); $diag =~s{([\\\x00-\x1f\x7f-\xff])}{ sprintf("\\x%02x",ord($1)) }esg; if ($ip6 && !IO::Socket::SSL->can_ipv6) { skip "no IPv6 support - $diag",1; } if ($idn && ! eval { IO::Socket::SSL::idn_to_ascii("fo") }) { skip "no IDNA library installed - $diag",1 } my %cert = ( subject => length($cn) ? { CN => $cn }:{}, @san ? ( subjectAltNames => \@san ):(), issuer_cert => $ca, issuer_key => $key, key => $key ); my $cert; eval { ($cert) = CERT_create(%cert) }; if ($@) { skip "failed to create cert: $diag\n$@",1 } #diag($diag); my $match = IO::Socket::SSL::verify_hostname_of_cert($hostname,$cert,'www')||0; if ( $match == $expect_match ) { pass("$expect_match|$diag"); } else { fail("$match != $expect_match |$diag"); #warn PEM_cert2string($cert); } CERT_free($cert); } } # based on # https://raw.githubusercontent.com/adobe/chromium/master/net/base/x509_certificate_unittest.cc # 16.5.2014 # # format: [ expect_match, hostname, CN, san_dns, san_ip ] sub tests {( [ 1, 'foo.com', 'foo.com' ], [ 1, 'f', 'f' ], [ 0, 'h', 'i' ], [ 1, 'bar.foo.com', '*.foo.com' ], [ 1, 'www.test.fr', 'common.name', '*.test.com,*.test.co.uk,*.test.de,*.test.fr' ], $libressl ? (): ([ 1, 'wwW.tESt.fr', 'common.name', ',*.*,*.test.de,*.test.FR,www' ]), [ 0, 'f.uk', '.uk' ], [ 0, 'w.bar.foo.com', '?.bar.foo.com' ], [ 0, 'www.foo.com', '(www|ftp).foo.com' ], [ 0, 'www.foo.com', "www.foo.com\0" ], # CERT_create just strips everything after \0 so we get not the expected # certificate and thus cannot run this test # [ 0, 'www.foo.com', '', "www.foo.com\0*.foo.com,\0,\0" ], [ 0, 'www.house.example', 'ww.house.example' ], [ 0, 'test.org', '', 'www.test.org,*.test.org,*.org' ], [ 0, 'w.bar.foo.com', 'w*.bar.foo.com' ], [ 0, 'www.bar.foo.com', 'ww*ww.bar.foo.com' ], [ 0, 'wwww.bar.foo.com', 'ww*ww.bar.foo.com' ], [ 1, 'wwww.bar.foo.com', 'w*w.bar.foo.com' ], [ 0, 'wwww.bar.foo.com', 'w*w.bar.foo.c0m' ], [ 1, 'WALLY.bar.foo.com', 'wa*.bar.foo.com' ], [ 1, 'wally.bar.foo.com', '*Ly.bar.foo.com' ], # disabled test: we don't accept URL encoded hostnames # [ 1, 'ww%57.foo.com', '', 'www.foo.com' ], # disabled test: & is not allowed in hostname - and CN should not # allow URL encoding # [ 1, 'www&.foo.com', 'www%26.foo.com' ], # Common name must not be used if subject alternative name was provided. [ 0, 'www.test.co.jp', 'www.test.co.jp', '*.test.de,*.jp,www.test.co.uk,www.*.co.jp' ], $libressl ? ():([ 0, 'www.bar.foo.com', 'www.bar.foo.com', '*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com,' ]), # I think they got this test wrong # common name should not be checked only if SAN contains DNS names # so in this case common name should be checked -> match # corrected test therefore # [ 0, 'www.bath.org', 'www.bath.org', '', '20.30.40.50' ], [ 1, 'www.bath.org', 'www.bath.org', '', '20.30.40.50' ], [ 0, '66.77.88.99', 'www.bath.org', 'www.bath.org' ], # IDN tests [ 1, 'xn--poema-9qae5a.com.br', 'xn--poema-9qae5a.com.br' ], [ 1, 'www.xn--poema-9qae5a.com.br', '*.xn--poema-9qae5a.com.br' ], $libressl? ():([ 0, 'xn--poema-9qae5a.com.br', '', '*.xn--poema-9qae5a.com.br,xn--poema-*.com.br,xn--*-9qae5a.com.br,*--poema-9qae5a.com.br' ]), # There should be no *.com.br certificates and public suffix catches this. # So this example is bad and we change it to .foo.com.br # [ 1, 'xn--poema-9qae5a.com.br', '*.com.br' ], [ 1, 'xn--poema-9qae5a.foo.com.br', '*.foo.com.br' ], # The following are adapted from the examples quoted from # http://tools.ietf.org/html/rfc6125#section-6.4.3 # (e.g., *.example.com would match foo.example.com but # not bar.foo.example.com or example.com). [ 1, 'foo.example.com', '*.example.com' ], [ 0, 'bar.foo.example.com', '*.example.com' ], [ 0, 'example.com', '*.example.com' ], # (e.g., baz*.example.net and *baz.example.net and b*z.example.net would # be taken to match baz1.example.net and foobaz.example.net and # buzz.example.net, respectively) [ 1, 'baz1.example.net', 'baz*.example.net' ], [ 1, 'foobaz.example.net', '*baz.example.net' ], [ 1, 'buzz.example.net', 'b*z.example.net' ], # Wildcards should not be valid unless there are at least three name # components. # There should be no *.co.uk certificates and public suffix catches this. # So change example to *.foo.com instead # [ 1, 'h.co.uk', '*.co.uk' ], [ 1, 'h.foo.com', '*.foo.com' ], [ 0, 'foo.com', '*.com' ], [ 0, 'foo.us', '*.us' ], [ 0, 'foo', '*' ], # Multiple wildcards are not valid. [ 0, 'foo.example.com', '*.*.com' ], [ 0, 'foo.bar.example.com', '*.bar.*.com' ], # Absolute vs relative DNS name tests. Although not explicitly specified # in RFC 6125, absolute reference names (those ending in a .) should # match either absolute or relative presented names. [ 1, 'foo.com', 'foo.com.' ], [ 1, 'foo.com.', 'foo.com' ], [ 1, 'foo.com.', 'foo.com.' ], [ 1, 'f', 'f.' ], [ 1, 'f.', 'f' ], [ 1, 'f.', 'f.' ], [ 1, 'www-3.bar.foo.com', '*.bar.foo.com.' ], [ 1, 'www-3.bar.foo.com.', '*.bar.foo.com' ], [ 1, 'www-3.bar.foo.com.', '*.bar.foo.com.' ], [ 0, '.', '.' ], [ 0, 'example.com', '*.com.' ], [ 0, 'example.com.', '*.com' ], [ 0, 'example.com.', '*.com.' ], [ 0, 'foo.', '*.' ], # IP addresses in common name; IPv4 only. [ 1, '127.0.0.1', '127.0.0.1' ], [ 1, '192.168.1.1', '192.168.1.1' ], # we expect proper IP and not this junk, so we will not allow these # [ 1, '676768', '0.10.83.160' ], # [ 1, '1.2.3', '1.2.0.3' ], [ 0, '192.169.1.1', '192.168.1.1' ], [ 0, '12.19.1.1', '12.19.1.1/255.255.255.0' ], [ 0, 'FEDC:ba98:7654:3210:FEDC:BA98:7654:3210', 'FEDC:BA98:7654:3210:FEDC:ba98:7654:3210' ], [ 0, '1111:2222:3333:4444:5555:6666:7777:8888', '1111:2222:3333:4444:5555:6666:7777:8888' ], [ 0, '::192.9.5.5', '[::192.9.5.5]' ], # No wildcard matching in valid IP addresses [ 0, '::192.9.5.5', '*.9.5.5' ], [ 0, '2010:836B:4179::836B:4179', '*:836B:4179::836B:4179' ], [ 0, '192.168.1.11', '*.168.1.11' ], [ 0, 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', '*.]' ], # IP addresses in subject alternative name (common name ignored) [ 1, '10.1.2.3', '', '', '10.1.2.3' ], # we expect proper IP and not this junk, so we will not allow this # [ 1, '14.15', '', '', '14.0.0.15' ], # according to RFC2818 common name should be checked if no DNS entries in SAN # so this must match if we match IP in common name -> changed expected result # [ 0, '10.1.2.7', '10.1.2.7', '', '10.1.2.6,10.1.2.8' ], [ 1, '10.1.2.7', '10.1.2.7', '', '10.1.2.6,10.1.2.8' ], [ 0, '10.1.2.8', '10.20.2.8', 'foo' ], [ 1, '::4.5.6.7', '', '', 'x00000000000000000000000004050607' ], [ 0, '::6.7.8.9', '::6.7.8.9', '::6.7.8.9', 'x00000000000000000000000006070808,x0000000000000000000000000607080a,xff000000000000000000000006070809,6.7.8.9' ], [ 1, 'FE80::200:f8ff:fe21:67cf', 'no.common.name', '', 'x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,xff0000000000000000000000060708ff,10.0.0.1' ], # Numeric only hostnames (none of these are considered valid IP addresses). [ 0, '12345.6', '12345.6' ], $libressl? ():([ 0, '121.2.3.512', '', '1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512', '121.2.3.0']), [ 0, '1.2.3.4.5.6', '*.2.3.4.5.6' ], # IP address should not be matched against SAN DNS entry -> skip test # [ 1, '1.2.3.4.5', '', '1.2.3.4.5' ], # Invalid host names. # this cert cannot be created currently # [ 0, "junk)()\$*!\@~\0", "junk)()\$*!\@~\0" ], [ 0, 'www.*.com', 'www.*.com' ], [ 0, 'w$w.f.com', 'w$w.f.com' ], [ 0, 'nocolonallowed:example', '', 'nocolonallowed:example' ], [ 0, 'www-1.[::FFFF:129.144.52.38]', '*.[::FFFF:129.144.52.38]' ], [ 0, '[::4.5.6.9]', '', '', 'x00000000000000000000000004050609' ], )} IO-Socket-SSL-2.085/t/core.t0000755000175000017500000002013714541232615015163 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/core.t' use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use Errno qw( EWOULDBLOCK EAGAIN ); do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; use Test::More; Test::More->builder->use_numbers(0); Test::More->builder->no_ending(1); my $CAN_NONBLOCK = eval "use 5.006; use IO::Select; 1"; my $CAN_PEEK = &Net::SSLeay::OPENSSL_VERSION_NUMBER >= 0x0090601f; my $numtests = 40; $numtests+=5 if $CAN_NONBLOCK; $numtests+=3 if $CAN_PEEK; plan tests => $numtests; # We need to detect the best TLS version supported by the server since we can # not offer SSLv23 for for a reliable SSL_error_trap because of how the old # SSLv2 compatible works. On the other side we can no longer rely on all systems # supporting TLS 1.0 either. my $tls_version; for(qw(TLSv1_2 TLSv1_1 TLSv1)) { my $method = sprintf("Net::SSLeay::CTX_%s_new",lc($_)); next if ! defined &$method; $tls_version = $_; last; } die "no TLS support" if ! $tls_version; my $error_trapped = 0; my $localip = '127.0.0.1'; my $server = IO::Socket::SSL->new( LocalAddr => $localip, LocalPort => 0, Listen => 2, Timeout => 30, ReuseAddr => 1, SSL_verify_mode => 0x00, SSL_ca_file => "t/certs/test-ca.pem", SSL_version => $tls_version, SSL_error_trap => sub { my $self = shift; print $self "This server is SSL only"; $error_trapped = 1; $self->close; }, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.enc", SSL_passwd_cb => sub { return "bluebell" }, ); ok( $server, "Server Initialization"); $server or exit; ok( fileno( $server), "Server Fileno Check"); my $saddr = $localip.':'.$server->sockport; unless (fork) { close $server; my $client = IO::Socket::INET->new( PeerAddr => $saddr, LocalAddr => $localip, ); print $client "Test\n"; like( <$client>, qr/This server is SSL only/, "Client non-SSL connection"); close $client; $client = IO::Socket::SSL->new( PeerAddr => $saddr, LocalAddr => $localip, Domain => AF_INET, SSL_verify_mode => 0x01, SSL_ca_file => "t/certs/test-ca.pem", SSL_use_cert => 1, SSL_cert_file => "t/certs/client-cert.pem", SSL_key_file => "t/certs/client-key.enc", SSL_passwd_cb => sub { return "opossum" }, SSL_verify_callback => \&verify_sub, ); sub verify_sub { my ($ok, $ctx_store, $cert, $error) = @_; $ok && $ctx_store && $cert && !$error or do { fail("client failure in verify_sub"); exit; }; like( $cert, qr/IO::Socket::SSL Demo CA/, "Client Verify-sub Check"); return 1; } $client || (print("not ok #client failure\n") && exit); ok( $client, "Client Initialization"); $client->fileno() || print "not "; ok( $client->fileno(), "Client Fileno Check"); # $client->untaint() if ($HAVE_SCALAR_UTIL); # In the future... ok( $client->dump_peer_certificate(), "Client Peer Certificate Check"); ok( $client->peer_certificate("issuer"), "Client Peer Certificate Issuer Check"); ok( $client->get_cipher(), "Client Cipher Check"); $client->syswrite('00waaaanf00', 7, 2); if ($CAN_PEEK) { my $buffer; $client->read($buffer,2); is( $buffer, "ok", "Client Peek Check"); } $client->print("Test\n"); $client->printf("\$%.2f\n%d\n%c\n%s", 1.0444442342, 4.0, ord("y"), "Test\nBeaver\nBeaver\n"); my $buffer="\0\0aaaaaaaaaaaaaaaaaaaa"; $client->sysread($buffer, 7, 2); is( $buffer, "\0\0waaaanf", "Client Sysread Check"); ## The future... # if ($HAVE_SCALAR_UTIL) { # print "not " if (is_tainted($buffer)); # &ok("client"); # } my @array = $client->getline(); is( $array[0], "Test\n", "Client Getline Check"); is( $client->getc, "\$", "Client Getc Check"); @array = $client->getlines; is( scalar @array, 6, "Client Getlines Check 1"); is( $array[0], "1.04\n", "Client Getlines Check 2"); is( $array[1], "4\n", "Client Getlines Check 3"); is( $array[2], "y\n", "Client Getlines Check 4"); is( join("", @array[3..5]), "Test\nBeaver\nBeaver\n", "Client Getlines Check 5"); ok( !<$client>, "Client Finished Reading Check"); $client->close(SSL_no_shutdown => 1); my $client_2 = IO::Socket::INET->new( PeerAddr => $saddr, LocalAddr => $localip ); ok( $client_2, "Second Client Initialization"); $client_2 = IO::Socket::SSL->new_from_fd($client_2->fileno, '+<>', SSL_reuse_ctx => $client); ok( $client_2, "Client Init from Fileno Check"); $buffer = <$client_2>; is( $buffer, "Boojums\n", "Client (fileno) Readline Check"); $client_2->close(SSL_ctx_free => 1); if ($CAN_NONBLOCK) { my $client_3 = IO::Socket::SSL->new( PeerAddr => $saddr, LocalAddr => $localip, Domain => AF_INET, SSL_verify_mode => 0x01, SSL_ca_file => "t/certs/test-ca.pem", SSL_use_cert => 1, SSL_cert_file => "t/certs/client-cert.pem", SSL_key_file => "t/certs/client-key.enc", SSL_passwd_cb => sub { return "opossum" }, Blocking => 0, ); ok( $client_3, "Client Nonblocking Check 1"); close $client_3; my $client_4 = IO::Socket::SSL->new( PeerAddr => $saddr, LocalAddr => $localip, Domain => AF_INET, SSL_reuse_ctx => $client_3, Blocking => 0 ); ok( $client_4, "Client Nonblocking Check 2"); $client_3->close(SSL_ctx_free => 1); } exit(0); } my $client = $server->accept; ok( $error_trapped, "Server non-SSL Client Check"); if ($client && $client->opened) { fail("client stayed alive"); exit; } ok( !$client, "Server Kill-client Check"); ($client, my $peer) = $server->accept; ok( $client, "Server Client Accept Check"); $client or exit; ok( $peer, "Accept returning peer address check."); ok( fileno($client), "Server Client Fileno Check"); my $buffer; if ($CAN_PEEK) { $client->peek($buffer, 7, 2); is( $buffer, "\0\0waaaanf","Server Peek Check"); is( $client->pending(), 7, "Server Pending Check"); print $client "ok"; } sysread($client, $buffer, 7, 2); is( $buffer, "\0\0waaaanf", "Server Sysread Check"); my @array = scalar <$client>; is( $array[0], "Test\n", "Server Getline Check"); is( getc($client), "\$", "Server Getc Check"); @array = map { scalar <$client> } (0..5); is( scalar @array, 6, "Server Getlines Check 1"); is( $array[0], "1.04\n", "Server Getlines Check 2"); is( $array[1], "4\n", "Server Getlines Check 3"); is( $array[2], "y\n", "Server Getlines Check 4"); is( join("", @array[3..5]), "Test\nBeaver\nBeaver\n", "Server Getlines Check 5"); syswrite($client, '00waaaanf00', 7, 2); print($client "Test\n"); printf $client "\$%.2f\n%d\n%c\n%s", (1.0444442342, 4.0, ord("y"), "Test\nBeaver\nBeaver\n"); close $client; ($client, $peer) = $server->accept or do { fail("client creation failed"); exit; }; is( inet_ntoa((unpack_sockaddr_in($peer))[1]), $localip, "Peer address check"); if ($CAN_NONBLOCK) { $client->blocking(0); $client->read($buffer, 20, 0); is( $SSL_ERROR, SSL_WANT_READ, "Server Nonblocking Check 1"); } ok( $client->opened, "Server Client Opened Check 1"); print $client "Boojums\n"; close($client); ${*$client}{'_SSL_opened'} = 1; ok( !$client->opened, "Server Client Opened Check 2"); ${*$client}{'_SSL_opened'} = 0; if ($CAN_NONBLOCK) { $client = $server->accept; ok( $client->opened, "Server Nonblocking Check 2"); close $client; $server->blocking(0); IO::Select->new($server)->can_read(30); $client = $server->accept; while ( ! $client ) { #DEBUG( "$!,$SSL_ERROR" ); if ( $! == EWOULDBLOCK || $! == EAGAIN ) { if ( $SSL_ERROR == SSL_WANT_WRITE ) { IO::Select->new( $server->opening )->can_write(30); } else { IO::Select->new( $server->opening )->can_read(30); } } else { last } $client = $server->accept; } ok( $client->opened, "Server Nonblocking Check 3"); close $client; } $server->close(SSL_ctx_free => 1); wait; ## The future.... #sub is_tainted { # my $arg = shift; # my $nada = substr($arg, 0, 0); # local $@; # eval {eval "# $nada"}; # return length($@); #} IO-Socket-SSL-2.085/t/io-socket-ip.t0000644000175000017500000000436314521466373016546 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/dhe.t' # make sure IO::Socket::INET6 will not be used BEGIN { $INC{'IO/Socket/INET6.pm'} = undef } use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; # check if we have loaded IO::Socket::IP, IO::Socket::SSL should do it by # itself if it is available unless( IO::Socket::SSL->CAN_IPV6 eq "IO::Socket::IP" ) { # not available or IO::Socket::SSL forgot to load it if ( ! eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.31) }) { print "1..0 # Skipped: usable IO::Socket::IP is not available\n"; } elsif (! defined &IO::Socket::SSL::_getnameinfo) { print "1..0 # Skipped: no IPv6 support despite IO::Socket::IP\n"; } else { print "1..1\nnot ok # automatic use of IO::Socket::IP\n"; } exit } my $addr = '::1'; # check if we can use ::1, e.g. if the computer has IPv6 enabled if ( ! IO::Socket::IP->new( Listen => 10, LocalAddr => $addr, )) { print "1..0 # no IPv6 enabled on this computer\n"; exit } $|=1; print "1..3\n"; print "# IO::Socket::IP version=$IO::Socket::IP::VERSION\n"; # first create simple ssl-server my $ID = 'server'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", ) || do { notok($!); exit }; ok("Server Initialization at $addr"); # add server port to addr $addr = "[$addr]:".$server->sockport; print "# server at $addr\n"; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( !$pid ) { ###### Client $ID = 'client'; close($server); my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, SSL_verify_mode => 0 ) || do { notok( "connect failed: ".IO::Socket::SSL->errstr() ); exit }; ok( "client connected" ); } else { ###### Server my $to_client = $server->accept || do { notok( "accept failed: ".$server->errstr() ); kill(9,$pid); exit; }; ok( "Server accepted" ); wait; } sub ok { print "ok # [$ID] @_\n"; } sub notok { print "not ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/npn.t0000644000175000017500000000365014521466373015034 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/dhe.t' use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; # check if we have NPN available # if it is available if ( ! IO::Socket::SSL->can_npn ) { print "1..0 # Skipped: NPN not available in Net::SSLeay\n"; exit } $|=1; print "1..5\n"; # first create simple ssl-server my $ID = 'server'; my $addr = '127.0.0.1'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, SSL_version => 'SSLv23:!TLSv1_3', # NPN does not exist in TLSv1.3 # https://github.com/openssl/openssl/issues/3665 SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', SSL_npn_protocols => [qw(one two)], ) || do { ok(0,$!); exit }; ok(1,"Server Initialization at $addr"); # add server port to addr $addr = "$addr:".$server->sockport; print "# server at $addr\n"; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( !$pid ) { ###### Client $ID = 'client'; close($server); my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, Domain => AF_INET, SSL_verify_mode => 0, SSL_npn_protocols => [qw(two three)], ) or do { ok(0, "connect failed: ".IO::Socket::SSL->errstr() ); exit }; ok(1,"client connected" ); my $proto = $to_server->next_proto_negotiated; ok($proto eq 'two',"negotiated $proto"); } else { ###### Server my $to_client = $server->accept or do { ok(0,"accept failed: ".$server->errstr() ); kill(9,$pid); exit; }; ok(1,"Server accepted" ); my $proto = $to_client->next_proto_negotiated; ok($proto eq 'two',"negotiated $proto"); wait; } sub ok { my $ok = shift; print $ok ? '' : 'not ', "ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/sni_verify.t0000644000175000017500000000513114521466373016412 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; if ( ! IO::Socket::SSL->can_server_sni() ) { print "1..0 # skipped because no server side SNI support - openssl/Net::SSleay too old\n"; exit; } if ( ! IO::Socket::SSL->can_client_sni() ) { print "1..0 # skipped because no client side SNI support - openssl/Net::SSleay too old\n"; exit; } print "1..17\n"; my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', Listen => 2, ReuseAddr => 1, SSL_server => 1, SSL_ca_file => "t/certs/test-ca.pem", SSL_cert_file => { 'server.local' => 't/certs/server-cert.pem', 'server2.local' => 't/certs/server2-cert.pem', 'smtp.mydomain.local' => "t/certs/server-wildcard.pem", '' => "t/certs/server-wildcard.pem", }, SSL_key_file => { 'server.local' => 't/certs/server-key.pem', 'server2.local' => 't/certs/server2-key.pem', 'smtp.mydomain.local' => "t/certs/server-wildcard.pem", '' => "t/certs/server-wildcard.pem", }, SSL_verify_mode => 1 ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; print "ok # Server Initialization\n"; my $saddr = $server->sockhost.':'.$server->sockport; # www13.other.local should match default '' # all other should match the specific entries my @tests = qw( server.local server2.local smtp.mydomain.local www13.other.local ); defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); for my $host (@tests) { my $client = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 1, SSL_hostname => $host, SSL_ca_file => 't/certs/test-ca.pem', SSL_cert_file => 't/certs/client-cert.pem', SSL_key_file => 't/certs/client-key.pem', ); if ($client) { print "ok # client ssl connect $host\n"; $client->verify_hostname($host,'http') or print "not "; print "ok # client verify hostname in cert $host\n"; # wait for server to send something to make sure finished accept <$client>; } else { print "not ok # client ssl connect $host - $SSL_ERROR\n"; print "ok # skip connect failed\n"; } } exit; } for my $host (@tests) { my $csock = $server->accept; if ($csock) { print "ok # server accept\n"; my $name = $csock->get_servername; print "not " if ! $name or $name ne $host; print "ok # server got SNI name $host\n"; print $csock "hi\n"; } else { print "not ok # server accept - $SSL_ERROR\n"; print "ok # skip accept failed\n"; } } wait; IO-Socket-SSL-2.085/t/memleak_bad_handshake.t0000644000175000017500000000434314521466373020470 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/nonblock.t' use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use IO::Select; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; my $getsize; if ( -f "/proc/$$/statm" ) { $getsize = sub { my $pid = shift; open( my $fh,'<', "/proc/$pid/statm"); my $line = <$fh>; return (split(' ',$line))[0] * 4; }; } elsif ( ! grep { $^O =~m{$_}i } qw( MacOS VOS vmesa riscos amigaos mswin32) ) { $getsize = sub { my $pid = shift; open( my $ps,'-|',"ps -o vsize -p $pid 2>/dev/null" ) or return; $ps && <$ps> or return; # header return int(<$ps>); # size }; } else { print "1..0 # Skipped: ps not implemented on this platform\n"; exit } if ( $^O =~m{aix}i ) { print "1..0 # Skipped: might hang, see https://rt.cpan.org/Ticket/Display.html?id=72170\n"; exit } $|=1; if ( ! $getsize->($$) ) { print "1..0 # Skipped: no usable ps\n"; exit; } my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 200, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', ); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork()) or die "fork failed: $!"; if ( $pid == 0 ) { # server while (1) { # socket accept, client handshake and client close $server->accept; } exit(0); } close($server); # plain non-SSL connect and close w/o sending data for(1..100) { IO::Socket::INET->new( $saddr ) or next; } my $size100 = $getsize->($pid); if ( ! $size100 ) { print "1..0 # Skipped: cannot get size of child process\n"; goto done; } for(100..200) { IO::Socket::INET->new( $saddr ) or next; } my $size200 = $getsize->($pid); for(200..300) { IO::Socket::INET->new( $saddr ) or next; } my $size300 = $getsize->($pid); if ($size100>$size200 or $size200<$size300) {; print "1..0 # skipped - do we measure the right thing?\n"; goto done; } print "1..1\n"; print "not " if $size100 < $size200 and $size200 < $size300; print "ok # check memleak failed handshake ($size100,$size200,$size300)\n"; done: kill(9,$pid); wait; exit; IO-Socket-SSL-2.085/t/protocol_version.t0000644000175000017500000001046114521466373017645 0ustar steffensteffen#!perl use strict; use warnings; use Test::More; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; plan skip_all => "Test::More has no done_testing" if !defined &done_testing; $|=1; my $XDEBUG = 0; my @versions = qw(SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3); my %server_args = ( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, SSL_server => 1, SSL_startHandshake => 0, SSL_version => 'SSLv23', # allow SSLv3 too SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', ); my %cipher_args = ( SSL_cipher_list => 'DEFAULT:@SECLEVEL=0', ); my $server = IO::Socket::SSL->new( %server_args, %cipher_args, ); if (!$server && $SSL_ERROR) { # likely SECLEVEL not supported diag("$SSL_ERROR - assuming SECLEVEL not supported"); %cipher_args = (SSL_cipher_list => 'DEFAULT'); $server = IO::Socket::SSL->new( %server_args, %cipher_args, ); } $server or BAIL_OUT("cannot listen on localhost: $!"); print "not ok\n", exit if !$server; my $saddr = $server->sockhost().':'.$server->sockport(); $XDEBUG && diag("server at $saddr"); defined( my $pid = fork() ) or BAIL_OUT("fork failed: $!"); if ($pid == 0) { close($server); my $check = sub { my ($ver,$expect) = @_; $XDEBUG && diag("try $ver, expect $expect"); # Hoping that this isn't necessary, but just in case we get a TCP # failure rather than SSL failure, wiping the previous value here # seems like it might be a useful precaution: $SSL_ERROR = ''; my $cl = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_startHandshake => 0, SSL_verify_mode => 0, SSL_version => $ver, %cipher_args, ) or do { # Might bail out before the starttls if we provide a known-unsupported # version, for example SSLv3 on openssl 1.0.2+ if($SSL_ERROR =~ /$ver not supported|null ssl method passed/) { $XDEBUG && diag("SSL connect failed with $ver: $SSL_ERROR"); return; } die "connection with $ver failed: $! (SSL error: $SSL_ERROR)"; }; $XDEBUG && diag("TCP connected"); print $cl "starttls $ver $expect\n"; <$cl>; if (!$cl->connect_SSL) { $XDEBUG && diag("SSL upgrade failed with $ver: $SSL_ERROR"); return; } $XDEBUG && diag("SSL connect done"); return $cl->get_sslversion(); }; my $stop = sub { my $cl = IO::Socket::INET->new($saddr) or return; print $cl "quit\n"; }; # find out the best protocol version the server can my %supported; my $ver = $check->('SSLv23','') or die "connect to server failed: $!"; $XDEBUG && diag("best protocol version: $ver"); for (@versions, 'foo') { $supported{$_} = 1; $ver eq $_ and last; } die "best protocol version server supports is $ver" if $supported{foo}; # Check if the OpenSSL was compiled without support for specific protocols for(qw(SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3)) { if ( ! $check->($_,'')) { diag("looks like OpenSSL was compiled without $_ support"); delete $supported{$_}; } } for my $ver (@versions) { next if ! $supported{$ver}; # requesting only this version should be done with this version $check->($ver,$ver); # requesting SSLv23 and disallowing anything better should give $ver too my $sslver = "SSLv23"; for(reverse grep { $supported{$_} } @versions) { last if $_ eq $ver; $sslver .= ":!$_"; } $check->($sslver,$ver); } $stop->(); exit(0); } vec( my $vs = '',fileno($server),1) = 1; while (select( my $rvs = $vs,undef,undef,15 )) { $XDEBUG && diag("got read event"); my $cl = $server->accept or do { $XDEBUG && diag("accept failed: $!"); next; }; $XDEBUG && diag("TCP accept done"); my $cmd = <$cl>; $XDEBUG && diag("got command $cmd"); my ($ver,$expect) = $cmd =~m{^starttls (\S+) (\S*)} or do { $XDEBUG && diag("finish"); done_testing() if $cmd =~m/^quit/; last; }; print $cl "ok\n"; $cl->accept_SSL() or do { $XDEBUG && diag("accept_SSL failed: $SSL_ERROR"); if ($expect) { fail("accept $ver"); } else { diag("failed to accept $ver"); } next; }; $XDEBUG && diag("SSL accept done"); if ($expect) { is($cl->get_sslversion,$expect,"accept $ver with $expect"); } else { pass("accept $ver with any, got ".$cl->get_sslversion); } close($cl); } wait; IO-Socket-SSL-2.085/t/nonblock.t0000644000175000017500000002566414521466373016057 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/nonblock.t' use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use IO::Select; use Errno qw( EWOULDBLOCK EAGAIN EINPROGRESS); do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; if ( ! eval "use 5.006; use IO::Select; return 1" ) { print "1..0 # Skipped: no support for nonblocking sockets\n"; exit; } $|=1; print "1..27\n"; my $START = time(); # first create simple non-blocking tcp-server my $ID = 'server'; my $server = IO::Socket::INET->new( Blocking => 0, LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ); print "not ok: $!\n", exit if !$server; # Address in use? ok("Server Initialization"); my $saddr = $server->sockhost.':'.$server->sockport; my $ssock = $server->sockname; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { ############################################################ # CLIENT == child process ############################################################ close($server); $ID = 'client'; # fast: try connect_SSL immediately after sending plain text # connect_SSL should fail on the first attempt because server # is not ready yet # slow: wait before calling connect_SSL # connect_SSL should succeed, because server was already waiting for my $test ( 'fast','slow' ) { # initial socket is unconnected, tcp, nonblocking my $to_server = IO::Socket::INET->new( Proto => 'tcp', Blocking => 0 ); # nonblocking connect of tcp socket while (1) { connect($to_server,$ssock ) && last; if ( $!{EINPROGRESS} ) { diag( 'connect in progress' ); IO::Select->new( $to_server )->can_write(30) && next; print "not "; last; } elsif ( $!{EWOULDBLOCK} || $!{EAGAIN} ) { diag( 'connect not yet completed'); # just wait select(undef,undef,undef,0.1); next; } elsif ( $!{EISCONN} ) { diag('claims that socket is already connected'); # found on Mac OS X, dunno why it does not tell me that # the connect succeeded before last; } diag( 'connect failed: '.$! ); print "not "; last; } ok( "client tcp connect" ); # work around (older?) systems where IO::Socket::INET # cannot do non-blocking connect by forcing non-blocking # again (we want to test non-blocking behavior of IO::Socket::SSL, # not IO::Socket::INET) $to_server->blocking(0); # send some plain text on non-ssl socket my $pmsg = 'plaintext'; while ( $pmsg ne '' ) { my $w = syswrite( $to_server,$pmsg ); if ( ! defined $w ) { if ( ! $!{EWOULDBLOCK} && ! $!{EAGAIN} ) { diag("syswrite failed with $!"); print "not "; last; } IO::Select->new($to_server)->can_write(30) or do { diag("failed to get write ready"); print "not "; last; }; } elsif ( $w>0 ) { diag("wrote $w bytes"); substr($pmsg,0,$w,''); } else { die "syswrite returned 0"; } } ok( "write plain text" ); # let server catch up, so that it awaits my connection # so that connect_SSL does not have to wait sleep(5) if ( $test eq 'slow' ); # upgrade to SSL socket w/o connection yet if ( ! IO::Socket::SSL->start_SSL( $to_server, SSL_startHandshake => 0, SSL_verify_mode => 0, SSL_key_file => "t/certs/server-key.enc", SSL_passwd_cb => sub { return "bluebell" }, )) { diag( 'start_SSL return undef' ); print "not "; } elsif ( !UNIVERSAL::isa( $to_server,'IO::Socket::SSL' ) ) { diag( 'failed to upgrade socket' ); print "not "; } ok( "upgrade client to IO::Socket::SSL" ); # SSL handshake thru connect_SSL # if $test eq 'fast' we expect one failed attempt because server # did not call accept_SSL yet my $attempts = 0; while ( 1 ) { $to_server->connect_SSL && last; diag( $SSL_ERROR ); if ( $SSL_ERROR == SSL_WANT_READ ) { $attempts++; IO::Select->new($to_server)->can_read(30) && next; # retry if can read } elsif ( $SSL_ERROR == SSL_WANT_WRITE ) { IO::Select->new($to_server)->can_write(30) && next; # retry if can write } diag( "failed to connect: $@" ); print "not "; last; } ok( "connected" ); if ( $test ne 'slow' ) { print "not " if !$attempts; ok( "nonblocking connect with $attempts attempts" ); } # send some data # we send up to 500000 bytes, server reads first 10 bytes and then sleeps # before reading more. In total server only reads 30000 bytes # the sleep will cause the internal buffers to fill up so that the syswrite # should return with EWOULDBLOCK+SSL_WANT_WRITE. # the socket close should cause EPIPE or ECONNRESET my $msg = "1234567890"; $attempts = 0; my $bytes_send = 0; # set send buffer to 8192 so it will definitely fail writing all 500000 bytes in it # beware that linux allocates twice as much (see tcp(7)) # AIX seems to get very slow if you set the sndbuf on localhost, so don't to it # https://rt.cpan.org/Public/Bug/Display.html?id=72305 if ( $^O !~m/aix/i ) { eval q{ setsockopt( $to_server, SOL_SOCKET, SO_SNDBUF, pack( "I",8192 )); diag( "sndbuf=".unpack( "I",getsockopt( $to_server, SOL_SOCKET, SO_SNDBUF ))); }; } # This test is too much dependant on OS my $test_might_fail = 1; my $can; WRITE: for( my $i=0;$i<50000;$i++ ) { my $offset = 0; my $sel_server = IO::Select->new($to_server); while (1) { if ($can && !$sel_server->$can(15)) { if ( $bytes_send > 30000 ) { diag("fail $can, but limit reached. Assume connection closed"); } else { diag("fail $can"); print "not "; } last WRITE; } my $n = syswrite( $to_server,$msg,length($msg)-$offset,$offset ); if ( !defined($n) ) { diag( "\$!=$! \$SSL_ERROR=$SSL_ERROR send=$bytes_send" ); if ( $! == EWOULDBLOCK || $! == EAGAIN ) { if ( $SSL_ERROR == SSL_WANT_WRITE ) { diag( 'wait for write' ); $can = 'can_write'; $attempts++; } elsif ( $SSL_ERROR == SSL_WANT_READ ) { diag( 'wait for read' ); $can = 'can_read'; } else { $can = 'can_write'; } } elsif ( $bytes_send > 30000 ) { diag( "connection closed" ); last WRITE; } next; } elsif ( $n == 0 ) { diag( "connection closed" ); last WRITE; } elsif ( $n<0 ) { diag( "syswrite returned $n!" ); print "not "; last WRITE; } $bytes_send += $n; if ( $n + $offset == 10 ) { last } else { $offset += $n; diag( "partial write of $n new offset=$offset" ); } } } ok( "syswrite" ); if ( ! $attempts && $test_might_fail ) { ok( "write attempts failed, but OK nevertheless because we know it can fail" ); } else { print "not " if !$attempts; ok( "multiple write attempts" ); } print "not " if $bytes_send < 30000; ok( "30000 bytes send" ); } } else { ############################################################ # SERVER == parent process ############################################################ # pendant to tests in client. Where client is slow (sleep # between plain text sending and connect_SSL) I need to # be fast and where client is fast I need to be slow (sleep # between receiving plain text and accept_SSL) foreach my $test ( 'slow','fast' ) { # accept a connection my $can_read = IO::Select->new( $server )->can_read(30); diag("tcp server socket is ".($can_read? "ready" : "NOT ready")); my $from_client = $server->accept or print "not "; ok( "tcp accept" ); $from_client || do { diag( "failed to tcp accept: $!" ); next; }; # make client non-blocking! $from_client->blocking(0); # read plain text data my $buf = ''; while ( length($buf) <9 ) { sysread( $from_client, $buf,9-length($buf),length($buf) ) && next; die "sysread failed: $!" if $! != EWOULDBLOCK && $! != EAGAIN; IO::Select->new( $from_client )->can_read(30); } $buf eq 'plaintext' || print "not "; ok( "received plain text" ); # upgrade socket to IO::Socket::SSL # no handshake yet if ( ! IO::Socket::SSL->start_SSL( $from_client, SSL_startHandshake => 0, SSL_server => 1, SSL_verify_mode => 0x00, SSL_ca_file => "t/certs/test-ca.pem", SSL_use_cert => 1, SSL_cert_file => "t/certs/client-cert.pem", SSL_key_file => "t/certs/client-key.enc", SSL_passwd_cb => sub { return "opossum" }, )) { diag( 'start_SSL return undef' ); print "not "; } elsif ( !UNIVERSAL::isa( $from_client,'IO::Socket::SSL' ) ) { diag( 'failed to upgrade socket' ); print "not "; } ok( "upgrade to_client to IO::Socket::SSL" ); sleep(5) if $test eq 'slow'; # wait until client calls connect_SSL # SSL handshake thru accept_SSL # if test is 'fast' (e.g. client is 'slow') we expect the first # accept_SSL attempt to fail because client did not call connect_SSL yet my $attempts = 0; while ( 1 ) { $from_client->accept_SSL && last; if ( $SSL_ERROR == SSL_WANT_READ ) { $attempts++; IO::Select->new($from_client)->can_read(30) && next; # retry if can read } elsif ( $SSL_ERROR == SSL_WANT_WRITE ) { $attempts++; IO::Select->new($from_client)->can_write(30) && next; # retry if can write } else { diag( "failed to ssl accept ($test): $@" ); print "not "; last; } } ok( "ssl accept handshake done" ); if ( $test eq 'fast' ) { print "not " if !$attempts; ok( "nonblocking accept_SSL with $attempts attempts" ); } # reading 10 bytes # then sleeping so that buffers from client to server gets # filled up and clients receives EWOULDBLOCK+SSL_WANT_WRITE IO::Select->new( $from_client )->can_read(30); ( sysread( $from_client, $buf,10 ) == 10 ) || print "not "; #diag($buf); ok( "received client message" ); sleep(5); my $bytes_received = 10; # read up to 30000 bytes from client, then close the socket my $can; READ: while ( ( my $diff = 30000 - $bytes_received ) > 0 ) { if ( $can && ! IO::Select->new($from_client)->$can(30)) { diag("failed $can"); print "not "; last READ; } my $n = sysread( $from_client,my $buf,$diff ); if ( !defined($n) ) { diag( "\$!=$! \$SSL_ERROR=$SSL_ERROR" ); if ( $! == EWOULDBLOCK || $! == EAGAIN ) { if ( $SSL_ERROR == SSL_WANT_READ ) { $attempts++; $can = 'can_read'; } elsif ( $SSL_ERROR == SSL_WANT_WRITE ) { $attempts++; $can = 'can_write'; } else { $can = 'can_read'; } } else { print "not "; last READ; } next; } elsif ( $n == 0 ) { diag( "connection closed" ); last READ; } elsif ( $n<0 ) { diag( "sysread returned $n!" ); print "not "; last READ; } $bytes_received += $n; #diag( "read of $n bytes total $bytes_received" ); } diag( "read $bytes_received ($attempts r/w attempts)" ); close($from_client); } # wait until client exits wait; } exit; sub ok { unshift @_, "ok # "; goto &_out } sub diag { unshift @_, "# "; goto &_out } sub _out { my $prefix = shift; printf "%s [%04d.%s:%03d] %s\n", $prefix, time() - $START, $ID, (caller())[2], "@_"; } IO-Socket-SSL-2.085/t/public_suffix_lib_encode_idn.t0000644000175000017500000000017214521466373022074 0ustar steffensteffenuse strict; use warnings; use FindBin; require "$FindBin::Bin/public_suffix_lib.pl"; run_with_lib( 'Net::IDN::Encode' ); IO-Socket-SSL-2.085/t/sni.t0000644000175000017500000000472214521466373015033 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; if ( ! IO::Socket::SSL->can_server_sni() ) { print "1..0 # skipped because no server side SNI support - openssl/Net::SSleay too old\n"; exit; } if ( ! IO::Socket::SSL->can_client_sni() ) { print "1..0 # skipped because no client side SNI support - openssl/Net::SSleay too old\n"; exit; } print "1..17\n"; my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', Listen => 2, ReuseAddr => 1, SSL_server => 1, SSL_ca_file => "t/certs/test-ca.pem", SSL_cert_file => { 'server.local' => 't/certs/server-cert.pem', 'server2.local' => 't/certs/server2-cert.pem', 'smtp.mydomain.local' => "t/certs/server-wildcard.pem", '' => "t/certs/server-wildcard.pem", }, SSL_key_file => { 'server.local' => 't/certs/server-key.pem', 'server2.local' => 't/certs/server2-key.pem', 'smtp.mydomain.local' => "t/certs/server-wildcard.pem", '' => "t/certs/server-wildcard.pem", }, ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; print "ok # Server Initialization\n"; my $saddr = $server->sockhost.':'.$server->sockport; # www13.other.local should match default '' # all other should match the specific entries my @tests = qw( server.local server2.local smtp.mydomain.local www13.other.local ); defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); for my $host (@tests) { my $client = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 1, SSL_hostname => $host, SSL_ca_file => 't/certs/test-ca.pem', ); if ($client) { print "ok # client ssl connect $host\n"; $client->verify_hostname($host,'http') or print "not "; print "ok # client verify hostname in cert $host\n"; # wait for server to send something to make sure finished accept <$client>; } else { print "not ok # client ssl connect $host - $SSL_ERROR\n"; print "ok # skip connect failed\n"; } } exit; } for my $host (@tests) { my $csock = $server->accept; if ($csock) { print "ok # server accept\n"; my $name = $csock->get_servername; print "not " if ! $name or $name ne $host; print "ok # server got SNI name $host\n"; print $csock "hi\n"; } else { print "not ok # server accept - $SSL_ERROR\n"; print "ok # skip accept failed\n"; } } wait; IO-Socket-SSL-2.085/t/sessions.t0000644000175000017500000001003614521466373016103 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/core.t' my $DEBUG = 0; use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; my $numtests = 17; print "1..$numtests\n"; my $what = 'server'; my @servers = map { IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ) } (1..3); if ( grep { !$_ } @servers > 0 ) { print "not ok # Server init\n"; exit; } ok("Server initialization"); my @saddr = map { $_->sockhost.':'.$_->sockport } @servers; defined(my $pid = fork()) or die "fork failed: $!"; if ($pid == 0) { server(); exit(0); } client(); wait; sub client { $what = 'client'; @servers = (); my $ctx = IO::Socket::SSL::SSL_Context->new( SSL_ca_file => "t/certs/test-ca.pem", # make cache large enough since we get multiple tickets with TLS 1.3 SSL_session_cache_size => 100, # LibreSSL has currently no support for TLS 1.3 session handling # therefore enforce TLS 1.2 Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER") ? (SSL_version => 'TLSv1_2') : # versions of Net::SSLeay with support for SESSION_up_ref have also the # other functionality needed for proper TLS 1.3 session handling defined(&Net::SSLeay::SESSION_up_ref) ? () : (SSL_version => 'SSLv23:!TLSv1_3:!SSLv3:!SSLv2'), ); my $cache = $ctx->{session_cache} or do { print "not ok \# Context init\n"; exit; }; ok("Context init"); my $dump_cache = $DEBUG ? sub { diag($cache->_dump) } : sub {}; IO::Socket::SSL::set_default_context($ctx); my @clients; push @clients, IO::Socket::SSL->new(PeerAddr => $saddr[0], Domain => AF_INET); push @clients, IO::Socket::SSL->new(PeerAddr => $saddr[1], Domain => AF_INET); my $sock3 = IO::Socket::INET->new($saddr[2]); push @clients, IO::Socket::SSL->start_SSL($sock3); if ( grep { !$_ } @clients >0 ) { print "not ok \# Client init $SSL_ERROR\n"; exit; } ok("Client init, version=".$clients[0]->get_sslversion); for(@clients) { <$_>; # read ping print $_ "pong!\n"; } &$dump_cache; print "not " if $cache->{room} >97; ok(">=3 entries in cache: ". (100- $cache->{room})); for(@saddr) { $cache->{shead}{$_} or print "not "; ok("$_ in cache"); } $cache->{ghead}[1] eq $saddr[2] or print "not "; ok("latest ($saddr[2]) on top of cache"); for (0..2) { # check if current session is cached $cache->get_session($saddr[$_], Net::SSLeay::get_session($clients[$_]->_get_ssl_object)) or print "not "; ok("session in client $_"); close $clients[$_]; } # check if sessions get reused @clients = map { IO::Socket::SSL->new(PeerAddr => $_, Domain => AF_INET) } @saddr; for(@clients) { print "not " if ! $_->get_session_reused; ok("client $_ reused"); <$_>; # read ping print $_ "pong!\n"; } &$dump_cache; } sub server { my @ctx = map { IO::Socket::SSL::SSL_Context->new( SSL_server => 1, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", SSL_ca_file => "t/certs/test-ca.pem", ); } @servers; my @clients; my $accept_all = sub { @clients = map { undef } @servers; for(my $i=0; $i<@servers; $i++) { my $cl = $servers[$i]->accept or next; IO::Socket::SSL->start_SSL($cl, SSL_server => 1, SSL_reuse_ctx => $ctx[$i] ) or next; $clients[$i] = $cl; } }; &$accept_all; if ( grep { !$_ } @clients > 0 ) { print "not ok \# Client init\n"; exit; } ok("Client init"); for(@clients) { print $_ "ping!\n"; <$_>; # read pong } ok("Server send pong, received ping"); close($_) for @clients; &$accept_all; for(@clients) { print $_ "ping!\n"; <$_>; # read pong } ok("Client again init + write + read"); } sub ok { my $line = (caller)[2]; print "ok # [$what]:$line $_[0]\n"; } sub diag { my $msg = shift; $msg =~s{^}{ # [$what] }mg; print STDERR $msg; } IO-Socket-SSL-2.085/t/verify_partial_chain.t0000644000175000017500000000232314521466373020417 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; if (!IO::Socket::SSL->can_partial_chain) { print "1..0 # no support for X509_V_FLAG_PARTIAL_CHAIN\n"; exit(0); } do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..3\n"; my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ReuseAddr => 1, SSL_cert_file => "t/certs/sub-server.pem", SSL_key_file => "t/certs/sub-server.pem", ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; ok("Server Initialization"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); my $client = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_ca_file => "t/certs/test-subca.pem", ) or print "not "; ok( "client ssl connect" ); if ($client) { my $issuer = $client->peer_certificate( 'issuer' ); print "not " if $issuer !~m{IO::Socket::SSL Demo Sub CA}; ok("issuer"); } else { ok("skip issuer check since no client"); } exit; } my $csock = $server->accept; wait; sub ok { print "ok #$_[0]\n"; } IO-Socket-SSL-2.085/t/sysread_write.t0000644000175000017500000000722714521466373017131 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/sysread_write.t' # This tests that sysread/syswrite behave different to read/write, e.g. # that the latter ones are blocking until they read/write everything while # the sys* function also can read/write partial data. use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..9\n"; ################################################################# # create Server socket before forking client, so that it is # guaranteed to be listening ################################################################# # first create simple ssl-server my $ID = 'server'; my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", ); print "not ok: $!\n", exit if !$server; ok("Server Initialization"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { ############################################################ # CLIENT == child process ############################################################ close($server); $ID = 'client'; my $to_server = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_ca_file => "t/certs/test-ca.pem", ) || do { print "not ok: connect failed: $!\n"; exit }; ok( "client connected" ); # write 512 byte, server reads it in 66 byte chunks which # should cause at least the last read to be less then 66 bytes # (and not block). alarm(10); $SIG{ALRM} = sub { print "not ok: timed out\n"; exit; }; #DEBUG( "send 2x512 byte" ); unless ( syswrite( $to_server, 'x' x 512 ) == 512 and syswrite( $to_server, 'x' x 512 ) == 512 ) { print "not ok: write to small: $!\n"; exit; } sysread( $to_server,my $ack,1 ) || print "not "; ok( "received ack" ); alarm(0); ok( "send in time" ); # make a syswrite with a buffer length greater than the # ssl message block size (16k for sslv3). It should send # only a partial packet of 16k my $n = syswrite( $to_server, 'x' x 18000 ); #DEBUG( "send $n bytes" ); print "not " if $n != 16384; ok( "partial write in syswrite" ); # but write should send everything because it does ssl_write_all $n = $to_server->write( 'x' x 18000 ); #DEBUG( "send $n bytes" ); print "not " if $n != 18000; ok( "full write in write ($n)" ); exit; } else { ############################################################ # SERVER == parent process ############################################################ my $to_client = $server->accept || do { print "not ok: accept failed: $!\n"; kill(9,$pid); exit; }; ok( "Server accepted" ); my $total = 1024; my $partial; while ( $total > 0 ) { #DEBUG( "reading 66 of $total bytes pending=".$to_client->pending() ); my $n = sysread( $to_client, my $buf,66 ); #DEBUG( "read $n bytes" ); if ( !$n ) { print "not ok: read failed: $!\n"; kill(9,$pid); exit; } elsif ( $n != 66 ) { $partial++; } $total -= $n; } print "not " if !$partial; ok( "partial read in sysread" ); # send ack back print "not " if !syswrite( $to_client, 'x' ); ok( "send ack back" ); # just read so that the writes will not block $to_client->read( my $buf,18000 ); $to_client->read( $buf,18000 ); # wait until client exits wait; } exit; sub ok { print "ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/dhe.t0000644000175000017500000000267014521466373015002 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/dhe.t' # This tests the use of Diffie Hellman Key Exchange (DHE) use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..3\n"; # first create simple ssl-server my $ID = 'server'; my $addr = '127.0.0.1'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, ReuseAddr => 1, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", SSL_cipher_list => 'DH:!aNULL', # allow only DH ciphers ) || do { notok($!); exit }; ok("Server Initialization"); # add server port to addr $addr.= ':'.(sockaddr_in( getsockname( $server )))[0]; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( !$pid ) { ###### Client $ID = 'client'; close($server); my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, Domain => AF_INET, SSL_verify_mode => 0 ) || do { notok( "connect failed: $SSL_ERROR" ); exit }; ok( "client connected" ); } else { ###### Server my $to_client = $server->accept || do { notok( "accept failed: $SSL_ERROR" ); kill(9,$pid); exit; }; ok( "Server accepted" ); wait; } sub ok { print "ok # [$ID] @_\n"; } sub notok { print "not ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/verify_fingerprint.t0000644000175000017500000000714214521466373020154 0ustar steffensteffenuse strict; use warnings; use Test::More; use IO::Socket::SSL; use IO::Socket::SSL::Utils; use File::Temp 'tempfile'; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; plan tests => 13; my ($ca1,$cakey1) = CERT_create( CA => 1, subject => { CN => 'ca1' }); my ($cert1,$key1) = CERT_create( subject => { CN => 'cert1' }, subjectAltNames => [ [ DNS => 'cert1' ], [ IP => '127.0.0.1' ] ], issuer => [ $ca1,$cakey1 ] ); my ($ca2,$cakey2) = CERT_create( CA => 1, subject => { CN => 'ca2' }); my ($ica2,$icakey2) = CERT_create( CA => 1, subject => { CN => 'ica2' }, issuer => [ $ca2,$cakey2 ] ); my ($cert2,$key2) = CERT_create( subject => { CN => 'cert2' }, subjectAltNames => [ [ DNS => 'cert2' ], [ IP => '127.0.0.1' ] ], issuer => [ $ica2,$icakey2 ] ); my ($saddr1,$fp1) = _server([$cert1],$key1); my ($saddr2,$fp2,$ifp2) = _server([$cert2,$ica2],$key2); my $fp1pub = $fp1->[1]; $_ = $_->[0] for($fp1,$fp2,$ifp2); for my $test ( [ $saddr1, undef, $fp1, "accept fp1 for saddr1", 1 ], [ $saddr1, undef, $fp1pub, "accept fp1 pubkey for saddr1", 1 ], [ $saddr2, undef, $fp2, "accept fp2 for saddr2", 1 ], [ $saddr2, undef, $ifp2, "reject ifp2 for saddr2", 0 ], [ $saddr1, undef, $fp2, "reject fp2 for saddr1", 0 ], [ $saddr2, undef, $fp1, "reject fp1 for saddr2", 0 ], [ $saddr1, undef, [$fp1,$fp2], "accept fp1|fp2 for saddr1", 1 ], [ $saddr2, undef, [$fp1,$fp2], "accept fp1|fp2 for saddr2", 1 ], [ $saddr2, [$ca1], $fp2, "accept fp2 for saddr2 even if ca1 given", 1 ], [ $saddr2, [$ca2], undef, "accept ca2 for saddr2", 1 ], [ $saddr1, [$ca2], undef, "reject ca2 for saddr1", 0 ], [ $saddr1, [$ca1,$ca2], undef, "accept ca[12] for saddr1", 1 ], (defined &Net::SSLeay::X509_V_FLAG_PARTIAL_CHAIN ? [ $saddr1, [$cert1], undef, "accept leaf cert1 as trust anchor for saddr1", 1 ] : [ $saddr1, [$cert1], undef, "reject leaf cert1 as trust anchor for saddr1", 0 ] ) ) { my ($saddr,$certs,$fp,$what,$expect) = @$test; my $cafile; my $cl = IO::Socket::INET->new( $saddr ) or die $!; syswrite($cl,"X",1); my $ok = IO::Socket::SSL->start_SSL($cl, SSL_verify_mode => 1, SSL_fingerprint => $fp, SSL_ca => $certs, SSL_ca_file => undef, SSL_ca_path => undef, ); ok( ($ok?1:0) == ($expect?1:0),$what); } # Notify server children to exit by connecting and disconnecting immediately, # kill only if they will not exit. alarm(10); my @child; END { kill 9,@child } IO::Socket::INET->new($saddr1); IO::Socket::INET->new($saddr2); while ( @child && ( my $pid = waitpid(-1,0))>0 ) { @child = grep { $_ != $pid } @child } sub _server { my ($certs,$key) = @_; my $sock = IO::Socket::INET->new( LocalAddr => '0.0.0.0', Listen => 10 ) or die $!; defined( my $pid = fork()) or die $!; if ( $pid ) { push @child,$pid; my $saddr = '127.0.0.1:'.$sock->sockport; close($sock); return ( $saddr, map { [ 'sha1$'.Net::SSLeay::X509_get_fingerprint($_,'sha1'), 'sha1$pub$'.unpack("H*",Net::SSLeay::X509_pubkey_digest($_, Net::SSLeay::EVP_get_digestbyname('sha1'))) ]} @$certs ); } # The chain certificates will be added without increasing reference counter # and will be destroyed at close of context, so we better have a common # context between all start_SSL. my $ctx = IO::Socket::SSL::SSL_Context->new( SSL_server => 1, SSL_cert => $certs, SSL_key => $key ); while (1) { #local $IO::Socket::SSL::DEBUG=10; my $cl = $sock->accept or next; sysread($cl,my $buf,1) || last; IO::Socket::SSL->start_SSL($cl, SSL_server => 1, SSL_reuse_ctx => $ctx, ); } exit(0); } IO-Socket-SSL-2.085/t/multiple-cert-rsa-ecc.t0000644000175000017500000000631714521466373020345 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use IO::Socket::SSL::Utils; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; if ( ! IO::Socket::SSL->can_server_sni() or ! IO::Socket::SSL->can_client_sni()) { print "1..0 # skipped because no full SNI support - openssl/Net::SSleay too old\n"; exit; } if ( ! IO::Socket::SSL->can_multi_cert() ) { print "1..0 # no support for multiple certificate types\n"; exit; } print "1..12\n"; my %certs = ( SSL_cert_file => { '' => 't/certs/server-cert.pem', '%ecc' => "t/certs/server-ecc-cert.pem", 'server2.local' => 't/certs/server2-cert.pem', }, SSL_key_file => { '' => 't/certs/server-key.pem', '%ecc' => 't/certs/server-ecc-key.pem', 'server2.local' => 't/certs/server2-key.pem', } ); my (%k2fp,%fp2k); Net::SSLeay::SSLeay_add_ssl_algorithms(); my $sha256 = Net::SSLeay::EVP_get_digestbyname('sha256') or die; for (keys %{ $certs{SSL_cert_file} }) { my $cert = PEM_file2cert($certs{SSL_cert_file}{$_}); my $fp = 'sha256$'.unpack('H*',Net::SSLeay::X509_digest($cert, $sha256)); $k2fp{$_} = $fp; $fp2k{$fp} = $_; } my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', Listen => 2, ReuseAddr => 1, SSL_server => 1, SSL_ca_file => "t/certs/test-ca.pem", SSL_honor_cipher_order => 0, SSL_cipher_list => 'ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA', %certs, ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; print "ok # Server Initialization\n"; my $saddr = $server->sockhost.':'.$server->sockport; my @tests = ( [ 'foo.bar', 'ECDHE-ECDSA-AES128-SHA', '%ecc' ], [ 'foo.bar', 'ECDHE-RSA-AES128-SHA', '' ], [ 'foo.bar', 'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA', '' ], [ 'foo.bar', 'ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA', '%ecc' ], [ 'server2.local', 'ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA', 'server2.local' ], [ 'server2.local', 'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA', 'server2.local' ], [ 'server2.local', 'ECDHE-ECDSA-AES128-SHA', 'FAIL' ], [ undef, 'ECDHE-ECDSA-AES128-SHA', '%ecc' ], [ undef, 'ECDHE-RSA-AES128-SHA', '' ], [ undef, 'ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA', '' ], [ undef, 'ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA', '%ecc' ], ); defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); for my $test (@tests) { my ($host,$ciphers,$expect) = @$test; my $what = ($host || ''). " $ciphers | expect='$expect'"; my $client = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 0, SSL_hostname => $host, SSL_ca_file => 't/certs/test-ca.pem', SSL_cipher_list => $ciphers, # don't use TLS 1.3 since the ciphers there don't specifify the # authentication mechanism SSL_version => 'SSLv23:!TLSv1_3', ); my $fp = $client ? $fp2k{$client->get_fingerprint('sha256')} : 'FAIL'; $fp = '???' if ! defined $fp; my $cipher = $client ? $client->get_cipher() : ''; print "not " if $fp ne $expect; print "ok # fingerprint match - $what - got='$fp' -- $cipher\n"; } exit; } for my $host (@tests) { $server->accept or next; } wait; IO-Socket-SSL-2.085/t/startssl.t0000644000175000017500000000724314521466373016122 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use IO::Socket::SSL::Utils; use IO::Select; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..21\n"; my $getfp = do { my (%file2fp); Net::SSLeay::SSLeay_add_ssl_algorithms(); my $sha256 = Net::SSLeay::EVP_get_digestbyname('sha256') or die; sub { my $file = shift; return $file2fp{$file} ||= do { my $cert = PEM_file2cert($file); 'sha256$'.unpack('H*',Net::SSLeay::X509_digest($cert, $sha256)); }; } }; my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ); print "not ok\n", exit if !$server; ok("Server Initialization"); print "not " if (!defined fileno($server)); ok("Server Fileno Check"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { close($server); my $client = IO::Socket::INET->new($saddr) || print "not "; ok( "client tcp connect" ); unless ( IO::Socket::SSL->start_SSL( $client, SSL_verify_mode => 0, SSL_cert_file => "t/certs/client-cert.pem", SSL_key_file => "t/certs/client-key.enc", SSL_passwd_cb => sub { return "opossum" } )) { #DEBUG( $SSL_ERROR ); print "not "; } ok( "sslify client" ); UNIVERSAL::isa( $client,'IO::Socket::SSL' ) || print "not "; ok( 'client reblessed as IO::Socket::SSL' ); $client->sock_certificate('subject') =~ /client\.local/ or print "not "; ok("client local certificate subject"); $client->sock_certificate('issuer') =~ /IO::Socket::SSL Demo CA/ or print "not "; ok("client local certificate issuer"); $client->get_fingerprint('sha256',$client->sock_certificate) eq $getfp->('t/certs/client-cert.pem') or print "not "; ok("client local certificate fingerprint"); $client->peer_certificate('subject') =~ /server\.local/ or print "not "; ok("client peer certificate subject"); $client->peer_certificate('issuer') =~ /IO::Socket::SSL Demo CA/ or print "not "; ok("client peer certificate issuer"); $client->get_fingerprint() eq $getfp->('t/certs/server-cert.pem') or print "not "; ok("client peer certificate fingerprint"); print $client "hannibal\n"; exit; } my $csock = $server->accept || print "not "; ok( "tcp accept" ); IO::Socket::SSL->start_SSL( $csock, SSL_server => 1, SSL_verify_mode => SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, SSL_ca_file => "t/certs/test-ca.pem", SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.enc", SSL_passwd_cb => sub { return "bluebell" }, ) || print "not "; #DEBUG( $IO::Socket::SSL::ERROR ); ok( 'sslify server' ); UNIVERSAL::isa( $csock,'IO::Socket::SSL' ) || print "not "; ok( 'server reblessed as IO::Socket::SSL' ); $csock->sock_certificate('subject') =~ /server\.local/ or print "not "; ok("server local certificate subject"); $csock->sock_certificate('issuer') =~ /IO::Socket::SSL Demo CA/ or print "not "; ok("server local certificate issuer"); $csock->get_fingerprint('sha256',$csock->sock_certificate) eq $getfp->('t/certs/server-cert.pem') or print "not "; ok("server local certificate fingerprint"); $csock->peer_certificate('subject') =~ /client\.local/ or print "not "; ok("server peer certificate subject"); $csock->peer_certificate('issuer') =~ /IO::Socket::SSL Demo CA/ or print "not "; ok("server peer certificate issuer"); $csock->get_fingerprint() eq $getfp->('t/certs/client-cert.pem') or print "not "; ok("server peer certificate fingerprint"); my $l = <$csock>; #DEBUG($l); print "not " if $l ne "hannibal\n"; ok( "received client message" ); wait; sub ok { print "ok #$_[0]\n"; } IO-Socket-SSL-2.085/t/start-stopssl.t0000644000175000017500000000602214521466373017077 0ustar steffensteffen#!perl use strict; use warnings; use IO::Socket::INET; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; my @tests = qw( start stop start close ); print "1..16\n"; my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, ) || die "not ok #tcp listen failed: $!\n"; print "ok #listen\n"; my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; $pid ? server():client(); wait; exit(0); sub client { close($server); my $client = IO::Socket::INET->new($saddr) or die "not ok #client connect: $!\n"; $client->autoflush; print "ok #client connect\n"; for my $test (@tests) { alarm(15); #print STDERR "begin test $test\n"; if ( $test eq 'start' ) { print $client "start\n"; sleep(1); # avoid race condition, if client calls start but server is not yet available #print STDERR ">>$$(client) start\n"; IO::Socket::SSL->start_SSL($client, SSL_verify_mode => 0 ) || die "not ok #client::start_SSL: $SSL_ERROR\n"; #print STDERR "<<$$(client) start\n"; print "ok # client::start_SSL\n"; ref($client) eq "IO::Socket::SSL" or print "not "; print "ok # client::class=".ref($client)."\n"; } elsif ( $test eq 'stop' ) { print $client "stop\n"; $client->stop_SSL || die "not ok #client::stop_SSL\n"; print "ok # client::stop_SSL\n"; ref($client) eq "IO::Socket::INET" or print "not "; print "ok # client::class=".ref($client)."\n"; } elsif ( $test eq 'close' ) { print $client "close\n"; my $class = ref($client); $client->close || die "not ok # client::close\n"; print "ok # client::close\n"; ref($client) eq $class or print "not "; print "ok # client::class=".ref($client)."\n"; last; } #print STDERR "cont test $test\n"; defined( my $line = <$client> ) or return; die "'$line'" if $line ne "OK\n"; } } sub server { my $client = $server->accept || die $!; $client->autoflush; while (1) { alarm(15); defined( my $line = <$client> ) or last; chomp($line); if ( $line eq 'start' ) { #print STDERR ">>$$ start\n"; IO::Socket::SSL->start_SSL( $client, SSL_server => 1, SSL_cert_file => "t/certs/client-cert.pem", SSL_key_file => "t/certs/client-key.pem" ) || die "not ok #server::start_SSL: $SSL_ERROR\n"; #print STDERR "<<$$ start\n"; ref($client) eq "IO::Socket::SSL" or print "not "; print "ok # server::class=".ref($client)."\n"; print $client "OK\n"; } elsif ( $line eq 'stop' ) { $client->stop_SSL || die "not ok #server::stop_SSL\n"; print "ok #server::stop_SSL\n"; ref($client) eq "IO::Socket::INET" or print "not "; print "ok # class=".ref($client)."\n"; print $client "OK\n"; } elsif ( $line eq 'close' ) { my $class = ref($client); $client->close || die "not ok #server::close\n"; print "ok #server::close\n"; ref($client) eq $class or print "not "; print "ok # class=".ref($client)."\n"; last; } } } IO-Socket-SSL-2.085/t/01loadmodule.t0000644000175000017500000000114614521466373016525 0ustar steffensteffenuse strict; use warnings; no warnings 'once'; use Test::More; plan tests => 3; ok( eval { require IO::Socket::SSL },"loaded"); diag( sprintf( "openssl version compiled=0x%0x linked=0x%0x -- %s", Net::SSLeay::OPENSSL_VERSION_NUMBER(), Net::SSLeay::SSLeay(), Net::SSLeay::SSLeay_version(0))); diag( sprintf( "Net::SSLeay version=%s", $Net::SSLeay::VERSION)); diag( sprintf( "parent %s version=%s", $_, $_->VERSION)) for (@IO::Socket::SSL::ISA); IO::Socket::SSL->import(':debug1'); is( $IO::Socket::SSL::DEBUG,1, "IO::Socket::SSL::DEBUG 1"); is( $Net::SSLeay::trace,1, "Net::SSLeay::trace 1"); IO-Socket-SSL-2.085/t/readline.t0000644000175000017500000000731014521466373016021 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/readline.t' # This tests the behavior of readline with the variety of # cases with $/: # $/ undef - read all # $/ '' - read up to next nonempty line: .*?\n\n+ # $/ s - read up to string s # $/ \$num - read $num bytes # scalar context - get first match # array context - get all matches use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; my @tests; push @tests, [ "multi\nple\n\n1234567890line\n\n\n\nbla\n\nblubb\n\nblip", sub { my $c = shift; local $/ = "\n\n"; my $b; ($b=<$c>) eq "multi\nple\n\n" || die "LFLF failed ($b)"; $/ = \"10"; ($b=<$c>) eq "1234567890" || die "\\size failed ($b)"; $/ = ''; ($b=<$c>) eq "line\n\n\n\n" || die "'' failed ($b)"; my @c = <$c>; die "'' @ failed: @c" unless $c[0] eq "bla\n\n" && $c[1] eq "blubb\n\n" && $c[2] eq "blip" && @c == 3; }, ]; push @tests, [ "some\nstring\nwith\nsome\nlines\nwhatever", sub { my $c = shift; local $/ = "\n"; my $b; ($b=<$c>) eq "some\n" || die "LF failed ($b)"; $/ = undef; ($b=<$c>) eq "string\nwith\nsome\nlines\nwhatever" || die "undef failed ($b)"; }, ]; push @tests, [ "some\nstring\nwith\nsome\nlines\nwhatever", sub { my $c = shift; local $/ = "\n"; my @c = <$c>; die "LF @ failed: @c" unless $c[0] eq "some\n" && $c[1] eq "string\n" && $c[2] eq "with\n" && $c[3] eq "some\n" && $c[4] eq "lines\n" && $c[5] eq "whatever" && @c == 6; }, ]; push @tests, [ "some\nstring\nwith\nsome\nlines\nwhatever", sub { my $c = shift; local $/; my @c = <$c>; die "undef @ failed: @c" unless $c[0] eq "some\nstring\nwith\nsome\nlines\nwhatever" && @c == 1; }, ]; push @tests, [ "1234567890", sub { my $c = shift; local $/ = \2; my @c = <$c>; die "\\2 @ failed: @c" unless $c[0] eq '12' && $c[1] eq '34' && $c[2] eq '56' && $c[3] eq '78' && $c[4] eq '90' && @c == 5; }, ]; push @tests, [ [ "bla\n","0","blubb\n","no newline" ], sub { my $c = shift; my $l = <$c>; $l eq "bla\n" or die "'bla\\n' failed"; $l = <$c>; $l eq "0blubb\n" or die "'0blubb\\n' failed"; $l = <$c>; $l eq "no newline" or die "'no newline' failed"; }, ]; $|=1; print "1..".(1+3*@tests)."\n"; # first create simple ssl-server my $ID = 'server'; my $addr = '127.0.0.1'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, ReuseAddr => 1, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", ) || do { notok($!); exit }; ok("Server Initialization"); # add server port to addr $addr.= ':'.(sockaddr_in( getsockname( $server )))[0]; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( $pid ) { ###### Server foreach my $test (@tests) { my $to_client = $server->accept || do { notok( "accept failed: ".$server->errstr() ); kill(9,$pid); exit; }; ok( "Server accepted" ); $to_client->autoflush; my $t = $test->[0]; $t = [$t] if ! ref($t); for(@$t) { $to_client->print($_); select(undef,undef,undef,0.1); } } wait; exit; } $ID = 'client'; close($server); my $testid = "Test00"; foreach my $test (@tests) { my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, Domain => AF_INET, SSL_verify_mode => 0 ) || do { notok( "connect failed: ".IO::Socket::SSL->errstr() ); exit }; ok( "client connected" ); eval { $test->[1]( $to_server ) }; $@ ? notok( "$testid $@" ) : ok( $testid ); $testid++ } sub ok { print "ok # [$ID] @_\n"; } sub notok { print "not ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/public_suffix_lib_uri.t0000644000175000017500000000016414521466373020605 0ustar steffensteffenuse strict; use warnings; use FindBin; require "$FindBin::Bin/public_suffix_lib.pl"; run_with_lib( 'URI::_idna' ); IO-Socket-SSL-2.085/t/mitm.t0000644000175000017500000000544514521466373015213 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; use IO::Socket::SSL::Intercept; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; print "1..8\n"; my @pid; END { kill 9,@pid } my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', Listen => 10, ); ok($server,"server ssl socket"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork ) or die $!; exit( server()) if ! $pid; # child -> server() push @pid,$pid; close($server); my $proxy = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 10, Reuse => 1, ); sys_ok($proxy,"proxy tcp socket"); my $paddr = $proxy->sockhost.':'.$proxy->sockport; defined( $pid = fork ) or die $!; exit( proxy()) if ! $pid; # child -> proxy() push @pid,$pid; close($proxy); # connect to server, check certificate my $cl = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 1, SSL_ca_file => 't/certs/test-ca.pem', ); ssl_ok($cl,"ssl connected to server"); ok( $cl->peer_certificate('subject') =~ m{server\.local}, "subject w/o mitm"); ok( $cl->peer_certificate('issuer') =~ m{IO::Socket::SSL Demo CA}, "issuer w/o mitm"); # connect to proxy, check certificate $cl = IO::Socket::SSL->new( PeerAddr => $paddr, Domain => AF_INET, SSL_verify_mode => 1, SSL_ca_file => 't/certs/proxyca.pem', ); ssl_ok($cl,"ssl connected to proxy"); ok( $cl->peer_certificate('subject') =~ m{server\.local}, "subject w/ mitm"); ok( $cl->peer_certificate('issuer') =~ m{IO::Socket::SSL::Intercept}, "issuer w/ mitm"); sub server { while (1) { my $cl = $server->accept or next; sleep(1); } } sub proxy { my $mitm = IO::Socket::SSL::Intercept->new( proxy_cert_file => 't/certs/proxyca.pem', proxy_key_file => 't/certs/proxyca.pem', ); while (1) { my $toc = $proxy->accept or next; my $tos = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 1, SSL_ca_file => 't/certs/test-ca.pem', ) or die "failed connect to server: $!, $SSL_ERROR"; my ($cert,$key) = $mitm->clone_cert($tos->peer_certificate); $toc = IO::Socket::SSL->start_SSL( $toc, SSL_server => 1, SSL_cert => $cert, SSL_key => $key, ) or die "ssl upgrade client failed: $SSL_ERROR"; sleep(1); } } sub ok { my ($what,$msg) = @_; print "not " if ! $what; print "ok # $msg\n"; } sub sys_ok { my ($what,$msg) = @_; if ( $what ) { print "ok # $msg\n"; } else { print "not ok # $msg - $!\n"; exit } } sub ssl_ok { my ($what,$msg) = @_; if ( $what ) { print "ok # $msg\n"; } else { print "not ok # $msg - $SSL_ERROR\n"; exit } } IO-Socket-SSL-2.085/t/io-socket-inet6.t0000644000175000017500000000463714521466373017167 0ustar steffensteffen#!perl # make sure IO::Socket::IP will not be used BEGIN { if ( eval { require Acme::Override::INET }) { print "1..0 # Skipped: will not work with Acme::Override::INET installed\n"; exit } $INC{'IO/Socket/IP.pm'} = undef } use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; # check first if we have loaded IO::Socket::IP, as if so we won't need or use # IO::Socket::INET6 if( IO::Socket::SSL->CAN_IPV6 eq "IO::Socket::IP" ) { print "1..0 # Skipped: using IO::Socket::IP instead\n"; exit; } # check if we have loaded INET6, IO::Socket::SSL should do it by itself # if it is available unless( IO::Socket::SSL->CAN_IPV6 eq "IO::Socket::INET6" ) { # not available or IO::Socket::SSL forgot to load it if ( ! eval { require IO::Socket::INET6 } ) { print "1..0 # Skipped: no IO::Socket::INET6 available\n"; } elsif ( ! eval { IO::Socket::INET6->VERSION(2.62) } ) { print "1..0 # Skipped: no IO::Socket::INET6 available\n"; } else { print "1..1\nnot ok # automatic use of INET6\n"; } exit } my $addr = '::1'; # check if we can use ::1, e.g. if the computer has IPv6 enabled if ( ! IO::Socket::INET6->new( Listen => 10, LocalAddr => $addr, )) { print "1..0 # no IPv6 enabled on this computer\n"; exit } $|=1; print "1..3\n"; print "# IO::Socket::INET6 version=$IO::Socket::INET6::VERSION\n"; # first create simple ssl-server my $ID = 'server'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, SSL_cert_file => "t/certs/server-cert.pem", SSL_key_file => "t/certs/server-key.pem", ) || do { notok($!); exit }; ok("Server Initialization at $addr"); # add server port to addr $addr = "[$addr]:".$server->sockport; print "# server at $addr\n"; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( !$pid ) { ###### Client $ID = 'client'; close($server); my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, SSL_verify_mode => 0, ) || do { notok( "connect failed: ".IO::Socket::SSL->errstr() ); exit }; ok( "client connected" ); } else { ###### Server my $to_client = $server->accept || do { notok( "accept failed: ".$server->errstr() ); kill(9,$pid); exit; }; ok( "Server accepted" ); wait; } sub ok { print "ok # [$ID] @_\n"; } sub notok { print "not ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/public_suffix_lib_libidn.t0000644000175000017500000000016514521466373021250 0ustar steffensteffenuse strict; use warnings; use FindBin; require "$FindBin::Bin/public_suffix_lib.pl"; run_with_lib( 'Net::LibIDN' ); IO-Socket-SSL-2.085/t/alpn.t0000644000175000017500000000343114521466373015170 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/alpn.t' use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; # check if we have ALPN available # if it is available if ( ! IO::Socket::SSL->can_alpn ) { print "1..0 # Skipped: ALPN not available in Net::SSLeay\n"; exit; } print "1..5\n"; # first create simple ssl-server my $ID = 'server'; my $addr = '127.0.0.1'; my $server = IO::Socket::SSL->new( LocalAddr => $addr, Listen => 2, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', SSL_alpn_protocols => [qw(one two)], ) || do { ok(0,"server creation failed: $!"); exit; }; ok(1,"Server Initialization at $addr"); # add server port to addr $addr = "$addr:".$server->sockport; print "# server at $addr\n"; my $pid = fork(); if ( !defined $pid ) { die $!; # fork failed } elsif ( !$pid ) { ###### Client $ID = 'client'; close($server); my $to_server = IO::Socket::SSL->new( PeerAddr => $addr, Domain => AF_INET, SSL_verify_mode => 0, SSL_alpn_protocols => [qw(two three)], ) or do { ok(0,"connect failed: ".IO::Socket::SSL->errstr()); exit; }; ok(1,"client connected" ); my $proto = $to_server->alpn_selected; ok($proto eq "two","negotiated $proto"); } else { ###### Server my $to_client = $server->accept or do { ok(0,"accept failed: ".$server->errstr()); kill(9,$pid); exit; }; ok(1,"Server accepted" ); my $proto = $to_client->alpn_selected; ok($proto eq "two","negotiated $proto"); wait; } sub ok { my $ok = shift; print $ok ? '' : 'not ', "ok # [$ID] @_\n"; } IO-Socket-SSL-2.085/t/signal-readline.t0000644000175000017500000000256314521466373017301 0ustar steffensteffen#!perl use strict; use warnings; use Net::SSLeay; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; if ( $^O =~m{mswin32}i ) { print "1..0 # Skipped: signals not relevant on this platform\n"; exit } print "1..9\n"; my $server = IO::Socket::SSL->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 2, SSL_server => 1, SSL_ca_file => "t/certs/test-ca.pem", SSL_cert_file => "t/certs/server-wildcard.pem", SSL_key_file => "t/certs/server-wildcard.pem", ); warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server; print "not ok\n", exit if !$server; ok("Server Initialization"); my $saddr = $server->sockhost.':'.$server->sockport; defined( my $pid = fork() ) || die $!; if ( $pid == 0 ) { $SIG{HUP} = sub { ok("got hup") }; close($server); my $client = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 0 ) || print "not "; ok( "client ssl connect" ); my $line = <$client>; print "not " if $line ne "foobar\n"; ok("got line"); exit; } my $csock = $server->accept; ok("accept"); syswrite($csock,"foo") or print "not "; ok("wrote foo"); sleep(1); kill HUP => $pid or print "not "; ok("send hup"); sleep(1); syswrite($csock,"bar\n") or print "not "; ok("wrote bar\\n"); wait; ok("wait: $?"); sub ok { print "ok #$_[0]\n"; } IO-Socket-SSL-2.085/t/compatibility.t0000644000175000017500000000350714521466373017113 0ustar steffensteffen#!perl # Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl t/compatibility.t' use strict; use warnings; use IO::Socket::SSL; use Socket; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; use Test::More tests => 9; Test::More->builder->use_numbers(0); Test::More->builder->no_ending(1); $SIG{'CHLD'} = "IGNORE"; IO::Socket::SSL::context_init(SSL_verify_mode => 0x01); my $server = IO::Socket::INET->new( LocalAddr => '127.0.0.1', LocalPort => 0, Listen => 1, ) or do { plan skip_all => "Bail out!". "Setup of test IO::Socket::INET client and server failed. All the rest of". "the tests in this suite will fail also unless you change the values in". "ssl_settings.req in the t/ directory."; }; pass("server create"); { package MyClass; use IO::Socket::SSL; our @ISA = "IO::Socket::SSL"; } my $saddr = $server->sockhost.':'.$server->sockport; unless (fork) { close $server; my $client = IO::Socket::INET->new($saddr); ok( MyClass->start_SSL($client, SSL_verify_mode => 0), "ssl upgrade"); is( ref( $client ), "MyClass", "class MyClass"); ok( $client->issuer_name, "issuer_name"); ok( $client->subject_name, "subject_name"); ok( $client->opened, "opened"); print $client "Ok to close\n"; close $client; exit(0); } my $contact = $server->accept; my $socket_to_ssl = IO::Socket::SSL::socketToSSL($contact, { SSL_server => 1, SSL_verify_mode => 0, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', }); ok( $socket_to_ssl, "socketToSSL"); <$contact>; close $contact; close $server; bless $contact, "MyClass"; ok( !IO::Socket::SSL::socket_to_SSL($contact, SSL_server => 1), "socket_to_SSL"); is( ref($contact), "MyClass", "upgrade is MyClass"); IO-Socket-SSL-2.085/t/cert_formats.t0000644000175000017500000000352714521466373016734 0ustar steffensteffenuse strict; use warnings; use Test::More; use IO::Socket::SSL; use File::Temp 'tempfile'; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; my $srv = IO::Socket::INET->new( LocalAddr => '127.0.0.1', Listen => 10, ); plan skip_all => "server creation failed: $!" if ! $srv; my $saddr = $srv->sockhost.':'.$srv->sockport; my ($fh,$pemfile) = tempfile(); my $master = $$; END { unlink($pemfile) if $$ == $master }; for ('t/certs/server-cert.pem','t/certs/server-key.pem') { open( my $pf,'<',$_ ) or die "open $_: $!"; print $fh do { local $/; <$pf> }; } close($fh); my @tests = ( 'PEM' => { SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', }, 'PEM_one_file' => { SSL_cert_file => $pemfile, }, 'PEM_keyenc' => { SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.enc', SSL_passwd_cb => sub { "bluebell" }, }, 'DER' => { SSL_cert_file => 't/certs/server-cert.der', SSL_key_file => 't/certs/server-key.der', }, 'PKCS12' => { SSL_cert_file => 't/certs/server.p12', }, 'PKCS12_enc' => { SSL_cert_file => 't/certs/server_enc.p12', SSL_passwd_cb => sub { "bluebell" }, }, ); plan tests => @tests/2; while (my ($name,$sslargs) = splice(@tests,0,2)) { defined(my $pid = fork()) or die "fork failed: $!"; if ($pid == 0) { # child = server my $cl = $srv->accept or die "accept $!"; if (!IO::Socket::SSL->start_SSL($cl, SSL_server => 1, Timeout => 10, %$sslargs )) { diag("start_SSL failed: $SSL_ERROR"); } exit(0); } else { # parent = client my $cl = IO::Socket::INET->new($saddr) or die "connect: $!"; if (!IO::Socket::SSL->start_SSL($cl, SSL_verify_mode => 0 )) { fail("[$name] ssl connect failed: $SSL_ERROR"); } else { pass("[$name] ssl connect success"); } wait; } } IO-Socket-SSL-2.085/t/acceptSSL-timeout.t0000644000175000017500000000352414521466373017546 0ustar steffensteffenuse strict; use warnings; use Socket; use IO::Socket::SSL; do './testlib.pl' || do './t/testlib.pl' || die "no testlib"; $|=1; print "1..15\n"; # first use SSL client { my ($server,$saddr) = create_listen_socket(); ok(1, "listening \@$saddr" ); my $srv = fork_sub( 'server',$server ); close($server); fd_grep_ok( 'Waiting', $srv ); my $cl = fork_sub( 'client_ssl',$saddr ); fd_grep_ok( 'Connect from',$srv ); fd_grep_ok( 'Connected', $cl ); fd_grep_ok( 'SSL Handshake OK', $srv ); fd_grep_ok( 'Hi!', $cl ); } # then try bad non-SSL client { my ($server,$saddr) = create_listen_socket(); ok(1, "listening \@$saddr" ); my $srv = fork_sub( 'server',$server ); close($server); fd_grep_ok( 'Waiting', $srv ); my $cl = fork_sub( 'client_no_ssl',$saddr ); fd_grep_ok( 'Connect from',$srv ); fd_grep_ok( 'Connected', $cl ); fd_grep_ok( 'SSL Handshake FAILED', $srv ); } sub server { my $server = shift; print "Waiting\n"; my $client = $server->accept || die "accept failed: $!"; print "Connect from ".$client->peerhost.':'.$client->peerport."\n"; if ( IO::Socket::SSL->start_SSL( $client, SSL_server => 1, Timeout => 5, SSL_cert_file => 't/certs/server-cert.pem', SSL_key_file => 't/certs/server-key.pem', )) { print "SSL Handshake OK\n"; print $client "Hi!\n"; } else { print "SSL Handshake FAILED - $!\n" } } sub client_no_ssl { my $saddr = shift; my $c = IO::Socket::INET->new( $saddr ) || die "connect failed: $!"; print "Connected\n"; while ( sysread( $c,my $buf,8000 )) {} } sub client_ssl { my $saddr = shift; my $c = IO::Socket::SSL->new( PeerAddr => $saddr, Domain => AF_INET, SSL_verify_mode => 0 ) || die "connect failed: $!|$SSL_ERROR"; print "Connected\n"; while ( sysread( $c,my $buf,8000 )) { print $buf } } IO-Socket-SSL-2.085/t/public_suffix_lib.pl0000644000175000017500000001511614521466373020101 0ustar steffensteffenuse strict; use warnings; use Test::More; use utf8; my $ps; sub run_with_lib { my @idnlib = @_; my %require = ( 'URI::_idna' => 0, 'Net::LibIDN' => 0, 'Net::IDN::Encode' => 0, map { $_ => 1 } @idnlib, ); my %block; my $can_idn; while ( my ($lib,$load) = each %require ) { if ( $load ) { $can_idn = eval "require $lib"; } else { $lib =~s{::}{/}g; $block{"$lib.pm"} = 1; } } unshift @INC, sub { return sub {0} if $block{$_[1]}; return; }; require IO::Socket::SSL::PublicSuffix; plan tests => 79; # all one-level, but co.uk two-level $ps = IO::Socket::SSL::PublicSuffix->from_string("*\nco.uk"); ok($ps,"create two-level"); minimal_private_suffix('com','','com'); minimal_private_suffix('bar.com','','bar.com'); minimal_private_suffix('www.bar.com','www','bar.com'); minimal_private_suffix('www.foo.bar.com','www.foo','bar.com'); minimal_private_suffix('uk','','uk'); minimal_private_suffix('co.uk','','co.uk'); minimal_private_suffix('www.co.uk','','www.co.uk'); minimal_private_suffix('www.bar.co.uk','www','bar.co.uk'); minimal_private_suffix('www.foo.bar.co.uk','www.foo','bar.co.uk'); minimal_private_suffix('bl.uk','','bl.uk'); minimal_private_suffix('www.bl.uk','www','bl.uk'); minimal_private_suffix('www.bar.bl.uk','www.bar','bl.uk'); minimal_private_suffix('www.foo.bar.bl.uk','www.foo.bar','bl.uk'); $ps = IO::Socket::SSL::PublicSuffix->default(min_suffix => 0); # taken from Mozilla::PublicSuffix 0.1.18 t/01-psuffix.t ------ # Obviously invalid input: is public_suffix(undef), undef; is public_suffix(''), undef; is public_suffix([]), undef; # Mixed case: is public_suffix('COM'), 'com'; is public_suffix('example.COM'), 'com'; is public_suffix('WwW.example.COM'), 'com'; is public_suffix('123bar.com'), 'com'; is public_suffix('foo.123bar.com'), 'com'; if(0) { # behaves different # - we return '' instead of undef if unknown extension # - we return com with *.com # Leading dot: is public_suffix('.com'), undef; is public_suffix('.example'), undef; is public_suffix('.example.com'), undef; is public_suffix('.example.example'), undef; # Unlisted TLD: is public_suffix('example'), undef; is public_suffix('example.example'), undef; is public_suffix('b.example.example'), undef; is public_suffix('a.b.example.example'), undef; # Listed, but non-Internet, TLD: is public_suffix('local'), undef; is public_suffix('example.local'), undef; is public_suffix('b.example.local'), undef; is public_suffix('a.b.example.local'), undef; } else { # Leading dot: is public_suffix('.com'), 'com'; is public_suffix('.example'), ''; is public_suffix('.example.com'), 'com'; is public_suffix('.example.example'), ''; # Unlisted TLD: is public_suffix('example'), ''; is public_suffix('example.example'), ''; is public_suffix('b.example.example'), ''; is public_suffix('a.b.example.example'), ''; # Listed, but non-Internet, TLD: is public_suffix('local'), ''; is public_suffix('example.local'), ''; is public_suffix('b.example.local'), ''; is public_suffix('a.b.example.local'), ''; } # TLD with only one rule: is public_suffix('biz'), 'biz'; is public_suffix('domain.biz'), 'biz'; is public_suffix('b.domain.biz'), 'biz'; is public_suffix('a.b.domain.biz'), 'biz'; # TLD with some two-level rules: is public_suffix('com'), 'com'; is public_suffix('example.com'), 'com'; is public_suffix('b.example.com'), 'com'; is public_suffix('a.b.example.com'), 'com'; # uk.com is not in the ICANN part of the list if(0) { is public_suffix('uk.com'), 'uk.com'; is public_suffix('example.uk.com'), 'uk.com'; is public_suffix('b.example.uk.com'), 'uk.com'; is public_suffix('a.b.example.uk.com'), 'uk.com'; } is public_suffix('test.ac'), 'ac'; # TLD with only one (wildcard) rule: if(0) { # we return '' not undef is public_suffix('bd'), undef; } else { is public_suffix('bd'), ''; } is public_suffix('c.bd'), 'c.bd'; is public_suffix('b.c.bd'), 'c.bd'; is public_suffix('a.b.c.bd'), 'c.bd'; # More complex suffixes: is public_suffix('jp'), 'jp'; is public_suffix('test.jp'), 'jp'; is public_suffix('www.test.jp'), 'jp'; is public_suffix('ac.jp'), 'ac.jp'; is public_suffix('test.ac.jp'), 'ac.jp'; is public_suffix('www.test.ac.jp'), 'ac.jp'; is public_suffix('kyoto.jp'), 'kyoto.jp'; is public_suffix('c.kyoto.jp'), 'kyoto.jp'; is public_suffix('b.c.kyoto.jp'), 'kyoto.jp'; is public_suffix('a.b.c.kyoto.jp'), 'kyoto.jp'; is public_suffix('ayabe.kyoto.jp'), 'ayabe.kyoto.jp'; is public_suffix('test.kobe.jp'), 'test.kobe.jp'; # Wildcard rule. is public_suffix('www.test.kobe.jp'), 'test.kobe.jp'; # Wildcard rule. is public_suffix('city.kobe.jp'), 'kobe.jp'; # Exception rule. is public_suffix('www.city.kobe.jp'), 'kobe.jp'; # Identity rule. # TLD with a wildcard rule and exceptions: if(0) { # we return '' not undef is public_suffix('ck'), undef; } else { is public_suffix('ck'), ''; } is public_suffix('test.ck'), 'test.ck'; is public_suffix('b.test.ck'), 'test.ck'; is public_suffix('a.b.test.ck'), 'test.ck'; is public_suffix('www.ck'), 'ck'; is public_suffix('www.www.ck'), 'ck'; # US K12: is public_suffix('us'), 'us'; is public_suffix('test.us'), 'us'; is public_suffix('www.test.us'), 'us'; is public_suffix('ak.us'), 'ak.us'; is public_suffix('test.ak.us'), 'ak.us'; is public_suffix('www.test.ak.us'), 'ak.us'; is public_suffix('k12.ak.us'), 'k12.ak.us'; is public_suffix('test.k12.ak.us'), 'k12.ak.us'; is public_suffix('www.test.k12.ak.us'), 'k12.ak.us'; # Domains and gTLDs with characters outside the ASCII range: SKIP: { if ( $can_idn ) { is public_suffix('test.敎育.hk'), '敎育.hk'; is public_suffix('ਭਾਰਤ.ਭਾਰਤ'), 'ਭਾਰਤ'; } else { skip "no IDN support with @idnlib",2 } } } sub minimal_private_suffix { my $host = shift; if ( @_ == 2 ) { my ($rest,$suffix) = @_; my @r = $ps->public_suffix($host,+1); if ( $r[0] eq $rest and $r[1] eq $suffix ) { pass("$host -> $rest + $suffix"); } else { fail("$host -> $r[0]($rest) + $r[1]($suffix)"); } } elsif ( @_ == 1 ) { my ($expect_suffix) = @_; my $got_suffix = $ps->public_suffix($host,+1); is( $got_suffix,$expect_suffix, "$host -> suffix=$expect_suffix"); } else { die "@_"; } } sub public_suffix { my $host = shift; my $suffix = $ps->public_suffix($host); return $suffix; } 1; IO-Socket-SSL-2.085/MANIFEST0000644000175000017500000000350614553536272014743 0ustar steffensteffenBUGS Changes docs/debugging.txt example/async_https_server.pl example/lwp-with-verifycn.pl example/simulate_proxy.pl example/ssl_client.pl example/ssl_mitm.pl example/ssl_server.pl lib/IO/Socket/SSL/Intercept.pm lib/IO/Socket/SSL.pm lib/IO/Socket/SSL.pod lib/IO/Socket/SSL/PublicSuffix.pm lib/IO/Socket/SSL/Utils.pm Makefile.PL MANIFEST This list of files README README.Win32 t/01loadmodule.t t/acceptSSL-timeout.t t/alpn.t t/auto_verify_hostname.t t/cert_formats.t t/cert_no_file.t t/certs/client-cert.pem t/certs/client-key.enc t/certs/client-key.pem t/certs/create-certs.pl t/certs/proxyca.pem t/certs/server2-cert.pem t/certs/server2-key.pem t/certs/server-cert.der t/certs/server-cert.pem t/certs/server-ecc-cert.pem t/certs/server-ecc-key.pem t/certs/server_enc.p12 t/certs/server-key.der t/certs/server-key.enc t/certs/server-key.pem t/certs/server.p12 t/certs/server-wildcard.pem t/certs/sub-server.pem t/certs/test-ca.pem t/certs/test-subca.pem t/compatibility.t t/connectSSL-timeout.t t/core.t t/dhe.t t/ecdhe.t t/external/fingerprint.pl t/external/ocsp.t t/external/usable_ca.t t/io-socket-inet6.t t/io-socket-ip.t t/memleak_bad_handshake.t t/mitm.t t/multiple-cert-rsa-ecc.t t/nonblock.t t/npn.t t/plain_upgrade_downgrade.t t/protocol_version.t t/public_suffix_lib_encode_idn.t t/public_suffix_lib_libidn.t t/public_suffix_lib.pl t/public_suffix_lib_uri.t t/public_suffix_ssl.t t/readline.t t/session_cache.t t/sessions.t t/session_ticket.t t/set_curves.t t/signal-readline.t t/sni.t t/sni_verify.t t/startssl-failed.t t/startssl.t t/start-stopssl.t t/sysread_write.t t/testlib.pl t/verify_fingerprint.t t/verify_hostname_standalone.t t/verify_hostname.t t/verify_partial_chain.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker)