helpers for generating private keys
This commit is contained in:
Родитель
689f9f9533
Коммит
214e2cbb23
|
@ -7,6 +7,22 @@ module SSHData
|
|||
@algo = kwargs[:algo]
|
||||
@comment = kwargs[:comment]
|
||||
end
|
||||
|
||||
# Generate a new private key.
|
||||
#
|
||||
# Returns a PublicKey::Base subclass instance.
|
||||
def self.generate(**kwargs)
|
||||
raise "implement me"
|
||||
end
|
||||
|
||||
# Make an SSH signature.
|
||||
#
|
||||
# signed_data - The String message over which to calculated the signature.
|
||||
#
|
||||
# Returns a binary String signature.
|
||||
def sign(signed_data)
|
||||
raise "implement me"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,18 @@
|
|||
class DSA < Base
|
||||
attr_reader :p, :q, :g, :x, :y, :openssl
|
||||
|
||||
# Generate a new private key.
|
||||
#
|
||||
# Returns a PublicKey::Base subclass instance.
|
||||
def self.generate
|
||||
from_openssl(OpenSSL::PKey::DSA.generate(1024))
|
||||
end
|
||||
|
||||
# Import an openssl private key.
|
||||
#
|
||||
# key - An OpenSSL::PKey::DSA instance.
|
||||
#
|
||||
# Returns a DSA instance.
|
||||
def self.from_openssl(key)
|
||||
new(
|
||||
algo: PublicKey::ALGO_DSA,
|
||||
|
|
|
@ -3,6 +3,25 @@ module SSHData
|
|||
class ECDSA < Base
|
||||
attr_reader :curve, :public_key_bytes, :private_key_bytes, :openssl
|
||||
|
||||
# Generate a new private key.
|
||||
#
|
||||
# curve - The String curve to use. One of SSHData::PublicKey::NISTP256,
|
||||
# SSHData::PublicKey::NISTP384, or SSHData::PublicKey::NISTP521.
|
||||
#
|
||||
# Returns a PublicKey::Base subclass instance.
|
||||
def self.generate(curve)
|
||||
openssl_curve = PublicKey::ECDSA::OPENSSL_CURVE_NAME_FOR_CURVE[curve]
|
||||
raise AlgorithmError, "unknown curve: #{curve}" if openssl_curve.nil?
|
||||
|
||||
openssl_key = OpenSSL::PKey::EC.new(openssl_curve).tap(&:generate_key)
|
||||
from_openssl(openssl_key)
|
||||
end
|
||||
|
||||
# Import an openssl private key.
|
||||
#
|
||||
# key - An OpenSSL::PKey::EC instance.
|
||||
#
|
||||
# Returns a DSA instance.
|
||||
def self.from_openssl(key)
|
||||
curve = PublicKey::ECDSA::CURVE_FOR_OPENSSL_CURVE_NAME[key.group.curve_name]
|
||||
algo = "ecdsa-sha2-#{curve}"
|
||||
|
|
|
@ -3,6 +3,13 @@ module SSHData
|
|||
class ED25519 < Base
|
||||
attr_reader :pk, :sk, :ed25519_key
|
||||
|
||||
# Generate a new private key.
|
||||
#
|
||||
# Returns a PublicKey::Base subclass instance.
|
||||
def self.generate
|
||||
from_ed25519(Ed25519::SigningKey.generate)
|
||||
end
|
||||
|
||||
# Create from a ::Ed25519::SigningKey instance.
|
||||
#
|
||||
# key - A ::Ed25519::SigningKey instance.
|
||||
|
|
|
@ -3,6 +3,27 @@ module SSHData
|
|||
class RSA < Base
|
||||
attr_reader :n, :e, :d, :iqmp, :p, :q, :openssl
|
||||
|
||||
|
||||
# Generate a new private key.
|
||||
#
|
||||
# size - The Integer key size to generate.
|
||||
# unsafe_allow_small_key: - Bool of whether to allow keys of less than
|
||||
# 2048 bits.
|
||||
#
|
||||
# Returns a PublicKey::Base subclass instance.
|
||||
def self.generate(size, unsafe_allow_small_key: false)
|
||||
unless size >= 2048 || unsafe_allow_small_key
|
||||
raise AlgorithmError, "key too small"
|
||||
end
|
||||
|
||||
from_openssl(OpenSSL::PKey::RSA.generate(size))
|
||||
end
|
||||
|
||||
# Import an openssl private key.
|
||||
#
|
||||
# key - An OpenSSL::PKey::DSA instance.
|
||||
#
|
||||
# Returns a DSA instance.
|
||||
def self.from_openssl(key)
|
||||
new(
|
||||
algo: PublicKey::ALGO_RSA,
|
||||
|
|
|
@ -3,22 +3,26 @@ module SSHData
|
|||
class ECDSA < Base
|
||||
attr_reader :curve, :public_key_bytes, :openssl
|
||||
|
||||
NISTP256 = "nistp256"
|
||||
NISTP384 = "nistp384"
|
||||
NISTP521 = "nistp521"
|
||||
|
||||
OPENSSL_CURVE_NAME_FOR_CURVE = {
|
||||
"nistp256" => "prime256v1",
|
||||
"nistp384" => "secp384r1",
|
||||
"nistp521" => "secp521r1",
|
||||
NISTP256 => "prime256v1",
|
||||
NISTP384 => "secp384r1",
|
||||
NISTP521 => "secp521r1",
|
||||
}
|
||||
|
||||
CURVE_FOR_OPENSSL_CURVE_NAME = {
|
||||
"prime256v1" => "nistp256",
|
||||
"secp384r1" => "nistp384",
|
||||
"secp521r1" => "nistp521",
|
||||
"prime256v1" => NISTP256,
|
||||
"secp384r1" => NISTP384,
|
||||
"secp521r1" => NISTP521,
|
||||
}
|
||||
|
||||
DIGEST_FOR_CURVE = {
|
||||
"nistp256" => OpenSSL::Digest::SHA256,
|
||||
"nistp384" => OpenSSL::Digest::SHA384,
|
||||
"nistp521" => OpenSSL::Digest::SHA512,
|
||||
NISTP256 => OpenSSL::Digest::SHA256,
|
||||
NISTP384 => OpenSSL::Digest::SHA384,
|
||||
NISTP521 => OpenSSL::Digest::SHA512,
|
||||
}
|
||||
|
||||
# Convert an SSH encoded ECDSA signature to DER encoding for verification with
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
require_relative "./spec_helper"
|
||||
|
||||
describe SSHData::Certificate do
|
||||
let(:rsa_ca) { SSHData::PrivateKey::RSA.from_openssl(OpenSSL::PKey::RSA.generate(2048)) }
|
||||
let(:dsa_ca) { SSHData::PrivateKey::DSA.from_openssl(OpenSSL::PKey::DSA.generate(1024)) }
|
||||
let(:ecdsa_ca) { SSHData::PrivateKey::ECDSA.from_openssl(OpenSSL::PKey::EC.new("prime256v1").tap(&:generate_key)) }
|
||||
let(:ed25519_ca) { SSHData::PrivateKey::ED25519.from_ed25519(Ed25519::SigningKey.generate) }
|
||||
let(:rsa_ca) { SSHData::PrivateKey::RSA.generate(2048) }
|
||||
let(:dsa_ca) { SSHData::PrivateKey::DSA.generate }
|
||||
let(:ecdsa_ca) { SSHData::PrivateKey::ECDSA.generate("nistp256") }
|
||||
let(:ed25519_ca) { SSHData::PrivateKey::ED25519.generate }
|
||||
|
||||
it "supports the deprecated Certificate.parse method" do
|
||||
expect {
|
||||
|
|
|
@ -10,6 +10,12 @@ describe SSHData::PrivateKey::DSA do
|
|||
|
||||
subject { described_class.from_openssl(private_key) }
|
||||
|
||||
it "can be generated" do
|
||||
expect {
|
||||
described_class.generate
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "can sign messages" do
|
||||
expect(subject.public_key.verify(message, subject.sign(message))).to eq(true)
|
||||
end
|
||||
|
|
|
@ -3,6 +3,12 @@ require_relative "../spec_helper"
|
|||
describe SSHData::PrivateKey::ECDSA do
|
||||
let(:openssh_key) { SSHData::PrivateKey.parse(fixture("ecdsa_leaf_for_rsa_ca")) }
|
||||
|
||||
it "can raises AlgorithmError for unknown curves" do
|
||||
expect {
|
||||
described_class.generate("foo")
|
||||
}.to raise_error(SSHData::AlgorithmError)
|
||||
end
|
||||
|
||||
it "can parse openssh-generate keys" do
|
||||
keys = openssh_key
|
||||
expect(keys).to be_an(Array)
|
||||
|
@ -21,6 +27,12 @@ describe SSHData::PrivateKey::ECDSA do
|
|||
|
||||
subject { described_class.from_openssl(private_key) }
|
||||
|
||||
it "can be generated" do
|
||||
expect {
|
||||
described_class.generate(ssh_curve)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "can sign messages" do
|
||||
expect(subject.public_key.verify(message, subject.sign(message))).to eq(true)
|
||||
end
|
||||
|
|
|
@ -17,6 +17,12 @@ describe SSHData::PrivateKey::ED25519 do
|
|||
)
|
||||
end
|
||||
|
||||
it "can be generated" do
|
||||
expect {
|
||||
described_class.generate
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "can sign messages" do
|
||||
expect(subject.public_key.verify(message, subject.sign(message))).to eq(true)
|
||||
end
|
||||
|
|
|
@ -10,6 +10,24 @@ describe SSHData::PrivateKey::RSA do
|
|||
|
||||
subject { described_class.from_openssl(private_key) }
|
||||
|
||||
it "can be generated" do
|
||||
expect {
|
||||
described_class.generate(2048)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "raises AlgorithmError on small key sizes" do
|
||||
expect {
|
||||
described_class.generate(1024)
|
||||
}.to raise_error(SSHData::AlgorithmError)
|
||||
end
|
||||
|
||||
it "can generate small keys if unsafe_allow_small_key is passed" do
|
||||
expect {
|
||||
described_class.generate(1024, unsafe_allow_small_key: true)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "can sign messages" do
|
||||
expect(subject.public_key.verify(message, subject.sign(message))).to eq(true)
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче