eassl 0.1.1635
Sign up to get free protection for your applications and to get access to all the features.
- data/README +2 -0
- data/Rakefile +45 -0
- data/lib/eassl/authority_certificate.rb +43 -0
- data/lib/eassl/certificate.rb +65 -0
- data/lib/eassl/certificate_authority.rb +21 -0
- data/lib/eassl/certificate_name.rb +33 -0
- data/lib/eassl/key.rb +64 -0
- data/lib/eassl/signing_request.rb +51 -0
- data/lib/eassl.rb +35 -0
- metadata +54 -0
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'fileutils'
|
7
|
+
include FileUtils
|
8
|
+
|
9
|
+
REV = File.read(".svn/entries")[/committed-rev="(\d+)"/, 1] rescue nil
|
10
|
+
VERS = ENV['VERSION'] || "0.1" + (REV ? ".#{REV}" : "")
|
11
|
+
|
12
|
+
task :default => [:package]
|
13
|
+
|
14
|
+
#setup_tests
|
15
|
+
|
16
|
+
summary = "EaSSL is a library aimed at making openSSL certificate generation and management easier and more ruby-ish."
|
17
|
+
dependencies = []
|
18
|
+
spec = Gem::Specification.new do |s|
|
19
|
+
s.name = "eassl"
|
20
|
+
s.version = VERS
|
21
|
+
s.platform = Gem::Platform::RUBY
|
22
|
+
s.author = "Paul Nicholson"
|
23
|
+
s.summary = summary
|
24
|
+
# s.test_file = "test/test_eassl.rb"
|
25
|
+
s.has_rdoc = true
|
26
|
+
s.extra_rdoc_files = [ "README" ]
|
27
|
+
dependencies.each do |dep|
|
28
|
+
s.add_dependency(*dep)
|
29
|
+
end
|
30
|
+
s.files = %w(README Rakefile) +
|
31
|
+
Dir.glob("{bin,doc,test,lib}/**/*")
|
32
|
+
|
33
|
+
s.require_path = "lib"
|
34
|
+
s.autorequire = "eassl"
|
35
|
+
end
|
36
|
+
|
37
|
+
Rake::GemPackageTask.new(spec) do |p|
|
38
|
+
p.gem_spec = spec
|
39
|
+
p.need_tar = true
|
40
|
+
end
|
41
|
+
|
42
|
+
task :install do
|
43
|
+
sh %{rake package}
|
44
|
+
sh %{gem install pkg/eassl-#{VERS}}
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'eassl'
|
3
|
+
module EaSSL
|
4
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
5
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
6
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
class AuthorityCertificate
|
9
|
+
def initialize(options)
|
10
|
+
@options = {
|
11
|
+
:key => nil, #required
|
12
|
+
:name => {}, #required, CertificateName
|
13
|
+
}.update(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ssl
|
17
|
+
cert = OpenSSL::X509::Certificate.new
|
18
|
+
cert.not_before = Time.now
|
19
|
+
cert.subject = cert.issuer = CertificateName.new({ :common_name => "CA" }.update(@options[:name])).ssl
|
20
|
+
cert.not_after = cert.not_before + (365 * 5) * 24 * 60 * 60
|
21
|
+
cert.public_key = @options[:key].public_key
|
22
|
+
cert.serial = 1
|
23
|
+
cert.version = 2 # X509v3
|
24
|
+
|
25
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
26
|
+
ef.subject_certificate = cert
|
27
|
+
ef.issuer_certificate = cert
|
28
|
+
cert.extensions = [
|
29
|
+
ef.create_extension("basicConstraints","CA:TRUE"),
|
30
|
+
ef.create_extension("keyUsage", "cRLSign, keyCertSign"),
|
31
|
+
ef.create_extension("subjectKeyIdentifier", "hash"),
|
32
|
+
ef.create_extension("nsComment", "Ruby/OpenSSL/EaSSL Generated Certificate"),
|
33
|
+
]
|
34
|
+
cert.add_extension(ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always"))
|
35
|
+
cert.sign(@options[:key].private_key, OpenSSL::Digest::SHA1.new)
|
36
|
+
cert
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method)
|
40
|
+
ssl.send(method)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'eassl'
|
3
|
+
module EaSSL
|
4
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
5
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
6
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
class Certificate
|
9
|
+
def initialize(options)
|
10
|
+
@options = {
|
11
|
+
:days_valid => (365 * 5),
|
12
|
+
:signing_request => nil, #required
|
13
|
+
:ca_certificate => nil, #required
|
14
|
+
:comment => "Ruby/OpenSSL/EaSSL Generated Certificate",
|
15
|
+
}.update(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def ssl
|
19
|
+
unless @ssl
|
20
|
+
@ssl = OpenSSL::X509::Certificate.new
|
21
|
+
@ssl.not_before = Time.now
|
22
|
+
@ssl.subject = @options[:signing_request].subject
|
23
|
+
@ssl.issuer = @options[:ca_certificate]? @options[:ca_certificate].subject : @ssl.subject
|
24
|
+
@ssl.not_after = @ssl.not_before + @options[:days_valid] * 24 * 60 * 60
|
25
|
+
@ssl.public_key = @options[:signing_request].public_key
|
26
|
+
@ssl.serial = @options[:serial] || 2
|
27
|
+
@ssl.version = 2 # X509v3
|
28
|
+
|
29
|
+
ef = OpenSSL::X509::ExtensionFactory.new
|
30
|
+
ef.subject_certificate = @ssl
|
31
|
+
ef.issuer_certificate = @options[:ca_certificate]? @options[:ca_certificate].ssl : @ssl
|
32
|
+
@ssl.extensions = [
|
33
|
+
ef.create_extension("basicConstraints","CA:FALSE"),
|
34
|
+
ef.create_extension("keyUsage", "digitalSignature, keyEncipherment"),
|
35
|
+
ef.create_extension("subjectKeyIdentifier", "hash"),
|
36
|
+
ef.create_extension("extendedKeyUsage", "serverAuth"),
|
37
|
+
ef.create_extension("nsComment", @options[:comment]),
|
38
|
+
]
|
39
|
+
@ssl.add_extension(ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always"))
|
40
|
+
end
|
41
|
+
@ssl
|
42
|
+
end
|
43
|
+
|
44
|
+
def sign(ca_key)
|
45
|
+
ssl.sign(ca_key.ssl, OpenSSL::Digest::SHA1.new)
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_pem
|
49
|
+
ssl.to_pem
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.load(pem_file_path)
|
53
|
+
new({}).load(File.read(pem_file_path))
|
54
|
+
end
|
55
|
+
|
56
|
+
def load(pem_string)
|
57
|
+
begin
|
58
|
+
@ssl = OpenSSL::X509::Certificate.new(pem_string)
|
59
|
+
rescue
|
60
|
+
raise "CertificateLoader: Error loading certificate"
|
61
|
+
end
|
62
|
+
self
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'eassl'
|
3
|
+
module EaSSL
|
4
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
5
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
6
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
class CertificateAuthority
|
9
|
+
attr_reader :key, :certificate
|
10
|
+
def initialize(options = {})
|
11
|
+
@key = Key.new({:password => 'ca_ssl_password'}.update(options))
|
12
|
+
@certificate = AuthorityCertificate.new(:key => @key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_certificate(signing_request)
|
16
|
+
cert = Certificate.new(:signing_request => signing_request, :ca_certificate => @certificate)
|
17
|
+
cert.sign(@key)
|
18
|
+
cert
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'eassl'
|
3
|
+
module EaSSL
|
4
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
5
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
6
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
class CertificateName
|
9
|
+
def initialize(options)
|
10
|
+
@options = {
|
11
|
+
:country => "US",
|
12
|
+
:state => "North Carolina",
|
13
|
+
:city => "Fuquay Varina",
|
14
|
+
:organization => "WebPower Design",
|
15
|
+
:department => "Web Security",
|
16
|
+
:common_name => nil, # required
|
17
|
+
:email => "eassl@rubyforge.org",
|
18
|
+
}.update(options)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ssl
|
22
|
+
OpenSSL::X509::Name.new([
|
23
|
+
['C', @options[:country], OpenSSL::ASN1::PRINTABLESTRING],
|
24
|
+
['ST', @options[:state], OpenSSL::ASN1::PRINTABLESTRING],
|
25
|
+
['L', @options[:city], OpenSSL::ASN1::PRINTABLESTRING],
|
26
|
+
['O', @options[:organization], OpenSSL::ASN1::UTF8STRING],
|
27
|
+
['OU', @options[:department], OpenSSL::ASN1::UTF8STRING],
|
28
|
+
['CN', @options[:common_name], OpenSSL::ASN1::UTF8STRING],
|
29
|
+
['emailAddress', @options[:email], OpenSSL::ASN1::UTF8STRING]
|
30
|
+
])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/eassl/key.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'eassl'
|
3
|
+
module EaSSL
|
4
|
+
# == EaSSL::Key creates and manages openSSL keys
|
5
|
+
#
|
6
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
7
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
8
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
9
|
+
# License:: Distributes under the same terms as Ruby
|
10
|
+
#
|
11
|
+
# ==== Usage
|
12
|
+
#
|
13
|
+
# ===== Availible Methods - including methods provided by openSSL::PKey:
|
14
|
+
# * public_key
|
15
|
+
# * private_key
|
16
|
+
# * to_text
|
17
|
+
class Key
|
18
|
+
# Create new Key using the provided options or using the defaults
|
19
|
+
def initialize(options = {}) #:params: options
|
20
|
+
@options = {
|
21
|
+
:bits => 2048,
|
22
|
+
:password => 'ssl_password',
|
23
|
+
}.update(options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def ssl
|
27
|
+
unless @ssl
|
28
|
+
$stderr.puts "Generating #{@options[:bits]} bit key\n" # <Should use some kind of logger on this>
|
29
|
+
@ssl = OpenSSL::PKey::RSA::new(@options[:bits])
|
30
|
+
end
|
31
|
+
@ssl
|
32
|
+
end
|
33
|
+
|
34
|
+
# This method is used to intercept and pass-thru calls to openSSL methods and instance
|
35
|
+
# variables.
|
36
|
+
def method_missing(method) # :nodoc:
|
37
|
+
ssl.send(method)
|
38
|
+
end
|
39
|
+
|
40
|
+
def private_key
|
41
|
+
ssl
|
42
|
+
end
|
43
|
+
|
44
|
+
# Export the encrypted key, returns a string
|
45
|
+
def to_pem
|
46
|
+
ssl.export(OpenSSL::Cipher::DES.new('EDE3-CBC'), @options[:password])
|
47
|
+
end
|
48
|
+
|
49
|
+
# Decrypt and load a PEM encoded Key from the file system with the provided password.
|
50
|
+
def self.load(pem_file_path, password=nil)
|
51
|
+
new.load(File.read(pem_file_path), password)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Decrypt and load a PEM encoded Key from provided string with the provided password.
|
55
|
+
def load(pem_string, password=nil)
|
56
|
+
begin
|
57
|
+
@ssl = OpenSSL::PKey::RSA::new(pem_string, password || @options[:password])
|
58
|
+
rescue
|
59
|
+
raise "KeyLoader: Error decrypting key with password"
|
60
|
+
end
|
61
|
+
self
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'eassl'
|
3
|
+
module EaSSL
|
4
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
5
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
6
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
class SigningRequest
|
9
|
+
def initialize(options = {})
|
10
|
+
@options = {
|
11
|
+
:name => {}, #required, CertificateName
|
12
|
+
:key => nil, #required
|
13
|
+
}.update(options)
|
14
|
+
@options[:key] ||= Key.new(@options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def ssl
|
18
|
+
unless @ssl
|
19
|
+
@ssl = OpenSSL::X509::Request.new
|
20
|
+
@ssl.version = 0
|
21
|
+
@ssl.subject = CertificateName.new(@options[:name]).ssl
|
22
|
+
@ssl.public_key = key.public_key
|
23
|
+
@ssl.sign(key.private_key, OpenSSL::Digest::MD5.new)
|
24
|
+
end
|
25
|
+
@ssl
|
26
|
+
end
|
27
|
+
|
28
|
+
def key
|
29
|
+
@options[:key]
|
30
|
+
end
|
31
|
+
|
32
|
+
# This method is used to intercept and pass-thru calls to openSSL methods and instance
|
33
|
+
# variables.
|
34
|
+
def method_missing(method)
|
35
|
+
ssl.send(method)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.load(pem_file_path)
|
39
|
+
new.load(File.read(pem_file_path))
|
40
|
+
end
|
41
|
+
|
42
|
+
def load(pem_string)
|
43
|
+
begin
|
44
|
+
@ssl = OpenSSL::X509::Request.new(pem_string)
|
45
|
+
rescue
|
46
|
+
raise "SigningRequestLoader: Error loading signing request"
|
47
|
+
end
|
48
|
+
self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/eassl.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
2
|
+
# = About EaSSL
|
3
|
+
#
|
4
|
+
# Author:: Paul Nicholson (mailto:paul@webpowerdesign.net)
|
5
|
+
# Co-Author:: Adam Williams (mailto:adam@thewilliams.ws)
|
6
|
+
# Copyright:: Copyright (c) 2006 WebPower Design
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
# By requiring <tt>eassl</tt>, you can load the full set of EaSSL classes.
|
10
|
+
#
|
11
|
+
# For a full list of features and instructions, see the #README.
|
12
|
+
#
|
13
|
+
# EaSSL is a module containing all of the great EaSSL classes for creating
|
14
|
+
# and managing openSSL keys, signing request, and certificates.
|
15
|
+
#
|
16
|
+
# * EaSSL::Key: the class for loading and creating SSL keys
|
17
|
+
# * EaSSL::SigningRequest: the class for creating SSL signing requests
|
18
|
+
|
19
|
+
module EaSSL
|
20
|
+
VERSION = '0.1'
|
21
|
+
|
22
|
+
def self.generate_self_signed(options)
|
23
|
+
ca = CertificateAuthority.new({:bits => 1024}.update(options[:ca_options]||{}))
|
24
|
+
sr = SigningRequest.new(options)
|
25
|
+
cert = ca.create_certificate(sr)
|
26
|
+
[ca, sr, cert]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'eassl/key'
|
31
|
+
require 'eassl/certificate_name'
|
32
|
+
require 'eassl/signing_request'
|
33
|
+
require 'eassl/certificate'
|
34
|
+
require 'eassl/authority_certificate'
|
35
|
+
require 'eassl/certificate_authority'
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: eassl
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.1635
|
7
|
+
date: 2006-11-16 00:00:00 -05:00
|
8
|
+
summary: EaSSL is a library aimed at making openSSL certificate generation and management easier and more ruby-ish.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email:
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: eassl
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Paul Nicholson
|
30
|
+
files:
|
31
|
+
- README
|
32
|
+
- Rakefile
|
33
|
+
- lib/eassl
|
34
|
+
- lib/eassl.rb
|
35
|
+
- lib/eassl/authority_certificate.rb
|
36
|
+
- lib/eassl/certificate.rb
|
37
|
+
- lib/eassl/certificate_authority.rb
|
38
|
+
- lib/eassl/certificate_name.rb
|
39
|
+
- lib/eassl/key.rb
|
40
|
+
- lib/eassl/signing_request.rb
|
41
|
+
test_files: []
|
42
|
+
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
extra_rdoc_files:
|
46
|
+
- README
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
dependencies: []
|
54
|
+
|