Skip to content

Commit

Permalink
Merge pull request #5 from krallin/ecdsa-support
Browse files Browse the repository at this point in the history
Support ECDSA private keys
  • Loading branch information
krallin authored Dec 5, 2017
2 parents 88c4505 + 01fa0fb commit b0a198a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
17 changes: 16 additions & 1 deletion lib/mini_ca/certificate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def initialize(
x509.version = 0x2
x509.serial = serial || 0

x509.public_key = send(:private_key).public_key
x509.public_key = public_key

x509.subject = OpenSSL::X509::Name.new

Expand Down Expand Up @@ -126,5 +126,20 @@ def bundle_pem
def private_key_pem
private_key.to_pem
end

def public_key
case private_key
when OpenSSL::PKey::RSA
private_key.public_key
when OpenSSL::PKey::EC
# See: https://github.com/ruby/openssl/issues/29#issuecomment-230664793
# See: https://alexpeattie.com/blog/signing-a-csr-with-ecdsa-in-ruby
pub = OpenSSL::PKey::EC.new(private_key.group)
pub.public_key = private_key.public_key
pub
else
raise Error, "Unsupported private_key: #{private_key.class}"
end
end
end
end
24 changes: 21 additions & 3 deletions spec/mini_ca/certificate_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,28 @@
end
end

it 'initializes with a custom private_key' do
it 'initializes with a custom private_key (RSA)' do
k = OpenSSL::PKey::RSA.new(512)
expect(described_class.new('x', private_key: k).private_key_pem)
.to eq(k.to_pem)

crt = described_class.new('x', private_key: k)
expect(crt.private_key_pem).to eq(k.to_pem)
expect(crt.x509.check_private_key(k)).to be_truthy
end

it 'initializes with a custom private_key (ECDSA)' do
k = OpenSSL::PKey::EC.new('prime256v1').tap(&:generate_key)

# Ruby < 2.4 lacks a #private? method on EC keys, which is used when
# signing. We're not going to monkey-patch this for users, but we want to
# monkey patch it for our own specs.
maj, min, = RUBY_VERSION.split('.').map { |e| Integer(e) }
unless maj >= 2 && min >= 4 || maj > 2
allow(k).to receive(:private?) { k.private_key? }
end

crt = described_class.new('x', private_key: k)
expect(crt.private_key_pem).to eq(k.to_pem)
expect(crt.x509.check_private_key(k)).to be_truthy
end
end

Expand Down

0 comments on commit b0a198a

Please sign in to comment.