rest_pki 1.0.0 → 1.1.0

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +6 -1
  4. data/lib/rest_pki.rb +32 -0
  5. data/lib/rest_pki/cades_signature.rb +52 -0
  6. data/lib/rest_pki/color.rb +37 -0
  7. data/lib/rest_pki/digest_algorithm.rb +158 -0
  8. data/lib/rest_pki/digest_algorithm_and_value.rb +29 -0
  9. data/lib/rest_pki/oids.rb +163 -0
  10. data/lib/rest_pki/pades_measurement_units.rb +6 -0
  11. data/lib/rest_pki/pades_page_orientation.rb +7 -0
  12. data/lib/rest_pki/pades_paper_size.rb +17 -0
  13. data/lib/rest_pki/pades_signature_explorer.rb +17 -0
  14. data/lib/rest_pki/pades_signer_info.rb +11 -0
  15. data/lib/rest_pki/pades_size.rb +17 -0
  16. data/lib/rest_pki/pades_visual_rectangle.rb +25 -0
  17. data/lib/rest_pki/page_optimization.rb +34 -0
  18. data/lib/rest_pki/pdf_container_definition.rb +266 -0
  19. data/lib/rest_pki/pdf_helper.rb +29 -0
  20. data/lib/rest_pki/pdf_mark.rb +81 -0
  21. data/lib/rest_pki/pdf_mark_element.rb +54 -0
  22. data/lib/rest_pki/pdf_mark_element_type.rb +7 -0
  23. data/lib/rest_pki/pdf_mark_image.rb +25 -0
  24. data/lib/rest_pki/pdf_mark_image_element.rb +33 -0
  25. data/lib/rest_pki/pdf_mark_page_options.rb +8 -0
  26. data/lib/rest_pki/pdf_mark_qr_code_element.rb +32 -0
  27. data/lib/rest_pki/pdf_mark_text_element.rb +47 -0
  28. data/lib/rest_pki/pdf_marker.rb +61 -0
  29. data/lib/rest_pki/pdf_text_section.rb +57 -0
  30. data/lib/rest_pki/pdf_text_style.rb +7 -0
  31. data/lib/rest_pki/pk_algorithms.rb +173 -0
  32. data/lib/rest_pki/pk_certificate.rb +99 -0
  33. data/lib/rest_pki/resource_content_or_reference.rb +25 -0
  34. data/lib/rest_pki/resources/pades_explorer_model.rb +12 -0
  35. data/lib/rest_pki/resources/pdf_marker_model.rb +12 -0
  36. data/lib/rest_pki/signature_algorithm_and_value.rb +11 -0
  37. data/lib/rest_pki/signature_explorer.rb +48 -0
  38. data/lib/rest_pki/signature_policy_identifier.rb +10 -0
  39. data/lib/rest_pki/validation_item.rb +2 -2
  40. data/lib/rest_pki/validation_results.rb +11 -11
  41. data/lib/rest_pki/version.rb +1 -1
  42. metadata +37 -3
@@ -0,0 +1,54 @@
1
+ module RestPki
2
+ class PdfMarkElement
3
+ attr_accessor :element_type, :relative_container, :rotation, :opacity
4
+
5
+ def initialize(element_type, relative_container = nil)
6
+ @element_type = element_type
7
+ @relative_container = relative_container
8
+ @rotation = 0
9
+ @opacity = 100
10
+ end
11
+
12
+ def to_model
13
+ {
14
+ elementType: @element_type,
15
+ relativeContainer: @relative_container,
16
+ rotation: @rotation,
17
+ opacity: @opacity,
18
+ }
19
+ end
20
+
21
+ #region FluentApi
22
+ def on_container(relative_container)
23
+ @relative_container = relative_container
24
+ self
25
+ end
26
+
27
+ def with_rotation(rotation)
28
+ @rotation = rotation
29
+ self
30
+ end
31
+
32
+ def rotate90_clockwise
33
+ @rotation = 270
34
+ self
35
+ end
36
+
37
+ def rotate90_counter_clockwise
38
+ @rotation = 90
39
+ self
40
+ end
41
+
42
+ def rotate180
43
+ @rotation = 180
44
+ self
45
+ end
46
+
47
+ def with_opacity(opacity)
48
+ @opacity = opacity
49
+ self
50
+ end
51
+
52
+ #endregion
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ module RestPki
2
+ class PdfMarkElementType
3
+ TEXT = 'Text'
4
+ IMAGE = 'Image'
5
+ QR_CODE = 'QRCode'
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ module RestPki
2
+ class PdfMarkImage
3
+ attr_accessor :resource
4
+
5
+ def initialize(image_content=nil, mime_type=nil)
6
+ @resource = ResourceContentOrReference.new
7
+ unless image_content.nil?
8
+ @resource.content = image_content
9
+ end
10
+
11
+ unless mime_type.nil?
12
+ @resource.mime_type = mime_type
13
+ end
14
+ end
15
+
16
+ def to_model
17
+ if @resource.content.nil? && @resource.url.nil?
18
+ raise 'The image content was not set, neither its URL'
19
+ end
20
+ {
21
+ resource: @resource.to_model
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ module RestPki
2
+ class PdfMarkImageElement < PdfMarkElement
3
+ attr_accessor :image
4
+
5
+ def initialize(relative_container = nil, image = nil)
6
+ super(PdfMarkElementType::IMAGE, relative_container)
7
+ @image = image
8
+ end
9
+
10
+ def to_model
11
+ model = super
12
+ unless @image.nil?
13
+ model['image'] = @image.to_model
14
+ end
15
+ model
16
+ end
17
+
18
+ #region FluentApi
19
+
20
+ def with_mark_image(image)
21
+ @image = image
22
+ self
23
+ end
24
+
25
+ def with_image(image_content, mime_type)
26
+ @image = PdfMarkImage.new(image_content, mime_type)
27
+ self
28
+ end
29
+
30
+ #endregion
31
+
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module RestPki
2
+ class PdfMarkPageOptions
3
+ ALL_PAGES = 'AllPages'
4
+ SINGLE_PAGE = 'SinglePage'
5
+ SINGLE_PAGE_FROM_END = 'SinglePageFromEnd'
6
+ NEW_PAGE = 'NewPage'
7
+ end
8
+ end
@@ -0,0 +1,32 @@
1
+ module RestPki
2
+ class PdfMarkQRCodeElement < PdfMarkElement
3
+ attr_accessor :qr_code_data, :draw_quiet_zone
4
+
5
+ def initialize(relative_container = nil, qr_code_data = nil)
6
+ super(PdfMarkElementType::QR_CODE, relative_container)
7
+ @qr_code_data = qr_code_data
8
+ @draw_quiet_zone = false
9
+ end
10
+
11
+ def to_model
12
+ model = super
13
+ model['qrCodeData'] = @qr_code_data
14
+ model['qrCodeDataDrawQuietZones'] = @draw_quiet_zone
15
+ model
16
+ end
17
+
18
+ #region FluentApi
19
+
20
+ def with_qr_code_data(qr_code_data)
21
+ @qr_code_data = qr_code_data
22
+ self
23
+ end
24
+
25
+ def draw_quiet_zone
26
+ @draw_quiet_zone = true
27
+ self
28
+ end
29
+
30
+ #endregion
31
+ end
32
+ end
@@ -0,0 +1,47 @@
1
+ module RestPki
2
+ class PdfMarkTextElement < PdfMarkElement
3
+ attr_accessor :text_sections, :align
4
+
5
+ def initialize(relative_container=nil, text_sections=[])
6
+ super(PdfMarkElementType::TEXT, relative_container)
7
+ @text_sections = text_sections
8
+ @align = 'Left'
9
+ end
10
+
11
+ def to_model
12
+ model = super
13
+ model['textSections'] = @text_sections.map { |s| s.to_model }
14
+ model['align'] = @align
15
+ model
16
+ end
17
+
18
+ #region FluentApi
19
+
20
+ def align_text_left
21
+ @align = 'Left'
22
+ self
23
+ end
24
+
25
+ def align_text_right
26
+ @align = 'Right'
27
+ self
28
+ end
29
+
30
+ def align_text_center
31
+ @align = 'Center'
32
+ self
33
+ end
34
+
35
+ def add_section(section)
36
+ @text_sections.push(section)
37
+ self
38
+ end
39
+
40
+ def add_section_with_text(text)
41
+ @text_sections.push(PdfTextSection.new(text))
42
+ self
43
+ end
44
+
45
+ #endregion
46
+ end
47
+ end
@@ -0,0 +1,61 @@
1
+ require 'base64'
2
+ module RestPki
3
+ class PdfMarker
4
+ attr_accessor :marks, :measurement_units, :page_optimization, :abort_if_signed
5
+ attr_reader :file_content
6
+
7
+ def initialize(client)
8
+ @client = client
9
+ @marks = []
10
+ @measurement_units = PadesMeasurementUnits::CENTIMETERS
11
+ @page_optimization = nil
12
+ @abort_if_signed = nil
13
+ @file_content = nil
14
+ end
15
+
16
+ def set_file_from_path(path)
17
+ File.open(path, 'rb') do |f|
18
+ @file_content = f.read
19
+ end
20
+ end
21
+
22
+ # region set_file
23
+
24
+ def set_file_from_content_raw(content_raw)
25
+ @file_content = content_raw
26
+ end
27
+
28
+ def set_file_from_content_base64(content_base64)
29
+ content = nil
30
+ unless content_base64.nil?
31
+ content = Base64.decode64(content_base64)
32
+ end
33
+ @file_content = content
34
+ end
35
+
36
+ # endregion
37
+
38
+ def apply
39
+ if @file_content.nil?
40
+ raise 'No file was provided'
41
+ end
42
+
43
+ marks = @marks.map { |m| m.to_model }
44
+ page_optimization = nil
45
+ unless @page_optimization.nil?
46
+ page_optimization = @page_optimization.to_model
47
+ end
48
+ request = {
49
+ marks: marks,
50
+ measurementUnits: @measurement_units,
51
+ pageOptimization: page_optimization,
52
+ abortIfSigned: abort_if_signed
53
+ }
54
+ request['file'] = {
55
+ content: Base64.encode64(@file_content)
56
+ }
57
+ model = @client.post('Api/Pdf/AddMarks', request, 'pdf_marker_model')
58
+ model.file_content
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,57 @@
1
+ module RestPki
2
+ class PdfTextSection
3
+ attr_accessor :text, :color, :font_size, :style
4
+
5
+ def initialize(text=nil, color=nil, font_size=nil)
6
+ if color.nil?
7
+ color = Color.from_rgb_string('#000000') # White
8
+ end
9
+ @style = PdfTextStyle::NORMAL
10
+ @text = text
11
+ @color = color
12
+ @font_size = font_size
13
+ end
14
+
15
+ def to_model
16
+ color = nil
17
+ unless @color.nil?
18
+ color = @color
19
+ end
20
+ {
21
+ style: @style,
22
+ text: @text,
23
+ color: color,
24
+ fontSize: @font_size,
25
+ }
26
+ end
27
+
28
+ #region FluentApi
29
+
30
+ def with_font_size(font_size)
31
+ @font_size = font_size
32
+ self
33
+ end
34
+
35
+ def with_text(text)
36
+ @text = text
37
+ self
38
+ end
39
+
40
+ def bold
41
+ @style = PdfTextStyle::BOLD
42
+ self
43
+ end
44
+
45
+ def italic
46
+ @style = PdfTextStyle::ITALIC
47
+ self
48
+ end
49
+
50
+ def with_color(color)
51
+ @color = color
52
+ self
53
+ end
54
+
55
+ #endregion
56
+ end
57
+ end
@@ -0,0 +1,7 @@
1
+ module RestPki
2
+ class PdfTextStyle
3
+ NORMAL = 'Normal'
4
+ BOLD = 'Bold'
5
+ ITALIC = 'Italic'
6
+ end
7
+ end
@@ -0,0 +1,173 @@
1
+ module RestPki
2
+
3
+ class SignatureAlgorithm
4
+ attr_reader :name, :oid, :xml_uri, :digest_algorithm, :pk_algorithm
5
+ def initialize(name, oid, xml_uri, digest_algorithm, pk_algorithm)
6
+ @name = name
7
+ @oid = oid
8
+ @xml_uri = xml_uri
9
+ @digest_algorithm = digest_algorithm
10
+ @pk_algorithm = pk_algorithm
11
+ end
12
+
13
+ def self.MD5_WITH_RSA; RSASignatureAlgorithm.new(DigestAlgorithm.MD5) end
14
+ def self.SHA1_WITH_RSA; RSASignatureAlgorithm.new(DigestAlgorithm.SHA1) end
15
+ def self.SHA256_WITH_RSA; RSASignatureAlgorithm.new(DigestAlgorithm.SHA256) end
16
+ def self.SHA384_WITH_RSA; RSASignatureAlgorithm.new(DigestAlgorithm.SHA384) end
17
+ def self.SHA512_WITH_RSA; RSASignatureAlgorithm.new(DigestAlgorithm.SHA512) end
18
+
19
+ def self.algorithms
20
+ [
21
+ SignatureAlgorithm.MD5_WITH_RSA,
22
+ SignatureAlgorithm.SHA1_WITH_RSA,
23
+ SignatureAlgorithm.SHA256_WITH_RSA,
24
+ SignatureAlgorithm.SHA384_WITH_RSA,
25
+ SignatureAlgorithm.SHA512_WITH_RSA
26
+ ]
27
+ end
28
+
29
+ def self.safe_algorithms
30
+ [
31
+ SignatureAlgorithm.SHA256_WITH_RSA,
32
+ SignatureAlgorithm.SHA384_WITH_RSA,
33
+ SignatureAlgorithm.SHA512_WITH_RSA
34
+ ]
35
+ end
36
+
37
+ def self.get_instance_by_name(name)
38
+ begin
39
+ sig = SignatureAlgorithm._algorithms.find{ |s| s.name == name}
40
+ rescue => exception
41
+ raise "Unrecognized digest algorithm name: #{name}"
42
+ end
43
+ sig
44
+ end
45
+
46
+ def self.get_instance_by_oid(oid)
47
+ begin
48
+ sig = SignatureAlgorithm._algorithms.find{ |s| s.oid == oid}
49
+ rescue => exception
50
+ raise "Unrecognized digest algorithm oid: #{oid}"
51
+ end
52
+ sig
53
+ end
54
+
55
+ def self.get_instance_by_xml_uri(xml_uri)
56
+ begin
57
+ sig = SignatureAlgorithm._algorithms.find{ |s| s.xml_uri == xml_uri}
58
+ rescue => exception
59
+ raise "Unrecognized digest algorithm XML URI: #{xml_uri}"
60
+ end
61
+ sig
62
+ end
63
+
64
+ def self.get_instance_by_api_model(model)
65
+ algorithm = model['algorithm']
66
+ case algorithm
67
+ when 'MD5WithRSA'
68
+ return SignatureAlgorithm.MD5_WITH_RSA
69
+ when 'SHA1WithRSA'
70
+ return SignatureAlgorithm.SHA1_WITH_RSA
71
+ when 'SHA256WithRSA'
72
+ return SignatureAlgorithm.SHA256_WITH_RSA
73
+ when 'SHA384WithRSA'
74
+ return SignatureAlgorithm.SHA384_WITH_RSA
75
+ when 'SHA512WithRSA'
76
+ return SignatureAlgorithm.SHA512_WITH_RSA
77
+ else
78
+ raise "Unsupported signature algorithm: #{algorithm}"
79
+ end
80
+ end
81
+ end
82
+ class RSASignatureAlgorithm < SignatureAlgorithm
83
+ def initialize(digest_algorithm)
84
+ name = "#{digest_algorithm.name} with RSA"
85
+ pk_algorithm = PKAlgorithm.RSA
86
+ oid = nil
87
+ xml_uri = nil
88
+ case digest_algorithm
89
+ when DigestAlgorithm.MD5
90
+ oid = Oids.oids["MD5_WITH_RSA"]
91
+ xml_uri = 'http://www.w3.org/2001/04/xmldsig-more#rsa-md5'
92
+ when DigestAlgorithm.SHA1
93
+ oid = Oids.oids["SHA1_WITH_RSA"]
94
+ xml_uri = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
95
+ when DigestAlgorithm.SHA256
96
+ oid = Oids.oids["SHA256_WITH_RSA"]
97
+ xml_uri = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
98
+ when DigestAlgorithm.SHA384
99
+ oid = Oids.oids["SHA384_WITH_RSA"]
100
+ xml_uri = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'
101
+ when DigestAlgorithm.SHA512
102
+ oid = Oids.oids["SHA512_WITH_RSA"]
103
+ xml_uri = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'
104
+ else
105
+ raise "Unsupported digest algorithm: #{digest_algorithm}"
106
+ end
107
+
108
+ super(name, oid, xml_uri, digest_algorithm, pk_algorithm)
109
+ end
110
+ end
111
+ class PKAlgorithm
112
+ attr_reader :name, :oid
113
+ def initialize(name, oid)
114
+ @name = name
115
+ @oid = oid
116
+ end
117
+
118
+ def ==(comparison_object)
119
+ if comparison_object.equal?(self)
120
+ return true
121
+ end
122
+ unless comparison_object.instance_of?(self.class)
123
+ return false
124
+ end
125
+ self.oid == comparison_object.oid
126
+ end
127
+
128
+ def self.RSA; RSAPKAlgorithm.new end
129
+
130
+ def self._algorithms
131
+ [PKAlgorithm.RSA]
132
+ end
133
+
134
+ def self.get_instance_by_name(name)
135
+ begin
136
+ alg = PKAlgorithm.algorithms.find{|a| a.name == name}
137
+ rescue => exception
138
+ raise "Unrecognized private key algorithm name: #{name}"
139
+ end
140
+ alg
141
+ end
142
+
143
+ def self.get_instance_by_oid(oid)
144
+ begin
145
+ alg = PKAlgorithm.algorithms.find{|a| a.name == oid}
146
+ rescue => exception
147
+ raise "Unrecognized private key algorithm oid: #{oid}"
148
+ end
149
+ alg
150
+ end
151
+
152
+ def self.get_instance_by_api_model(algorithm)
153
+ case algorithm
154
+ when 'RSA'
155
+ return PKAlgorithm.RSA
156
+ else
157
+ raise "Unsupported private key algorithms #{algorithm}"
158
+ end
159
+ end
160
+
161
+ end
162
+ class RSAPKAlgorithm < PKAlgorithm
163
+ def initialize
164
+ name = 'RSA'
165
+ oid = Oids.oids["RSA"]
166
+ super(name, oid)
167
+ end
168
+
169
+ def self.get_signature_algorithm(digest_algorithm)
170
+ RSASignatureAlgorithm.new(digest_algorithm)
171
+ end
172
+ end
173
+ end