From e207b8d4da8b308535bb40a6f49dae3bc9bffa9d Mon Sep 17 00:00:00 2001 From: gotoyuzo Date: Wed, 23 Jul 2003 16:12:24 +0000 Subject: * ext/openssl: imported. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4128 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- sample/c_rehash.rb | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++ sample/cipher.rb | 29 +++++++++ sample/echo_cli.rb | 36 +++++++++++ sample/echo_svr.rb | 64 +++++++++++++++++++ sample/gen_csr.rb | 52 +++++++++++++++ sample/smime_read.rb | 23 +++++++ sample/smime_write.rb | 23 +++++++ sample/wget.rb | 33 ++++++++++ 8 files changed, 434 insertions(+) create mode 100644 sample/c_rehash.rb create mode 100644 sample/cipher.rb create mode 100644 sample/echo_cli.rb create mode 100644 sample/echo_svr.rb create mode 100644 sample/gen_csr.rb create mode 100644 sample/smime_read.rb create mode 100644 sample/smime_write.rb create mode 100644 sample/wget.rb (limited to 'sample') diff --git a/sample/c_rehash.rb b/sample/c_rehash.rb new file mode 100644 index 0000000..386eef5 --- /dev/null +++ b/sample/c_rehash.rb @@ -0,0 +1,174 @@ +#!/usr/bin/env ruby + +require 'openssl' +require 'md5' + +class CHashDir + include Enumerable + + def initialize(dirpath) + @dirpath = dirpath + @fingerprint_cache = @cert_cache = @crl_cache = nil + end + + def hash_dir(silent = false) + # ToDo: Should lock the directory... + @silent = silent + @fingerprint_cache = Hash.new + @cert_cache = Hash.new + @crl_cache = Hash.new + do_hash_dir + end + + def get_certs(name = nil) + if name + @cert_cache[hash_name(name)] + else + @cert_cache.values.flatten + end + end + + def get_crls(name = nil) + if name + @crl_cache[hash_name(name)] + else + @crl_cache.values.flatten + end + end + + def delete_crl(crl) + File.unlink(crl_filename(crl)) + hash_dir(true) + end + + def add_crl(crl) + File.open(crl_filename(crl), "w") do |f| + f << crl.to_pem + end + hash_dir(true) + end + + def load_pem_file(filepath) + str = File.read(filepath) + begin + OpenSSL::X509::Certificate.new(str) + rescue + begin + OpenSSL::X509::CRL.new(str) + rescue + begin + OpenSSL::X509::Request.new(str) + rescue + nil + end + end + end + end + +private + + def crl_filename(crl) + path(hash_name(crl.issuer)) + '.pem' + end + + def do_hash_dir + Dir.chdir(@dirpath) do + delete_symlink + Dir.glob('*.pem') do |pemfile| + cert = load_pem_file(pemfile) + case cert + when OpenSSL::X509::Certificate + link_hash_cert(pemfile, cert) + when OpenSSL::X509::CRL + link_hash_crl(pemfile, cert) + else + STDERR.puts("WARNING: #{pemfile} does not contain a certificate or CRL: skipping") unless @silent + end + end + end + end + + def delete_symlink + Dir.entries(".").each do |entry| + next unless /^[\da-f]+\.r{0,1}\d+$/ =~ entry + File.unlink(entry) if FileTest.symlink?(entry) + end + end + + def link_hash_cert(org_filename, cert) + name_hash = hash_name(cert.subject) + fingerprint = fingerprint(cert.to_der) + filepath = link_hash(org_filename, name_hash, fingerprint) { |idx| + "#{name_hash}.#{idx}" + } + unless filepath + unless @silent + STDERR.puts("WARNING: Skipping duplicate certificate #{org_filename}") + end + else + (@cert_cache[name_hash] ||= []) << path(filepath) + end + end + + def link_hash_crl(org_filename, crl) + name_hash = hash_name(crl.issuer) + fingerprint = fingerprint(crl.to_der) + filepath = link_hash(org_filename, name_hash, fingerprint) { |idx| + "#{name_hash}.r#{idx}" + } + unless filepath + unless @silent + STDERR.puts("WARNING: Skipping duplicate CRL #{org_filename}") + end + else + (@crl_cache[name_hash] ||= []) << path(filepath) + end + end + + def link_hash(org_filename, name, fingerprint) + idx = 0 + filepath = nil + while true + filepath = yield(idx) + break unless FileTest.symlink?(filepath) or FileTest.exist?(filepath) + if @fingerprint_cache[filepath] == fingerprint + return false + end + idx += 1 + end + STDOUT.puts("#{org_filename} => #{filepath}") unless @silent + symlink(org_filename, filepath) + @fingerprint_cache[filepath] = fingerprint + filepath + end + + def symlink(from, to) + begin + File.symlink(from, to) + rescue + File.open(to, "w") do |f| + f << File.read(from) + end + end + end + + def path(filename) + File.join(@dirpath, filename) + end + + def hash_name(name) + sprintf("%x", name.hash) + end + + def fingerprint(der) + MD5.hexdigest(der).upcase + end +end + +if $0 == __FILE__ + dirlist = ARGV + dirlist << '/usr/ssl/certs' if dirlist.empty? + dirlist.each do |dir| + CHashDir.new(dir).hash_dir + end +end diff --git a/sample/cipher.rb b/sample/cipher.rb new file mode 100644 index 0000000..844b6ee --- /dev/null +++ b/sample/cipher.rb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'openssl' + +text = "abcdefghijklmnopqrstuvwxyz" +key = "key" +alg = "DES-EDE3-CBC" +#alg = "AES-128-CBC" + +puts "--Setup--" +puts %(clear text: "#{text}") +puts %(symmetric key: "#{key}") +puts %(cipher alg: "#{alg}") +puts + +puts "--Encrypting--" +des = OpenSSL::Cipher::Cipher.new(alg) +des.encrypt(key) #, "iv12345678") +cipher = des.update(text) +cipher << des.final +puts %(encrypted text: #{cipher.inspect}) +puts + +puts "--Decrypting--" +des = OpenSSL::Cipher::Cipher.new(alg) +des.decrypt(key) #, "iv12345678") +out = des.update(cipher) +out << des.final +puts %(decrypted text: "#{out}") +puts diff --git a/sample/echo_cli.rb b/sample/echo_cli.rb new file mode 100644 index 0000000..87dacaf --- /dev/null +++ b/sample/echo_cli.rb @@ -0,0 +1,36 @@ +#!/usr/bin/env ruby + +require 'socket' +require 'openssl' +require 'getopts' + +getopts nil, "p:2000", "c:", "k:", "C:" + +host = ARGV[0] || "localhost" +port = $OPT_p +cert_file = $OPT_c +key_file = $OPT_k +ca_path = $OPT_C + +ctx = OpenSSL::SSL::SSLContext.new() +if cert_file && key_file + ctx.cert = OpenSSL::X509::Certificate.new(File::read(cert_file)) + ctx.key = OpenSSL::PKey::RSA.new(File::read(key_file)) +end +if ca_path + ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER + ctx.ca_path = ca_path +else + $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!" +end + +s = TCPSocket.new(host, port) +ssl = OpenSSL::SSL::SSLSocket.new(s, ctx) +ssl.connect +while line = $stdin.gets + ssl.write line + print ssl.gets +end + +ssl.close +s.close diff --git a/sample/echo_svr.rb b/sample/echo_svr.rb new file mode 100644 index 0000000..e35ad12 --- /dev/null +++ b/sample/echo_svr.rb @@ -0,0 +1,64 @@ +#!/usr/bin/env ruby + +require 'socket' +require 'openssl' +require 'getopts' + +getopts nil, "p:2000", "c:", "k:", "C:" + +port = $OPT_p +cert_file = $OPT_c +key_file = $OPT_k +ca_path = $OPT_C + +if cert_file && key_file + cert = OpenSSL::X509::Certificate.new(File::read(cert_file)) + key = OpenSSL::PKey::RSA.new(File::read(key_file)) +else + key = OpenSSL::PKey::RSA.new(512){ print "." } + puts + cert = OpenSSL::X509::Certificate.new + cert.version = 2 + cert.serial = 0 + name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]]) + cert.subject = name + cert.issuer = name + cert.not_before = Time.now + cert.not_after = Time.now + 3600 + cert.public_key = key.public_key + ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) + cert.extensions = [ + ef.create_extension("basicConstraints","CA:FALSE"), + ef.create_extension("subjectKeyIdentifier","hash"), + ef.create_extension("extendedKeyUsage","serverAuth"), + ef.create_extension("keyUsage", + "keyEncipherment,dataEncipherment,digitalSignature") + ] + ef.issuer_certificate = cert + cert.add_extension ef.create_extension("authorityKeyIdentifier", + "keyid:always,issuer:always") + cert.sign(key, OpenSSL::Digest::SHA1.new) +end + +ctx = OpenSSL::SSL::SSLContext.new() +ctx.key = key +ctx.cert = cert +if ca_path + ctx.verify_mode = + OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT + ctx.ca_path = ca_path +else + $stderr.puts "!!! WARNING: PEER CERTIFICATE WON'T BE VERIFIED !!!" +end + +svr = TCPServer.new(port) +loop do + ns = svr.accept + ssl = OpenSSL::SSL::SSLSocket.new(ns, ctx) + ssl.accept + while line = ssl.gets + ssl.write line + end + ssl.close + ns.close +end diff --git a/sample/gen_csr.rb b/sample/gen_csr.rb new file mode 100644 index 0000000..c22073b --- /dev/null +++ b/sample/gen_csr.rb @@ -0,0 +1,52 @@ +#!/usr/bin/env ruby + +require 'getopts' +require 'openssl' + +include OpenSSL + +def usage + myname = File::basename($0) + $stderr.puts <