ovpn-key 0.8 → 0.8.5

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: 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