devpki 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/a.cer +0 -0
- data/b.cer +0 -0
- data/bin/devpki +12 -0
- data/c.cer +0 -0
- data/ca.crt +0 -0
- data/ca2.crt +0 -0
- data/d.cer +0 -0
- data/devpki.gemspec +25 -0
- data/lib/devpki/ca.rb +122 -0
- data/lib/devpki/cli/ca/_hack.rb +17 -0
- data/lib/devpki/cli/ca/delete.rb +28 -0
- data/lib/devpki/cli/ca/init.rb +31 -0
- data/lib/devpki/cli/ocsp.rb +121 -0
- data/lib/devpki/cli.rb +15 -0
- data/lib/devpki/data_directory.rb +35 -0
- data/lib/devpki/version.rb +3 -0
- data/lib/devpki.rb +14 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 11f6846c98a3b3dbbe24f57d5fa4f4e619fa0587
|
4
|
+
data.tar.gz: b54ac7be253248ea001141cb5c501119b675b3f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e2d7d58b4895f5b63b4e8f319eab48d3a60c9c2feabc7ac2b4242299af17f2a34e9831205e2ebee88ee95983b065fbadef3f569a4cd9eef8a9bc048eb0007b03
|
7
|
+
data.tar.gz: 59fc8a36ffa80468cd8beb76a43fbc386f5e1495e6830b51e02f854e8660d200c64d394304f304d1ddad9756e5d6d266377577c7ee5431253141b1289b0ff841
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Jānis Kiršteins
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jānis Kiršteins
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Devpki
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'devpki'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install devpki
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/a.cer
ADDED
File without changes
|
data/b.cer
ADDED
File without changes
|
data/bin/devpki
ADDED
data/c.cer
ADDED
File without changes
|
data/ca.crt
ADDED
File without changes
|
data/ca2.crt
ADDED
File without changes
|
data/d.cer
ADDED
File without changes
|
data/devpki.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'devpki/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "devpki"
|
8
|
+
spec.version = DevPKI::VERSION
|
9
|
+
spec.authors = ["Jānis Kiršteins"]
|
10
|
+
spec.email = ["janis@montadigital.com"]
|
11
|
+
spec.description = "Tool for doing common PKI-related tasks"
|
12
|
+
spec.summary = "Tool for doing common PKI-related tasks"
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "thor"
|
22
|
+
spec.add_runtime_dependency "sqlite3"
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
end
|
data/lib/devpki/ca.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'devpki'
|
2
|
+
require 'devpki/data_directory'
|
3
|
+
require 'sqlite3'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
module DevPKI
|
8
|
+
class CA
|
9
|
+
|
10
|
+
attr_accessor :sqlite_db
|
11
|
+
attr_accessor :id
|
12
|
+
|
13
|
+
def initialize(id=0)
|
14
|
+
raise CADBError.new("CA ##{id} does not exist. It must be initialized first.") if not DevPKI::CA.exists?(id)
|
15
|
+
|
16
|
+
@sqlite_db = SQLite3::Database.open(DevPKI::CA.db_path(id))
|
17
|
+
@id = id
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.delete(id)
|
21
|
+
raise InvalidOption.new("CA with ID #{id} does not exist.") if not self.exists?(id)
|
22
|
+
File.delete self.db_path(id)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Initializes an empty CA database and generates a certificate for self
|
26
|
+
def self.init(id, name=nil, parent_ca_id=nil)
|
27
|
+
raise InvalidOption.new("CA with ID #{id} already exists!") if self.exists?(id)
|
28
|
+
raise InvalidOption.new("Parent CA with ID #{id} does not exist!") if parent_ca_id != nil and not self.exists?(parent_ca_id)
|
29
|
+
|
30
|
+
db = SQLite3::Database.new(self.db_path(id))
|
31
|
+
|
32
|
+
sql = <<-SQL
|
33
|
+
create table certificates (
|
34
|
+
id integer primary key autoincrement,
|
35
|
+
private_key_id integer not null,
|
36
|
+
pem text,
|
37
|
+
|
38
|
+
FOREIGN KEY(private_key_id) REFERENCES private_keys(id)
|
39
|
+
);
|
40
|
+
|
41
|
+
create table private_keys (
|
42
|
+
id integer primary key autoincrement,
|
43
|
+
pem text
|
44
|
+
);
|
45
|
+
SQL
|
46
|
+
|
47
|
+
db.execute_batch(sql)
|
48
|
+
|
49
|
+
if parent_ca_id != nil
|
50
|
+
raise InvalidOption.new("Parent CA with ID #{id} does not exist!") if not self.exists?(parent_ca_id)
|
51
|
+
puts "Exists: #{self.exists?(parent_ca_id)}"
|
52
|
+
parent_db = SQLite3::Database.open(self.db_path(parent_ca_id))
|
53
|
+
|
54
|
+
parent_ca_raw = parent_db.get_first_value( "select pem from certificates" )
|
55
|
+
parent_key_raw = parent_db.get_first_value( "select pem from private_keys" )
|
56
|
+
|
57
|
+
parent_ca_cert = OpenSSL::X509::Certificate.new parent_ca_raw
|
58
|
+
parent_ca_key = OpenSSL::PKey::RSA.new parent_key_raw
|
59
|
+
end
|
60
|
+
|
61
|
+
key = OpenSSL::PKey::RSA.new(2048)
|
62
|
+
public_key = key.public_key
|
63
|
+
|
64
|
+
name ||= "Generic DevPKI CA ##{id}"
|
65
|
+
subject = "/CN=#{name}"
|
66
|
+
|
67
|
+
cert = OpenSSL::X509::Certificate.new
|
68
|
+
cert.subject = OpenSSL::X509::Name.parse(subject)
|
69
|
+
if parent_ca_id == nil
|
70
|
+
cert.issuer = cert.subject
|
71
|
+
else
|
72
|
+
cert.issuer = parent_ca_cert.subject
|
73
|
+
end
|
74
|
+
cert.not_before = Time.now
|
75
|
+
cert.not_after = Time.now + 2 * 365 * 24 * 60 * 60
|
76
|
+
cert.public_key = public_key
|
77
|
+
cert.serial = Random.rand(1..100000)
|
78
|
+
cert.version = 2
|
79
|
+
|
80
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
81
|
+
ef.subject_certificate = cert
|
82
|
+
|
83
|
+
if parent_ca_id == nil
|
84
|
+
ef.issuer_certificate = cert
|
85
|
+
else
|
86
|
+
ef.issuer_certificate = parent_ca_cert
|
87
|
+
end
|
88
|
+
|
89
|
+
cert.extensions = [
|
90
|
+
ef.create_extension("basicConstraints","CA:TRUE", true),
|
91
|
+
ef.create_extension("subjectKeyIdentifier", "hash"),
|
92
|
+
]
|
93
|
+
cert.add_extension ef.create_extension("authorityKeyIdentifier",
|
94
|
+
"keyid:always,issuer:always")
|
95
|
+
|
96
|
+
if parent_ca_id == nil
|
97
|
+
cert.sign key, OpenSSL::Digest::SHA512.new
|
98
|
+
else
|
99
|
+
cert.sign parent_ca_key, OpenSSL::Digest::SHA512.new
|
100
|
+
end
|
101
|
+
|
102
|
+
db.execute( "INSERT INTO private_keys (pem) VALUES ( ? )", key.to_pem )
|
103
|
+
private_key_id = db.last_insert_row_id
|
104
|
+
|
105
|
+
db.execute( "INSERT INTO certificates (private_key_id, pem) VALUES ( ?, ? )", private_key_id, cert.to_pem)
|
106
|
+
|
107
|
+
puts key.to_pem
|
108
|
+
puts cert.to_pem
|
109
|
+
end
|
110
|
+
|
111
|
+
# Checks if CA with given ID exists
|
112
|
+
def self.exists?(id)
|
113
|
+
File.exists?(self.db_path(id))
|
114
|
+
end
|
115
|
+
|
116
|
+
# Returns the path to a CA database
|
117
|
+
def self.db_path(id)
|
118
|
+
DevPKI::DataDirectory::absolute_path_for("ca_#{id}.db")
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'devpki'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module DevPKI
|
5
|
+
module SUBCLI
|
6
|
+
class CA < Thor
|
7
|
+
|
8
|
+
# Hack to override the help message produced by Thor.
|
9
|
+
# https://github.com/wycats/thor/issues/261#issuecomment-16880836
|
10
|
+
def self.banner(command, namespace = nil, subcommand = nil)
|
11
|
+
"#{basename} ca #{command.usage}"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'devpki'
|
2
|
+
require 'thor'
|
3
|
+
require 'devpki/ca'
|
4
|
+
require 'devpki/data_directory'
|
5
|
+
|
6
|
+
module DevPKI
|
7
|
+
module SUBCLI
|
8
|
+
class CA < Thor
|
9
|
+
desc "delete <id> [-all]", "Delete a CA"
|
10
|
+
long_desc <<-LONGDESC
|
11
|
+
Deletes a certification authority (CA) and its database.
|
12
|
+
|
13
|
+
If ID is not given, it is assumed to be 0.
|
14
|
+
|
15
|
+
With option --all, all CA databases will be deleted.
|
16
|
+
LONGDESC
|
17
|
+
option :all, :type => :boolean
|
18
|
+
def delete(id=0)
|
19
|
+
if options[:all]
|
20
|
+
DevPKI::DataDirectory::reset_to_empty
|
21
|
+
else
|
22
|
+
DevPKI::CA.delete(id)
|
23
|
+
puts "CA database deleted."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'devpki'
|
2
|
+
require 'thor'
|
3
|
+
require 'devpki/ca'
|
4
|
+
|
5
|
+
module DevPKI
|
6
|
+
module SUBCLI
|
7
|
+
class CA < Thor
|
8
|
+
desc "init <id> [--name=<name>] [--with-parent=<id>]", "Create a new CA"
|
9
|
+
long_desc <<-LONGDESC
|
10
|
+
Initializes a new certification authority (CA) with given ID. The given ID must not already be in use
|
11
|
+
by another CA.
|
12
|
+
|
13
|
+
The ID provides a way to specify which CA you wish to target with other commands.
|
14
|
+
You may omit the <id> argument, if you wish, in which case it is assumed to be 'default'.
|
15
|
+
|
16
|
+
You only need to specify ID, if you plan to use multiple CAs.
|
17
|
+
|
18
|
+
If the --name option is given, the value will be included in the CA's commmon name.
|
19
|
+
|
20
|
+
If the option --with-parent is given, the CA will be created as a subordinate CA to the specified parent CA.
|
21
|
+
Without this option, the CA will be created as a root CA.
|
22
|
+
LONGDESC
|
23
|
+
option :name, :banner => "<name>", :desc => "Value to include in the CA's certificate common name"
|
24
|
+
option :"with-parent", :banner => "<id>", :desc => "ID of the parent CA. If ommitted, the CA will be created as a root CA"
|
25
|
+
|
26
|
+
def init(id="default")
|
27
|
+
DevPKI::CA.init(id, options[:name], options[:"with-parent"])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'devpki'
|
2
|
+
require 'thor'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
module DevPKI
|
6
|
+
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
|
+
long_desc <<-LONGDESC
|
9
|
+
This command performs an OCSP query against the given OCSP URI, over HTTP. To perform
|
10
|
+
a query, at least 2 certificates are needed - the CA certificate and the subject certificate
|
11
|
+
file that is to be checked for revocation.
|
12
|
+
|
13
|
+
Only HTTP POST method is supported at the moment (RFC 2560).
|
14
|
+
|
15
|
+
EXAMPLE:
|
16
|
+
|
17
|
+
To test subj_a.cer (issuer certificate ca.cer) against http://ocsp.ca.com:
|
18
|
+
|
19
|
+
> $ devpki ocsp --uri=http://ocsp.ca.com ca.cer:subj_a.cer
|
20
|
+
|
21
|
+
|
22
|
+
LONGDESC
|
23
|
+
option :method, :default => "post", :banner => "get|post", :desc => "Method to use. GET as per RFC5019, or POST as per RFC2560. Defaults to POST."
|
24
|
+
option :uri, :banner => "<ocsp uri>", :required => true, :desc => "OCSP responder URI."
|
25
|
+
|
26
|
+
def ocsp(*cer_files)
|
27
|
+
|
28
|
+
raise InvalidOption.new("Please specify at least one CA and subject certificate file.") if cer_files.empty?
|
29
|
+
|
30
|
+
ca_subj_map = {}
|
31
|
+
cer_files.each do |ca_subj_pair|
|
32
|
+
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
|
+
|
34
|
+
ca_subjlist_split = ca_subj_pair.split(":")
|
35
|
+
|
36
|
+
ca_file = ca_subjlist_split.first
|
37
|
+
|
38
|
+
raise InvalidOption.new("No subject certificates specified for CA file \"#{ca_file}\". Please pass a pair with format similar to \"ca.cer:a.cer[,b.cer...]\"") if ca_subjlist_split.length != 2
|
39
|
+
subj_files = ca_subjlist_split.last.split(",")
|
40
|
+
|
41
|
+
ca_subj_map[ca_file] = subj_files
|
42
|
+
end
|
43
|
+
|
44
|
+
ca_subj_map.each_pair do |ca_file,subj_file_list|
|
45
|
+
raise InvalidOption.new("CA certificate file \"#{ca_file}\" does not exist.") if not File.exist?(ca_file)
|
46
|
+
subj_file_list.each do |subj_file|
|
47
|
+
raise InvalidOption.new("Subject certificate file \"#{subj_file}\" does not exist.") if not File.exist?(subj_file)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
method = options[:method].upcase
|
52
|
+
raise InvalidOption.new("GET method not implemented yet.") if method == "GET"
|
53
|
+
|
54
|
+
###### -------------- move this to DevPKI::OCSP
|
55
|
+
|
56
|
+
cert_ids = []
|
57
|
+
store = OpenSSL::X509::Store.new
|
58
|
+
|
59
|
+
ca_subj_map.each_pair do |ca_file, subj_file_list|
|
60
|
+
ca_cert = OpenSSL::X509::Certificate.new File.read(ca_file)
|
61
|
+
store.add_cert(ca_cert)
|
62
|
+
|
63
|
+
subj_file_list.each do |subj_file|
|
64
|
+
subj_cert = OpenSSL::X509::Certificate.new File.read(subj_file)
|
65
|
+
|
66
|
+
cert_ids << OpenSSL::OCSP::CertificateId.new(subj_cert, ca_cert)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
request = OpenSSL::OCSP::Request.new
|
71
|
+
cert_ids.each do |cert_id|
|
72
|
+
request.add_certid(cert_id)
|
73
|
+
end
|
74
|
+
|
75
|
+
request_uri = URI(options[:uri])
|
76
|
+
|
77
|
+
http_req = Net::HTTP::Post.new(request_uri.path)
|
78
|
+
http_req.content_type = "application/ocsp-request"
|
79
|
+
http_req.body = request.to_der
|
80
|
+
|
81
|
+
http_response = Net::HTTP.new(request_uri.host, request_uri.port).start do |http|
|
82
|
+
http.request(http_req)
|
83
|
+
end
|
84
|
+
|
85
|
+
## ----
|
86
|
+
|
87
|
+
if http_response.code != "200"
|
88
|
+
raise StandardError, "Invalid response code from OCSP responder: #{http_response.code}"
|
89
|
+
end
|
90
|
+
|
91
|
+
response = OpenSSL::OCSP::Response.new(http_response.body)
|
92
|
+
puts "Status: #{response.status}"
|
93
|
+
puts "Status string: #{response.status_string}"
|
94
|
+
|
95
|
+
if response.status != 0
|
96
|
+
raise StandardError, "Not a successful status"
|
97
|
+
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
|
+
|
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.
|
113
|
+
|
114
|
+
if response.basic.verify([],store) != true
|
115
|
+
raise StandardError, "Response not signed by a trusted certificate"
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
data/lib/devpki/cli.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
require 'devpki'
|
4
|
+
require 'devpki/cli/ca/init'
|
5
|
+
require 'devpki/cli/ca/delete'
|
6
|
+
require 'devpki/cli/ca/_hack'
|
7
|
+
|
8
|
+
require 'devpki/cli/ocsp'
|
9
|
+
|
10
|
+
module DevPKI
|
11
|
+
class CLI < Thor
|
12
|
+
desc "ca [<id>] <command> [<args>]", "PKI CA functionality"
|
13
|
+
subcommand "ca", DevPKI::SUBCLI::CA
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'devpki'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
Dir["lib/devpki/cli/**/*.rb"].each {|file| require file[4..-1] }
|
5
|
+
|
6
|
+
module DevPKI
|
7
|
+
class DataDirectory
|
8
|
+
|
9
|
+
# Only support OSX atm
|
10
|
+
def self.platform_supported?
|
11
|
+
(/darwin/ =~ RUBY_PLATFORM) != nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.reset_to_empty
|
15
|
+
FileUtils.rm_rf(self.absolute_path)
|
16
|
+
self.get
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.absolute_path
|
20
|
+
File.expand_path("~/Library/Application Support/devpki")
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.absolute_path_for(file_name)
|
24
|
+
File.expand_path(file_name, self.absolute_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.get
|
28
|
+
if not Dir.exists?(self.absolute_path)
|
29
|
+
Dir.mkdir(self.absolute_path)
|
30
|
+
end
|
31
|
+
Dir.new(self.absolute_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/devpki.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "devpki/version"
|
2
|
+
|
3
|
+
module DevPKI
|
4
|
+
autoload :CLI, 'devpki/cli'
|
5
|
+
|
6
|
+
class DevPKIError < StandardError
|
7
|
+
def self.status_code(code)
|
8
|
+
define_method(:status_code) { code }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class InvalidOption < DevPKIError; status_code(10) ; end
|
13
|
+
class CADBError < DevPKIError; status_code(11) ; end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: devpki
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jānis Kiršteins
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sqlite3
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Tool for doing common PKI-related tasks
|
70
|
+
email:
|
71
|
+
- janis@montadigital.com
|
72
|
+
executables:
|
73
|
+
- devpki
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- a.cer
|
84
|
+
- b.cer
|
85
|
+
- bin/devpki
|
86
|
+
- c.cer
|
87
|
+
- ca.crt
|
88
|
+
- ca2.crt
|
89
|
+
- d.cer
|
90
|
+
- devpki.gemspec
|
91
|
+
- lib/devpki.rb
|
92
|
+
- lib/devpki/ca.rb
|
93
|
+
- lib/devpki/cli.rb
|
94
|
+
- lib/devpki/cli/ca/_hack.rb
|
95
|
+
- lib/devpki/cli/ca/delete.rb
|
96
|
+
- lib/devpki/cli/ca/init.rb
|
97
|
+
- lib/devpki/cli/ocsp.rb
|
98
|
+
- lib/devpki/data_directory.rb
|
99
|
+
- lib/devpki/version.rb
|
100
|
+
homepage: ''
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.1.9
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Tool for doing common PKI-related tasks
|
124
|
+
test_files: []
|