comparison test/test_dropbearconvert.py @ 1909:43ebe0028187

Add tests for dropbearconvert
author Matt Johnston <matt@ucc.asn.au>
date Tue, 29 Mar 2022 22:29:17 +0800
parents
children ced53051e200
comparison
equal deleted inserted replaced
1908:eadd023fde4d 1909:43ebe0028187
1 import subprocess
2 import tempfile
3
4 import pytest
5
6 keytypes = [
7 "rsa", "rsa-4096",
8 "ed25519",
9 "ecdsa", "ecdsa-256", "ecdsa-384", "ecdsa-521",
10 "dss",
11 ]
12
13 def parse_keytype(kt):
14 if '-' in kt:
15 return kt.split('-')
16 else:
17 return (kt, None)
18
19 @pytest.mark.parametrize("keytype", keytypes)
20 @pytest.mark.parametrize("keyformat", [None, "PEM"])
21 def test_from_openssh(request, tmp_path, keytype, keyformat):
22 """
23 Convert OpenSSH to Dropbear format,
24 PEM and OpenSSH internal
25 """
26 opt = request.config.option
27 kt, keybits = parse_keytype(keytype)
28
29 if kt == 'dss' and keyformat is None:
30 pytest.xfail("dss doesn't support openssh format")
31
32 if kt == 'ecdsa' and keyformat is None:
33 pytest.skip("ecdsa doesn't support openssh format yet")
34
35 os_kt = kt
36 if os_kt == 'dss':
37 # OpenSSH calls it 'dsa', Dropbear calls it 'dss'
38 os_kt = 'dsa'
39
40 os_key = tmp_path / 'oskey1'
41 db_key = tmp_path / 'dbkey1'
42
43 # Generate an OpenSSH key
44 args = [
45 opt.ssh_keygen,
46 '-f', os_key,
47 '-t', os_kt,
48 '-N', '', # no password
49 ]
50 if keybits is not None:
51 args += ['-b', keybits]
52 if keyformat:
53 args += ['-m', keyformat]
54 p = subprocess.run(args, check=True)
55
56 # Convert to dropbear format
57 args = [
58 opt.dropbearconvert,
59 'openssh', 'dropbear',
60 os_key, db_key,
61 ]
62 p = subprocess.run(args, check=True)
63
64 # Compare pubkeys
65 args = [
66 opt.dropbearkey,
67 '-f', db_key,
68 '-y'
69 ]
70 p = subprocess.run(args, check=True, stdout=subprocess.PIPE, text=True)
71 db_pubkey = p.stdout.splitlines()[1].strip()
72 os_pubkey = os_key.with_suffix('.pub').open().read().strip()
73 # we compare the whole key including comment since it currently matches
74 assert db_pubkey == os_pubkey
75
76 @pytest.mark.parametrize("keytype", keytypes)
77 def test_roundtrip(request, tmp_path, keytype):
78 """
79 Dropbear's private key format is deterministic so
80 we can compare round trip conversion. (OpenSSH's
81 format has more variable comments and other fields).
82 """
83 opt = request.config.option
84 kt, keybits = parse_keytype(keytype)
85
86 os_key = tmp_path / 'oskey1'
87 db_key1 = tmp_path / 'dbkey1'
88 db_key2 = tmp_path / 'dbkey2'
89
90 # generate a key
91 args = [
92 opt.dropbearkey,
93 '-t', kt,
94 '-f', db_key1,
95 ]
96 if keybits is not None:
97 args += ['-s', keybits]
98 p = subprocess.run(args, check=True)
99
100 # convert to openssh
101 args = [
102 opt.dropbearconvert,
103 'dropbear', 'openssh',
104 db_key1, os_key,
105 ]
106 p = subprocess.run(args, check=True)
107
108 # Check ssh-keygen can read it
109 args = [
110 opt.ssh_keygen,
111 '-f', os_key,
112 '-y',
113 ]
114 p = subprocess.run(args, check=True, text=True, stdout=subprocess.PIPE)
115 os_pubkey = p.stdout.strip()
116
117 # Compare public keys
118 args = [
119 opt.dropbearkey,
120 '-f', db_key1,
121 '-y',
122 ]
123 p = subprocess.run(args, check=True, text=True, stdout=subprocess.PIPE)
124 db_pubkey = p.stdout.splitlines()[1].strip()
125 # comment may differ
126 db_pubkey = db_pubkey.split(' ')[:2]
127 os_pubkey = os_pubkey.split(' ')[:2]
128 assert db_pubkey == os_pubkey
129
130 # convert back to dropbear
131 args = [
132 opt.dropbearconvert,
133 'openssh', 'dropbear',
134 os_key, db_key2,
135 ]
136 p = subprocess.run(args, check=True)
137 # check the round trip is identical
138 assert db_key1.open('rb').read() == db_key2.open('rb').read()