summaryrefslogtreecommitdiff
path: root/lib/webrick/https.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/webrick/https.rb')
-rw-r--r--lib/webrick/https.rb127
1 files changed, 11 insertions, 116 deletions
diff --git a/lib/webrick/https.rb b/lib/webrick/https.rb
index fa8c667d2a..4e44cfab32 100644
--- a/lib/webrick/https.rb
+++ b/lib/webrick/https.rb
@@ -8,31 +8,11 @@
#
# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $
-require 'webrick'
-require 'openssl'
+require 'webrick/ssl'
module WEBrick
module Config
- HTTP.update(
- :SSLEnable => true,
- :SSLCertificate => nil,
- :SSLPrivateKey => nil,
- :SSLClientCA => nil,
- :SSLCACertificateFile => nil,
- :SSLCACertificatePath => nil,
- :SSLCertificateStore => nil,
- :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
- :SSLVerifyDepth => nil,
- :SSLVerifyCallback => nil, # custom verification
- :SSLTimeout => nil,
- :SSLOptions => nil,
- # Must specify if you use auto generated certificate.
- :SSLCertName => nil,
- :SSLCertComment => "Generated by Ruby/OpenSSL"
- )
-
- osslv = ::OpenSSL::OPENSSL_VERSION.split[1]
- HTTP[:ServerSoftware] << " OpenSSL/#{osslv}"
+ HTTP.update(SSL)
end
class HTTPRequest
@@ -41,16 +21,18 @@ module WEBrick
alias orig_parse parse
def parse(socket=nil)
+ if socket && socket.is_a?(OpenSSL::SSL::SSLSocket)
+ @server_cert = @config[:SSLCertificate]
+ @client_cert = socket.peer_cert
+ @cipher = socket.cipher
+ end
orig_parse(socket)
- @cipher = socket.respond_to?(:cipher) ? socket.cipher : nil
- @client_cert = socket.respond_to?(:peer_cert) ? socket.peer_cert : nil
- @server_cert = @config[:SSLCertificate]
end
alias orig_parse_uri parse_uri
def parse_uri(str, scheme="https")
- if @config[:SSLEnable]
+ if @server_cert
return orig_parse_uri(str, scheme)
end
return orig_parse_uri(str)
@@ -60,100 +42,13 @@ module WEBrick
def meta_vars
meta = orig_meta_vars
- if @config[:SSLEnable]
+ if @server_cert
meta["HTTPS"] = "on"
- meta["SSL_CIPHER"] = @cipher ? @cipher[0] : ""
+ meta["SSL_SERVER_CERT"] = @server_cert.to_pem
meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : ""
- meta["SSL_SERVER_CERT"] = @server_cert ? @server_cert.to_pem : ""
+ meta["SSL_CIPHER"] = @cipher[0]
end
meta
end
end
-
- class HTTPServer
- alias orig_init initialize
-
- def initialize(*args)
- orig_init(*args)
-
- if @config[:SSLEnable]
- unless @config[:SSLCertificate]
- rsa = OpenSSL::PKey::RSA.new(512){|p, n|
- case p
- when 0; $stderr.putc "." # BN_generate_prime
- when 1; $stderr.putc "+" # BN_generate_prime
- when 2; $stderr.putc "*" # searching good prime,
- # n = #of try,
- # but also data from BN_generate_prime
- when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
- # but also data from BN_generate_prime
- else; $stderr.putc "*" # BN_generate_prime
- end
- }
- cert = OpenSSL::X509::Certificate.new
- cert.version = 3
- cert.serial = 0
- name = OpenSSL::X509::Name.new(@config[:SSLCertName])
- 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 = 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.issuer_certificate = cert
- ext = ef.create_extension("authorityKeyIdentifier",
- "keyid:always,issuer:always")
- cert.add_extension(ext)
- if comment = @config[:SSLCertComment]
- cert.add_extension(ef.create_extension("nsComment", comment))
- end
- cert.sign(rsa, OpenSSL::Digest::SHA1.new)
-
- @config[:SSLPrivateKey] = rsa
- @config[:SSLCertificate] = cert
- @logger.info cert.to_s
- end
- @ctx = OpenSSL::SSL::SSLContext.new
- set_ssl_context(@ctx, @config)
- end
- end
-
- alias orig_run run
-
- def run(sock)
- if @config[:SSLEnable]
- ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
- ssl.sync = true
- ssl.accept
- Thread.current[:WEBrickSocket] = ssl
- orig_run(ssl)
- Thread.current[:WEBrickSocket] = sock
- ssl.close
- else
- orig_run(sock)
- end
- end
-
- private
-
- def set_ssl_context(ctx, config)
- ctx.key = config[:SSLPrivateKey]
- ctx.cert = config[:SSLCertificate]
- ctx.client_ca = config[:SSLClientCA]
- ctx.ca_file = config[:SSLCACertificateFile]
- ctx.ca_path = config[:SSLCACertificatePath]
- ctx.cert_store = config[:SSLCertificateStore]
- ctx.verify_mode = config[:SSLVerifyClient]
- ctx.verify_depth = config[:SSLVerifyDepth]
- ctx.verify_callback = config[:SSLVerifyCallback]
- ctx.timeout = config[:SSLTimeout]
- ctx.options = config[:SSLOptions]
- end
- end
end