rest_pki 1.0.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 +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