#!/usr/bin/env ruby require 'socket' require 'openssl' require 'getopts' begin require 'verify_cb'; rescue LoadError; end include OpenSSL include SSL getopts "v", "C:", "p:2000", "c:", "k:" p [ $OPT_p, $OPT_k, $OPT_c ] if $OPT_k p rsa = PKey::RSA.new(File.open($OPT_k).read) else p rsa = PKey::RSA.new(512){|p, n| case p when 0; putc "." # BN_generate_prime when 1; putc "+" # BN_generate_prime when 2; putc "*" # searching good prime, n = #of try, # but also data from BN_generate_prime when 3; putc "\n" # found good prime, n==0 - p, n==1 - q, # but also data from BN_generate_prime else; putc "*" # BN_generate_prime end } end if $OPT_c p cert = X509::Certificate.new(File.open($OPT_c).read) else cert = X509::Certificate.new cert.version = 2 cert.serial = 0 name = X509::Name.new([["C","CZ"],["O","Ruby"],["CN","Test"]]) cert.subject = name cert.issuer = name cert.not_before = Time.now cert.not_after = Time.now + (365*24*60*60) cert.public_key = rsa.public_key ef = X509::ExtensionFactory.new(nil,cert) cert.extensions = [ ef.create_extension("basicConstraints","CA:FALSE"), ef.create_extension("subjectKeyIdentifier", "hash") ] ef.issuer_certificate = cert cert.add_extension ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always") cert.add_extension ef.create_extension("nsComment", "Generated by OpenSSL for Ruby!") cert.sign(rsa, Digest::SHA1.new) puts cert.to_str end ns = TCPServer.new($OPT_p) loop do begin s = ns.accept STDERR.print "connect from #{s.peeraddr[3]}.\n" ssl = SSLSocket.new(s, cert, rsa) ###ssl.ca_cert = X509::Certificate.new(File.open($OPT_C).read) if $OPT_C && FileTest::file?($OPT_C) ssl.ca_file = $OPT_C if $OPT_C && FileTest::file?($OPT_C) ssl.ca_path = $OPT_C if $OPT_C && FileTest::directory?($OPT_C) ssl.verify_mode = VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT if $OPT_v ssl.verify_callback = VerifyCallbackProc if defined? VerifyCallbackProc STDERR.print "SSLSocket initialized.\n" ssl.accept STDERR.print "SSLSocket accepted.\n" STDERR.print ssl.peer_cert.inspect, "\n" if ssl.peer_cert rescue ssl.close s.close print $!, "\n" next end Thread.start{ puts "Thread started" while line = ssl.gets p line end STDERR.print "connection closed.\n" ssl.close s.close } end