#!/usr/bin/perl

# (C) Sergey Kandaurov
# (C) Nginx, Inc.

# Tests for http ssl module, ssl_verify_client.

###############################################################################

use warnings;
use strict;

use Test::More;

use Socket qw/ :DEFAULT CRLF /;

BEGIN { use FindBin; chdir($FindBin::Bin); }

use lib 'lib';
use Test::Nginx;

###############################################################################

select STDERR; $| = 1;
select STDOUT; $| = 1;

eval {
	require Net::SSLeay;
	Net::SSLeay::load_error_strings();
	Net::SSLeay::SSLeay_add_ssl_algorithms();
	Net::SSLeay::randomize();
};
plan(skip_all => 'Net::SSLeay not installed') if $@;

eval {
	my $ctx = Net::SSLeay::CTX_new() or die;
	my $ssl = Net::SSLeay::new($ctx) or die;
	Net::SSLeay::set_tlsext_host_name($ssl, 'example.org') == 1 or die;
};
plan(skip_all => 'Net::SSLeay with OpenSSL SNI support required') if $@;

my $t = Test::Nginx->new()->has(qw/http http_ssl sni/)
	->has_daemon('openssl')->plan(10);

$t->write_file_expand('nginx.conf', <<'EOF');

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
    %%TEST_GLOBALS_HTTP%%

    add_header X-Verify x$ssl_client_verify:${ssl_client_cert}x;

    ssl_certificate_key 1.example.com.key;
    ssl_certificate 1.example.com.crt;

    server {
        listen       127.0.0.1:8080;
        server_name  localhost;

        ssl_verify_client on;
        ssl_client_certificate 2.example.com.crt;
    }

    server {
        listen       127.0.0.1:8081 ssl;
        server_name  on;

        ssl_verify_client on;
        ssl_client_certificate 2.example.com.crt;
    }

    server {
        listen       127.0.0.1:8081 ssl;
        server_name  optional;

        ssl_verify_client optional;
        ssl_client_certificate 2.example.com.crt;
        ssl_trusted_certificate 3.example.com.crt;
    }

    server {
        listen       127.0.0.1:8081 ssl;
        server_name  optional_no_ca;

        ssl_verify_client optional_no_ca;
        ssl_client_certificate 2.example.com.crt;
    }
}

EOF

$t->write_file('openssl.conf', <<EOF);
[ req ]
default_bits = 1024
encrypt_key = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
EOF

my $d = $t->testdir();

foreach my $name ('1.example.com', '2.example.com', '3.example.com') {
	system('openssl req -x509 -new '
		. "-config $d/openssl.conf -subj /CN=$name/ "
		. "-out $d/$name.crt -keyout $d/$name.key "
		. ">>$d/openssl.out 2>&1") == 0
		or die "Can't create certificate for $name: $!\n";
}

$t->write_file('t', 'SEE-THIS');

$t->run();

###############################################################################

like(http_get('/t'), qr/x:x/, 'plain connection');
like(get('on'), qr/400 Bad Request/, 'no cert');
like(get('optional'), qr/NONE:x/, 'no optional cert');
like(get('optional', '1.example.com'), qr/400 Bad/, 'bad optional cert');
like(get('optional_no_ca', '1.example.com'), qr/FAILED.*BEGIN/,
	'bad optional_no_ca cert');

like(get('localhost', '2.example.com'), qr/SUCCESS.*BEGIN/, 'good cert');
like(get('optional', '2.example.com'), qr/SUCCESS.*BEGI/, 'good cert optional');
like(get('optional', '3.example.com'), qr/SUCCESS.*BEGIN/, 'good cert trusted');

SKIP: {
skip 'Net::SSLeay version >= 1.36 required', 1 if $Net::SSLeay::VERSION < 1.36;

my $ca = join ' ', get('optional', '3.example.com');
is($ca, '/CN=2.example.com', 'no trusted sent');

}

like(get('optional', undef, 'localhost'), qr/421 Misdirected/, 'misdirected');

###############################################################################

sub get {
	my ($sni, $cert, $host) = @_;

	local $SIG{PIPE} = 'IGNORE';

	$host = $sni if !defined $host;

	my $dest_ip = inet_aton('127.0.0.1');
	my $dest_serv_params = sockaddr_in(port(8081), $dest_ip);

	socket(my $s, &AF_INET, &SOCK_STREAM, 0) or die "socket: $!";
	connect($s, $dest_serv_params) or die "connect: $!";

	my $ctx = Net::SSLeay::CTX_new() or die("Failed to create SSL_CTX $!");
	Net::SSLeay::set_cert_and_key($ctx, "$d/$cert.crt", "$d/$cert.key")
		or die if $cert;
	my $ssl = Net::SSLeay::new($ctx) or die("Failed to create SSL $!");
	Net::SSLeay::set_tlsext_host_name($ssl, $sni) == 1 or die;
	Net::SSLeay::set_fd($ssl, fileno($s));
	Net::SSLeay::connect($ssl) or die("ssl connect");

	Net::SSLeay::write($ssl, 'GET /t HTTP/1.0' . CRLF);
	Net::SSLeay::write($ssl, "Host: $host" . CRLF . CRLF);
	my $buf = Net::SSLeay::read($ssl);
	log_in($buf);
	return $buf unless wantarray();

	my $list = Net::SSLeay::get_client_CA_list($ssl);
	my @names;
	for my $i (0 .. Net::SSLeay::sk_X509_NAME_num($list) - 1) {
		my $name = Net::SSLeay::sk_X509_NAME_value($list, $i);
		push @names, Net::SSLeay::X509_NAME_oneline($name);
	}
	return @names;
}

###############################################################################
