rest_pki 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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