rest_pki 1.0.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 +7 -0
  2. data/.gitignore +28 -0
  3. data/CHANGELOG.md +12 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +19 -0
  7. data/Rakefile +2 -0
  8. data/lib/rest_pki.rb +35 -0
  9. data/lib/rest_pki/authentication.rb +43 -0
  10. data/lib/rest_pki/cades_signature_finisher.rb +48 -0
  11. data/lib/rest_pki/cades_signature_starter.rb +148 -0
  12. data/lib/rest_pki/full_xml_signature_starter.rb +51 -0
  13. data/lib/rest_pki/namespace_manager.rb +16 -0
  14. data/lib/rest_pki/object.rb +126 -0
  15. data/lib/rest_pki/pades_signature_finisher.rb +50 -0
  16. data/lib/rest_pki/pades_signature_starter.rb +110 -0
  17. data/lib/rest_pki/pades_visual_positioning_presets.rb +32 -0
  18. data/lib/rest_pki/resources/authentication_model.rb +5 -0
  19. data/lib/rest_pki/resources/cades_model.rb +5 -0
  20. data/lib/rest_pki/resources/pades_model.rb +5 -0
  21. data/lib/rest_pki/resources/response_model.rb +5 -0
  22. data/lib/rest_pki/resources/xml_model.rb +5 -0
  23. data/lib/rest_pki/rest_base_error.rb +12 -0
  24. data/lib/rest_pki/rest_error.rb +16 -0
  25. data/lib/rest_pki/rest_unreachable_error.rb +13 -0
  26. data/lib/rest_pki/restpki_client.rb +95 -0
  27. data/lib/rest_pki/restpki_error.rb +16 -0
  28. data/lib/rest_pki/signature_finisher.rb +33 -0
  29. data/lib/rest_pki/signature_starter.rb +59 -0
  30. data/lib/rest_pki/standard_security_contexts.rb +10 -0
  31. data/lib/rest_pki/standard_signature_policies.rb +25 -0
  32. data/lib/rest_pki/validation_error.rb +11 -0
  33. data/lib/rest_pki/validation_item.rb +33 -0
  34. data/lib/rest_pki/validation_results.rb +107 -0
  35. data/lib/rest_pki/version.rb +3 -0
  36. data/lib/rest_pki/xml_element_signature_starter.rb +68 -0
  37. data/lib/rest_pki/xml_id_resolution_table.rb +40 -0
  38. data/lib/rest_pki/xml_insertion_options.rb +11 -0
  39. data/lib/rest_pki/xml_signature_finisher.rb +52 -0
  40. data/lib/rest_pki/xml_signature_starter.rb +84 -0
  41. data/rest_pki.gemspec +30 -0
  42. metadata +146 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: efdf855b8c7a4a0f5884d7cbb7ae6237f57ef12a7b8e5fb9e3f97fd3b559cba4
4
+ data.tar.gz: f4ae7fd56adca41b9be2723d376a98adc4d054b6cf1a837b9c2f9dce9af65f32
5
+ SHA512:
6
+ metadata.gz: 958e4840d4e0eaaaadf0fcc7e5eaa12bbc8c89480f9393feda3c57004617c5ce729ef8d7ded10573202946e648a91f8a887666faef8e24fdea0d7cc700c13725
7
+ data.tar.gz: 97e35162fe53d8b8fe4a53bcdaf1ef7ccdc418efcdf9ad8fc0dc7889601d7ae4fc3a4b7b81f83644a9661998c02ae6226349ff62df2d068a02e929c3511261a4
@@ -0,0 +1,28 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.gem
16
+ *.rbc
17
+ .DS_Store
18
+ .bundle
19
+ .rvmrc
20
+ .ruby-version
21
+ .yardoc
22
+ .rake_tasks~
23
+ Gemfile.lock
24
+ coverage/*
25
+ doc/*
26
+ log/*
27
+ pkg/*
28
+ .idea/*
@@ -0,0 +1,12 @@
1
+ ## 1.0.0 (2018-04-11)
2
+ * First publicly available version
3
+ * Main features on this version:
4
+ * Certificate authentications
5
+ * PAdES signatures
6
+ * Using direct integration with Web PKI
7
+ * Using server key
8
+ * CAdES signatures
9
+ * Using direct integration with Web PKI
10
+ * Using server key
11
+ * Full XML signatures
12
+ * XML element signatures
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rest_pki.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Murilo Zaffalon
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ REST PKI client lib for Ruby
2
+ ============================
3
+
4
+ This library contains classes that encapsulate the calls to the REST PKI API.
5
+
6
+ The recommended way to install **REST PKI Client lib** is through setting in your Gemfile:
7
+
8
+ ````ruby
9
+ gem 'rest_pki', '~> 1.0.0'
10
+ ````
11
+
12
+ And with installing via [Bundler](http://bundler.io/) on your project root folder:
13
+
14
+ bundle install
15
+
16
+ Samples
17
+ -------
18
+ Please visit the [Rest PKI samples repository](https://github.com/LacunaSoftware/RestPkiSamples/tree/master/Ruby)
19
+ for examples on how to use this library.
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+
@@ -0,0 +1,35 @@
1
+ require 'rest_pki/version'
2
+
3
+ require_relative 'rest_pki/rest_base_error'
4
+ require_relative 'rest_pki/rest_error'
5
+ require_relative 'rest_pki/restpki_error'
6
+ require_relative 'rest_pki/rest_unreachable_error'
7
+ require_relative 'rest_pki/validation_error'
8
+ require_relative 'rest_pki/object'
9
+ require_relative 'rest_pki/authentication'
10
+ require_relative 'rest_pki/signature_finisher'
11
+ require_relative 'rest_pki/signature_starter'
12
+ require_relative 'rest_pki/cades_signature_starter'
13
+ require_relative 'rest_pki/cades_signature_finisher'
14
+ require_relative 'rest_pki/xml_signature_starter'
15
+ require_relative 'rest_pki/full_xml_signature_starter'
16
+ require_relative 'rest_pki/namespace_manager'
17
+ require_relative 'rest_pki/pades_signature_finisher'
18
+ require_relative 'rest_pki/pades_signature_starter'
19
+ require_relative 'rest_pki/pades_visual_positioning_presets'
20
+ require_relative 'rest_pki/restpki_client'
21
+ require_relative 'rest_pki/standard_security_contexts'
22
+ require_relative 'rest_pki/standard_signature_policies'
23
+ require_relative 'rest_pki/validation_item'
24
+ require_relative 'rest_pki/validation_results'
25
+ require_relative 'rest_pki/xml_element_signature_starter'
26
+ require_relative 'rest_pki/xml_id_resolution_table'
27
+ require_relative 'rest_pki/xml_insertion_options'
28
+ require_relative 'rest_pki/xml_signature_finisher'
29
+
30
+ Dir[File.expand_path('../rest_pki/resources/*.rb', __FILE__)].map do |path|
31
+ require path
32
+ end
33
+
34
+ module RestPki
35
+ end
@@ -0,0 +1,43 @@
1
+ require 'uri'
2
+ require 'rest_client'
3
+ require 'multi_json'
4
+
5
+ module RestPki
6
+ class Authentication
7
+ attr_accessor :ignore_revocation_status_unknown
8
+
9
+ def initialize(restpki_client)
10
+ @restpki_client = restpki_client
11
+ @certificate_info = nil
12
+ @done = false
13
+ @ignore_revocation_status_unknown = false
14
+ end
15
+
16
+ def start_with_webpki(security_context_id)
17
+ request = {
18
+ securityContextId: security_context_id,
19
+ ignoreRevocationStatusUnknown: @ignore_revocation_status_unknown
20
+ }
21
+ response = @restpki_client.post('Api/Authentications', request, 'authentication_model')
22
+ response['token']
23
+ end
24
+
25
+ def complete_with_webpki(token)
26
+ response = @restpki_client.post("Api/Authentications/#{token}/Finalize", nil, 'authentication_model')
27
+
28
+ unless response['certificate'].nil?
29
+ @certificate_info = response['certificate']
30
+ end
31
+ @done = true
32
+
33
+ ValidationResults.new(response['validationResults'])
34
+ end
35
+
36
+ def certificate_info
37
+ unless @done
38
+ raise 'The field "certificate_info" can only be accessed after calling the complete_with_webpki method'
39
+ end
40
+ @certificate_info
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+
2
+ module RestPki
3
+ class CadesSignatureFinisher < SignatureFinisher
4
+
5
+ def initialize(restpki_client)
6
+ super(restpki_client)
7
+ @cms = nil
8
+ end
9
+
10
+ def finish
11
+ if @token.to_s.blank?
12
+ raise 'The token was not set'
13
+ end
14
+
15
+ if @signature.to_s.blank?
16
+ response = @restpki_client.post("Api/CadesSignatures/#{@token}/Finalize", nil, 'cades_model')
17
+ else
18
+ request = { signature: @signature }
19
+ response = @restpki_client.post("Api/CadesSignatures/#{@token}/SignedBytes", request, 'cades_model')
20
+ end
21
+
22
+ @cms = Base64.decode64(response['cms'])
23
+ @callback_argument = response['callbackArgument']
24
+ @certificate_info = response['certificate']
25
+ @done = true
26
+
27
+ @cms
28
+ end
29
+
30
+ def cms
31
+ unless @done
32
+ raise 'The field "cms" can only be accessed after calling the finish method'
33
+ end
34
+
35
+ @cms
36
+ end
37
+
38
+ def write_cms_to_path(path)
39
+ unless @done
40
+ raise 'The method write_cms_to_path can only be called after calling the finish method'
41
+ end
42
+
43
+ file = File.open(path, 'wb')
44
+ file.write(@cms)
45
+ file.close
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,148 @@
1
+ require 'base64'
2
+
3
+ module RestPki
4
+ class CadesSignatureStarter < SignatureStarter
5
+ attr_accessor :encapsulate_content
6
+
7
+ def initialize(restpki_client)
8
+ super(restpki_client)
9
+ @file_tosign_content_base64 = nil
10
+ @cms_tocosign_content_base64 = nil
11
+ end
12
+
13
+ #region set_file_tosign
14
+
15
+ def set_file_tosign_from_path(path)
16
+ file = File.open(path, 'rb')
17
+ @file_tosign_content_base64 = Base64.encode64(file.read)
18
+ file.close
19
+
20
+ @file_tosign_content_base64
21
+ end
22
+
23
+ def set_file_tosign_from_raw(content_raw)
24
+ @file_tosign_content_base64 = Base64.encode64(content_raw)
25
+ end
26
+
27
+ def set_file_tosign_from_base64(content_base64)
28
+ @file_tosign_content_base64 = content_base64
29
+ end
30
+
31
+ def set_file_content_tosign(content_raw)
32
+ set_file_tosign_from_raw(content_raw)
33
+ end
34
+
35
+ def set_file_to_sign(path)
36
+ set_file_tosign_from_path(path)
37
+ end
38
+
39
+ #endregion
40
+
41
+ #region set_cms_tocosign
42
+
43
+ def set_cms_tocosign_from_path(path)
44
+ file = File.open(path, 'rb')
45
+ @cms_tocosign_content_base64 = Base64.encode64(file.read)
46
+ file.close
47
+
48
+ @cms_tocosign_content_base64
49
+ end
50
+
51
+ def set_cms_tocosign_from_raw(content_raw)
52
+ @cms_tocosign_content_base64 = Base64.encode64(content_raw)
53
+ end
54
+
55
+ def set_cms_tocosign_from_base64(content_base64)
56
+ @cms_tocosign_content_base64 = content_base64
57
+ end
58
+
59
+ def set_cms_content_tocosign(content_raw)
60
+ set_cms_tocosign_from_raw(content_raw)
61
+ end
62
+
63
+ def set_cms_tocosign(path)
64
+ set_cms_tocosign_from_path(path)
65
+ end
66
+
67
+ #endregion
68
+
69
+ def start_with_webpki
70
+ if @file_tosign_content_base64.to_s.blank? and @cms_tocosign_content_base64.to_s.blank?
71
+ raise 'The content to sign was not set and no CMS to be co-signed was given'
72
+ end
73
+ if @signature_policy_id.to_s.blank?
74
+ raise 'The signature policy was not set'
75
+ end
76
+
77
+ request = {
78
+ securityContextId: @security_context_id,
79
+ signaturePolicyId: @signature_policy_id,
80
+ callbackArgument: @callback_argument,
81
+ encapsulateContent: @encapsulate_content,
82
+ ignoreRevocationStatusUnknown: @ignore_revocation_status_unknown
83
+ }
84
+ unless @signer_certificate_base64.to_s.blank?
85
+ request['certificate'] = Base64.encode64(@signer_certificate_base64)
86
+ end
87
+ unless @file_tosign_content_base64.nil?
88
+ request['contentToSign'] = @file_tosign_content_base64
89
+ end
90
+ unless @cms_tocosign_content_base64.nil?
91
+ request['cmsToCoSign'] = @cms_tocosign_content_base64
92
+ end
93
+
94
+ response = @restpki_client.post('Api/CadesSignatures', request, 'cades_model')
95
+
96
+ unless response['certificate'].nil?
97
+ @certificate = response['certificate']
98
+ end
99
+ @done = true
100
+
101
+ response['token']
102
+ end
103
+
104
+ def start
105
+ if @file_tosign_content_base64.to_s.blank? and @cms_tocosign_content_base64.to_s.blank?
106
+ raise 'The content to sign was not set and no CMS to be co-signed was given'
107
+ end
108
+ if @signature_policy_id.to_s.blank?
109
+ raise 'The signature policy was not set'
110
+ end
111
+ if @signer_certificate_base64.to_s.blank?
112
+ raise 'The signer certificate was not set'
113
+ end
114
+
115
+ request = {
116
+ securityContextId: @security_context_id,
117
+ signaturePolicyId: @signature_policy_id,
118
+ callbackArgument: @callback_argument,
119
+ encapsulateContent: @encapsulate_content,
120
+ ignoreRevocationStatusUnknown: @ignore_revocation_status_unknown
121
+ }
122
+ unless @signer_certificate_base64.to_s.blank?
123
+ request['certificate'] = Base64.encode64(@signer_certificate_base64)
124
+ end
125
+ unless @file_tosign_content_base64.nil?
126
+ request['contentToSign'] = @file_tosign_content_base64
127
+ end
128
+ unless @cms_tocosign_content_base64.nil?
129
+ request['cmsToCoSign'] = @cms_tocosign_content_base64
130
+ end
131
+
132
+ response = @restpki_client.post('Api/CadesSignatures', request, 'cades_model')
133
+
134
+ unless response['certificate'].nil?
135
+ @certificate = response['certificate']
136
+ end
137
+ @done = true
138
+
139
+ {
140
+ :token => response['token'],
141
+ :to_sign_data => response['toSignData'],
142
+ :to_sign_hash => response['toSignHash'],
143
+ :digest_algorithm_oid => response['digestAlgorithmOid'],
144
+ :signature_algorithm => get_signature_algorithm(response['digestAlgorithmOid'])
145
+ }
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,51 @@
1
+ module RestPki
2
+ class FullXmlSignatureStarter < XmlSignatureStarter
3
+
4
+ def initialize(restpki_client)
5
+ super(restpki_client)
6
+ end
7
+
8
+ def start_with_webpki
9
+ verify_common_parameters(true)
10
+ if @xml_content_base64.to_s.blank?
11
+ raise 'The XML to sign was not set'
12
+ end
13
+
14
+ request = get_request
15
+
16
+ response = @restpki_client.post('Api/XmlSignatures/FullXmlSignature', request, 'xml_model')
17
+
18
+ unless response['certificate'].nil?
19
+ @certificate = response['certificate']
20
+ end
21
+ @done = true
22
+
23
+ response['token']
24
+ end
25
+
26
+ def start
27
+ verify_common_parameters(true)
28
+ if @xml_content_base64.to_s.blank?
29
+ raise 'The XML to sign was not set'
30
+ end
31
+
32
+ request = get_request
33
+
34
+ response = @restpki_client.post('Api/XmlSignatures/FullXmlSignature', request, 'xml_model')
35
+
36
+ unless response['certificate'].nil?
37
+ @certificate = response['certificate']
38
+ end
39
+ @done = true
40
+
41
+ {
42
+ :token => response['token'],
43
+ :to_sign_data => response['toSignData'],
44
+ :to_sign_hash => response['toSignHash'],
45
+ :digest_algorithm_oid => response['digestAlgorithmOid'],
46
+ :signature_algorithm => get_signature_algorithm(response['digestAlgorithmOid'])
47
+ }
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module RestPki
3
+ class NamespaceManager
4
+ attr_accessor :namespaces
5
+
6
+ def initialize
7
+ @namespaces = []
8
+ end
9
+
10
+ def add_namespace(prefix, uri)
11
+ ns = { prefix: prefix, uri: uri }
12
+ @namespaces.push(ns)
13
+ end
14
+
15
+ end
16
+ end