ovpn-key 0.8 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ecf480dc290e372a3b081ebc12dceb82e2f0ca22ea508cbbe622e8e1ce80b58f
4
- data.tar.gz: 585a28ba43b652afd0add8b912a8ff0590ad99ffcb96abcb9929c8ca488c03b1
3
+ metadata.gz: 7416051f932e40fb29c714599ad2ae7090b33dd0cf90ac31d3186993adc5a29a
4
+ data.tar.gz: 85b35e1706fd1ea6892363cb01caf734b7c6bf84614aac5a31d3d31c1f10bf8d
5
5
  SHA512:
6
- metadata.gz: 47783d3b02d6948cb19fc4434dff11a980c0fc9f22675a66d2cc6fc34423be7e7b2dc6b4e46f420eaa85755ef14ca8e787dddaa30eacd707837033138239753f
7
- data.tar.gz: 405a4389cf9b26a8a8cf6e4e615a04dc2bcf80b6fe71ed7b22c3380c3e5d215e70bab5d3ef8ba78eab20e94e19e74d1dd3c58fe47e118760cae842fbfc1e7c40
6
+ metadata.gz: 4c6baffe4fe1c9340cc4a2cff365eb82ea5a63aa4e943ea4aecd3bb629459558363f6fcd4621b97f287427a91f05562689ab4451915bf84b2dfde192970a6d1e
7
+ data.tar.gz: 4759d340ff8f701aa5f1ea2e084070dd55a9511ddd9ee0583feb6d1c51a62187661207022a6e401010f89c9435dff71df767e34bbfef5c0c42f03aec1a67e2e7
data/README.md CHANGED
@@ -40,7 +40,7 @@ If you're brave, [let me know](https://github.com/chillum/ovpn-key/issues), wher
40
40
 
41
41
  ### Configuration
42
42
 
43
- Most of configuration is done in `open-vpn.key` and `openssl.ini` files in the directory.
43
+ It's just a single simple YAML file named [`ovpn-key.yml`](https://github.com/chillum/ovpn-key/blob/master/defaults/ovpn-key.yml).
44
44
 
45
45
  ovpn-key also processes `~/.ovpn-key.yml` file, for now it has only one possible setting:
46
46
  ```yaml
data/bin/ovpn-key CHANGED
@@ -15,7 +15,9 @@ CRL_FILE = 'crl.pem'
15
15
  SERIAL_FILE = 'serial'
16
16
 
17
17
  options = {}
18
+ # rubocop:disable Metrics/BlockLength
18
19
  OptionParser.new do |opts|
20
+ # rubocop:enable Metrics/BlockLength
19
21
  opts.banner = "Usage: #{File.basename $PROGRAM_NAME} <options> [--nopass]"
20
22
  opts.on('--init [directory]', 'Init a CA directory (defaults to current)') do |v|
21
23
  options[:init] = v || '.'
@@ -44,7 +46,7 @@ OptionParser.new do |opts|
44
46
  check_client(v)
45
47
  options[:generate_zip] = v
46
48
  end
47
- opts.on("--revoke [name]', 'Revoke a certificate (using #{CRL_FILE}) and delete it") do |v|
49
+ opts.on('--revoke [name]', "Revoke a certificate (using #{CRL_FILE}) and delete it") do |v|
48
50
  abort 'Please specify what certificate to revoke' unless v
49
51
  options[:revoke] = v
50
52
  end
@@ -63,7 +65,6 @@ if options[:generate_client] && options[:generate_zip]
63
65
  # I assume that user likely wants one of them and is confused with usage
64
66
  abort 'There can be only one: --client or --zip'
65
67
  end
66
- umask = File.umask 0o077
67
68
 
68
69
  if options[:init]
69
70
  unless options[:init] == '.'
@@ -178,7 +179,6 @@ if options[:generate_zip]
178
179
 
179
180
  zip_file = File.join(File.expand_path(ZIP_DIR), "#{File.basename ovpn_file, '.ovpn'}.tblk.zip")
180
181
  File.delete(zip_file) if File.exist?(zip_file)
181
- File.umask umask
182
182
  Zip::File.open(zip_file, Zip::File::CREATE) do |zip|
183
183
  zip.get_output_stream(ovpn_file) {|f|
184
184
  f.write File.read(ovpn_file)
data/lib/functions.rb CHANGED
@@ -26,6 +26,17 @@ def ask_password(name)
26
26
  password
27
27
  end
28
28
 
29
+ def unencrypt_ca_key(pass = '')
30
+ begin
31
+ OpenSSL::PKey::RSA.new File.read('ca.key'), pass
32
+ rescue OpenSSL::PKey::RSAError
33
+ # this means pass is wrong, so ask for it
34
+ OpenSSL::PKey::RSA.new File.read('ca.key'), ask_password('ca')
35
+ end
36
+ rescue OpenSSL::PKey::RSAError
37
+ retry
38
+ end
39
+
29
40
  def gen_and_sign(type, certname, password)
30
41
  gen_key(certname, password)
31
42
  sign_key(type, certname, password)
@@ -39,36 +50,48 @@ def gen_key(certname, password)
39
50
  end
40
51
 
41
52
  # type is one of: 'ca', 'server', 'client'
42
- # rubocop:disable Naming/MethodParameterName
43
53
  def sign_key(type, cn, password)
44
- # rubocop:enable Naming/MethodParameterName
45
54
  certname = type == 'ca' ? 'ca' : cn
46
55
  key = OpenSSL::PKey::RSA.new File.read("#{certname}.key"), password
47
- subj = OpenSSL::X509::Name.new([['CN', cn]] + REQ.to_a)
48
- serial = begin
49
- File.read(SERIAL_FILE).to_i
50
- rescue Errno::ENOENT
51
- 0
52
- end + 1
56
+ serial = new_serial
57
+ cert = gen_cert(type, cn, key.public_key, serial)
53
58
 
59
+ ca_key = type == 'ca' ? key : unencrypt_ca_key
60
+ cert.sign ca_key, OpenSSL::Digest.new(DIGEST)
61
+
62
+ File.open(SERIAL_FILE, 'w') {|f| f.write serial }
63
+ File.open("#{certname}.crt", 'w') {|f| f.write cert.to_pem }
64
+ end
65
+
66
+ def gen_cert(type, cn, pubkey, serial)
67
+ cert = basic_cert(type, cn)
68
+ cert.public_key = pubkey
69
+ cert.serial = serial
70
+
71
+ customize_cert(type, cert)
72
+ end
73
+
74
+ def basic_cert(type, cn)
54
75
  cert = OpenSSL::X509::Certificate.new
76
+
55
77
  cert.version = 2
56
- cert.serial = serial
57
- cert.not_before = Time.now
58
- cert.not_after =
59
- Time.now +
60
- case type
61
- when 'ca'
62
- EXPIRE['ca']
63
- when 'server'
64
- EXPIRE['server']
65
- when 'client'
66
- EXPIRE['client']
67
- # days to seconds
68
- end * 86_400
69
- cert.public_key = key.public_key
70
- cert.subject = subj
78
+ cert.subject = OpenSSL::X509::Name.new([['CN', cn]] + REQ.to_a)
71
79
  cert.issuer = OpenSSL::X509::Name.new([['CN', CN_CA]] + REQ.to_a)
80
+ cert.not_before = Time.now
81
+ cert.not_after = time_after_days(EXPIRE[type])
82
+
83
+ cert
84
+ end
85
+
86
+ def time_after_days(days)
87
+ Time.now + days * 86_400 # days to seconds
88
+ end
89
+
90
+ # rubocop:disable Metrics/MethodLength
91
+ # rubocop:disable Metrics/AbcSize
92
+ def customize_cert(type, cert)
93
+ # rubocop:enable Metrics/AbcSize
94
+ # rubocop:enable Metrics/MethodLength
72
95
 
73
96
  ef = OpenSSL::X509::ExtensionFactory.new nil, cert
74
97
  ef.issuer_certificate = cert
@@ -80,7 +103,6 @@ def sign_key(type, cn, password)
80
103
  case type
81
104
  when 'ca'
82
105
  cert.add_extension ef.create_extension('keyUsage', 'cRLSign,keyCertSign')
83
- cert.sign key, OpenSSL::Digest.new(DIGEST)
84
106
  when 'server'
85
107
  cert.add_extension ef.create_extension('keyUsage', 'keyEncipherment,digitalSignature')
86
108
  cert.add_extension ef.create_extension('extendedKeyUsage', 'serverAuth')
@@ -88,34 +110,21 @@ def sign_key(type, cn, password)
88
110
  cert.add_extension ef.create_extension('keyUsage', 'digitalSignature')
89
111
  cert.add_extension ef.create_extension('extendedKeyUsage', 'clientAuth')
90
112
  end
91
- unless type == 'ca'
92
- ca_key = begin
93
- OpenSSL::PKey::RSA.new File.read('ca.key'), ask_password('ca')
94
- rescue OpenSSL::PKey::RSAError
95
- retry
96
- end
97
- cert.sign ca_key, OpenSSL::Digest.new(DIGEST)
98
- end
99
-
100
- File.open(SERIAL_FILE, 'w') {|f| f.write serial }
101
- File.open("#{certname}.crt", 'w') {|f| f.write cert.to_pem }
113
+ cert
102
114
  end
103
115
 
116
+ # rubocop:disable Metrics/AbcSize
104
117
  def revoke(certname)
118
+ # rubocop:enable Metrics/AbcSize
105
119
  crl = OpenSSL::X509::CRL.new(File.read(CRL_FILE))
106
120
  cert = OpenSSL::X509::Certificate.new(File.read("#{certname}.crt"))
107
121
  revoke = OpenSSL::X509::Revoked.new.tap {|rev|
108
122
  rev.serial = cert.serial
109
123
  rev.time = Time.now
110
124
  }
111
- crl.next_update = Time.now + EXPIRE['crl'] * 86_400 # days to seconds
125
+ crl.next_update = time_after_days(EXPIRE['crl'])
112
126
  crl.add_revoked(revoke)
113
- begin
114
- update_crl(crl, ask_password('ca'))
115
- rescue OpenSSL::PKey::RSAError
116
- retry
117
- end
118
-
127
+ update_crl(crl, '')
119
128
  %w[crt key].each {|ext| File.delete "#{certname}.#{ext}" }
120
129
  end
121
130
 
@@ -128,14 +137,19 @@ def gen_crl(ca_pass)
128
137
  end
129
138
 
130
139
  def update_crl(crl, ca_pass)
131
- ca_key = OpenSSL::PKey::RSA.new File.read('ca.key'), ca_pass
140
+ ca_key = unencrypt_ca_key(ca_pass)
132
141
  crl.last_update = Time.now
133
- crl.next_update = Time.now + EXPIRE['crl'] * 86_400 # days to seconds
134
- crl.version = crl.version + 1
142
+ crl.next_update = time_after_days(EXPIRE['crl'])
135
143
  crl.sign(ca_key, OpenSSL::Digest.new(DIGEST))
136
144
  File.open(CRL_FILE, 'w') {|f| f.write crl.to_pem }
137
145
  end
138
146
 
147
+ def new_serial
148
+ File.read(SERIAL_FILE).to_i + 1
149
+ rescue Errno::ENOENT
150
+ 0
151
+ end
152
+
139
153
  def create_dir(name)
140
154
  return if Dir.exist? name
141
155
 
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ::VERSION = '0.8'
3
+ ::VERSION = '0.8.5'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ovpn-key
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.8'
4
+ version: 0.8.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vasily Korytov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-08 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip