Class: R509::PrivateKey

Inherits:
Object
  • Object
show all
Defined in:
lib/r509/private_key.rb

Overview

private key management

Constant Summary

KNOWN_TYPES =

a list of key types

["RSA","DSA","EC"]
DEFAULT_TYPE =

the default type

"RSA"
DEFAULT_STRENGTH =

default bit length for DSA/RSA

2048
DEFAULT_CURVE =

default curve name for EC

"secp384r1"

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (PrivateKey) initialize(opts = {})

A new instance of PrivateKey

Parameters:

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :type (Symbol)

    Defaults to R509::PrivateKey::DEFAULT_TYPE. Allows R509::PrivateKey::KNOWN_TYPES.

  • :curve_name (String) — default: "secp384r1"

    Only used if :type is EC

  • :bit_length (Integer) — default: 2048

    Only used if :type is RSA or DSA

  • :bit_strength (Integer) — default: 2048

    Deprecated, identical to bit_length.

  • :password (String)
  • :key (String, OpenSSL::PKey::RSA, OpenSSL::PKey::DSA, OpenSSL::PKey::EC)
  • :engine (OpenSSL::Engine)
  • :key_name (string) — default: used with engine


27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/r509/private_key.rb', line 27

def initialize(opts={})
  if not opts.kind_of?(Hash)
    raise ArgumentError, 'Must provide a hash of options'
  end
  validate_engine(opts)

  if opts.has_key?(:key)
    validate_key(opts)
  else
    generate_key(opts)
  end
end

Class Method Details

+ (R509::PrivateKey) load_from_file(filename, password = nil)

Helper method to quickly load a private key from the filesystem

Parameters:

  • filename (String)

    Path to file you want to load

Returns:



44
45
46
# File 'lib/r509/private_key.rb', line 44

def self.load_from_file( filename, password = nil )
  return R509::PrivateKey.new(:key => IOHelpers.read_data(filename), :password => password )
end

Instance Method Details

- (Integer) bit_length Also known as: bit_strength

Returns the bit length of the key

Returns:

  • (Integer)


52
53
54
55
56
57
58
59
60
# File 'lib/r509/private_key.rb', line 52

def bit_length
  if self.rsa?
    return self.public_key.n.num_bits
  elsif self.dsa?
    return self.public_key.p.num_bits
  elsif self.ec?
    raise R509::R509Error, 'Bit length is not available for EC at this time.'
  end
end

- (String) curve_name

Returns the short name of the elliptic curve used to generate the private key if the key is EC. If not, raises an error.

Returns:

  • (String)

    elliptic curve name



67
68
69
70
71
72
73
# File 'lib/r509/private_key.rb', line 67

def curve_name
  if self.ec?
    self.key.group.curve_name
  else
    raise R509::R509Error, 'Curve name is only available with EC private keys'
  end
end

- (Boolean) dsa?

Returns whether the key is DSA

Returns:

  • (Boolean)

    true if the key is DSA, false otherwise



187
188
189
# File 'lib/r509/private_key.rb', line 187

def dsa?
  self.key.kind_of?(OpenSSL::PKey::DSA)
end

- (Boolean) ec?

Returns whether the key is EC

Returns:

  • (Boolean)

    true if the key is EC, false otherwise



194
195
196
# File 'lib/r509/private_key.rb', line 194

def ec?
  self.key.kind_of?(OpenSSL::PKey::EC)
end

- (Boolean) in_hardware?

Whether the key is resident in hardware or not

Returns:

  • (Boolean)

    whether the key is resident in hardware or not



85
86
87
88
89
90
91
# File 'lib/r509/private_key.rb', line 85

def in_hardware?
  if not @engine.nil?
    true
  else
    false
  end
end

- (OpenSSL::PKey::RSA, ...) key

This method may return the PKey object itself or a handle to the private key in the HSM (which will not show the private key, just public)

Returns:

  • (OpenSSL::PKey::RSA, OpenSSL::PKey::DSA, OpenSSL::Engine pkey)

    this method may return the PKey object itself or a handle to the private key in the HSM (which will not show the private key, just public)



76
77
78
79
80
81
82
# File 'lib/r509/private_key.rb', line 76

def key
  if in_hardware?
    @engine.load_private_key(@key_name)
  else
    @key
  end
end

- (OpenSSL::PKey::RSA, ...) public_key Also known as: to_s

Public key

Returns:

  • (OpenSSL::PKey::RSA, OpenSSL::PKey::DSA, OpenSSL::PKey::EC)

    public key



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/r509/private_key.rb', line 94

def public_key
  if self.ec?
    # OpenSSL::PKey::EC.public_key returns an OpenSSL::PKey::EC::Point, which isn't consistent
    # with the way OpenSSL::PKey::RSA/DSA do it. We could return the original PKey::EC object
    # but if we do that then it has the private_key as well. Here's a ghetto workaround.
    # We have to supply the curve name to the temporary key object or else #public_key= fails
    curve_name = self.key.group.curve_name
    temp_key = OpenSSL::PKey::EC.new(curve_name)
    temp_key.public_key=self.key.public_key
    temp_key
  else
    self.key.public_key
  end
end

- (Boolean) rsa?

Returns whether the key is RSA

Returns:

  • (Boolean)

    true if the key is RSA, false otherwise



180
181
182
# File 'lib/r509/private_key.rb', line 180

def rsa?
  self.key.kind_of?(OpenSSL::PKey::RSA)
end

- (String) to_der

Converts the key into the DER format

Returns:

  • (String)

    the key converted into DER format.



140
141
142
143
144
145
# File 'lib/r509/private_key.rb', line 140

def to_der
  if in_hardware?
    raise R509::R509Error, "This method cannot be called when using keys in hardware"
  end
  self.key.to_der
end

- (String) to_encrypted_pem(cipher, password)

Converts the key into encrypted PEM format

full list of available ciphers can be obtained with OpenSSL::Cipher.ciphers (common ones are des3, aes256, aes128)

Parameters:

  • cipher (String, OpenSSL::Cipher)

    to use for encryption

  • password (String)

    password

Returns:

  • (String)

    the key converted into encrypted PEM format.



128
129
130
131
132
133
134
# File 'lib/r509/private_key.rb', line 128

def to_encrypted_pem(cipher,password)
  if in_hardware?
    raise R509::R509Error, "This method cannot be called when using keys in hardware"
  end
  cipher = OpenSSL::Cipher::Cipher.new(cipher)
  self.key.to_pem(cipher,password)
end

- (String) to_pem

Converts the key into the PEM format

Returns:

  • (String)

    the key converted into PEM format.



114
115
116
117
118
119
# File 'lib/r509/private_key.rb', line 114

def to_pem
  if in_hardware?
    raise R509::R509Error, "This method cannot be called when using keys in hardware"
  end
  self.key.to_pem
end

- (Object) write_der(filename_or_io)

Writes the key into the DER format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.



172
173
174
# File 'lib/r509/private_key.rb', line 172

def write_der(filename_or_io)
  write_data(filename_or_io, self.to_der)
end

- (Object) write_encrypted_pem(filename_or_io, cipher, password)

Writes the key into encrypted PEM format with specified cipher

full list of available ciphers can be obtained with OpenSSL::Cipher.ciphers (common ones are des3, aes256, aes128)

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.

  • cipher (String, OpenSSL::Cipher)

    to use for encryption

  • password (String)

    password



164
165
166
# File 'lib/r509/private_key.rb', line 164

def write_encrypted_pem(filename_or_io,cipher,password)
  write_data(filename_or_io, to_encrypted_pem(cipher,password))
end

- (Object) write_pem(filename_or_io)

Writes the key into the PEM format

Parameters:

  • filename_or_io (String, #write)

    Either a string of the path for the file that you'd like to write, or an IO-like object.



151
152
153
# File 'lib/r509/private_key.rb', line 151

def write_pem(filename_or_io)
  write_data(filename_or_io, self.to_pem)
end