Class: Tem::Keys::Asymmetric

Inherits:
Tem::Key show all
Defined in:
lib/tem/keys/asymmetric.rb

Overview

Wraps a TEM asymmetric key, e.g. an RSA key.

Instance Attribute Summary

Attributes inherited from Tem::Key

#ssl_key

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Tem::Key

new_from_ssl_key, #to_tem_key

Constructor Details

#initialize(ssl_key, padding_type = :pkcs1) ⇒ Asymmetric

Returns a new instance of Asymmetric.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/tem/keys/asymmetric.rb', line 35

def initialize(ssl_key, padding_type = :pkcs1)
  super ssl_key
  @is_public = !ssl_key.d
  @padding_type = padding_type
  
  case padding_type
  when :oaep
    @padding_id = OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING 
    @padding_bytes = 42
  when :pkcs1
    @padding_id = OpenSSL::PKey::RSA::PKCS1_PADDING
    @padding_bytes = 11
  else
    raise "Unknown padding type #{padding_type}\n"
  end
  
  @size = 0
  n = @is_public ? @ssl_key.n : (@ssl_key.p * @ssl_key.q)
  while n != 0 do
    @size += 1
    n >>= 8
  end
end

Class Method Details

.generate_pairObject

Generate a pair of asymmetric keys.



24
25
26
27
# File 'lib/tem/keys/asymmetric.rb', line 24

def self.generate_pair
  ssl_key = OpenSSL::PKey::RSA.generate(2048, 65537)
  new_pair_from_ssl_key ssl_key
end

.new_from_array(array) ⇒ Object



6
7
8
# File 'lib/tem/keys/asymmetric.rb', line 6

def self.new_from_array(array)
  self.new(OpenSSL::PKey::RSA.new(array[0]), *array[1..-1])      
end

.new_from_yaml_str(yaml_str) ⇒ Object



10
11
12
13
# File 'lib/tem/keys/asymmetric.rb', line 10

def self.new_from_yaml_str(yaml_str)
  array = YAML.load yaml_str
  new_from_array array
end

.new_pair_from_ssl_key(ssl_key) ⇒ Object

Creates a pair of asymmetric keys wrapping an OpenSSL private key.



30
31
32
33
# File 'lib/tem/keys/asymmetric.rb', line 30

def self.new_pair_from_ssl_key(ssl_key)
  { :public => Tem::Keys::Asymmetric.new(ssl_key.public_key),
    :private => Tem::Keys::Asymmetric.new(ssl_key) }
end

Instance Method Details

#decrypt(data) ⇒ Object



69
70
71
72
# File 'lib/tem/keys/asymmetric.rb', line 69

def decrypt(data)
  encrypt_or_decrypt data, @size,
                     @is_public ? :public_decrypt : :private_decrypt      
end

#encrypt(data) ⇒ Object



64
65
66
67
# File 'lib/tem/keys/asymmetric.rb', line 64

def encrypt(data)
  encrypt_or_decrypt data, @size - @padding_bytes,
                     @is_public ? :public_encrypt : :private_encrypt      
end

#is_public?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/tem/keys/asymmetric.rb', line 60

def is_public?
  @is_public
end

#sign(data) ⇒ Object



74
75
76
77
78
79
# File 'lib/tem/keys/asymmetric.rb', line 74

def sign(data)
  data = data.pack 'C*' if data.respond_to? :pack
  # PKCS1-padding is forced in by openssl... sigh!
  out_data = @ssl_key.sign OpenSSL::Digest::SHA1.new, data
  data.respond_to?(:pack) ? out_data : out_data.unpack('C*')
end

#to_arrayObject



15
16
17
# File 'lib/tem/keys/asymmetric.rb', line 15

def to_array
  [@ssl_key.to_pem, @padding_type]
end

#to_yaml_strObject



19
20
21
# File 'lib/tem/keys/asymmetric.rb', line 19

def to_yaml_str
  self.to_array.to_yaml.to_s
end

#verify(data, signature) ⇒ Object



81
82
83
84
85
86
# File 'lib/tem/keys/asymmetric.rb', line 81

def verify(data, signature)
  data = data.pack 'C*' if data.respond_to? :pack
  signature = signature.pack 'C*' if signature.respond_to? :pack
  # PKCS1-padding is forced in by openssl... sigh!
  @ssl_key.verify OpenSSL::Digest::SHA1.new, signature, data
end