lib/localhost/authority.rb in localhost-1.0.0 vs lib/localhost/authority.rb in localhost-1.1.0
- old
+ new
@@ -44,10 +44,11 @@
@hostname = hostname
@key = nil
@name = nil
@certificate = nil
+ @store = nil
end
def key
@key ||= OpenSSL::PKey::RSA.new(1024)
end
@@ -71,17 +72,47 @@
extension_factory = OpenSSL::X509::ExtensionFactory.new
extension_factory.subject_certificate = certificate
extension_factory.issuer_certificate = certificate
+ # Because we are using a self-signed root certificate, we also need to make it a "pseudo-CA".
+ # https://security.stackexchange.com/questions/143061/does-openssl-refuse-self-signed-certificates-without-basic-constraints
+ certificate.add_extension extension_factory.create_extension("basicConstraints", "CA:TRUE", true)
+ certificate.add_extension extension_factory.create_extension("keyUsage", "keyCertSign, cRLSign, digitalSignature", true)
+ certificate.add_extension extension_factory.create_extension("subjectKeyIdentifier", "hash")
+
certificate.sign self.key, OpenSSL::Digest::SHA256.new
end
end
# The certificate store which is used for validating the server certificate:
def store
@store ||= OpenSSL::X509::Store.new.tap do |store|
store.add_cert(self.certificate)
+ end
+ end
+
+ def server_context(*args)
+ OpenSSL::SSL::SSLContext.new(*args).tap do |context|
+ context.key = self.key
+ context.cert = self.certificate
+
+ context.session_id_context = "localhost"
+
+ context.set_params(
+ verify_hostname: false,
+ )
+ end
+ end
+
+ def client_context(*args)
+ OpenSSL::SSL::SSLContext.new(*args).tap do |context|
+ context.cert_store = self.store
+
+ context.set_params(
+ verify_mode: OpenSSL::SSL::VERIFY_PEER,
+ verify_hostname: false,
+ )
end
end
def load(path)
if File.directory? path