Subject: | [PATCH] Support for get_peer_cert_chain |
Hi,
could you please integrate the attached patch which adds get_peer_cert_chain() to Net::SSLeay.
Markus
Subject: | Net-SSLeay-get_peer_cert_chain.patch |
diff --git a/SSLeay.xs b/SSLeay.xs
index bbe2323..3d01c8f 100644
--- a/SSLeay.xs
+++ b/SSLeay.xs
@@ -1542,6 +1542,24 @@ SSL_get_peer_certificate(s)
SSL * s
void
+SSL_get_peer_cert_chain(s)
+ SSL * s
+ PREINIT:
+ STACK_OF(X509) *chain = NULL;
+ X509 *x;
+ int i;
+ PPCODE:
+ chain = SSL_get_peer_cert_chain(s);
+ if( chain == NULL ) {
+ return;
+ }
+ for (i=0; i<sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
+ XPUSHs(sv_2mortal(newSViv(PTR2IV(x))));
+ }
+ sk_X509_free(chain);
+
+void
SSL_set_verify(s,mode,callback)
SSL * s
int mode
diff --git a/lib/Net/SSLeay.pm b/lib/Net/SSLeay.pm
index 6441434..f4e3485 100644
--- a/lib/Net/SSLeay.pm
+++ b/lib/Net/SSLeay.pm
@@ -273,6 +273,7 @@ $VERSION = '1.55';
get_httpx
get_httpx4
get_peer_certificate
+ get_peer_cert_chain
get_rbio
get_read_ahead
get_server_random
diff --git a/lib/Net/SSLeay.pod b/lib/Net/SSLeay.pod
index ee145ec..9a8d077 100644
--- a/lib/Net/SSLeay.pod
+++ b/lib/Net/SSLeay.pod
@@ -3320,6 +3320,17 @@ Get the X509 certificate of the peer.
Check openssl doc L<http://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html|http://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html>
+=item * get_peer_cert_chain
+
+Get the certificate chain of the peer as an array of X509 structures.
+
+ my @rv = Net::SSLeay::get_peer_certificate($ssl);
+ # $ssl - value corresponding to openssl's SSL structure
+ #
+ # returns: list of X509 structures
+
+Check openssl doc L<http://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html|http://www.openssl.org/docs/ssl/SSL_get_peer_certificate.html>
+
=item * get_quiet_shutdown
Returns the 'quiet shutdown' setting of ssl.
diff --git a/t/external/20_cert_chain.t b/t/external/20_cert_chain.t
new file mode 100644
index 0000000..153304c
--- /dev/null
+++ b/t/external/20_cert_chain.t
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Test::More;
+use Socket;
+use Net::SSLeay qw( die_if_ssl_error );
+
+Net::SSLeay::randomize();
+Net::SSLeay::load_error_strings();
+Net::SSLeay::ERR_load_crypto_strings();
+Net::SSLeay::SSLeay_add_ssl_algorithms();
+
+my @sites = qw( www.verisign.com );
+
+if (@sites) {
+ plan tests => scalar @sites * 3;
+}
+else {
+ plan skip_all => 'No external hosts specified for SSL testing';
+}
+
+for my $site (@sites) {
+ SKIP: {
+ my $port = getservbyname ('https', 'tcp');
+ my $dest_ip = gethostbyname ( $site );
+
+ socket (S, &AF_INET, &SOCK_STREAM, 0) or die "socket: $!";
+ connect (S, sockaddr_in($port, $dest_ip) ) or die "connect: $!";
+ select (S); $| = 1; select (STDOUT);
+
+ my $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!");
+ my $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!");
+ Net::SSLeay::set_fd($ssl, fileno(S)); # Must use fileno
+ Net::SSLeay::connect($ssl);
+ die_if_ssl_error('bulk: ssl connect');
+
+ my @chain = Net::SSLeay::get_peer_cert_chain($ssl);
+ ok(scalar @chain, 'get_peer_cert_chain returns some elements');
+ SKIP: {
+ if( ! scalar @chain ) {
+ skip('check returned no certificate chain!', 2);
+ }
+ my $x509 = $chain[0];
+ ok(my $subject = Net::SSLeay::X509_get_subject_name($x509), "X509_get_subject_name");
+ like(Net::SSLeay::X509_NAME_oneline($subject), qr|/OU=.*?/CN=|, "X509_NAME_oneline");
+ };
+ }
+}