thales-pse 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9822d9ede725eb7e93e61f5da6edd57880e9085263fac58f4e0d28ac72949747
4
+ data.tar.gz: c3c6041f5dbde1e17a4709092be0a425f752f11535fb2db9074cb39d2a19abbb
5
+ SHA512:
6
+ metadata.gz: 8bfc6a8cd47b76425c40c9d00959997583d07c5a62394a7e6f928ff367d89905c5dbcc189c0aebbc780a1e33753501c980b2bd74dc09f5403732e327e78d3f3b
7
+ data.tar.gz: 51661eade08e5edfd65a7d61a2e3d4e32978e5c07aebb0552067ef92623e091b44f9e8e1d7b39eda3ea916f9d45315ef99819ae2ff8b7fca49e55d2aa644b0e7
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in thales-pse.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ #gem 'toolrack', path: '/mnt/Vault/08.Dev/01.Workspaces/WIP/toolrack'
13
+
data/Gemfile.lock ADDED
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ thales-pse (0.1.0)
5
+ tlogger
6
+ toolrack
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ base58 (0.2.3)
12
+ devops_helper (0.5.0)
13
+ git_cli
14
+ gvcs
15
+ tlogger
16
+ toolrack
17
+ tty-prompt (= 0.22.0)
18
+ diff-lcs (1.4.4)
19
+ git_cli (0.8.0)
20
+ gvcs (>= 0.1.0)
21
+ ptools (~> 1.4.0)
22
+ tlogger (>= 0.21)
23
+ toolrack (>= 0.4.0)
24
+ gvcs (0.1.0)
25
+ pastel (0.8.0)
26
+ tty-color (~> 0.5)
27
+ ptools (1.4.2)
28
+ rake (13.0.6)
29
+ rspec (3.10.0)
30
+ rspec-core (~> 3.10.0)
31
+ rspec-expectations (~> 3.10.0)
32
+ rspec-mocks (~> 3.10.0)
33
+ rspec-core (3.10.1)
34
+ rspec-support (~> 3.10.0)
35
+ rspec-expectations (3.10.1)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.10.0)
38
+ rspec-mocks (3.10.2)
39
+ diff-lcs (>= 1.2.0, < 2.0)
40
+ rspec-support (~> 3.10.0)
41
+ rspec-support (3.10.2)
42
+ tlogger (0.26.1)
43
+ toolrack (0.15.0)
44
+ base58
45
+ tlogger
46
+ tty-color (0.6.0)
47
+ tty-cursor (0.7.1)
48
+ tty-prompt (0.22.0)
49
+ pastel (~> 0.8)
50
+ tty-reader (~> 0.8)
51
+ tty-reader (0.9.0)
52
+ tty-cursor (~> 0.7)
53
+ tty-screen (~> 0.8)
54
+ wisper (~> 2.0)
55
+ tty-screen (0.8.1)
56
+ wisper (2.0.1)
57
+
58
+ PLATFORMS
59
+ java
60
+ universal-java-1.8
61
+ x86_64-linux
62
+
63
+ DEPENDENCIES
64
+ devops_helper
65
+ rake (~> 13.0)
66
+ rspec (~> 3.0)
67
+ thales-pse!
68
+
69
+ BUNDLED WITH
70
+ 2.2.28
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Thales::Pse
2
+
3
+ Collection of utilities to integrates with the Thales (Previously SafeNet) ProtectServer External (PSE) HSM.
4
+
5
+ It is tested to ease the usage for local development with the simulator. Not for production use.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'thales-pse'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install thales-pse
22
+
23
+ ## Usage
24
+
25
+ Check the usage inside the spec/thales/hsm\_spec.rb
26
+
27
+ Currently it is just API to assist in setting up the HSM for usage.
28
+
29
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ require 'devops_helper'
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "thales/pse"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,69 @@
1
+
2
+ require 'pty'
3
+ require 'expect'
4
+ require 'timeout'
5
+
6
+ module Thales
7
+ module Pse
8
+ module Cli
9
+ include TR::CondUtils
10
+ include TR::CliUtils
11
+
12
+ class ExecutableNotFoundError < StandardError; end
13
+
14
+ def cli_exec(exec, &block)
15
+
16
+ exePath = which(exec)
17
+ raise ExecutableNotFoundError, "#{exec} cannot be found" if is_empty?(exePath)
18
+ raise Error, "Block is required" if not block
19
+
20
+ params = block.call(:params) || []
21
+ expect_list = block.call(:expect_list)
22
+
23
+ output = block.call(:output) || TR::NullOut.new
24
+
25
+ cmd = "#{exePath} #{params.join(" ")}"
26
+
27
+ logger.tdebug :cmd, "cli_exec command : #{cmd}"
28
+
29
+ PTY.spawn(exePath, *params) do |read, write, pid|
30
+
31
+ begin
32
+
33
+ if not is_empty?(expect_list)
34
+ expect_list.each do |ex|
35
+ to = ex[:timeout] || 1
36
+ cont = read.expect(/#{ex[:matcher]}/, to)
37
+ output.puts cont
38
+ write.puts block.call(ex[:block_key], cont)
39
+ end
40
+ end
41
+
42
+ Timeout.timeout(1) do
43
+ read.each do |l|
44
+ output.puts l if not_empty?(l)
45
+ end
46
+ end
47
+
48
+ rescue Timeout::Error => e
49
+ read.close
50
+ write.close
51
+ Process.kill('TERM',pid)
52
+ output.puts "Process #{cmd} ('#{pid}') killed due to timeout"
53
+ rescue Errno::EIO
54
+ output.puts "[Done] #{cmd}"
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ def logger
61
+ if @logger.nil?
62
+ @logger = Tlogger.new
63
+ end
64
+ @logger
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,313 @@
1
+
2
+ require 'pty'
3
+ require 'expect'
4
+ require 'toolrack'
5
+ require 'timeout'
6
+
7
+ require_relative 'cli'
8
+
9
+ module Thales
10
+ module Pse
11
+ module Config
12
+ include TR::CondUtils
13
+ include TR::CliUtils
14
+ include Cli
15
+
16
+ def init(&block)
17
+
18
+ expect = [
19
+ { key: "enter new Admin SO pin:", block_key: :admin_so_pin, timeout: 1 },
20
+ { key: "confirm new Admin SO pin:", block_key: :admin_so_pin_confirm, timeout: 1 },
21
+ { key: "enter new Administrator\'s pin:", block_key: :admin_pin, timeout: 1 },
22
+ { key: "confirm new Administrator\'s pin:", block_key: :admin_pin_confirm, timeout: 1 }
23
+ ]
24
+
25
+ begin
26
+
27
+ cli_exec("ctconf") do |ops|
28
+ case ops
29
+ when :expect_list
30
+ expect
31
+ else
32
+ block.call(ops)
33
+ end
34
+ end
35
+
36
+ rescue ExecutableNotFoundError
37
+ raise Error, "Executable 'ctconf' not found from PATH. Please install the driver or add the executable to PATH"
38
+ end
39
+
40
+ end
41
+
42
+ def init_token(&block)
43
+
44
+ raise Error, "Block is required" if not block
45
+
46
+ expect = [
47
+ { key: "new token label:", block_key: :token_label, timeout: 1 },
48
+ { key: "enter Security Officer\'s pin:", block_key: :token_so_pin, timeout: 1 },
49
+ { key: "confirm Security Officer\'s pin:", block_key: :token_so_pin_confirm, timeout: 1 }
50
+ ]
51
+
52
+ slot = block.call(:slot) || 0
53
+
54
+ begin
55
+
56
+ cli_exec("ctconf") do |ops|
57
+ case ops
58
+ when :params
59
+ ["-n#{slot}"]
60
+ when :expect_list
61
+ expect
62
+ else
63
+ block.call(ops)
64
+ end
65
+ end
66
+
67
+ rescue ExecutableNotFoundError
68
+ raise Error, "Executable 'ctconf' not found from PATH. Please install the driver or add the executable to PATH"
69
+ end
70
+
71
+ end
72
+
73
+ def init_user_pin(&block)
74
+
75
+ raise Error, "Block is required" if not block
76
+
77
+ expect = [
78
+ # this key is handled locally not passed to external
79
+ { key: "Security Officer PIN.+:|current user PIN.+:", block_key: :auth_pin, timeout: 3 },
80
+ { key: "enter the new user PIN.+:", block_key: :token_user_pin, timeout: 1 },
81
+ { key: "confirm the new user PIN.+:", block_key: :token_user_pin_confirm, timeout: 1 }
82
+ ]
83
+
84
+ slot = block.call(:slot) || 0
85
+
86
+ begin
87
+
88
+ cli_exec("ctkmu") do |ops, val|
89
+ case ops
90
+ when :params
91
+ ["p","-s#{slot}"]
92
+ when :expect_list
93
+ expect
94
+ when :auth_pin
95
+ if not_empty?(val)
96
+ if val.join =~ /Security Officer/
97
+ block.call(:token_so_pin)
98
+ else
99
+ block.call(:token_user_pin)
100
+ end
101
+ end
102
+ else
103
+ block.call(ops)
104
+ end
105
+ end
106
+
107
+ rescue ExecutableNotFoundError
108
+ raise Error, "Executable 'ctconf' not found from PATH. Please install the driver or add the executable to PATH"
109
+ end
110
+
111
+ end
112
+
113
+
114
+ def genkey(type, &block)
115
+
116
+ raise Error, "Block is required" if not block
117
+
118
+ expect = [
119
+ { key: "Enter user PIN.+:", block_key: :slot_user_pin, timeout: 1 }
120
+ ]
121
+
122
+ case type
123
+ when :rsa
124
+ else
125
+ raise Error, "Unsupported key type #{type}"
126
+ end
127
+
128
+ slot = block.call(:slot) || 0
129
+
130
+ name = block.call(:name)
131
+ raise Error, "Name is required " if is_empty?(name)
132
+ name.gsub!(" ","_")
133
+
134
+ attr = block.call(:attr)
135
+ raise Error, "Attributes (attr) is required " if is_empty?(attr)
136
+ attr = [attr] if not attr.is_a?(Array)
137
+ atRes = []
138
+ attr.each do |at|
139
+ case at
140
+ when :private
141
+ atRes << "P"
142
+ when :modifiable
143
+ atRes << "M"
144
+ when :sensitive
145
+ atRes << "T"
146
+ when :wrap
147
+ atRes << "W"
148
+ when :export
149
+ atRes << "w"
150
+ when :import
151
+ atRes << "I"
152
+ when :unwrap
153
+ atRes << "U"
154
+ when :extractable
155
+ atRes << "X"
156
+ when :exportable
157
+ atRes << "x"
158
+ when :derive
159
+ atRes << "R"
160
+ when :encrypt
161
+ atRes << "E"
162
+ when :decrypt
163
+ atRes << "D"
164
+ when :sign
165
+ atRes << "S"
166
+ when :verify
167
+ atRes << "V"
168
+ when :sign_local_cert
169
+ atRes << "L"
170
+ when :usage_count
171
+ atRes << "C"
172
+ end
173
+ end
174
+
175
+ keysize = block.call(:keysize) || 2048
176
+
177
+ begin
178
+
179
+ cli_exec("ctkmu") do |ops, val|
180
+ case ops
181
+ when :params
182
+ ["c","-t#{type}","-s#{slot}","-n#{name}","-a#{atRes.join}"]
183
+ when :expect_list
184
+ expect
185
+ else
186
+ block.call(ops)
187
+ end
188
+ end
189
+
190
+ rescue ExecutableNotFoundError
191
+ raise Error, "Executable 'ctkmu' not found from PATH. Please install the driver or add the executable to PATH"
192
+ end
193
+
194
+
195
+ end
196
+
197
+ def gencert(&block)
198
+
199
+ raise Error, "Block is required" if not block
200
+
201
+ expect = [
202
+ { key: "Enter user PIN.+:", block_key: :slot_user_pin, timeout: 1 },
203
+ ]
204
+
205
+ keylabel = block.call(:keylabel)
206
+ raise Error, "Keylabel should not be empty" if is_empty?(keylabel)
207
+ keylabel.gsub!(" ","_")
208
+
209
+ slot = block.call(:slot)
210
+ validFrom = block.call(:valid_from)
211
+ #if is_empty?(validFrom) or not validFrom.is_a?(Time)
212
+ # today = Time.now
213
+ # validFrom = Time.new(today.year, today.month, today.day)
214
+ #end
215
+ validity = block.call(:validity)
216
+ if not (validity =~ /h|d|m|y/)
217
+ raise Error, "Validity requires unit in hour (h), day (d), month (m) or year (y)"
218
+ end
219
+ validTo = block.call(:valid_to)
220
+ raise Error, "Valid_to requires a time object" if (not_empty?(validTo) and not validTo.is_a?(Time))
221
+
222
+ slot = block.call(:slot) || 0
223
+ certFile = block.call(:cert_file)
224
+
225
+ cn = block.call(:common_name)
226
+ raise Error, "Common name is mandatory" if is_empty?(cn)
227
+ expect << { key: "Common Name:", block_key: :cn, timeout: 1 }
228
+ org = block.call(:org)
229
+ expect << { key: "Organization:", block_key: :org, timeout: 1 }
230
+ ou = block.call(:ou)
231
+ expect << { key: "Organizational Unit:", block_key: :ou, timeout: 1 }
232
+ loc = block.call(:locality)
233
+ expect << { key: "Locality:", block_key: :loc, timeout: 1 }
234
+ st = block.call(:state)
235
+ expect << { key: "State:", block_key: :st, timeout: 1 }
236
+ ctry = block.call(:country)
237
+ expect << { key: "Country:", block_key: :ctry, timeout: 1 }
238
+ sn = block.call(:serial_no) || SecureRandom.uuid.gsub("-","")
239
+ expect << { key: "certificate\'s serial number.+:", block_key: :sn, timeout: 1 }
240
+
241
+ params = ["c","-l#{keylabel}", "-s#{slot}"]
242
+ if not_empty?(validFrom)
243
+ params << "-b#{validFrom.strftime("%Y%m%d%H%M%S")}"
244
+ end
245
+ if not_empty?(validity)
246
+ params << "-d#{validity}"
247
+ end
248
+ if not_empty?(validTo)
249
+ params << "-e#{validTo.strftime("%Y%m%d%H%M%S")}"
250
+ end
251
+
252
+ begin
253
+
254
+ cli_exec("ctcert") do |ops, val|
255
+ case ops
256
+ when :params
257
+ params
258
+ when :expect_list
259
+ expect
260
+ when :cn
261
+ cn
262
+ when :org
263
+ org
264
+ when :ou
265
+ ou
266
+ when :loc
267
+ loc
268
+ when :st
269
+ st
270
+ when :ctry
271
+ ctry
272
+ when :sn
273
+ sn
274
+ else
275
+ block.call(ops)
276
+ end
277
+ end
278
+
279
+ rescue ExecutableNotFoundError
280
+ raise Error, "Executable 'ctkmu' not found from PATH. Please install the driver or add the executable to PATH"
281
+ end
282
+
283
+ if not_empty?(certFile)
284
+ export_cert(keylabel, certFile, slot)
285
+ end
286
+
287
+ end # gencert
288
+
289
+ def export_cert(label, outFile, slot = 0, &block)
290
+
291
+ raise Error, "Key label cannot be empty" if is_empty?(label)
292
+ raise Error, "Output file cannot be empty" if is_empty?(outFile)
293
+
294
+ label.gsub!(" ","_")
295
+
296
+ begin
297
+
298
+ cli_exec("ctcert") do |ops|
299
+ case ops
300
+ when :params
301
+ ["x","-l#{label}","-s#{slot}","-f#{outFile}"]
302
+ end
303
+ end
304
+
305
+ rescue ExecutableNotFoundError
306
+ raise Error, "Executable 'ctcert' not found from PATH. Please install the driver or add the executable to PATH"
307
+ end
308
+
309
+ end # export_cert
310
+
311
+ end
312
+ end
313
+ end
@@ -0,0 +1,75 @@
1
+
2
+ require_relative 'cli'
3
+ require_relative 'slot'
4
+
5
+ module Thales
6
+ module Pse
7
+
8
+ class HSM
9
+
10
+ def self.instance(eng = :cli)
11
+ case eng
12
+ when :cli
13
+ h = HSM.new
14
+ h.extend(Cli::HSM)
15
+ h
16
+ else
17
+ h = HSM.new
18
+ h.extend(Cli::HSM)
19
+ h
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ module Cli
26
+ module HSM
27
+ include TR::CondUtils
28
+ include TR::CliUtils
29
+ include Cli
30
+
31
+ def init_hsm(*args,&block)
32
+
33
+ expect = [
34
+ { matcher: "enter new Admin SO pin:", block_key: :admin_so_pin, timeout: 5 },
35
+ { matcher: "confirm new Admin SO pin:", block_key: :admin_so_pin_confirm, timeout: 5 },
36
+ { matcher: "enter new Administrator\'s pin:", block_key: :admin_pin, timeout: 5 },
37
+ { matcher: "confirm new Administrator\'s pin:", block_key: :admin_pin_confirm, timeout: 5 }
38
+ ]
39
+
40
+ begin
41
+
42
+ cli_exec("ctconf") do |ops|
43
+ case ops
44
+ when :expect_list
45
+ expect
46
+ else
47
+ block.call(ops)
48
+ end
49
+ end
50
+
51
+ rescue ExecutableNotFoundError
52
+ raise Error, "Executable 'ctconf' not found from PATH. Please install the driver or add the executable to PATH"
53
+ end
54
+
55
+
56
+ end
57
+
58
+ def default_user_slot
59
+ if @defUserSlot.nil?
60
+ @defUserSlot = Slot.new(0)
61
+ end
62
+ @defUserSlot
63
+ end
64
+
65
+ def default_admin_slot
66
+ if @defAdminSlot.nil?
67
+ @defAdminSlot = Slot.new(1)
68
+ end
69
+ @defAdminSlot
70
+ end
71
+
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,23 @@
1
+
2
+ require_relative 'token'
3
+
4
+ module Thales
5
+ module Pse
6
+ class Slot
7
+
8
+ attr_reader :id, :token
9
+ def initialize(id)
10
+ @id = id
11
+ end
12
+
13
+ def default_token
14
+ if @token.nil?
15
+ @token = Token.new(self)
16
+ end
17
+ @token
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,313 @@
1
+
2
+
3
+ require_relative 'cli'
4
+
5
+ module Thales
6
+ module Pse
7
+ module Cli
8
+ module Token
9
+ include TR::CondUtils
10
+ include TR::CliUtils
11
+ include Cli
12
+
13
+ def init_token(*args, &block)
14
+
15
+ init_token_so(&block)
16
+ init_token_user(&block)
17
+
18
+ end
19
+
20
+ def init_token_so(*args, &block)
21
+
22
+ raise TokenError, "Block is required" if not block
23
+ raise TokenError, "Slot is not available!" if is_empty?(@slot)
24
+
25
+ expect = [
26
+ { matcher: "new token label:", block_key: :token_label, timeout: 1 },
27
+ { matcher: "enter Security Officer\'s pin:", block_key: :token_so_pin, timeout: 1 },
28
+ { matcher: "confirm Security Officer\'s pin:", block_key: :token_so_pin_confirm, timeout: 1 }
29
+ ]
30
+
31
+ #slot = block.call(:slot) || 0
32
+ slot = @slot.id
33
+
34
+ begin
35
+
36
+ cli_exec("ctconf") do |ops|
37
+ case ops
38
+ when :params
39
+ ["-n#{slot}"]
40
+ when :expect_list
41
+ expect
42
+ else
43
+ block.call(ops)
44
+ end
45
+ end
46
+
47
+ rescue ExecutableNotFoundError
48
+ raise Error, "Executable 'ctconf' not found from PATH. Please install the driver or add the executable to PATH"
49
+ end
50
+
51
+ end
52
+
53
+ def init_token_user(*args, &block)
54
+
55
+ raise TokenError, "Block is required" if not block
56
+ raise TokenError, "Slot is not available!" if is_empty?(@slot)
57
+
58
+ expect = [
59
+ # this key is handled locally not passed to external
60
+ { matcher: "Security Officer PIN.+:|current user PIN.+:", block_key: :auth_pin, timeout: 3 },
61
+ { matcher: "enter the new user PIN.+:", block_key: :token_user_pin, timeout: 1 },
62
+ { matcher: "confirm the new user PIN.+:", block_key: :token_user_pin_confirm, timeout: 1 }
63
+ ]
64
+
65
+ #slot = block.call(:slot) || 0
66
+ slot = @slot.id
67
+
68
+ begin
69
+
70
+ cli_exec("ctkmu") do |ops, val|
71
+ case ops
72
+ when :params
73
+ ["p","-s#{slot}"]
74
+ when :expect_list
75
+ expect
76
+ when :auth_pin
77
+ if not_empty?(val)
78
+ if val.join =~ /Security Officer/
79
+ block.call(:token_so_pin)
80
+ else
81
+ block.call(:token_user_pin)
82
+ end
83
+ end
84
+ else
85
+ block.call(ops)
86
+ end
87
+ end
88
+
89
+ rescue ExecutableNotFoundError
90
+ raise Error, "Executable 'ctconf' not found from PATH. Please install the driver or add the executable to PATH"
91
+ end
92
+
93
+ end
94
+
95
+ def genkey(*args, &block)
96
+
97
+ raise TokenError, "Block is required" if not block
98
+ raise TokenError, "Slot is not available!" if is_empty?(@slot)
99
+
100
+ expect = [
101
+ { matcher: "Enter user PIN.+:", block_key: :token_user_pin, timeout: 1 }
102
+ ]
103
+
104
+ type = args.first
105
+ case type
106
+ when :rsa
107
+ else
108
+ raise Error, "Unsupported key type #{type}"
109
+ end
110
+
111
+ #slot = block.call(:slot) || 0
112
+ slot = @slot.id
113
+
114
+ keylabel = block.call(:keylabel)
115
+ raise Error, "Keylabel is required " if is_empty?(keylabel)
116
+ keylabel.gsub!(" ","_")
117
+
118
+ attr = block.call(:attr)
119
+ raise Error, "Attributes (attr) is required " if is_empty?(attr)
120
+ attr = [attr] if not attr.is_a?(Array)
121
+ atRes = []
122
+ attr.each do |at|
123
+ case at
124
+ when :private
125
+ atRes << "P"
126
+ when :modifiable
127
+ atRes << "M"
128
+ when :sensitive
129
+ atRes << "T"
130
+ when :wrap
131
+ atRes << "W"
132
+ when :export
133
+ atRes << "w"
134
+ when :import
135
+ atRes << "I"
136
+ when :unwrap
137
+ atRes << "U"
138
+ when :extractable
139
+ atRes << "X"
140
+ when :exportable
141
+ atRes << "x"
142
+ when :derive
143
+ atRes << "R"
144
+ when :encrypt
145
+ atRes << "E"
146
+ when :decrypt
147
+ atRes << "D"
148
+ when :sign
149
+ atRes << "S"
150
+ when :verify
151
+ atRes << "V"
152
+ when :sign_local_cert
153
+ atRes << "L"
154
+ when :usage_count
155
+ atRes << "C"
156
+ end
157
+ end
158
+
159
+ keysize = block.call(:keysize) || 2048
160
+
161
+ begin
162
+
163
+ cli_exec("ctkmu") do |ops, val|
164
+ case ops
165
+ when :params
166
+ ["c","-t#{type}","-s#{slot}","-n#{keylabel}","-a#{atRes.join}"]
167
+ when :expect_list
168
+ expect
169
+ else
170
+ block.call(ops)
171
+ end
172
+ end
173
+
174
+ rescue ExecutableNotFoundError
175
+ raise Error, "Executable 'ctkmu' not found from PATH. Please install the driver or add the executable to PATH"
176
+ end
177
+
178
+ end
179
+
180
+ def gencert(*args, &block)
181
+
182
+ raise TokenError, "Block is required" if not block
183
+ raise TokenError, "Slot is not available!" if is_empty?(@slot)
184
+
185
+ expect = [
186
+ { matcher: "Enter user PIN.+:", block_key: :token_user_pin, timeout: 1 },
187
+ ]
188
+
189
+ keylabel = block.call(:keylabel)
190
+ raise Error, "Keylabel should not be empty" if is_empty?(keylabel)
191
+ keylabel.gsub!(" ","_")
192
+
193
+ validFrom = block.call(:valid_from)
194
+ #if is_empty?(validFrom) or not validFrom.is_a?(Time)
195
+ # today = Time.now
196
+ # validFrom = Time.new(today.year, today.month, today.day)
197
+ #end
198
+ validity = block.call(:validity)
199
+ if not (validity =~ /h|d|m|y/)
200
+ raise Error, "Validity requires unit in hour (h), day (d), month (m) or year (y)"
201
+ end
202
+ validTo = block.call(:valid_to)
203
+ raise Error, "Valid_to requires a time object" if (not_empty?(validTo) and not validTo.is_a?(Time))
204
+
205
+ #slot = block.call(:slot) || 0
206
+ slot = @slot.id
207
+ certFile = block.call(:cert_file)
208
+
209
+ cn = block.call(:common_name)
210
+ raise Error, "Common name is mandatory" if is_empty?(cn)
211
+ expect << { matcher: "Common Name:", block_key: :cn, timeout: 1 }
212
+ org = block.call(:org)
213
+ expect << { matcher: "Organization:", block_key: :org, timeout: 1 }
214
+ ou = block.call(:ou)
215
+ expect << { matcher: "Organizational Unit:", block_key: :ou, timeout: 1 }
216
+ loc = block.call(:locality)
217
+ expect << { matcher: "Locality:", block_key: :loc, timeout: 1 }
218
+ st = block.call(:state)
219
+ expect << { matcher: "State:", block_key: :st, timeout: 1 }
220
+ ctry = block.call(:country)
221
+ expect << { matcher: "Country:", block_key: :ctry, timeout: 1 }
222
+ sn = block.call(:serial_no) || SecureRandom.uuid.gsub("-","")
223
+ expect << { matcher: "certificate\'s serial number.+:", block_key: :sn, timeout: 1 }
224
+
225
+ params = ["c","-l#{keylabel}", "-s#{slot}"]
226
+ if not_empty?(validFrom)
227
+ params << "-b#{validFrom.strftime("%Y%m%d%H%M%S")}"
228
+ end
229
+ if not_empty?(validity)
230
+ params << "-d#{validity}"
231
+ end
232
+ if not_empty?(validTo)
233
+ params << "-e#{validTo.strftime("%Y%m%d%H%M%S")}"
234
+ end
235
+
236
+ begin
237
+
238
+ cli_exec("ctcert") do |ops, val|
239
+ case ops
240
+ when :params
241
+ params
242
+ when :expect_list
243
+ expect
244
+ when :cn
245
+ cn
246
+ when :org
247
+ org
248
+ when :ou
249
+ ou
250
+ when :loc
251
+ loc
252
+ when :st
253
+ st
254
+ when :ctry
255
+ ctry
256
+ when :sn
257
+ sn
258
+ else
259
+ block.call(ops)
260
+ end
261
+ end
262
+
263
+ rescue ExecutableNotFoundError
264
+ raise Error, "Executable 'ctkmu' not found from PATH. Please install the driver or add the executable to PATH"
265
+ end
266
+
267
+ if not_empty?(certFile)
268
+ export_cert(keylabel, certFile)
269
+ end
270
+
271
+ end
272
+
273
+ def export_cert(label, outFile, &block)
274
+
275
+ raise TokenError, "Key label cannot be empty" if is_empty?(label)
276
+ raise TokenError, "Output file cannot be empty" if is_empty?(outFile)
277
+ raise TokenError, "Slot is not available!" if is_empty?(@slot)
278
+
279
+ slot = @slot.id
280
+ label.gsub!(" ","_")
281
+
282
+ begin
283
+
284
+ cli_exec("ctcert") do |ops|
285
+ case ops
286
+ when :params
287
+ ["x","-l#{label}","-s#{slot}","-f#{outFile}"]
288
+ end
289
+ end
290
+
291
+ rescue ExecutableNotFoundError
292
+ raise Error, "Executable 'ctcert' not found from PATH. Please install the driver or add the executable to PATH"
293
+ end
294
+
295
+
296
+ end
297
+
298
+ end
299
+ end # Cli
300
+
301
+ class Token
302
+ include Cli::Token
303
+
304
+ attr_accessor :slot
305
+ def initialize(slot)
306
+ @slot = slot
307
+ end
308
+
309
+ end
310
+
311
+ end
312
+
313
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Thales
4
+ module Pse
5
+ VERSION = "0.1.1"
6
+ end
7
+ end
data/lib/thales/pse.rb ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tlogger'
4
+ require 'toolrack'
5
+
6
+ require_relative "pse/version"
7
+ require_relative "pse/hsm"
8
+
9
+ module Thales
10
+ module Pse
11
+ class Error < StandardError; end
12
+
13
+ class HSMError < StandardError; end
14
+ class SlotError < StandardError; end
15
+ class TokenError < StandardError; end
16
+
17
+ # Your code goes here...
18
+
19
+
20
+ end
21
+ end
data/pty_test.rb ADDED
@@ -0,0 +1,23 @@
1
+
2
+ require 'pty'
3
+
4
+ prs, pws = PTY.open
5
+ r, w = IO.pipe
6
+
7
+ pid = spawn("/opt/safenet/protecttoolkit5/cpsdk/bin/linux-x86_64/ctconf 2>&1", in: r, out: pws)
8
+
9
+ r.close
10
+ pws.close
11
+
12
+ loop do
13
+ begin
14
+ line = prs.gets
15
+ rescue Errno::EIO => ex
16
+ p ex
17
+ Process.kill('TERM', pid)
18
+ break
19
+ end
20
+ end
21
+
22
+ puts "done"
23
+
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/thales/pse/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "thales-pse"
7
+ spec.version = Thales::Pse::VERSION
8
+ spec.authors = ["Ian"]
9
+ spec.email = ["cameronian0@protonmail.com"]
10
+
11
+ spec.summary = ""
12
+ spec.description = ""
13
+ spec.homepage = ""
14
+ spec.required_ruby_version = ">= 2.4.0"
15
+
16
+ #spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
17
+
18
+ #spec.metadata["homepage_uri"] = spec.homepage
19
+ #spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
20
+ #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
21
+
22
+ # Specify which files should be added to the gem when it is released.
23
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
27
+ end
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_dependency 'tlogger'
34
+ spec.add_dependency 'toolrack'
35
+
36
+ spec.add_development_dependency "devops_helper"
37
+
38
+ # Uncomment to register a new dependency of your gem
39
+ # spec.add_dependency "example-gem", "~> 1.0"
40
+
41
+ # For more information and examples about making a new gem, checkout our
42
+ # guide at: https://bundler.io/guides/creating_gem.html
43
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thales-pse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ian
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-10-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tlogger
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: toolrack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: devops_helper
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: ''
56
+ email:
57
+ - cameronian0@protonmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".rspec"
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - README.md
66
+ - Rakefile
67
+ - bin/console
68
+ - bin/setup
69
+ - lib/thales/pse.rb
70
+ - lib/thales/pse/cli.rb
71
+ - lib/thales/pse/config.rb
72
+ - lib/thales/pse/hsm.rb
73
+ - lib/thales/pse/slot.rb
74
+ - lib/thales/pse/token.rb
75
+ - lib/thales/pse/version.rb
76
+ - pty_test.rb
77
+ - thales-pse.gemspec
78
+ homepage: ''
79
+ licenses: []
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 2.4.0
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubygems_version: 3.2.22
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: ''
100
+ test_files: []