localhost 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47320a58186ec6b563f8b2f33605a8a5b089bad34372b96b8f75bcf5e46bc702
4
- data.tar.gz: d5881e19b6cfc2e12dabd2b8a0fc05d1a5e58e9440f45013d0220c5f398999c1
3
+ metadata.gz: fda0f07449ce52b5f8f53a578c249733f5f391d44095dc2a5d433db2df0ae5bf
4
+ data.tar.gz: ea02fcc0c8fb3ecbd84febf29aa7530046b15d49bea236cef0a8837cf59acf5a
5
5
  SHA512:
6
- metadata.gz: a14c685f31632fec950b0adad3717497a1981f94ca19b3851d955a97422035d12809677106e3515a29dc2575bd3edbd457c7eb5401506c474e09b180e103e52d
7
- data.tar.gz: 2e47b4b98fb60fdc885a971b744d8eeda298e29aa3cbe2d9a47586d8926758e56fd9e547ff05840fd0b34153e714c97d7f1022f100c11a4959589aff87b275c6
6
+ metadata.gz: db94e6a6b1f615f0e146d33a13bee540ce6ce3dc17d2ac77add5c469dfd12dbd970a0622c29ee9d12d6a23e4bcef5aef4ea7c54b4729ba8687a682a30b6088d2
7
+ data.tar.gz: 3f0f2d90424313e5b8988746219ad74e25db7a4c6ffe36cd02acf44908a3b2006c10db4294d24e6576a2bae4a7d263c5fbc5d41e02f14a46fadf1bbd84c88d25
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ /ssl/
data/Gemfile CHANGED
@@ -4,3 +4,8 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  # Specify your gem's dependencies in localhost.gemspec
6
6
  gemspec
7
+
8
+ group :development do
9
+ gem 'async-io'
10
+ gem 'async-rspec'
11
+ end
data/README.md CHANGED
@@ -30,15 +30,41 @@ This example shows how to generate a certificate for an SSL secured web server:
30
30
 
31
31
  ```ruby
32
32
  require 'localhost/authority'
33
+ require 'socket'
33
34
 
34
35
  authority = Localhost::Authority.fetch
35
36
 
36
- OpenSSL::SSL::SSLContext.new.tap do |context|
37
- context.cert = authority.certificate
38
- context.key = authority.key
37
+ server_thread = Thread.new do
38
+ server = OpenSSL::SSL::SSLServer.new(TCPServer.new("localhost", 4050), authority.server_context)
39
+
40
+ server.listen
41
+
42
+ peer = server.accept
43
+
44
+ puts "Writing..."
45
+ peer.flush
46
+
47
+ peer.close
39
48
  end
49
+
50
+ client = OpenSSL::SSL::SSLSocket.new(TCPSocket.new("localhost", 4050), authority.client_context)
51
+
52
+ # Initialize SSL connection
53
+ client.connect
54
+
55
+ puts client.read
56
+
57
+ client.close
58
+
59
+ server_thread.join
40
60
  ```
41
61
 
62
+ If you use Safari to access such a server, it will allow you to add the certificate to your keychain without much work. Once you've done this, you won't need to do it again for any other site when running such a development environment from the same user account.
63
+
64
+ ### Files
65
+
66
+ The certificate and private key are stored in `~/.localhost/`.
67
+
42
68
  ## Contributing
43
69
 
44
70
  1. Fork it
@@ -46,6 +46,7 @@ module Localhost
46
46
  @key = nil
47
47
  @name = nil
48
48
  @certificate = nil
49
+ @store = nil
49
50
  end
50
51
 
51
52
  def key
@@ -73,6 +74,12 @@ module Localhost
73
74
  extension_factory.subject_certificate = certificate
74
75
  extension_factory.issuer_certificate = certificate
75
76
 
77
+ # Because we are using a self-signed root certificate, we also need to make it a "pseudo-CA".
78
+ # https://security.stackexchange.com/questions/143061/does-openssl-refuse-self-signed-certificates-without-basic-constraints
79
+ certificate.add_extension extension_factory.create_extension("basicConstraints", "CA:TRUE", true)
80
+ certificate.add_extension extension_factory.create_extension("keyUsage", "keyCertSign, cRLSign, digitalSignature", true)
81
+ certificate.add_extension extension_factory.create_extension("subjectKeyIdentifier", "hash")
82
+
76
83
  certificate.sign self.key, OpenSSL::Digest::SHA256.new
77
84
  end
78
85
  end
@@ -84,6 +91,30 @@ module Localhost
84
91
  end
85
92
  end
86
93
 
94
+ def server_context(*args)
95
+ OpenSSL::SSL::SSLContext.new(*args).tap do |context|
96
+ context.key = self.key
97
+ context.cert = self.certificate
98
+
99
+ context.session_id_context = "localhost"
100
+
101
+ context.set_params(
102
+ verify_hostname: false,
103
+ )
104
+ end
105
+ end
106
+
107
+ def client_context(*args)
108
+ OpenSSL::SSL::SSLContext.new(*args).tap do |context|
109
+ context.cert_store = self.store
110
+
111
+ context.set_params(
112
+ verify_mode: OpenSSL::SSL::VERIFY_PEER,
113
+ verify_hostname: false,
114
+ )
115
+ end
116
+ end
117
+
87
118
  def load(path)
88
119
  if File.directory? path
89
120
  key_path = File.join(path, "#{@hostname}.key")
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Localhost
22
- VERSION = "1.0.0"
22
+ VERSION = "1.1.0"
23
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: localhost
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-03 00:00:00.000000000 Z
11
+ date: 2018-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler