devpki 0.0.3 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6955eee6a2a6194ffed37756e37a08addf819630
4
- data.tar.gz: c034539b017c45656535e837435115a32b9a535d
3
+ metadata.gz: fbc7720cc112b9758de034e6fa6f28f9ae19c364
4
+ data.tar.gz: feebcd561f7f8b042b008ddb16ec3e304a2e273d
5
5
  SHA512:
6
- metadata.gz: 53625e5fc5e30459f56872633c8d32a4adcd542a3f85ce145bd2d6ea3a27485510f00593ea245c98ee3facff55d02211e8769e9319bdfbbe831fbd700e42f0e1
7
- data.tar.gz: afcecd2f7a8702c57cc7d94f477b0b73259aaf290e1444fa0eab6a876c86058d75932aac132ee8efe61d0713d93d8a172bbdc9370a8e934694d8e16b6dc655e3
6
+ metadata.gz: 813fc219225e95e0639863df5ce58c90ded9139f663664788ec2b4c948adafb11c02d97735380d08d4c098f6115357279138225061790411363d7a5f29f7b193
7
+ data.tar.gz: 7a2e93ee9961430d3642c43dfe34cc31383e75e3a7fd5740ab43d74def64ee667cee22acf275ae02e16e926633071e789505e59c7e4e212038a722ba627c2c81
@@ -22,5 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency "sqlite3"
23
23
  spec.add_runtime_dependency "xdg"
24
24
  spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "pry"
25
26
  spec.add_development_dependency "rake"
26
27
  end
@@ -1,10 +1,11 @@
1
1
  require 'devpki'
2
2
  require 'thor'
3
3
  require 'net/http'
4
+ require 'pry'
4
5
 
5
6
  module DevPKI
6
7
  class CLI < Thor
7
- desc "ocsp [--method=get|post] --uri=<ocsp uri> ISSUER_CER_FILE:SUBJ_A.CER[,SUBJ_B.CER...]...", "Performs an OCSP query"
8
+ desc "ocsp [--method=get|post] --uri=<ocsp uri> [--chain-certs=ca1.cer,ca2.cer...] ISSUER_CER_FILE:SUBJ_A.CER[,SUBJ_B.CER...]...", "Performs an OCSP query"
8
9
  long_desc <<-LONGDESC
9
10
  This command performs an OCSP query against the given OCSP URI, over HTTP. To perform
10
11
  a query, at least 2 certificates are needed - the CA certificate and the subject certificate
@@ -22,13 +23,20 @@ module DevPKI
22
23
  LONGDESC
23
24
  option :method, :default => "post", :banner => "get|post", :desc => "Method to use. GET as per RFC5019, or POST as per RFC2560. Defaults to POST."
24
25
  option :uri, :banner => "<ocsp uri>", :required => true, :desc => "OCSP responder URI."
26
+ option :"chain-certs", :banner => "ca1.cer,ca2.cer...", :desc => "Trusted certificates that can be used, when verifying OCSP response signature."
25
27
 
26
28
  def ocsp(*cer_files)
27
29
 
28
30
  raise InvalidOption.new("Please specify at least one CA and subject certificate file.") if cer_files.empty?
29
31
 
32
+ chain_cert_files = []
33
+ if options[:"chain-certs"] != nil
34
+ chain_cert_files=options[:"chain-certs"].split(",")
35
+ end
36
+
30
37
  ca_subj_map = {}
31
38
  cer_files.each do |ca_subj_pair|
39
+
32
40
  raise InvalidOption.new("\"#{ca_subj_pair}\" is an invalid CA and subject pair. Please pass a pair with format similar to \"ca.cer:a.cer[,b.cer...]\"") if not ca_subj_pair.include?(":")
33
41
 
34
42
  ca_subjlist_split = ca_subj_pair.split(":")
@@ -55,6 +63,12 @@ module DevPKI
55
63
 
56
64
  cert_ids = []
57
65
  store = OpenSSL::X509::Store.new
66
+ chain_cert_files.each do |chain_cert_file|
67
+ puts "Adding #{chain_cert_file} to store"
68
+ store.add_file(chain_cert_file)
69
+ end
70
+ #store.set_default_paths
71
+ #store.add_file("root.crt")
58
72
 
59
73
  ca_subj_map.each_pair do |ca_file, subj_file_list|
60
74
  ca_cert = OpenSSL::X509::Certificate.new File.read(ca_file)
@@ -73,6 +87,7 @@ module DevPKI
73
87
  end
74
88
 
75
89
  request_uri = URI(options[:uri])
90
+ request_uri.path = "/" if request_uri.path.to_s.empty?
76
91
 
77
92
  http_req = Net::HTTP::Post.new(request_uri.path)
78
93
  http_req.content_type = "application/ocsp-request"
@@ -92,26 +107,61 @@ module DevPKI
92
107
  puts "Status: #{response.status}"
93
108
  puts "Status string: #{response.status_string}"
94
109
 
110
+ # Statuses from http://tools.ietf.org/html/rfc2560 section 4.2.1
111
+ #
112
+ # successful (0), --Response has valid confirmations
113
+ # malformedRequest (1), --Illegal confirmation request
114
+ # internalError (2), --Internal error in issuer
115
+ # tryLater (3), --Try again later
116
+ # --(4) is not used
117
+ # sigRequired (5), --Must sign the request
118
+ # unauthorized (6) --Request unauthorized
95
119
  if response.status != 0
96
120
  raise StandardError, "Not a successful status"
97
121
  end
98
- if response.basic[0][0].serial != cert.serial
99
- raise StandardError, "Not the same serial"
100
- end
101
- if response.basic[0][1] != 0 # 0 is good, 1 is revoked, 2 is unknown.
102
- raise StandardError, "Not a good status"
103
- end
104
- current_time = Time.now
105
- if response.basic[0][4] > current_time or response.basic[0][5] < current_time
106
- raise StandardError, "The response is not within its validity window"
107
- end
108
122
 
109
- # we also need to verify that the OCSP response is signed by
110
- # a certificate that is allowed and chains up to a trusted root.
111
- # To do this you'll need to build an OpenSSL::X509::Store object
112
- # that contains the certificate you're checking + intermediates + root.
123
+ # response.basic.status will be populated, if response.status == 0
124
+ cert_ids.each_with_index do |cert_id,ix|
125
+
126
+ # SingleResponse structure from http://tools.ietf.org/html/rfc2560 section 4.2.1
127
+ #
128
+ # SingleResponse ::= SEQUENCE {
129
+ # certID CertID,
130
+ # certStatus CertStatus,
131
+ # thisUpdate GeneralizedTime,
132
+ # nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
133
+ # singleExtensions [1] EXPLICIT Extensions OPTIONAL }
134
+ # single_response = response.basic.status[ix]
135
+
136
+ # Find the single response that matches current cert_id
137
+ single_response = nil
138
+ response.basic.status.each do |single_response_candidate|
139
+ if single_response_candidate[0].serial.to_s == cert_id.serial.to_s
140
+ single_response = single_response_candidate
141
+ break
142
+ end
143
+ end
144
+
145
+ raise StandardError.new("SingleResponse for certificate s/n ##{cert_id.serial.to_s} not found.") if single_response == nil
146
+
147
+ # CertStatus from from http://tools.ietf.org/html/rfc2560 section 4.2.1
148
+ #
149
+ # CertStatus ::= CHOICE {
150
+ # good [0] IMPLICIT NULL,
151
+ # revoked [1] IMPLICIT RevokedInfo,
152
+ # unknown [2] IMPLICIT UnknownInfo }
153
+ if single_response[1] != 0
154
+ raise StandardError, "CertStatus for cert s/n #{cert_id.serial.to_s} is #{single_response[1]}"
155
+ end
156
+
157
+ current_time = Time.now
158
+ if single_response[4] > current_time or single_response[5] < current_time
159
+ raise StandardError, "The response for cert_id s/n #{cert_id.serial.to_s} is not within its validity window"
160
+ end
161
+ end
113
162
 
114
163
  if response.basic.verify([],store) != true
164
+ binding.pry
115
165
  raise StandardError, "Response not signed by a trusted certificate"
116
166
  end
117
167
 
@@ -1,3 +1,3 @@
1
1
  module DevPKI
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devpki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jānis Kiršteins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-24 00:00:00.000000000 Z
11
+ date: 2013-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rake
71
85
  requirement: !ruby/object:Gem::Requirement