Author: Manos Pitsidianakis [manos@pitsidianak.is]
Hash: ec91fc1f521b23f7d938f41efba0bfe39ac9ed53
Timestamp: Tue, 26 Dec 2023 09:15:38 +0000 (8 months ago)

+100 -34 +/-4 browse
WIP: web/auth: use RFC9500 test keys
WIP: web/auth: use RFC9500 test keys

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
1diff --git a/web/rsa b/web/rsa
2new file mode 100644
3index 0000000..9e28cde
4--- /dev/null
5+++ b/web/rsa
6 @@ -0,0 +1,15 @@
7+ -----BEGIN RSA PRIVATE KEY-----
8+ MIICXQIBAAKBgQCw0YNSqI9T1VFvRsIOejZ9feiKz1SgGfbe9Xq5tEzt2yJCsbyg
9+ +xtcuCswNhdqY5A1ZN7G60HbL4/Hh/TlLhFJ4zNHVylz9mDDx3yp4IIcK2lb566d
10+ fTD0B5EQ9Iqub4twLUdLKQCBfyhmJJvsEqKxm4J4QWgI+Brh/Pm3d4piPwIDAQAB
11+ AoGASC6fj6TkLfMNdYHLQqG9kOlPfys4fstarpZD7X+fUBJ/H/7y5DzeZLGCYAIU
12+ +QeAHWv6TfZIQjReW7Qy00RFJdgwFlTFRCsKXhG5x+IB+jL0Grr08KbgPPDgy4Jm
13+ xirRHZVtU8lGbkiZX+omDIU28EHLNWL6rFEcTWao/tERspECQQDp2G5Nw0qYWn7H
14+ Wm9Up1zkUTnkUkCzhqtxHbeRvNmHGKE7ryGMJEk2RmgHVstQpsvuFY4lIUSZEjAc
15+ DUFJERhFAkEAwZH6O1ULORp8sHKDdidyleYcZU8L7y9Y3OXJYqELfddfBgFUZeVQ
16+ duRmJj7ryu0g0uurOTE+i8VnMg/ostxiswJBAOc64Dd8uLJWKa6uug+XPr91oi0n
17+ OFtM+xHrNK2jc+WmcSg3UJDnAI3uqMc5B+pERLq0Dc6hStehqHjUko3RnZECQEGZ
18+ eRYWciE+Cre5dzfZkomeXE0xBrhecV0bOq6EKWLSVE+yr6mAl05ThRK9DCfPSOpy
19+ F6rgN3QiyCA9J/1FluUCQQC5nX+PTU1FXx+6Ri2ZCi6EjEKMHr7gHcABhMinZYOt
20+ N59pra9UdVQw9jxCU9G7eMyb0jJkNACAuEwakX3gi27b
21+ -----END RSA PRIVATE KEY-----
22 diff --git a/web/rsa.pub b/web/rsa.pub
23new file mode 100644
24index 0000000..7b318d7
25--- /dev/null
26+++ b/web/rsa.pub
27 @@ -0,0 +1 @@
28+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCw0YNSqI9T1VFvRsIOejZ9feiKz1SgGfbe9Xq5tEzt2yJCsbyg+xtcuCswNhdqY5A1ZN7G60HbL4/Hh/TlLhFJ4zNHVylz9mDDx3yp4IIcK2lb566dfTD0B5EQ9Iqub4twLUdLKQCBfyhmJJvsEqKxm4J4QWgI+Brh/Pm3d4piPw==
29 diff --git a/web/src/auth.rs b/web/src/auth.rs
30index 5da49ae..4d625b9 100644
31--- a/web/src/auth.rs
32+++ b/web/src/auth.rs
33 @@ -743,45 +743,33 @@ pub mod auth_request {
34 #[cfg(test)]
35 mod tests {
36 use super::*;
37- const PKEY: &str = concat!(
38- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzXp8nLJL8GPNw7S+Dqt0m3Dw/",
39- "xFOAdwKXcekTFI9cLDEUII2rNPf0uUZTpv57OgU+",
40- "QOEEIvWMjz+5KSWBX8qdP8OtV0QNvynlZkEKZN0cUqGKaNXo5a+PUDyiJ2rHroPe1aMo6mUBL9kLR6J2U1CYD/dLfL8ywXsAGmOL0bsK0GRPVBJAjpUNRjpGU/",
41- "2FFIlU6s6GawdbDXEHDox/UoOVAKIlhKabaTrFBA0ACFLRX2/GCBmHqqt5d4ZZjefYzReLs/beOjafYImoyhHC428wZDcUjvLrpSJbIOE/",
42- "gSPCWlRbcsxg4JGcKOtALUurE+ok+avy9M7eFjGhLGSlTKLdshIVQr/3W667M7bYfOT6xP/",
43- "lyjxeWIUYyj7rjlqKJ9tzygek7QNxCtuqH5xsZAZqzQCN8wfrPAlwDykvWityKOw+Bt2DWjimITqyKgsBsOaA+",
44- "eVCllFvooJxoYvAjODASjAUoOdgVzyBDpFnOhLFYiIIyL3F6NROS9i7z086paX7mrzcQzvLr4ckF9qT7DrI88ikISCR9bFR4vPq3aH",
45- "zJdjDDpWxACa5b11NG8KdCJPe/L0kDw82Q00U13CpW9FI9sZjvk+",
46- "lyw8bTFvVsIl6A0ueboFvrNvznAqHrtfWu75fXRh5sKj2TGk8rhm3vyNgrBSr5zAfFVM8LgqBxbAAYw=="
47- );
48
49+ /// This is the public key of RSA-1024 key "testRSA1024" of [RFC9500 **Standard Public Key Cryptography (PKC) Test Keys**](https://www.rfc-editor.org/rfc/rfc9500.html#section-2.1-2) in OpenSSH format, calculated with the script `testRSA1024_to_ssh.py` included in the source repository and here for reference.
50+ ///
51+ /// <details>
52+ /// <summary>The source code of the script.</summary>
53+ ///
54+ /// ```python3
55+ #[doc = include_str!("testRSA1024_to_ssh.py")]
56+ /// ```
57+ ///
58+ /// </details>
59+ const PKEY: &str = r#"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCw0YNSqI9T1VFvRsIOejZ9feiKz1SgGfbe9Xq5tEzt2yJCsbyg+xtcuCswNhdqY5A1ZN7G60HbL4/Hh/TlLhFJ4zNHVylz9mDDx3yp4IIcK2lb566dfTD0B5EQ9Iqub4twLUdLKQCBfyhmJJvsEqKxm4J4QWgI+Brh/Pm3d4piPw=="#;
60+
61+ /// The expected SSH signature for test `test_ssh_verify`
62 const ARMOR_SIG: &str = concat!(
63 "-----BEGIN SSH SIGNATURE-----\n",
64- "U1NIU0lHAAAAAQAAAhcAAAAHc3NoLXJzYQAAAAMBAAEAAAIBALNenycskvwY83DtL4Oq3S\n",
65- "bcPD/EU4B3Apdx6RMUj1wsMRQgjas09/S5RlOm/ns6BT5A4QQi9YyPP7kpJYFfyp0/w61X\n",
66- "RA2/KeVmQQpk3RxSoYpo1ejlr49QPKInaseug97VoyjqZQEv2QtHonZTUJgP90t8vzLBew\n",
67- "AaY4vRuwrQZE9UEkCOlQ1GOkZT/YUUiVTqzoZrB1sNcQcOjH9Sg5UAoiWEpptpOsUEDQAI\n",
68- "UtFfb8YIGYeqq3l3hlmN59jNF4uz9t46Np9giajKEcLjbzBkNxSO8uulIlsg4T+BI8JaVF\n",
69- "tyzGDgkZwo60AtS6sT6iT5q/L0zt4WMaEsZKVMot2yEhVCv/dbrrsztth85PrE/+XKPF5Y\n",
70- "hRjKPuuOWoon23PKB6TtA3EK26ofnGxkBmrNAI3zB+s8CXAPKS9aK3Io7D4G3YNaOKYhOr\n",
71- "IqCwGw5oD55UKWUW+ignGhi8CM4MBKMBSg52BXPIEOkWc6EsViIgjIvcXo1E5L2LvPTzql\n",
72- "pfuavNxDO8uvhyQX2pPsOsjzyKQhIJH1sVHi8+rdofMl2MMOlbEAJrlvXU0bwp0Ik978vS\n",
73- "QPDzZDTRTXcKlb0Uj2xmO+T6XLDxtMW9WwiXoDS55ugW+s2/OcCoeu19a7vl9dGHmwqPZM\n",
74- "aTyuGbe/I2CsFKvnMB8VUzwuCoHFsABjAAAAFGRvYy10ZXN0QGV4YW1wbGUuY29tAAAAAA\n",
75- "AAAAZzaGE1MTIAAAIUAAAADHJzYS1zaGEyLTUxMgAAAgBxaMqIfeapKTrhQzggDssD+76s\n",
76- "jZxv3XxzgsuAjlIdtw+/nyxU6skTnrGoam2shpmQvx0HuqSQ7HyS2USBK7T4LZNoE53zR/\n",
77- "ZmHLGoyQAoexiHSEW9Lk53kyRNPhpXQedTvm8REHPGM3zw6WO6mAXVVxvebvawf81LTbBb\n",
78- "p9ubNRcHgktVeywMO/sD6zWSyShq1gjVv1PdRBOjUgqkwjImL8dFKi1QUeoffCxyk3JhTO\n",
79- "siTy79HZSz/kOvkvL1vQuqaP2R8lE9P1uaD19dGOMTPRod3u+QmpYX47ri5KM3Fmkfxdwq\n",
80- "p8JVmfAA9nme7bmNS1hWgmF2Nbh9qjh1zOZvCimIpuNtz5eEl9K+1DxG6w5tX86wSGvBMO\n",
81- "znx0k1gGfkiAULqgrkdul7mqMPRvPN9J6QlNJ7SLFChRhzlJIJc6tOvCs7qkVD43Zcb+I5\n",
82- "Z+K4NiFf5jf8kVX/pjjeW/ucbrctJIkGsZ58OkHKi1EDRcq7NtCF6SKlcv8g3fMLd9wW6K\n",
83- "aaed0TBDC+s+f6naNIGvWqfWCwDuK5xGyDTTmJGcrsMwWuT9K6uLk8cGdv7t5mOFuWi5jl\n",
84- "E+IKZKVABMuWqSj96ErMIiBjtsAZfNSezpsK49wQztoSPhdwLhD6fHrSAyPCqN2xRkcsIb\n",
85- "6PxWKC/OELf3gyEBRPouxsF7xSZQ==\n",
86- "-----END SSH SIGNATURE-----\n"
87+ "U1NIU0lHAAAAAQAAAJcAAAAHc3NoLXJzYQAAAAMBAAEAAACBALDRg1Koj1PVUW9Gwg56Nn\n",
88+ "196IrPVKAZ9t71erm0TO3bIkKxvKD7G1y4KzA2F2pjkDVk3sbrQdsvj8eH9OUuEUnjM0dX\n",
89+ "KXP2YMPHfKngghwraVvnrp19MPQHkRD0iq5vi3AtR0spAIF/KGYkm+wSorGbgnhBaAj4Gu\n",
90+ "H8+bd3imI/AAAAFGRvYy10ZXN0QGV4YW1wbGUuY29tAAAAAAAAAAZzaGE1MTIAAACUAAAA\n",
91+ "DHJzYS1zaGEyLTUxMgAAAIBPAklSrJp00Y0j+kN5UaD9YnWvYHfC8f3DWajVx8xJS634xz\n",
92+ "zjI3E8UC8GNoMu9eljeZqMhKa5HucIDLv9PLLGxkR7wfZd5Wr/X3rd5Xnf3xthEOMFvYIs\n",
93+ "tGr8Np8X+39FB2NtICLWLeiReT7fvc7Pw648tJSBaYW9mDCysaOidQ==\n",
94+ "-----END SSH SIGNATURE-----\n",
95 );
96
97+ /// Utility function to create the same signature in every test.
98 fn create_sig() -> SshSignature {
99 SshSignature {
100 email: "user@example.com".to_string(),
101 diff --git a/web/src/testRSA1024_to_ssh.py b/web/src/testRSA1024_to_ssh.py
102new file mode 100755
103index 0000000..72325ae
104--- /dev/null
105+++ b/web/src/testRSA1024_to_ssh.py
106 @@ -0,0 +1,62 @@
107+ #!/usr/bin/env python3
108+
109+ # pip install pycryptodome
110+ from Crypto.PublicKey import RSA
111+
112+ # rfc9500
113+ # RSA-1024 key "testRSA1024"
114+
115+ # fmt: off
116+
117+ n = int.from_bytes(
118+ [ 0xB0, 0xD1, 0x83, 0x52, 0xA8, 0x8F, 0x53, 0xD5, 0x51, 0x6F, 0x46, 0xC2, 0x0E, 0x7A, 0x36, 0x7D, 0x7D, 0xE8, 0x8A, 0xCF, 0x54, 0xA0, 0x19, 0xF6, 0xDE, 0xF5, 0x7A, 0xB9, 0xB4, 0x4C, 0xED, 0xDB, 0x22, 0x42, 0xB1, 0xBC, 0xA0, 0xFB, 0x1B, 0x5C, 0xB8, 0x2B, 0x30, 0x36, 0x17, 0x6A, 0x63, 0x90, 0x35, 0x64, 0xDE, 0xC6, 0xEB, 0x41, 0xDB, 0x2F, 0x8F, 0xC7, 0x87, 0xF4, 0xE5, 0x2E, 0x11, 0x49, 0xE3, 0x33, 0x47, 0x57, 0x29, 0x73, 0xF6, 0x60, 0xC3, 0xC7, 0x7C, 0xA9, 0xE0, 0x82, 0x1C, 0x2B, 0x69, 0x5B, 0xE7, 0xAE, 0x9D, 0x7D, 0x30, 0xF4, 0x07, 0x91, 0x10, 0xF4, 0x8A, 0xAE, 0x6F, 0x8B, 0x70, 0x2D, 0x47, 0x4B, 0x29, 0x00, 0x81, 0x7F, 0x28, 0x66, 0x24, 0x9B, 0xEC, 0x12, 0xA2, 0xB1, 0x9B, 0x82, 0x78, 0x41, 0x68, 0x08, 0xF8, 0x1A, 0xE1, 0xFC, 0xF9, 0xB7, 0x77, 0x8A, 0x62, 0x3F, ],
119+ byteorder="big",
120+ )
121+ e = int.from_bytes(
122+ [ 0x01, 0x00, 0x01, ],
123+ byteorder="big",
124+ )
125+ d = int.from_bytes(
126+ [ 0x48, 0x2E, 0x9F, 0x8F, 0xA4, 0xE4, 0x2D, 0xF3, 0x0D, 0x75, 0x81, 0xCB, 0x42, 0xA1, 0xBD, 0x90, 0xE9, 0x4F, 0x7F, 0x2B, 0x38, 0x7E, 0xCB, 0x5A, 0xAE, 0x96, 0x43, 0xED, 0x7F, 0x9F, 0x50, 0x12, 0x7F, 0x1F, 0xFE, 0xF2, 0xE4, 0x3C, 0xDE, 0x64, 0xB1, 0x82, 0x60, 0x02, 0x14, 0xF9, 0x07, 0x80, 0x1D, 0x6B, 0xFA, 0x4D, 0xF6, 0x48, 0x42, 0x34, 0x5E, 0x5B, 0xB4, 0x32, 0xD3, 0x44, 0x45, 0x25, 0xD8, 0x30, 0x16, 0x54, 0xC5, 0x44, 0x2B, 0x0A, 0x5E, 0x11, 0xB9, 0xC7, 0xE2, 0x01, 0xFA, 0x32, 0xF4, 0x1A, 0xBA, 0xF4, 0xF0, 0xA6, 0xE0, 0x3C, 0xF0, 0xE0, 0xCB, 0x82, 0x66, 0xC6, 0x2A, 0xD1, 0x1D, 0x95, 0x6D, 0x53, 0xC9, 0x46, 0x6E, 0x48, 0x99, 0x5F, 0xEA, 0x26, 0x0C, 0x85, 0x36, 0xF0, 0x41, 0xCB, 0x35, 0x62, 0xFA, 0xAC, 0x51, 0x1C, 0x4D, 0x66, 0xA8, 0xFE, 0xD1, 0x11, 0xB2, 0x91, ],
127+ byteorder="big",
128+ )
129+ p = int.from_bytes(
130+ [ 0xE9, 0xD8, 0x6E, 0x4D, 0xC3, 0x4A, 0x98, 0x5A, 0x7E, 0xC7, 0x5A, 0x6F, 0x54, 0xA7, 0x5C, 0xE4, 0x51, 0x39, 0xE4, 0x52, 0x40, 0xB3, 0x86, 0xAB, 0x71, 0x1D, 0xB7, 0x91, 0xBC, 0xD9, 0x87, 0x18, 0xA1, 0x3B, 0xAF, 0x21, 0x8C, 0x24, 0x49, 0x36, 0x46, 0x68, 0x07, 0x56, 0xCB, 0x50, 0xA6, 0xCB, 0xEE, 0x15, 0x8E, 0x25, 0x21, 0x44, 0x99, 0x12, 0x30, 0x1C, 0x0D, 0x41, 0x49, 0x11, 0x18, 0x45, ],
131+ byteorder="big",
132+ )
133+ q = int.from_bytes(
134+ [ 0xC1, 0x91, 0xFA, 0x3B, 0x55, 0x0B, 0x39, 0x1A, 0x7C, 0xB0, 0x72, 0x83, 0x76, 0x27, 0x72, 0x95, 0xE6, 0x1C, 0x65, 0x4F, 0x0B, 0xEF, 0x2F, 0x58, 0xDC, 0xE5, 0xC9, 0x62, 0xA1, 0x0B, 0x7D, 0xD7, 0x5F, 0x06, 0x01, 0x54, 0x65, 0xE5, 0x50, 0x76, 0xE4, 0x66, 0x26, 0x3E, 0xEB, 0xCA, 0xED, 0x20, 0xD2, 0xEB, 0xAB, 0x39, 0x31, 0x3E, 0x8B, 0xC5, 0x67, 0x32, 0x0F, 0xE8, 0xB2, 0xDC, 0x62, 0xB3, ],
135+ byteorder="big",
136+ )
137+
138+ # fmt: on
139+
140+ # Sanity checks
141+ assert len((n.to_bytes(length=1024).lstrip(bytes([0x00])))) * 8 == 1024
142+ assert len((d.to_bytes(length=1024).lstrip(bytes([0x00])))) * 8 == 1024
143+ assert len((p.to_bytes(length=1024).lstrip(bytes([0x00])))) * 8 == 512
144+ assert len((q.to_bytes(length=1024).lstrip(bytes([0x00])))) * 8 == 512
145+
146+ key = RSA.construct((n, e, d, p, q), consistency_check=True)
147+
148+ # RSA-1024 key in encoded form:
149+
150+ encoded = b"""-----BEGIN RSA PRIVATE KEY-----
151+ MIICXQIBAAKBgQCw0YNSqI9T1VFvRsIOejZ9feiKz1SgGfbe9Xq5tEzt2yJCsbyg
152+ +xtcuCswNhdqY5A1ZN7G60HbL4/Hh/TlLhFJ4zNHVylz9mDDx3yp4IIcK2lb566d
153+ fTD0B5EQ9Iqub4twLUdLKQCBfyhmJJvsEqKxm4J4QWgI+Brh/Pm3d4piPwIDAQAB
154+ AoGASC6fj6TkLfMNdYHLQqG9kOlPfys4fstarpZD7X+fUBJ/H/7y5DzeZLGCYAIU
155+ +QeAHWv6TfZIQjReW7Qy00RFJdgwFlTFRCsKXhG5x+IB+jL0Grr08KbgPPDgy4Jm
156+ xirRHZVtU8lGbkiZX+omDIU28EHLNWL6rFEcTWao/tERspECQQDp2G5Nw0qYWn7H
157+ Wm9Up1zkUTnkUkCzhqtxHbeRvNmHGKE7ryGMJEk2RmgHVstQpsvuFY4lIUSZEjAc
158+ DUFJERhFAkEAwZH6O1ULORp8sHKDdidyleYcZU8L7y9Y3OXJYqELfddfBgFUZeVQ
159+ duRmJj7ryu0g0uurOTE+i8VnMg/ostxiswJBAOc64Dd8uLJWKa6uug+XPr91oi0n
160+ OFtM+xHrNK2jc+WmcSg3UJDnAI3uqMc5B+pERLq0Dc6hStehqHjUko3RnZECQEGZ
161+ eRYWciE+Cre5dzfZkomeXE0xBrhecV0bOq6EKWLSVE+yr6mAl05ThRK9DCfPSOpy
162+ F6rgN3QiyCA9J/1FluUCQQC5nX+PTU1FXx+6Ri2ZCi6EjEKMHr7gHcABhMinZYOt
163+ N59pra9UdVQw9jxCU9G7eMyb0jJkNACAuEwakX3gi27b
164+ -----END RSA PRIVATE KEY-----"""
165+
166+ assert key.export_key(format="PEM") == encoded
167+
168+ print(key.publickey().export_key(format="OpenSSH"))