Skip to content

Commit

Permalink
Added Crypto::Key::EC (closes #261).
Browse files Browse the repository at this point in the history
  • Loading branch information
postmodern committed May 10, 2022
1 parent 5dcb04c commit 05b2dbc
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
102 changes: 102 additions & 0 deletions lib/ronin/support/crypto/key/ec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#
# Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# This file is part of Ronin Support.
#
# Ronin Support is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ronin Support is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
#

require 'ronin/support/crypto/openssl'

module Ronin
module Support
module Crypto
module Key
#
# Represents an EC key.
#
# ## Examples
#
# ### List supported curves
#
# Crypto::Key::EC.supported_curves
# # => ["secp224r1", "secp256k1", "secp384r1", "secp521r1", "prime256v1"]
#
# ### Generate a random key
#
# ec = Crypto::Key::EC.random("secp224r1")
#
# @see https://rubydoc.info/stdlib/openssl/OpenSSL/PKey/EC.html
#
# @since 1.0.0
#
# @api public
#
class EC < OpenSSL::PKey::EC

#
# The supported elliptical curves.
#
# @return [Array<String>]
# The supported curve names.
#
def self.supported_curves
builtin_curves.map { |(name,desc)| name }
end

#
# Generates a new random EC key.
#
# @param [String] curve
# The elliptical curve to use.
#
# @return [EC]
# The newly generated key.
#
def self.random(curve)
ec = generate(curve)
ec.generate_key
end

#
# Parses an PEM encoded EC key.
#
# @param [String] key
# The key text.
#
# @return [EC]
# The parsed EC key.
#
def self.parse(key)
new(key)
end

#
# Opens an EC key file.
#
# @param [String] path
# The path to the RSA key file.
#
# @return [EC]
# The parsed RSA key.
#
def self.open(path)
parse(File.read(path))
end

end
end
end
end
end
5 changes: 5 additions & 0 deletions spec/crypto/key/ec.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICihRqHFCAlcxEtJbPt8nXE6MUDyA7gaD+BE4VF0s586oAoGCCqGSM49
AwEHoUQDQgAEBEvOEJ7vM+teNfbMpJeV9Sg96R6aZ6oO+Ool4D18APpGJ3K0Pr0Y
SjmNMq7OY3bW3Mxakdmnoq/MSZlK0NY+Uw==
-----END EC PRIVATE KEY-----
48 changes: 48 additions & 0 deletions spec/crypto/key/ec_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require 'spec_helper'
require 'ronin/support/crypto/key/ec'

describe Ronin::Support::Crypto::Key::EC do
let(:path) { File.join(__dir__,'ec.key') }
let(:pem) { File.read(path) }

describe ".supported_curves" do
subject { described_class }

it do
expect(subject.supported_curves).to_not be_empty
expect(subject.supported_curves).to all(be_kind_of(String))
end
end

describe ".random" do
subject { described_class }

let(:curve) { 'prime256v1' }

it "must call .generate with the curve name and then call .generate_key" do
new_key = subject.random(curve)

expect(new_key).to be_kind_of(described_class)
expect(new_key.public_key).to be_kind_of(OpenSSL::PKey::EC::Point)
expect(new_key.private_key).to be_kind_of(OpenSSL::BN)
end
end

describe ".parse" do
subject { described_class }

it "must parse a PEM encoded EC key" do
expect(subject.parse(pem).to_pem).to eq(pem)
end
end

describe ".open" do
subject { described_class }

it "must read and parse the path to the key file" do
expect(subject.open(path).to_pem).to eq(pem)
end
end

subject { described_class.open(path) }
end

0 comments on commit 05b2dbc

Please sign in to comment.