Skip to content
Snippets Groups Projects
Verified Commit bec3c0c5 authored by Frank Sauerburger's avatar Frank Sauerburger
Browse files

Protect SSH from invalid keys

parent 7147b68c
No related branches found
No related tags found
1 merge request!9Resolve "Protect against key decode errors"
from base64 import b64encode, b64decode
from base64 import b64encode, b64decode, binascii
import struct
import hashlib
from django.db import models
......@@ -20,17 +20,22 @@ class SSHPublicKey(models.Model):
return f"{self.hostname} ({self.keytype})"
def fingerprint_sha256(self):
raw_key = b64decode(self.key)
try:
raw_key = b64decode(self.key)
except (ValueError, binascii.Error) as e:
return None
digest = b64encode(hashlib.sha256(raw_key).digest())
return digest.decode().replace("=", "")
def fingerprint_md5(self):
raw_key = b64decode(self.key)
try:
raw_key = b64decode(self.key)
except (ValueError, binascii.Error) as e:
return None
digest = hashlib.md5(raw_key).hexdigest()
return ":".join(a + b for a, b in zip(digest[::2], digest[1::2]))
def key_length(self):
decoded = b64decode(self.key)
def pop(binary):
if len(binary) < 4:
......@@ -39,6 +44,11 @@ class SSHPublicKey(models.Model):
content = binary[4:4 + length]
return content, binary[4 + length:]
try:
decoded = b64decode(self.key)
except (ValueError, binascii.Error) as e:
return None
algo, decoded = pop(decoded)
if algo == b"ssh-rsa":
e, decoded = pop(decoded)
......@@ -47,7 +57,6 @@ class SSHPublicKey(models.Model):
elif algo == b"ssh-ed25519":
a, decoded = pop(decoded)
return len(a) * 8
return None
def key_algo(self):
......
from django.test import TestCase
from django.urls import reverse
from django.contrib.auth.models import Group
from guardian.shortcuts import assign_perm
from . import models
# Create your tests here.
class KeyDecodeerror(TestCase):
"""Check pages load even if the key cannot be decoded"""
def setUp(self):
self.toykey = models.SSHPublicKey.objects.create(
hostname="example.com",
keytype="",
key="no such thing",
)
any_user = Group.objects.get(name="any-user")
assign_perm('view_sshpublickey', any_user, self.toykey)
def test_detail(self):
"""Check that the detail page loads successfully"""
response = self.client.get(
reverse('ssh-detail', args=[self.toykey.pk])
)
self.assertEqual(response.status_code, 200)
def test_list(self):
"""Check that the list page loads successfully"""
response = self.client.get(
reverse('ssh-list')
)
self.assertEqual(response.status_code, 200)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment