Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2017-08-21 13:30:03 +0300
committerNick Thomas <nick@gitlab.com>2017-08-30 22:50:44 +0300
commitb0f982fbdf69c292ab4530c0aaaf1ab42f4e7a01 (patch)
tree0d76c74fb6260de1e3c9694a8501491b2eb486ef /spec/lib
parent81f08d30e641dc1a6666022ab1f5d36dbcdced7e (diff)
Add settings for minimum key strength and allowed key type
This is an amalgamation of: * Cory Hinshaw: Initial implementation !5552 * Rémy Coutable: Updates !9350 * Nick Thomas: Resolve conflicts and add ED25519 support !13712
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/gitlab/git_access_spec.rb42
-rw-r--r--spec/lib/gitlab/key_fingerprint_spec.rb82
-rw-r--r--spec/lib/gitlab/ssh_public_key_spec.rb132
3 files changed, 174 insertions, 82 deletions
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 295a979da76..a67902c7209 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -155,6 +155,48 @@ describe Gitlab::GitAccess do
end
end
+ shared_examples '#check with a key that is not valid' do
+ before do
+ project.add_master(user)
+ end
+
+ context 'key is too small' do
+ before do
+ stub_application_setting(minimum_rsa_bits: 4096)
+ end
+
+ it 'does not allow keys which are too small' do
+ aggregate_failures do
+ expect(actor).not_to be_valid
+ expect { pull_access_check }.to raise_unauthorized('Your SSH key length must be at least 4096 bits.')
+ expect { push_access_check }.to raise_unauthorized('Your SSH key length must be at least 4096 bits.')
+ end
+ end
+ end
+
+ context 'key type is not allowed' do
+ before do
+ stub_application_setting(allowed_key_types: ['ecdsa'])
+ end
+
+ it 'does not allow keys which are too small' do
+ aggregate_failures do
+ expect(actor).not_to be_valid
+ expect { pull_access_check }.to raise_unauthorized('Your SSH key type is not allowed. Must be ECDSA.')
+ expect { push_access_check }.to raise_unauthorized('Your SSH key type is not allowed. Must be ECDSA.')
+ end
+ end
+ end
+ end
+
+ it_behaves_like '#check with a key that is not valid' do
+ let(:actor) { build(:rsa_key_2048, user: user) }
+ end
+
+ it_behaves_like '#check with a key that is not valid' do
+ let(:actor) { build(:rsa_deploy_key_2048, user: user) }
+ end
+
describe '#check_project_moved!' do
before do
project.add_master(user)
diff --git a/spec/lib/gitlab/key_fingerprint_spec.rb b/spec/lib/gitlab/key_fingerprint_spec.rb
deleted file mode 100644
index d643dc5342d..00000000000
--- a/spec/lib/gitlab/key_fingerprint_spec.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::KeyFingerprint, lib: true do
- KEYS = {
- rsa:
- 'example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5z65PwQ1GE6foJgwk' \
- '9rmQi/glaXbUeVa5uvQpnZ3Z5+forcI7aTngh3aZ/H2UDP2L70TGy7kKNyp0J3a8/OdG' \
- 'Z08y5yi3JlbjFARO1NyoFEjw2H1SJxeJ43L6zmvTlu+hlK1jSAlidl7enS0ufTlzEEj4' \
- 'iJcuTPKdVzKRgZuTRVm9woWNVKqIrdRC0rJiTinERnfSAp/vNYERMuaoN4oJt8p/NEek' \
- 'rmFoDsQOsyDW5RAnCnjWUU+jFBKDpfkJQ1U2n6BjJewC9dl6ODK639l3yN4WOLZEk4tN' \
- 'UysfbGeF3rmMeflaD6O1Jplpv3YhwVGFNKa7fMq6k3Z0tszTJPYh',
- ecdsa:
- 'example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAI' \
- 'bmlzdHAyNTYAAABBBKTJy43NZzJSfNxpv/e2E6Zy3qoHoTQbmOsU5FEfpWfWa1MdTeXQ' \
- 'YvKOi+qz/1AaNx6BK421jGu74JCDJtiZWT8=',
- ed25519:
- '@revoked example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjq' \
- 'uxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf',
- dss:
- 'example.com ssh-dss AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdS' \
- 'PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f' \
- '6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iID' \
- 'GZ3RSAHHAAAAFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QAAAIEA9+GghdabPd7LvKtcNrhX' \
- 'uXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwW' \
- 'eotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6A' \
- 'e1UlZAFMO/7PSSoAAACBAJcQ4JODqhuGbXIEpqxetm7PWbdbCcr3y/GzIZ066pRovpL6' \
- 'qm3qCVIym4cyChxWwb8qlyCIi+YRUUWm1z/wiBYT2Vf3S4FXBnyymCkKEaV/EY7+jd4X' \
- '1bXI58OD2u+bLCB/sInM4fGB8CZUIWT9nJH0Ve9jJUge2ms348/QOJ1+'
- }.freeze
-
- MD5_FINGERPRINTS = {
- rsa: '06:b2:8a:92:df:0e:11:2c:ca:7b:8f:a4:ba:6e:4b:fd',
- ecdsa: '45:ff:5b:98:9a:b6:8a:41:13:c1:30:8b:09:5e:7b:4e',
- ed25519: '2e:65:6a:c8:cf:bf:b2:8b:9a:bd:6d:9f:11:5c:12:16',
- dss: '57:98:86:02:5f:9c:f4:9b:ad:5a:1e:51:92:0e:fd:2b'
- }.freeze
-
- BIT_COUNTS = {
- rsa: 2048,
- ecdsa: 256,
- ed25519: 256,
- dss: 1024
- }.freeze
-
- describe '#type' do
- KEYS.each do |type, key|
- it "calculates the type of #{type} keys" do
- calculated_type = described_class.new(key).type
-
- expect(calculated_type).to eq(type.to_s.upcase)
- end
- end
- end
-
- describe '#fingerprint' do
- KEYS.each do |type, key|
- it "calculates the MD5 fingerprint for #{type} keys" do
- fp = described_class.new(key).fingerprint
-
- expect(fp).to eq(MD5_FINGERPRINTS[type])
- end
- end
- end
-
- describe '#bits' do
- KEYS.each do |type, key|
- it "calculates the number of bits in #{type} keys" do
- bits = described_class.new(key).bits
-
- expect(bits).to eq(BIT_COUNTS[type])
- end
- end
- end
-
- describe '#key' do
- it 'carries the unmodified key data' do
- key = described_class.new(KEYS[:rsa]).key
-
- expect(key).to eq(KEYS[:rsa])
- end
- end
-end
diff --git a/spec/lib/gitlab/ssh_public_key_spec.rb b/spec/lib/gitlab/ssh_public_key_spec.rb
new file mode 100644
index 00000000000..d3314552d31
--- /dev/null
+++ b/spec/lib/gitlab/ssh_public_key_spec.rb
@@ -0,0 +1,132 @@
+require 'spec_helper'
+
+describe Gitlab::SSHPublicKey, lib: true do
+ let(:key) { attributes_for(:rsa_key_2048)[:key] }
+ let(:public_key) { described_class.new(key) }
+
+ describe '.technology_names' do
+ it 'returns the available technology names' do
+ expect(described_class.technology_names).to eq(%w[rsa dsa ecdsa ed25519])
+ end
+ end
+
+ describe '.allowed_sizes(name)' do
+ where(:name, :sizes) do
+ [
+ ['rsa', [1024, 2048, 3072, 4096]],
+ ['dsa', [1024, 2048, 3072]],
+ ['ecdsa', [256, 384, 521]],
+ ['ed25519', [256]]
+ ]
+ end
+
+ subject { described_class.allowed_sizes(name) }
+
+ with_them do
+ it { is_expected.to eq(sizes) }
+ end
+ end
+
+ describe '.allowed_type?' do
+ it 'determines the key type' do
+ expect(described_class.allowed_type?('foo')).to be(false)
+ end
+ end
+
+ describe '#valid?' do
+ subject { public_key }
+
+ context 'with a valid SSH key' do
+ it { is_expected.to be_valid }
+ end
+
+ context 'with an invalid SSH key' do
+ let(:key) { 'this is not a key' }
+
+ it { is_expected.not_to be_valid }
+ end
+ end
+
+ describe '#type' do
+ subject { public_key.type }
+
+ where(:factory, :type) do
+ [
+ [:rsa_key_2048, :rsa],
+ [:dsa_key_2048, :dsa],
+ [:ecdsa_key_256, :ecdsa],
+ [:ed25519_key_256, :ed25519]
+ ]
+ end
+
+ with_them do
+ let(:key) { attributes_for(factory)[:key] }
+
+ it { is_expected.to eq(type) }
+ end
+
+ context 'with an invalid SSH key' do
+ let(:key) { 'this is not a key' }
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe '#bits' do
+ subject { public_key.bits }
+
+ where(:factory, :bits) do
+ [
+ [:rsa_key_2048, 2048],
+ [:dsa_key_2048, 2048],
+ [:ecdsa_key_256, 256],
+ [:ed25519_key_256, 256]
+ ]
+ end
+
+ with_them do
+ let(:key) { attributes_for(factory)[:key] }
+
+ it { is_expected.to eq(bits) }
+ end
+
+ context 'with an invalid SSH key' do
+ let(:key) { 'this is not a key' }
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe '#fingerprint' do
+ subject { public_key.fingerprint }
+
+ where(:factory, :fingerprint) do
+ [
+ [:rsa_key_2048, '2e:ca:dc:e0:37:29:ed:fc:f0:1d:bf:66:d4:cd:51:b1'],
+ [:dsa_key_2048, 'bc:c1:a4:be:7e:8c:84:56:b3:58:93:53:c6:80:78:8c'],
+ [:ecdsa_key_256, '67:a3:a9:7d:b8:e1:15:d4:80:40:21:34:bb:ed:97:38'],
+ [:ed25519_key_256, 'e6:eb:45:8a:3c:59:35:5f:e9:5b:80:12:be:7e:22:73']
+ ]
+ end
+
+ with_them do
+ let(:key) { attributes_for(factory)[:key] }
+
+ it { is_expected.to eq(fingerprint) }
+ end
+
+ context 'with an invalid SSH key' do
+ let(:key) { 'this is not a key' }
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe '#key_text' do
+ let(:key) { 'this is not a key' }
+
+ it 'carries the unmodified key data' do
+ expect(public_key.key_text).to eq(key)
+ end
+ end
+end