Class: R509::SPKI

Inherits:
Object
  • Object
show all
Includes:
IOHelpers
Defined in:
lib/r509/spki.rb

Overview

class for loading/generating SPKAC/SPKI requests (typically generated by the <keygen> tag

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Methods included from IOHelpers

#read_data, read_data, #write_data, write_data

Constructor Details

- (SPKI) initialize(opts = {})

A new instance of SPKI

Parameters:

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

    a customizable set of options

Options Hash (opts):

  • :spki (String, OpenSSL::Netscape::SPKI)

    the spki you want to parse

  • :key (R509::PrivateKey, String)

    optional private key to supply. either an unencrypted PEM/DER string or an R509::PrivateKey object (use the latter if you need password/hardware support). if supplied you do not need to pass an spki.

  • :message_digest (String)

    Optional digest. sha1, sha224, sha256, sha384, sha512, md5. Defaults to sha1. Only used if you supply a :key and no :spki



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/r509/spki.rb', line 14

def initialize(opts={})
  if not opts.kind_of?(Hash)
    raise ArgumentError, 'Must provide a hash of options'
  elsif not opts.has_key?(:spki) and not opts.has_key?(:key)
    raise ArgumentError, 'Must provide either :spki or :key'
  end

  if opts.has_key?(:key)
    if opts[:key].kind_of?(R509::PrivateKey)
      @key = opts[:key]
    else
      @key = R509::PrivateKey.new(:key => opts[:key])
    end
  end
  if opts.has_key?(:spki)
    spki = opts[:spki]
    # first let's try cleaning up the input a bit so OpenSSL is happy with it
    # OpenSSL hates SPKAC=
    spki.sub!("SPKAC=","")
    # it really hates newlines (Firefox loves 'em)
    # so let's normalize line endings
    spki.gsub!(/\r\n?/, "\n")
    # and nuke 'em
    spki.gsub!("\n", "")
    # ...and leading/trailing whitespace
    spki.strip!
    @spki = OpenSSL::Netscape::SPKI.new(spki)
    if not @key.nil? and not @spki.verify(@key.public_key) then
      raise R509Error, 'Key does not match SPKI.'
    end
  end
  # create the SPKI from the private key if it wasn't passed in
  if @spki.nil?
    @spki = OpenSSL::Netscape::SPKI.new
    @spki.public_key = @key.public_key
    if @key.dsa?
      #only DSS1 is acceptable for DSA signing in OpenSSL < 1.0
      #post-1.0 you can sign with anything, but let's be conservative
      #see: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/PKey/DSA.html
      message_digest = R509::MessageDigest.new('dss1')
    elsif opts.has_key?(:message_digest)
      message_digest = R509::MessageDigest.new(opts[:message_digest])
    else
      message_digest = R509::MessageDigest.new('sha1')
    end
    @spki.sign(@key.key,message_digest.digest)
  end
end

Instance Attribute Details

- (Object) key (readonly)

Returns the value of attribute key



10
11
12
# File 'lib/r509/spki.rb', line 10

def key
  @key
end

- (Object) spki (readonly)

Returns the value of attribute spki



10
11
12
# File 'lib/r509/spki.rb', line 10

def spki
  @spki
end

Instance Method Details

- (Integer) bit_strength

Returns the bit strength of the key used to create the SPKI

Returns:

  • (Integer)

    the integer bit strength.



129
130
131
132
133
134
135
136
137
# File 'lib/r509/spki.rb', line 129

def bit_strength
  if self.rsa?
    return @spki.public_key.n.num_bits
  elsif self.dsa?
    return @spki.public_key.p.num_bits
  elsif self.ec?
    raise R509::R509Error, 'Bit strength 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 public key if the key is EC. If not, raises an error.

Returns:

  • (String)

    elliptic curve name



143
144
145
146
147
148
149
# File 'lib/r509/spki.rb', line 143

def curve_name
  if self.ec?
    @spki.public_key.group.curve_name
  else
    raise R509::R509Error, 'Curve name is only available with EC SPKIs'
  end
end

- (Boolean) dsa?

Returns whether the public key is DSA

Returns:

  • (Boolean)

    true if the public key is DSA, false otherwise



116
117
118
# File 'lib/r509/spki.rb', line 116

def dsa?
  @spki.public_key.kind_of?(OpenSSL::PKey::DSA)
end

- (Boolean) ec?

Returns whether the public key is EC

Returns:

  • (Boolean)

    true if the public key is EC, false otherwise



123
124
125
# File 'lib/r509/spki.rb', line 123

def ec?
  @spki.public_key.kind_of?(OpenSSL::PKey::EC)
end

- (String) key_algorithm

Returns key algorithm (RSA/DSA)

Returns:

  • (String)

    value of the key algorithm. RSA or DSA



154
155
156
157
158
159
160
161
162
# File 'lib/r509/spki.rb', line 154

def key_algorithm
  if self.rsa?
    :rsa
  elsif self.dsa?
    :dsa
  elsif self.ec?
    :ec
  end
end

- (OpenSSL::PKey::RSA) public_key

Public key

Returns:

  • (OpenSSL::PKey::RSA)

    public key



64
65
66
# File 'lib/r509/spki.rb', line 64

def public_key
  @spki.public_key
end

- (Boolean) rsa?

Returns whether the public key is RSA

Returns:

  • (Boolean)

    true if the public key is RSA, false otherwise



109
110
111
# File 'lib/r509/spki.rb', line 109

def rsa?
  @spki.public_key.kind_of?(OpenSSL::PKey::RSA)
end

- (String) to_der

Converts the SPKI into the DER format

Returns:

  • (String)

    the SPKI converted into DER format.



86
87
88
# File 'lib/r509/spki.rb', line 86

def to_der
  @spki.to_der
end

- (String) to_pem Also known as: to_s

Converts the SPKI into the PEM format

Returns:

  • (String)

    the SPKI converted into PEM format.



77
78
79
# File 'lib/r509/spki.rb', line 77

def to_pem
  @spki.to_pem
end

- (Boolean) verify_signature

Verifies the integrity of the signature on the SPKI

Returns:

  • (Boolean)


70
71
72
# File 'lib/r509/spki.rb', line 70

def verify_signature
  @spki.verify(public_key)
end

- (Object) write_der(filename_or_io)

Writes the SPKI 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.



102
103
104
# File 'lib/r509/spki.rb', line 102

def write_der(filename_or_io)
  write_data(filename_or_io, @spki.to_der)
end

- (Object) write_pem(filename_or_io)

Writes the SPKI 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.



94
95
96
# File 'lib/r509/spki.rb', line 94

def write_pem(filename_or_io)
  write_data(filename_or_io, @spki.to_pem)
end