metafusion 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ module Metafusion
2
+ module Crypto
3
+ end
4
+ end
5
+
6
+ require 'base64'
7
+
8
+ require 'metafusion/crypto/version'
9
+ require 'metafusion/crypto/meta'
10
+ require 'metafusion/crypto/base'
@@ -0,0 +1,132 @@
1
+ # Cryptography helper module <tt>Metafusion::Crypto</tt> as well as
2
+ # <tt>Metafusion::Crypto::PrivateKey</tt> and
3
+ # <tt>Metafusion::Crypto::DigitalSignature</tt> classes.
4
+
5
+ require 'openssl'
6
+ require 'digest/sha1'
7
+
8
+ # Module that contains Cryptography helper methods and the
9
+ # <tt>Metafusion::Crypto::Key</tt> class to be utilized in
10
+ # public key encryption.
11
+ module Metafusion::Crypto
12
+
13
+ # Generate private and public keys
14
+ # 1. <tt>private_file</tt> - file name of private key to generate (default = "rsa_key")
15
+ # 2. <tt>public_file</tt> - file name of public key to generate (default = "#{private_key}.pub")
16
+ # 3. <tt>bits</tt> - number of bits for key (default = 1024)
17
+ # 4. <tt>clean</tt> - specifies if existing key files should
18
+ # zapped and replaced by newly generated keys (default = true)
19
+ #
20
+ # Returns the private key generated.
21
+ #
22
+ # Usage:
23
+ # priv_key = Metafusion::Crypto.generate_key_pair
24
+ def self.generate_key_pair(private_file = "rsa_key",
25
+ public_file = "#{private_file}.pub",
26
+ bits = 512, clean = true)
27
+ if clean
28
+ File.delete(private_file) if File.exists?(private_file)
29
+ File.delete(public_file) if File.exists?(public_file)
30
+ end
31
+ private_key = OpenSSL::PKey::RSA.new(bits)
32
+ File.open(private_file, "w+") do |fp|
33
+ fp << private_key.to_s
34
+ end
35
+ File.open(public_file, "w+") do |fp|
36
+ fp << private_key.public_key.to_s
37
+ end
38
+ private_key
39
+ end
40
+
41
+ # <tt>Metafusion::Crypto::DigitalSignature</tt> provides easier
42
+ # a more streamlined API to create digital signatures without
43
+ # needing to know what that entails.
44
+ #
45
+ # Usage:
46
+ # include Metafusion::Crypto
47
+ # sig = DigitalSignature.from_file('rsa_key.pub', 'rsa_key')
48
+ # original_text = "my clear text message"
49
+ # crypted_text = sig.encrypt(original_text)
50
+ # plain_text = sig.decrypt(crypted_text)
51
+ # puts "It worked - let's celebrate!" if original_text == plain_text
52
+ class DigitalSignature
53
+ # Class methods
54
+ class << self
55
+ # Loads and constructs key from file <tt>private_filename</tt> given.
56
+ def from_keys(public_filename = "rsa_key.pub",
57
+ private_filename = nil)
58
+ return self.new(File.read(public_filename)) unless private_filename
59
+ self.new(File.read(public_filename), File.read(private_filename))
60
+ end
61
+ end
62
+
63
+ # Constructor that takes the private and public key data.
64
+ # Only the <tt>public_data</tt> is required since not all
65
+ # <tt>DigitalSignature</tt> class clients will have access
66
+ # to the private key.
67
+ def initialize(public_data, private_data = nil)
68
+ @private_key = OpenSSL::PKey::RSA.new(private_data) if private_data
69
+ @public_key = OpenSSL::PKey::RSA.new(public_data)
70
+ end
71
+
72
+ # Encrypts given <tt>text</tt> using key instance. This assumes
73
+ # that private key data was provided at instantiation step.
74
+ def encrypt(text)
75
+ Base64.encode64(@private_key.send("private_encrypt", text)) if @private_key
76
+ end
77
+
78
+ # Decrypts given <tt>text</tt> using key instance.
79
+ def decrypt(text)
80
+ @public_key.send("public_decrypt", Base64.decode64(text))
81
+ end
82
+
83
+ private
84
+ attr_accessor :private_key, :public_key
85
+ end
86
+
87
+ # <tt>Metafusion::Crypto::PrivateKey</tt> provides class that wraps
88
+ # the boilerplate private key encryption API from the Ruby
89
+ # standard library OpenSSL implementation.
90
+ #
91
+ # Usage:
92
+ # include Metafusion::Crypto
93
+ # pkey = PrivateKey.new('mypassphrase')
94
+ # original_text = 'Yo yo yo. What up dog?'
95
+ # crypted_text = pkey.encrypt(original_text)
96
+ # plain_text = pkey.decrypt(crypted_text)
97
+ # puts "Let's roll and celebrate - it worked" if original_text == plain_text
98
+ class PrivateKey
99
+ # Class methods
100
+ class << self
101
+ # Read in private key from file
102
+ def from_file(key_file = 'rsa_key')
103
+ return self.new(File.read(key_file))
104
+ end
105
+ end
106
+
107
+ # Creates <tt>PrivateKey</tt> instance given
108
+ # <tt>raw_passphrase</tt> and <tt>cipher</tt>.
109
+ # The default cipher is AES-256-CBC.
110
+ def initialize(raw_passphrase, cipher = "aes-256-cbc")
111
+ @encrypt_cipher = OpenSSL::Cipher::Cipher.new(cipher)
112
+ @decrypt_cipher = OpenSSL::Cipher::Cipher.new(cipher)
113
+ @key = Digest::SHA1.hexdigest(raw_passphrase)
114
+ end
115
+
116
+ # Encrypts given <tt>text</tt> using key instance
117
+ def encrypt(text)
118
+ @encrypt_cipher.encrypt(@key)
119
+ s = @encrypt_cipher.update(text)
120
+ s << @encrypt_cipher.final
121
+ Base64.encode64(s)
122
+ end
123
+
124
+ # Decrypts given <tt>text</tt> using key instance
125
+ def decrypt(text)
126
+ @decrypt_cipher.decrypt(@key)
127
+ s = @decrypt_cipher.update(Base64.decode64(text))
128
+ s << @decrypt_cipher.final
129
+ s
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,57 @@
1
+ # meta.rb contains <tt>Metafusion::Crypto::Meta</tt> and related classes that
2
+ # help define the metadata of the <tt>Metafusion::Crypto4R</tt> project.
3
+
4
+ require('rubygems')
5
+ require('erb')
6
+
7
+ class Metafusion::Crypto::Meta #:nodoc:
8
+ attr_accessor :root_dir
9
+ attr_reader :gem_spec, :project_files, :spec_files
10
+
11
+ # Initializer for Metafusion::Crypto::Meta class. Takes <tt>root_dir</tt> as parameter.
12
+ def initialize(root_dir)
13
+ @root_dir = root_dir
14
+ end
15
+
16
+ # Returns package information defined in <tt>root_dir</tt>/pkg-info.yml
17
+ def pkg_info
18
+ yaml_file = File.join(@root_dir, 'pkg-info.yml')
19
+ ryaml = ERB.new(File.read(yaml_file), 0)
20
+ s = ryaml.result(binding)
21
+ YAML.load(s)
22
+ end
23
+
24
+ # Returns RubyGems spec information
25
+ def spec_info
26
+ self.pkg_info['spec'] if self.pkg_info
27
+ end
28
+
29
+ # Returns list of project files
30
+ def project_files
31
+ @project_files ||= Dir.glob(File.join(@root_dir, 'lib/**/*.rb'))
32
+ @project_files
33
+ end
34
+
35
+ # Returns list of specification files
36
+ def spec_files
37
+ @spec_files ||= Dir.glob(File.join(@root_dir, 'spec/**/*_spec.rb'))
38
+ @spec_files
39
+ end
40
+
41
+ # Returns RubyGem specification for Metafusion::Crypto project
42
+ def gem_spec
43
+ @gem_spec ||= Gem::Specification.new do |spec|
44
+ self.spec_info.each do |key, val|
45
+ # if val.is_a?(Hash)
46
+ # puts val.inspect
47
+ # val.each do |k, v|
48
+ # spec.send(key, k, v)
49
+ # end
50
+ # else
51
+ spec.send("#{key}=", val)
52
+ # end
53
+ end
54
+ end
55
+ @gem_spec
56
+ end
57
+ end
@@ -0,0 +1,19 @@
1
+ # version.rb contains <tt>Metafusion::Crypto::Version</tt> that provides helper
2
+ # methods related to versioning of the <tt>Metafusion::Crypto4R</tt> project.
3
+
4
+ module Metafusion::Crypto::Version #:nodoc:
5
+ MAJOR = 0
6
+ MINOR = 1
7
+ REVISION = 0
8
+ class << self
9
+ # Returns X.Y.Z formatted version string
10
+ def to_version
11
+ "#{MAJOR}.#{MINOR}.#{REVISION}"
12
+ end
13
+
14
+ # Returns X-Y-Z formatted version name
15
+ def to_name
16
+ "#{MAJOR}_#{MINOR}_#{REVISION}"
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,113 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ PRIVATE_KEY = 'rsa_key'
4
+ PUBLIC_KEY = 'rsa_key.pub'
5
+
6
+ def remove_rsa_keys(priv = PRIVATE_KEY, pub = PUBLIC_KEY)
7
+ File.delete(priv) if File.exists?(priv)
8
+ File.delete(pub) if File.exists?(pub)
9
+ end
10
+
11
+ describe Metafusion::Crypto, ".generate_key_pair" do
12
+ before(:each) do
13
+ remove_rsa_keys
14
+ end
15
+
16
+ it "should create a private and public RSA key pair" do
17
+ Metafusion::Crypto.generate_key_pair
18
+ File.exists?(PRIVATE_KEY).should be_true
19
+ File.exists?(PUBLIC_KEY).should be_true
20
+ end
21
+
22
+ after(:each) do
23
+ remove_rsa_keys
24
+ end
25
+ end
26
+
27
+ describe Metafusion::Crypto::DigitalSignature do
28
+ before(:each) do
29
+ # ensure the keys are generated
30
+ Metafusion::Crypto.generate_key_pair
31
+ @private_key = "private key"
32
+ @public_key = "public key"
33
+ File.stub!(:read).and_return(@public_key, @private_key)
34
+ end
35
+
36
+ it "should create instance from from_keys class method" do
37
+ Metafusion::Crypto::DigitalSignature.should_receive(:new).with(@public_key,@private_key)
38
+ Metafusion::Crypto::DigitalSignature.from_keys(PUBLIC_KEY, PRIVATE_KEY)
39
+ end
40
+
41
+ it "should create instance from from_keys class method using private key data when only public key provided" do
42
+ Metafusion::Crypto::DigitalSignature.should_receive(:new).with(@public_key)
43
+ Metafusion::Crypto::DigitalSignature.from_keys(PUBLIC_KEY)
44
+ end
45
+
46
+ after(:each) do
47
+ remove_rsa_keys
48
+ end
49
+ end
50
+
51
+ describe Metafusion::Crypto::DigitalSignature do
52
+ before(:each) do
53
+ @original_text = "Charlotte Bronte rules"
54
+ Metafusion::Crypto.generate_key_pair
55
+ @digital_signature = Metafusion::Crypto::DigitalSignature.from_keys('rsa_key.pub', 'rsa_key')
56
+ end
57
+
58
+ it "should encrypt/decrypt round-trip back to original text" do
59
+ crypted_text = @digital_signature.encrypt(@original_text)
60
+ decrypted_text = @digital_signature.decrypt(crypted_text)
61
+ decrypted_text.should eql(@original_text)
62
+ end
63
+
64
+ it "should encrypt original text to a 90 character base64 string" do
65
+ crypted_text = @digital_signature.encrypt(@original_text)
66
+ crypted_text.size.should be(90)
67
+ end
68
+
69
+ after(:each) do
70
+ remove_rsa_keys
71
+ end
72
+ end
73
+
74
+ describe Metafusion::Crypto::PrivateKey do
75
+ before(:each) do
76
+ @original_text = "Was Jane Eyre the ultimate feminist?"
77
+ @private_key = Metafusion::Crypto::PrivateKey.new("currerbell1847")
78
+ end
79
+
80
+ it "should encrypt/decrypt round-trip back to original text" do
81
+ crypted_text = @private_key.encrypt(@original_text)
82
+ decrypted_text = @private_key.decrypt(crypted_text)
83
+ decrypted_text.should eql(@original_text)
84
+ end
85
+
86
+ after(:each) do
87
+ remove_rsa_keys
88
+ end
89
+ end
90
+
91
+ describe Metafusion::Crypto::PrivateKey, ".from_file" do
92
+ before(:each) do
93
+ @file_name = "key_file"
94
+ @key_content = "the key goes here"
95
+ File.stub!(:read).and_return(@key_content)
96
+ @pkey = mock(Metafusion::Crypto::PrivateKey)
97
+ end
98
+
99
+ it "should create new instance of PrivateKey with contents of key file supplied" do
100
+ Metafusion::Crypto::PrivateKey.should_receive(:new).with(@key_content).and_return(@pkey)
101
+ Metafusion::Crypto::PrivateKey.from_file(@file_name)
102
+ end
103
+
104
+ it "should read contents of file given" do
105
+ File.should_receive(:read).with(@file_name).and_return("")
106
+ Metafusion::Crypto::PrivateKey.from_file(@file_name)
107
+ end
108
+
109
+ after(:each) do
110
+ @pkey = nil
111
+ @file_name = nil
112
+ end
113
+ end
@@ -0,0 +1,90 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ def glob_files(*path_elements)
4
+ Dir.glob(File.join(*path_elements))
5
+ end
6
+
7
+ def load_erb_yaml(path, context)
8
+ ryaml = ERB.new(File.read(path), 0)
9
+ YAML.load(ryaml.result(context))
10
+ end
11
+
12
+ module ERBMetaMixin
13
+ # Needed to make the YAML load work...
14
+ def project_files
15
+ glob_files(@root_dir, 'lib', '**/*.rb')
16
+ end
17
+
18
+ # Needed to make the YAML load work...
19
+ def spec_files
20
+ glob_files(@root_dir, 'spec', '**/*_spec.rb')
21
+ end
22
+ end
23
+
24
+ describe "Metafusion::Crypto::Meta cache policy" do
25
+ include ERBMetaMixin
26
+ before(:each) do
27
+ @root_dir = project_root_dir
28
+ @meta = Metafusion::Crypto::Meta.new(@root_dir)
29
+ @expected_pkg_info = load_erb_yaml(File.join(@root_dir, 'pkg-info.yml'), binding)
30
+ @expected_project_files = project_files
31
+ @expected_spec_files = spec_files
32
+ end
33
+
34
+ it "should store value returned from project_files in @project_files after first glob" do
35
+ @meta.instance_eval("@project_files").should eql(nil)
36
+ @meta.project_files
37
+ @meta.instance_eval("@project_files").should eql(@expected_project_files)
38
+ @meta.project_files
39
+ @meta.instance_eval("@project_files").should eql(@expected_project_files)
40
+ end
41
+
42
+ it "should store value returned from spec_files in @spec_files after first glob" do
43
+ @meta.instance_eval("@spec_files").should eql(nil)
44
+ @meta.spec_files
45
+ @meta.instance_eval("@spec_files").should eql(@expected_spec_files)
46
+ @meta.spec_files
47
+ @meta.instance_eval("@spec_files").should eql(@expected_spec_files)
48
+ end
49
+ end
50
+
51
+ describe "Metafusion::Crypto::Meta" do
52
+ include ERBMetaMixin
53
+ before(:each) do
54
+ @root_dir = project_root_dir
55
+ @meta = Metafusion::Crypto::Meta.new(@root_dir)
56
+ @expected_yaml_hash = load_erb_yaml(File.join(@root_dir, 'pkg-info.yml'), binding)
57
+ @expected_project_files = project_files
58
+ @expected_spec_files = spec_files
59
+ end
60
+
61
+ it "should load and return YAML file into Hash object upon #pkg_info call" do
62
+ yaml_hash = @meta.pkg_info
63
+ yaml_hash.should.eql? @expected_yaml_hash
64
+ end
65
+
66
+ it "should return the embedded hash responding to key 'spec' of #pkg_info call upon #spec_info call" do
67
+ yaml_hash = @meta.spec_info
68
+ yaml_hash.should.eql? @expected_yaml_hash['spec']
69
+ end
70
+
71
+ it "should return list of files matching ROOT_DIR/lib/**/*.rb upon #project_files call" do
72
+ project_files = @meta.project_files
73
+ project_files.should.eql? @expected_project_files
74
+ end
75
+
76
+ it "should return list of files matching ROOT_DIR/spec/**/*.rb upon #spec_files call" do
77
+ spec_files = @meta.spec_files
78
+ spec_files.should.eql? @expected_spec_files
79
+ end
80
+
81
+ it "should return Gem specification based on YAML file contents and #project_files and #spec_files return values" do
82
+ spec = @meta.gem_spec
83
+ expected_spec_hash = @expected_yaml_hash['spec']
84
+ expected_spec_hash.each do |key, val|
85
+ unless val.is_a?(Hash)
86
+ spec.send(key).to_s.should eql(expected_spec_hash[key].to_s)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,19 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
2
+
3
+ VERSION_LIST = [Metafusion::Crypto::Version::MAJOR, Metafusion::Crypto::Version::MINOR, Metafusion::Crypto::Version::REVISION]
4
+
5
+ EXPECTED_VERSION = VERSION_LIST.join('.')
6
+ EXPECTED_NAME = VERSION_LIST.join('_')
7
+
8
+ describe Metafusion::Crypto::Version, ".to_version" do
9
+ it "should return #{EXPECTED_VERSION}" do
10
+ Metafusion::Crypto::Version.to_version.should eql(EXPECTED_VERSION)
11
+ end
12
+ end
13
+
14
+ describe Metafusion::Crypto::Version, ".to_name" do
15
+ it "should return #{EXPECTED_NAME}" do
16
+ Metafusion::Crypto::Version.to_name.should eql(EXPECTED_NAME)
17
+ end
18
+ end
19
+
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: metafusion
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2007-09-29 00:00:00 -05:00
8
+ summary: Provides private key and digital signature encryption mechanisms for application developers that do not want to worry about the details.
9
+ require_paths:
10
+ - lib
11
+ email: metafusion@googlegroups.com
12
+ homepage: http://metafusion.rubyforge.org
13
+ rubyforge_project: metafusion
14
+ description:
15
+ autorequire: metafusion
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: 1.8.2
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Susan Potter
31
+ files:
32
+ - lib/metafusion/crypto.rb
33
+ - lib/metafusion/crypto/base.rb
34
+ - lib/metafusion/crypto/version.rb
35
+ - lib/metafusion/crypto/meta.rb
36
+ - spec/metafusion/crypto/base_spec.rb
37
+ - spec/metafusion/crypto/version_spec.rb
38
+ - spec/metafusion/crypto/meta_spec.rb
39
+ test_files: []
40
+
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ requirements:
50
+ - Ruby 1.8.4+
51
+ - jcode (for unicode support)
52
+ dependencies: []
53
+