noxxi / p5-io-socket-ssl

IO::Socket::SSL Perl Module
36 stars 60 forks source link

Net-SSLeay-1.68 : request informations / $arg_hash->{SSL_ca} #33

Closed nicolas2k closed 9 years ago

nicolas2k commented 9 years ago

Hello

I found not anywhere of a detail documentation clear about SSL_key or SSL_ca from variables and without from flat files : eg : my-ca.pem or client-cert.pem.

So, I’d like just use by variables a key of CA public without file of "$certdir/my-ca.pem" and open a new socket :

Example of perl 5.14.2 (strawberry 32bits): $ca_key = q{-----BEGIN CERTIFICATE----- MIIE+DCCA …. blabla …. tZPMIxRNeUKRg== -----END CERTIFICATE-----};

$x509 = PEM_string2cert($ca_key); #=> it's work !

if(!($socket = IO::Socket::SSL->new( Listen => 5, LocalPort => $port, Proto => 'tcp', Reuse => 0, SSL_ca_path => $certdir,

SSL_ca_file => "$certdir/my-ca.pem", => it's work fine with all keys

      SSL_ca => $x509, 
      SSL_cert_file  => "$certdir/server-cert.pem", 
      SSL_key_file  => "$certdir/server-key.pem", 
      SSL_use_cert => 1,
      SSL_verify_mode => SSL_VERIFY_PEER,
      SSL_reuse_ctx => 0,
      SSL_server => 1,
      SSL_version => 'SSLv3',
      SSL_cipher_list =>  'SHA:AES:3DES:!RC4:!MD5',
      SSL_passwd_cb => sub {return "$secret"},
   )) )

And I've some erro : DB<2> Can't use string ("61536080") as an ARRAY ref while "strict refs" in use at E:/strawberry-5.14.2.1-32bit/perl/site/lib/IO/Socket/SSL.pm line 2273. at E:/strawberry-5.14.2.1-32bit/perl/site/lib/IO/Socket/SSL.pm line 2273 IO::Socket::SSL::SSL_Context::new('IO::Socket::SSL::SSL_Context', 'HASH(0x242df6c)') called at E:/strawberry-5.14.2.1-32bit/perl/site/lib/IO/Socket/SSL.pm line 512

Is it possible and which’s a good practice ?

Many thanks for advance.

Best regards

Nicolas

noxxi commented 9 years ago

from the documentation:

... as an internal representation of a X509* object with SSL_cert ...or as an internal representation of a EVP_PKEY* object with SSL_key

You can get to these presentation by either using Net::SSLeay directly or using the PEM_string2cert and similar function from IO::Socket::SSL::Utils. Same with SSL_ca, where you can give an array of X509* handles.

nicolas2k commented 9 years ago

Sorry, I'm always confused during four hours : in case : my %sslarg = ( Listen => 5, LocalPort => $port, Proto => 'tcp', Reuse => 0, SSL_ca_path => $certdir, SSL_ca_file => "$certdir/my-ca.pem", SSL_cert_file => "$certdir/server-cert.pem", SSL_key_file => "$certdir/server-key.pem", SSL_use_cert => 1, SSL_verify_mode => SSL_VERIFY_PEER, SSL_reuse_ctx => 0, SSL_server => 1, SSL_version => 'SSLv3', SSL_cipher_list => 'SHA:AES:3DES:!RC4:!MD5', SSL_passwd_cb => sub {return "secret"}, ); if(!($socket = IO::Socket::SSL->new( %sslarg )) ) => it work fine !

in case : my $ca_cert= '----BEGIN CERTIFICATE ... (PEM formated)'; my $x509 = PEM_string2cert($ca_cert); my $x509b = CERT_asHash($x509); my $x509c = PEM_cert2string($x509); my $x509d = %$x509c; my %sslarg = ( Listen => 5, LocalPort => $port, Proto => 'tcp', Reuse => 0, SSL_ca_path => $certdir, SSL_ca => $x509, # or other variable SSL_cert_file => "$certdir/server-cert.pem", SSL_key_file => "$certdir/server-key.pem", SSL_use_cert => 1, SSL_verify_mode => SSL_VERIFY_PEER, SSL_reuse_ctx => 0, SSL_server => 1, SSL_version => 'SSLv3', SSL_cipher_list => 'SHA:AES:3DES:!RC4:!MD5', SSL_passwd_cb => sub {return "$info{CODESSL}"}, ); if(!($socket = IO::Socket::SSL->new( %sslarg )) )

It said some error of ARRAY nothing of x509, x509b, x509c and x509d worked.

I find not my mistake of method, and I understood of structure x509.h or x509v3.h ...

What should I put into the variable $arg_hash->{SSL_ca} ?

Thanks indeed

nicolas2k commented 9 years ago

I seem that the section SSL_ca of SSL.pm don’t work correctly, because I’ve check with a method of SSL_key which work very fine :

my $ca_cert= '----BEGIN CERTIFICATE ... (PEM formated)'; my $srv_pkey = '----BEGIN RSA PRIVATE [...]';

my $ctx = Net::SSLeay::CTX_new() or die "ERROR: CTX_new failed"; Net::SSLeay::CTX_set_options($ctx, &Net::SSLeay::OP_ALL);

my $bio_cert = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()) or die; Net::SSLeay::BIO_write($bio_cert, $ca_cert) or die "no cert"; my $x509 = Net::SSLeay::PEM_read_bio_X509($bio_cert) or die "no x509 structure"; Net::SSLeay::CTX_use_certificate($ctx, $x509) or die ; Net::SSLeay::BIO_free($bio_cert);

my $bio_key = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()) or die; Net::SSLeay::BIO_write($bio_key, $srv_pkey) or die "no key"; my $evp_pkey = Net::SSLeay::PEM_read_bio_PrivateKey($bio_key, sub {return "secret"}) or die "no evp_pkey structure"; Net::SSLeay::CTX_use_PrivateKey($ctx, $evp_pkey); Net::SSLeay::BIO_free($bio_key);

my %sslarg = ( Listen => 5, LocalPort => $port, Proto => 'tcp', Reuse => 0, SSL_ca_path => $certdir,

SSL_ca => $x509,

SSL_ca_file => "$certdir/my-ca.pem", SSL_key => $evp_pkey,

SSL_key_file => "$certdir/server-key.pem",

SSL_cert_file => "$certdir/server-cert.pem", SSL_use_cert => 1, SSL_verify_mode => SSL_VERIFY_PEER, SSL_reuse_ctx => 0, SSL_server => 1, SSL_version => 'SSLv3', SSL_cipher_list => 'SHA:AES:3DES:!RC4:!MD5', SSL_passwd_cb => sub {return "secret"}, );

if(!($socket = IO::Socket::SSL->new( %sslarg )) ) { print ("unable to create socket: ", &IO::Socket::SSL::errstr, "\n"); warn "unable to create socket: ", &IO::Socket::SSL::errstr, "\n"; exit(0); }

Thanks your assistance

noxxi commented 9 years ago

I'm really confused of what you are doing, which is caused by both bad formatting and bad problem description. Please provide a fully working and minimal example with nicely intended code (see help for how to format your messages in a readable way). Also, SSL_ca needs a list of X509* objects (as documented) and not a single object.

nicolas2k commented 9 years ago

I've sent you mail (xxx at cpan) and I'm sorry that my language is not very well.

So, I've tested and I've modified .\site\lib\IO\Socket\SSL.pm at 2272 this : my $store = Net::SSLeay::CTX_get_cert_store($ctx);

for (@{$arg_hash->{SSL_ca}})

{
    # Net::SSLeay::X509_STORE_add_cert($store,$_) or
    Net::SSLeay::X509_STORE_add_cert($store,$arg_hash->{SSL_ca}) or return IO::Socket::SSL->error(
        "Failed to add certificate to CA store");
}

And they now work fine : SSL_ca as SSL_key. But I don't find an alternative for a variable of $x509 of before correction.

Thanks

noxxi commented 9 years ago

What you did it is to change the code, so that it uses a single X509* object as the CA list. But the documentation states for a reason that you should give a list of X509* objects, because usually you have not a single CA but multiple (browsers have 100+). Instead your usage is wrong and you should use a list, i.e.

   SSL_ca => [ $x509 ]
nicolas2k commented 9 years ago

Hi,

ok, Thanks very much but I make two mistakes :

Thanks, They work all fine !

noxxi commented 9 years ago

I've updated the documentation to make it more clear which kind of objects are expected and how to get them.