pki_express 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +3 -0
  3. data/.gitignore +28 -0
  4. data/CHANGELOG.md +2 -0
  5. data/Gemfile +4 -0
  6. data/README.md +24 -0
  7. data/Rakefile +1 -0
  8. data/lib/pki_express.rb +48 -0
  9. data/lib/pki_express/auth_complete_result.rb +22 -0
  10. data/lib/pki_express/auth_start_result.rb +77 -0
  11. data/lib/pki_express/authentication.rb +285 -0
  12. data/lib/pki_express/base_signer.rb +55 -0
  13. data/lib/pki_express/cades_signature_starter.rb +242 -0
  14. data/lib/pki_express/command_error.rb +14 -0
  15. data/lib/pki_express/commands.rb +21 -0
  16. data/lib/pki_express/enum.rb +9 -0
  17. data/lib/pki_express/error_codes.rb +46 -0
  18. data/lib/pki_express/installation_not_found_error.rb +8 -0
  19. data/lib/pki_express/name.rb +48 -0
  20. data/lib/pki_express/pades_horizontal_align.rb +9 -0
  21. data/lib/pki_express/pades_measurement_units.rb +8 -0
  22. data/lib/pki_express/pades_page_optimization.rb +51 -0
  23. data/lib/pki_express/pades_page_orientation.rb +9 -0
  24. data/lib/pki_express/pades_paper_size.rb +21 -0
  25. data/lib/pki_express/pades_signature_starter.rb +232 -0
  26. data/lib/pki_express/pades_size.rb +17 -0
  27. data/lib/pki_express/pades_text_horizontal_align.rb +8 -0
  28. data/lib/pki_express/pades_vertical_align.rb +9 -0
  29. data/lib/pki_express/pades_visual_auto_positioning.rb +22 -0
  30. data/lib/pki_express/pades_visual_image.rb +52 -0
  31. data/lib/pki_express/pades_visual_manual_positioning.rb +17 -0
  32. data/lib/pki_express/pades_visual_positioning.rb +28 -0
  33. data/lib/pki_express/pades_visual_rectangle.rb +74 -0
  34. data/lib/pki_express/pades_visual_representation.rb +22 -0
  35. data/lib/pki_express/pades_visual_text.rb +35 -0
  36. data/lib/pki_express/pk_certificate.rb +62 -0
  37. data/lib/pki_express/pki_brazil_certificate_fields.rb +58 -0
  38. data/lib/pki_express/pki_brazil_certificate_types.rb +19 -0
  39. data/lib/pki_express/pki_express_config.rb +26 -0
  40. data/lib/pki_express/pki_express_operator.rb +216 -0
  41. data/lib/pki_express/pki_italy_certificate_fields.rb +16 -0
  42. data/lib/pki_express/pki_italy_certificate_types.rb +11 -0
  43. data/lib/pki_express/signature_finisher.rb +298 -0
  44. data/lib/pki_express/signature_start_result.rb +13 -0
  45. data/lib/pki_express/signature_starter.rb +115 -0
  46. data/lib/pki_express/signer.rb +106 -0
  47. data/lib/pki_express/standard_signature_policies.rb +36 -0
  48. data/lib/pki_express/timestamp_authority.rb +51 -0
  49. data/lib/pki_express/validation_error.rb +8 -0
  50. data/lib/pki_express/validation_item.rb +43 -0
  51. data/lib/pki_express/validation_results.rb +121 -0
  52. data/lib/pki_express/version.rb +3 -0
  53. data/lib/pki_express/version_manager.rb +21 -0
  54. data/pki_express.gemspec +27 -0
  55. metadata +129 -0
@@ -0,0 +1,9 @@
1
+ module PkiExpress
2
+ class PadesHorizontalAlign < Enum
3
+ LEFT = 'Left'
4
+ CENTER = 'Center'
5
+ RIGHT = 'Right'
6
+
7
+ VALUES = [ LEFT, CENTER, RIGHT ]
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module PkiExpress
2
+ class PadesMeasurementUnits < Enum
3
+ CENTIMETERS = 'Centimeters'
4
+ PDF_POINTS = 'PdfPoints'
5
+
6
+ VALUES = [ CENTIMETERS, PDF_POINTS ]
7
+ end
8
+ end
@@ -0,0 +1,51 @@
1
+ module PkiExpress
2
+ class PadesPageOptimization
3
+ attr_reader :custom_paper_size, :paper_size, :page_orientation
4
+
5
+ def initialize(paper_size=nil, custom_paper_size=nil)
6
+ @page_orientation = PadesPageOrientation::AUTO
7
+ if custom_paper_size
8
+ @paper_size = PadesPaperSize::CUSTOM
9
+ @custom_paper_size = custom_paper_size
10
+ else
11
+ @paper_size = paper_size
12
+ end
13
+ end
14
+
15
+ def custom_paper_size=(value)
16
+ @custom_paper_size = value
17
+ @paper_size = PadesPaperSize::CUSTOM
18
+ end
19
+
20
+ def paper_size=(value)
21
+ unless PadesPaperSize.contains?(value)
22
+ raise 'The provided "paper_size" is not valid. Try using PadesPaperSize constants'
23
+ end
24
+ @paper_size = value
25
+ end
26
+
27
+ def page_orientation=(value)
28
+ unless PadesPageOrientation.contains?(value)
29
+ raise 'The provided "page_orientation" is not valid. Try using PadesPageOrientation constants'
30
+ end
31
+ @page_orientation = value
32
+ end
33
+
34
+ def to_model
35
+ custom_paper_size = nil
36
+ if @paper_size == PadesPaperSize::CUSTOM
37
+ if @custom_paper_size
38
+ custom_paper_size = @custom_paper_size&.to_model
39
+ else
40
+ raise 'paper_size is set to :custom but no custom_paper_size was set'
41
+ end
42
+ end
43
+
44
+ {
45
+ 'pageSize': @paper_size,
46
+ 'customPageSize': custom_paper_size,
47
+ 'pageOrientation': @page_orientation,
48
+ }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,9 @@
1
+ module PkiExpress
2
+ class PadesPageOrientation < Enum
3
+ AUTO = 'Auto'
4
+ PORTRAIT = 'Portrait'
5
+ LANDSCAPE = 'Landscape'
6
+
7
+ VALUES = [ AUTO, PORTRAIT, LANDSCAPE ]
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module PkiExpress
2
+ class PadesPaperSize < Enum
3
+ CUSTOM = 'Custom'
4
+ A0 = 'A0'
5
+ A1 = 'A1'
6
+ A2 = 'A2'
7
+ A3 = 'A3'
8
+ A4 = 'A4'
9
+ A5 = 'A5'
10
+ A6 = 'A6'
11
+ A7 = 'A7'
12
+ A8 = 'A8'
13
+ LETTER = 'Letter'
14
+ LEGAL = 'Legal'
15
+ LEDGER = 'Ledger'
16
+
17
+ VALUES = [
18
+ CUSTOM, A0, A1, A2, A3, A4, A5, A6, A7, A8, LETTER, LEGAL, LEDGER
19
+ ]
20
+ end
21
+ end
@@ -0,0 +1,232 @@
1
+ module PkiExpress
2
+ class PadesSignatureStarter < SignatureStarter
3
+ attr_accessor :suppress_default_visual_representation
4
+
5
+ def initialize(config=PkiExpressConfig.new)
6
+ super(config)
7
+ @pdf_to_sign_path = nil
8
+ @vr_json_path = nil
9
+ @suppress_default_visual_representation = false
10
+ end
11
+
12
+ # region The "pdf_to_sign" accessors
13
+
14
+ def pdf_to_sign
15
+ _get_pdf_to_sign
16
+ end
17
+
18
+ def _get_pdf_to_sign
19
+ unless @pdf_to_sign_path
20
+ return nil
21
+ end
22
+
23
+ File.read(@pdf_to_sign_path)
24
+ end
25
+ private :_get_pdf_to_sign
26
+
27
+ def pdf_to_sign=(content_raw)
28
+ _set_pdf_to_sign(content_raw)
29
+ end
30
+
31
+ def _set_pdf_to_sign(content_raw)
32
+ unless content_raw
33
+ raise 'The provided "pdf_to_sign" is not valid'
34
+ end
35
+
36
+ temp_file_path = self.create_temp_file
37
+ File.open(temp_file_path, 'wb') do |f|
38
+ f.write(content_raw)
39
+ end
40
+ @pdf_to_sign_path = temp_file_path
41
+ end
42
+ private :_set_pdf_to_sign
43
+
44
+ def pdf_to_sign_base64
45
+ _get_pdf_to_sign_base64
46
+ end
47
+
48
+ def _get_pdf_to_sign_base64
49
+ unless @pdf_to_sign_path
50
+ return nil
51
+ end
52
+
53
+ content = File.read(@pdf_to_sign_path)
54
+ Base64.encode64(content)
55
+ end
56
+ private :_get_pdf_to_sign_base64
57
+
58
+ def pdf_to_sign_base64=(content_base64)
59
+ _set_pdf_to_sign_base64(content_base64)
60
+ end
61
+
62
+ def _set_pdf_to_sign_base64(content_base64)
63
+ unless content_base64
64
+ raise 'The provided "pdf_to_sign_base64" is not valid'
65
+ end
66
+
67
+ begin
68
+ content_raw = Base64.decode64(content_base64)
69
+ rescue Error
70
+ raise 'The provided "pdf_to_sign_base64" is not Base64-encoded'
71
+ end
72
+
73
+ _set_pdf_to_sign(content_raw)
74
+ end
75
+ private :_set_pdf_to_sign_base64
76
+
77
+ def pdf_to_sign_path
78
+ _get_pdf_to_sign_path
79
+ end
80
+
81
+ def _get_pdf_to_sign_path
82
+ @pdf_to_sign_path
83
+ end
84
+ private :_get_pdf_to_sign_path
85
+
86
+ def pdf_to_sign_path=(path)
87
+ _set_pdf_to_sign_path(path)
88
+ end
89
+
90
+ def _set_pdf_to_sign_path(path)
91
+ unless path
92
+ raise 'The provided "pdf_to_sign_path" is not valid'
93
+ end
94
+ unless File.exists?(path)
95
+ raise 'The provided "pdf_to_sign_path" does not exist'
96
+ end
97
+ @pdf_to_sign_path = path
98
+ end
99
+ private :_set_pdf_to_sign_path
100
+
101
+ # endregion
102
+
103
+ # region set_visual_representation
104
+
105
+ def visual_representation_content_raw
106
+ _get_visual_representation_content_raw
107
+ end
108
+
109
+ def _get_visual_representation_content_raw
110
+ unless @vr_json_path
111
+ return nil
112
+ end
113
+
114
+ File.read(@vr_json_path)
115
+ end
116
+ private :_get_visual_representation_content_raw
117
+
118
+ def visual_representation_content_raw=(content_raw)
119
+ _set_visual_representation_content_raw(content_raw)
120
+ end
121
+
122
+ def _set_visual_representation_content_raw(content_raw)
123
+ unless content_raw
124
+ raise 'The provided "visual_representation" is not valid'
125
+ end
126
+
127
+ temp_file_path = self.create_temp_file
128
+ File.open(temp_file_path, 'wb') do |f|
129
+ f.write(content_raw)
130
+ end
131
+ @vr_json_path = temp_file_path
132
+ end
133
+ private :_set_visual_representation_content_raw
134
+
135
+ def visual_representation_path
136
+ _get_visual_representation_path
137
+ end
138
+
139
+ def _get_visual_representation_path
140
+ @vr_json_path
141
+ end
142
+ private :_get_visual_representation_path
143
+
144
+ def visual_representation_path=(path)
145
+ _set_visual_representation_path(path)
146
+ end
147
+
148
+ def _set_visual_representation_path(path)
149
+ unless path
150
+ raise 'The provided "visual_representation_path" is not valid'
151
+ end
152
+ unless File.exists?(path)
153
+ raise 'The provided "visual_representation_path" does not exist'
154
+ end
155
+ @vr_json_path = path
156
+ end
157
+ private :_set_visual_representation_path
158
+
159
+ def visual_representation
160
+ _get_visual_representation
161
+ end
162
+
163
+ def _get_visual_representation
164
+ unless @vr_json_path
165
+ return nil
166
+ end
167
+
168
+ content = File.read(@vr_json_path)
169
+ JSON.parse(content)
170
+ end
171
+ private :_get_visual_representation
172
+
173
+
174
+ def visual_representation=(vr)
175
+ _set_visual_representation(vr)
176
+ end
177
+
178
+ def _set_visual_representation(vr)
179
+ temp_file_path = self.create_temp_file
180
+ json = JSON.pretty_generate(vr.to_model)
181
+ File.open(temp_file_path, 'w') do |f|
182
+ f.write(json)
183
+ end
184
+ @vr_json_path = temp_file_path
185
+ end
186
+ private :_set_visual_representation
187
+
188
+ # endregion
189
+
190
+ def start
191
+ unless @pdf_to_sign_path
192
+ raise 'The PDF to be signed was not set'
193
+ end
194
+
195
+ unless @certificate_path
196
+ raise 'The certificate was not set'
197
+ end
198
+
199
+ # Generate transfer file.
200
+ transfer_file_id = get_transfer_filename
201
+
202
+ args = [
203
+ @pdf_to_sign_path,
204
+ @certificate_path,
205
+ File.expand_path(transfer_file_id, @config.transfer_data_folder),
206
+ ]
207
+
208
+ # Verify and add common options between signers.
209
+ verify_and_add_common_options(args)
210
+
211
+ if @vr_json_path
212
+ args.append('--visual-rep')
213
+ args.append(@vr_json_path)
214
+ end
215
+
216
+ if @suppress_default_visual_representation
217
+ args.append('--suppress-default-visual-rep')
218
+
219
+ # This option can only be used on versions greater than 1.13.1 of the
220
+ # PKI Express.
221
+ @version_manager.require_version('1.13.1')
222
+ end
223
+
224
+ # Invoke command.
225
+ result = invoke(Commands::START_PADES, args)
226
+
227
+ # Parse output and return model.
228
+ model = parse_output(result)
229
+ SignatureStartResult.new(model, transfer_file_id)
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,17 @@
1
+ module PkiExpress
2
+ class PadesSize
3
+ attr_accessor :width, :height
4
+
5
+ def initialize(width, height)
6
+ @width = width
7
+ @height = height
8
+ end
9
+
10
+ def to_model
11
+ {
12
+ width: @width,
13
+ height: @height,
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ module PkiExpress
2
+ class PadesTextHorizontalAlign < Enum
3
+ LEFT = 'Left'
4
+ RIGHT = 'Right'
5
+
6
+ VALUES = [ LEFT, RIGHT ]
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module PkiExpress
2
+ class PadesVerticalAlign < Enum
3
+ TOP = 'Top'
4
+ CENTER = 'Center'
5
+ BOTTOM = 'Bottom'
6
+
7
+ VALUES = [ TOP, CENTER, BOTTOM ]
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ module PkiExpress
2
+ class PadesVisualAutoPositioning < PadesVisualPositioning
3
+ attr_accessor :container, :signature_rectangle_size, :row_spacing
4
+
5
+ def initialize(page_number=nil, measurement_units=nil, container=nil, signature_rectangle_size=nil, row_spacing=nil)
6
+ super(page_number, measurement_units)
7
+ @container = container
8
+ @signature_rectangle_size = signature_rectangle_size
9
+ @row_spacing = row_spacing
10
+ end
11
+
12
+ def to_model
13
+ model = super
14
+ model['auto'] = {
15
+ 'container': @container&.to_model,
16
+ 'signatureRectangleSize': @signature_rectangle_size&.to_model,
17
+ 'rowSpacing': @row_spacing,
18
+ }
19
+ model
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,52 @@
1
+ module PkiExpress
2
+ class PadesVisualImage
3
+ attr_reader :horizontal_align, :vertical_align
4
+ attr_accessor :opacity, :content, :url,
5
+ :mime_type
6
+
7
+ def initialize(image_content=nil, image_url = nil, image_mime_type=nil)
8
+ @opacity = 100
9
+ @horizontal_align = PadesHorizontalAlign::CENTER
10
+ @vertical_align = PadesVerticalAlign::CENTER
11
+ @content = image_content
12
+ @url = image_url
13
+ @mime_type = image_mime_type
14
+ end
15
+
16
+ def horizontal_align=(value)
17
+ unless PadesHorizontalAlign.contains?(value)
18
+ raise 'The provided "horizontal_align" is not valid. Try using PadesHorizontalAlign constants'
19
+ end
20
+
21
+ @horizontal_align = value
22
+ end
23
+
24
+ def vertical_align=(value)
25
+ unless PadesVerticalAlign.contains?(value)
26
+ raise 'The provided "vertical_align" is not valid. Try using PadesVerticalAlign constants'
27
+ end
28
+
29
+ @vertical_align = value
30
+ end
31
+
32
+ def to_model
33
+ resource_model = {
34
+ 'mimeType': @mime_type,
35
+ }
36
+ if @content
37
+ resource_model['content'] = Base64.encode64(@content)
38
+ elsif @url
39
+ resource_model['url'] = @url
40
+ else
41
+ raise 'The image content was not set, neither its URL'
42
+ end
43
+
44
+ {
45
+ resource: resource_model,
46
+ opacity: @opacity,
47
+ horizontal_align: @horizontal_align,
48
+ vertical_align: @vertical_align,
49
+ }
50
+ end
51
+ end
52
+ end