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.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/tem/keys/asymmetric.rb', line 42

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.



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

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



13
14
15
# File 'lib/tem/keys/asymmetric.rb', line 13

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



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

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.



37
38
39
40
# File 'lib/tem/keys/asymmetric.rb', line 37

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



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

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

#encrypt(data) ⇒ Object



71
72
73
74
# File 'lib/tem/keys/asymmetric.rb', line 71

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

#is_public?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/tem/keys/asymmetric.rb', line 67

def is_public?
  @is_public
end

#sign(data) ⇒ Object



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

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



22
23
24
# File 'lib/tem/keys/asymmetric.rb', line 22

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

#to_yaml_strObject



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

def to_yaml_str
  self.to_array.to_yaml.to_s
end

#verify(data, signature) ⇒ Object



88
89
90
91
92
93
# File 'lib/tem/keys/asymmetric.rb', line 88

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