TestOpenSSHKey.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /*
  2. * Copyright (C) 2017 Toni Spets <toni.spets@iki.fi>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 or (at your option)
  7. * version 3 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "TestOpenSSHKey.h"
  18. #include "crypto/Crypto.h"
  19. #include "sshagent/BinaryStream.h"
  20. #include "sshagent/OpenSSHKey.h"
  21. #include <QTest>
  22. QTEST_GUILESS_MAIN(TestOpenSSHKey)
  23. void TestOpenSSHKey::initTestCase()
  24. {
  25. QVERIFY(Crypto::init());
  26. }
  27. void TestOpenSSHKey::testParse()
  28. {
  29. // mixed line endings and missing ones are intentional, we only require 3 lines total
  30. const QString keyString = QString("\r\n\r"
  31. "-----BEGIN OPENSSH PRIVATE KEY-----\n"
  32. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW"
  33. "QyNTUxOQAAACDdlO5F2kF2WzedrBAHBi9wBHeISzXZ0IuIqrp0EzeazAAAAKjgCfj94An4"
  34. "/QAAAAtzc2gtZWQyNTUxOQAAACDdlO5F2kF2WzedrBAHBi9wBHeISzXZ0IuIqrp0EzeazA"
  35. "AAAEBe1iilZFho8ZGAliiSj5URvFtGrgvmnEKdiLZow5hOR92U7kXaQXZbN52sEAcGL3AE"
  36. "d4hLNdnQi4iqunQTN5rMAAAAH29wZW5zc2hrZXktdGVzdC1wYXJzZUBrZWVwYXNzeGMBAg"
  37. "MEBQY=\r"
  38. "-----END OPENSSH PRIVATE KEY-----\r\n\r");
  39. const QByteArray keyData = keyString.toLatin1();
  40. OpenSSHKey key;
  41. QVERIFY(key.parsePKCS1PEM(keyData));
  42. QVERIFY(!key.encrypted());
  43. QCOMPARE(key.cipherName(), QString("none"));
  44. QCOMPARE(key.type(), QString("ssh-ed25519"));
  45. QCOMPARE(key.comment(), QString("opensshkey-test-parse@keepassxc"));
  46. QCOMPARE(key.fingerprint(), QString("SHA256:D1fVmA15YXzaJ5sdO9dXxo5coHL/pnNaIfCvokHzTA4"));
  47. QCOMPARE(key.fingerprint(QCryptographicHash::Md5), QString("MD5:2d:e8:04:09:13:b4:2b:73:5e:87:43:cf:4e:6f:62:f1"));
  48. QByteArray publicKey, privateKey;
  49. BinaryStream publicStream(&publicKey), privateStream(&privateKey);
  50. QVERIFY(key.writePublic(publicStream));
  51. QVERIFY(key.writePrivate(privateStream));
  52. QVERIFY(publicKey.length() == 51);
  53. QVERIFY(privateKey.length() == 154);
  54. }
  55. void TestOpenSSHKey::testParseDSA()
  56. {
  57. const QString keyString = QString("-----BEGIN DSA PRIVATE KEY-----\n"
  58. "MIIBuwIBAAKBgQCudjbvSh8JxQOr2laCqZM1t4kNWBETVOXz5vgk9iw6Z5opB9/k\n"
  59. "g4nFc1PVq7fdAIc8W/5WCAjugKcxPb9PIHfcwY2fimmiPWFK68/eHKLoCuIn2wxB\n"
  60. "63ig2hAhx5U5aYG9QHkNCaT6VX7rc19nToSeZXlpja4x54/DaQaqOEWYsQIVAOer\n"
  61. "UQWfccz7KXUu6+x7heGob6I3AoGAVDRFJIlL0DI/4nePIcgwgwbfgs2ojSu21g4w\n"
  62. "dQoXvqU34XydPgPQ985XIIuiDkaomRw4yYd/Sh4ZapFcrP++iJ1V+WS6kLcWPHMq\n"
  63. "poYwk8mq6GLbPFLEjr+n6HgX5ln15n3i4WAopNH7mEl0glY9L0rxmcN0XOpqw6Ux\n"
  64. "ETGEfAwCgYAiOeYwblMkkTIGtVx5NvNsOlfrBYL4GqUP9oQMO5I+xLZLWQIf+7Jp\n"
  65. "8t6mwxSBz0RHjNVQ11vZowNjq3587aLy57bVwf2lIm9KSvS6z9HoNbHgQimcBorR\n"
  66. "J9l9RUrj7TnsZgiVw66j2r34nHRHRtggiO+qrMtw7MJc0Q7jiuTmzgIVAMXbk0T9\n"
  67. "nBfSLWQz/L8RexU2GR4e\n"
  68. "-----END DSA PRIVATE KEY-----\n");
  69. const QByteArray keyData = keyString.toLatin1();
  70. OpenSSHKey key;
  71. QVERIFY(key.parsePKCS1PEM(keyData));
  72. QVERIFY(!key.encrypted());
  73. QCOMPARE(key.cipherName(), QString("none"));
  74. QCOMPARE(key.type(), QString("ssh-dss"));
  75. QCOMPARE(key.comment(), QString(""));
  76. QCOMPARE(key.fingerprint(), QString("SHA256:tbbNuLN1hja8JNASDTlLOZQsbTlJDzJlz/oAGK3sX18"));
  77. }
  78. void TestOpenSSHKey::testDecryptRSAAES128CBC()
  79. {
  80. const QString keyString = QString("-----BEGIN RSA PRIVATE KEY-----\n"
  81. "Proc-Type: 4,ENCRYPTED\n"
  82. "DEK-Info: AES-128-CBC,804E4D214D1263FF94E3743FE799DBB4\n"
  83. "\n"
  84. "lM9TDfOTbiRhaGGDh7Hn+rqw8CCWcYBZYu7smyYLdnWKXKPmbne8CQFZBAS1FJwZ\n"
  85. "6Mj6n075yFGyzN9/OfeqKiUA4adlbwLbGwB+yyKsC2FlsvRIEr4hup02WWM47vHj\n"
  86. "DS4TRmNkE7MKFLhpNCyt5OGGM45s+/lwVTw51K0Hm99TBd72IrX4jfY9ZxAVbL3l\n"
  87. "aTohL8x6oOTe7q318QgJoFi+DjJhDWLGLLJ7fBqD2imz2fmrY4j8Jpw2sDe1rj82\n"
  88. "gMqqNG3FrfN0S4uYlWYH5pAh+BUcB1UdmTU/rV5wJMK1oUytmZv/J2+X/0k3Y93F\n"
  89. "aw6JWOy28OizW+TQXvv8gREWsp5PEclqUZhhGQbVbCQCiDOxg+xiXNySdRH1IqjR\n"
  90. "zQiKgD4SPzkxQekExPaIQT/KutWZdMNYybEqooCx8YyeDoN31z7Wa2rv6OulOn/j\n"
  91. "wJFvyd2PT/6brHKI4ky8RYroDf4FbVYKfyEW5CSAg2OyL/tY/kSPgy/k0WT7fDwq\n"
  92. "dPSuYM9yeWNL6kAhDqDOv8+s3xvOVEljktBvQvItQwVLmHszC3E2AcnaxzdblKPu\n"
  93. "e3+mBT80NXHjERK2ht+/9JYseK1ujNbNAaG8SbKfU3FF0VlyJ0QW6TuIEdpNnymT\n"
  94. "0fm0cDfKNaoeJIFnBRZhgIOJAic9DM0cTe/vSG69DaUYsaQPp36al7Fbux3GpFHS\n"
  95. "OtJEySYGro/6zvJ9dDIEfIGZjA3RaMt6+DuyJZXQdT2RNXa9j60xW7dXh0En4n82\n"
  96. "JUKTxYhDPLS5c8BzpJqoopxpKwElmrJ7Y3xpd6z2vIlD8ftuZrkk6siTMNQ2s7MI\n"
  97. "Xl332O+0H4k7uSfczHPOOw36TFhNjGQAP0b7O+0/RVG0ttOIoAn7ZkX3nfdbtG5B\n"
  98. "DWKvDaopvrcC2/scQ5uLUnqnBiGw1XiYpdg5ang7knHNzHZAIekVaYYZigpCAKp+\n"
  99. "OtoaDeUEzqFhYVmF8ad1fgvC9ZUsuxS4XUHCKl0H6CJcvW9MJPVbveqYoK+j9qKd\n"
  100. "iMIkQBP1kE2rzGZVGUkZTpM9LVD9nP0nsbr6E8BatFcNgRirsg2BTJglNpXlCmY6\n"
  101. "ldzJ/ELBbzoXIn+0wTGai0o4eBPx55baef69JfPuZqEB9pLNE+mHstrqIwcfqYu4\n"
  102. "M+Vzun1QshRMj9a1PVkIHfs1fLeebI4QCHO0vJlc9K4iYPM4rsDNO3YaAgGRuARS\n"
  103. "f3McGiGFxkv5zxe8i05ZBnn+exE77jpRKxd223jAMe2wu4WiFB7ZVo4Db6b5Oo2T\n"
  104. "TPh3VuY7TNMEKkcUi+mGLKjroocQ5j8WQYlfnyOaTalUVQDzOTNb67QIIoiszR0U\n"
  105. "+AXGyxHj0QtotZFoPME+AbS9Zqy3SgSOuIzPBPU5zS4uoKNdD5NPE5YAuafCjsDy\n"
  106. "MT4DVy+cPOQYUK022S7T2nsA1btmvUvD5LL2Mc8VuKsWOn/7FKZua6OCfipt6oX0\n"
  107. "1tzYrw0/ALK+CIdVdYIiPPfxGZkr+JSLOOg7u50tpmen9GzxgNTv63miygwUAIDF\n"
  108. "u0GbQwOueoA453/N75FcXOgrbqTdivyadUbRP+l7YJk/SfIytyJMOigejp+Z1lzF\n"
  109. "-----END RSA PRIVATE KEY-----\n");
  110. const QByteArray keyData = keyString.toLatin1();
  111. OpenSSHKey key;
  112. QVERIFY(key.parsePKCS1PEM(keyData));
  113. QVERIFY(key.encrypted());
  114. QCOMPARE(key.cipherName(), QString("AES-128-CBC"));
  115. QVERIFY(!key.openKey("incorrectpassphrase"));
  116. QVERIFY(key.openKey("correctpassphrase"));
  117. QCOMPARE(key.type(), QString("ssh-rsa"));
  118. QCOMPARE(key.comment(), QString(""));
  119. QCOMPARE(key.fingerprint(), QString("SHA256:1Hsebt2WWnmc72FERsUOgvaajIGHkrMONxXylcmk87U"));
  120. }
  121. void TestOpenSSHKey::testParseRSA()
  122. {
  123. const QString keyString = QString("-----BEGIN RSA PRIVATE KEY-----\n"
  124. "MIIEpAIBAAKCAQEAsCHtJicDPWnvHSIKbnTZaJkIB9vgE0pmLdK580JUqBuonVbB\n"
  125. "y1QTy0ZQ7/TtqvLPgwPK88TR46OLO/QGCzo2+XxgJ85uy0xfuyUYRmSuw0drsErN\n"
  126. "mH8vU91lSBxsGDp9LtBbgHKoR23vMWZ34IxFRc55XphrIH48ijsMaL6bXBwF/3tD\n"
  127. "9T3lm2MpP1huyVNnIY9+GRRWCy4f9LMj/UGu/n4RtwwfpOZBBRwYkq5QkzA9lPm/\n"
  128. "VzF3MP1rKTMkvAw+Nfb383mkmc6MRnsa6uh6iDa9aVB7naegM13UJQX/PY1Ks6pO\n"
  129. "XDpy/MQ7iCh+HmYNq5dRmARyaNl9xIXJNhz1cQIDAQABAoIBAQCnEUc1LUQxeM5K\n"
  130. "wANNCqE+SgoIClPdeHC7fmrLh1ttqe6ib6ybBUFRS31yXs0hnfefunVEDKlaV8K2\n"
  131. "N52UAMAsngFHQNRvGh6kEWeZPd9Xc+N98TZbNCjcT+DGKc+Om8wqH5DrodZlCq4c\n"
  132. "GaoT4HnE4TjWtZTH2XXrWF9I66PKFWf070R44nvyVcvaZi4pC2YmURRPuGF6K1iK\n"
  133. "dH8zM6HHG1UGu2W6hLNn+K01IulG0Lb8eWNaNYMmtQWaxyp7I2IWkkecUs3nCuiR\n"
  134. "byFOoomCjdh8r9yZFvwxjGUhgtkALN9GCU0Mwve+s11IB2gevruN+q9/Qejbyfdm\n"
  135. "IlgLAeTRAoGBANRcVzW9CYeobCf+U9hKJFEOur8XO+J2mTMaELA0EjWpTJFAeIT7\n"
  136. "KeRpCRG4/vOSklxxRF6vP1EACA4Z+5BlN+FTipHHs+bSEgqkPZiiANDH7Zot5Iqv\n"
  137. "1q0fRyldNRZNZK7DWp08BPNVWGA/EnEuKJiURxnxBaxNXbUyMCdjxvMvAoGBANRT\n"
  138. "utbrqS/bAa/DcHKn3V6DRqBl3TDOfvCNjiKC84a67F2uXgzLIdMktr4d1NyCZVJd\n"
  139. "7/zVgWORLIdg1eAi6rYGoOvNV39wwga7CF+m9sBY0wAaKYCELe6L26r4aQHVCX6n\n"
  140. "rnIgUv+4o4itmU2iP0r3wlmDC9pDRQP82vfvQPlfAoGASwhleANW/quvq2HdViq8\n"
  141. "Mje2HBalfhrRfpDTHK8JUBSFjTzuWG42GxJRtgVbb8x2ElujAKGDCaetMO5VSGu7\n"
  142. "Fs5hw6iAFCpdXY0yhl+XUi2R8kwM2EPQ4lKO3jqkq0ClNmqn9a5jQWcCVt9yMLNS\n"
  143. "fLbHeI8EpiCf34ngIcrLXNkCgYEAzlcEZuKkC46xB+dNew8pMTUwSKZVm53BfPKD\n"
  144. "44QRN6imFbBjU9mAaJnwQbfp6dWKs834cGPolyM4++MeVfB42iZ88ksesgmZdUMD\n"
  145. "szkl6O0pOJs0I+HQZVdjRbadDZvD22MHQ3+oST1dJ3FVXz3Cdo9qPuT8esMO6f4r\n"
  146. "qfDH2s8CgYAXC/lWWHQ//PGP0pH4oiEXisx1K0X1u0xMGgrChxBRGRiKZUwNMIvJ\n"
  147. "TqUu7IKizK19cLHF/NBvxHYHFw+m7puNjn6T1RtRCUjRZT7Dx1VHfVosL9ih5DA8\n"
  148. "tpbZA5KGKcvHtB5DDgT0MHwzBZnb4Q//Rhovzn+HXZPsJTTgHHy3NQ==\n"
  149. "-----END RSA PRIVATE KEY-----\n");
  150. const QByteArray keyData = keyString.toLatin1();
  151. OpenSSHKey key;
  152. QVERIFY(key.parsePKCS1PEM(keyData));
  153. QVERIFY(!key.encrypted());
  154. QCOMPARE(key.cipherName(), QString("none"));
  155. QCOMPARE(key.type(), QString("ssh-rsa"));
  156. QCOMPARE(key.comment(), QString(""));
  157. QCOMPARE(key.fingerprint(), QString("SHA256:DYdaZciYNxCejr+/8x+OKYxeTU1D5UsuIFUG4PWRFkk"));
  158. QCOMPARE(key.fingerprint(QCryptographicHash::Md5), QString("MD5:c2:26:5b:3d:62:19:56:b0:c3:67:99:7a:a6:4c:66:06"));
  159. }
  160. void TestOpenSSHKey::testParseRSACompare()
  161. {
  162. const QString oldKeyString = QString("-----BEGIN RSA PRIVATE KEY-----\n"
  163. "MIIEpAIBAAKCAQEAsCHtJicDPWnvHSIKbnTZaJkIB9vgE0pmLdK580JUqBuonVbB\n"
  164. "y1QTy0ZQ7/TtqvLPgwPK88TR46OLO/QGCzo2+XxgJ85uy0xfuyUYRmSuw0drsErN\n"
  165. "mH8vU91lSBxsGDp9LtBbgHKoR23vMWZ34IxFRc55XphrIH48ijsMaL6bXBwF/3tD\n"
  166. "9T3lm2MpP1huyVNnIY9+GRRWCy4f9LMj/UGu/n4RtwwfpOZBBRwYkq5QkzA9lPm/\n"
  167. "VzF3MP1rKTMkvAw+Nfb383mkmc6MRnsa6uh6iDa9aVB7naegM13UJQX/PY1Ks6pO\n"
  168. "XDpy/MQ7iCh+HmYNq5dRmARyaNl9xIXJNhz1cQIDAQABAoIBAQCnEUc1LUQxeM5K\n"
  169. "wANNCqE+SgoIClPdeHC7fmrLh1ttqe6ib6ybBUFRS31yXs0hnfefunVEDKlaV8K2\n"
  170. "N52UAMAsngFHQNRvGh6kEWeZPd9Xc+N98TZbNCjcT+DGKc+Om8wqH5DrodZlCq4c\n"
  171. "GaoT4HnE4TjWtZTH2XXrWF9I66PKFWf070R44nvyVcvaZi4pC2YmURRPuGF6K1iK\n"
  172. "dH8zM6HHG1UGu2W6hLNn+K01IulG0Lb8eWNaNYMmtQWaxyp7I2IWkkecUs3nCuiR\n"
  173. "byFOoomCjdh8r9yZFvwxjGUhgtkALN9GCU0Mwve+s11IB2gevruN+q9/Qejbyfdm\n"
  174. "IlgLAeTRAoGBANRcVzW9CYeobCf+U9hKJFEOur8XO+J2mTMaELA0EjWpTJFAeIT7\n"
  175. "KeRpCRG4/vOSklxxRF6vP1EACA4Z+5BlN+FTipHHs+bSEgqkPZiiANDH7Zot5Iqv\n"
  176. "1q0fRyldNRZNZK7DWp08BPNVWGA/EnEuKJiURxnxBaxNXbUyMCdjxvMvAoGBANRT\n"
  177. "utbrqS/bAa/DcHKn3V6DRqBl3TDOfvCNjiKC84a67F2uXgzLIdMktr4d1NyCZVJd\n"
  178. "7/zVgWORLIdg1eAi6rYGoOvNV39wwga7CF+m9sBY0wAaKYCELe6L26r4aQHVCX6n\n"
  179. "rnIgUv+4o4itmU2iP0r3wlmDC9pDRQP82vfvQPlfAoGASwhleANW/quvq2HdViq8\n"
  180. "Mje2HBalfhrRfpDTHK8JUBSFjTzuWG42GxJRtgVbb8x2ElujAKGDCaetMO5VSGu7\n"
  181. "Fs5hw6iAFCpdXY0yhl+XUi2R8kwM2EPQ4lKO3jqkq0ClNmqn9a5jQWcCVt9yMLNS\n"
  182. "fLbHeI8EpiCf34ngIcrLXNkCgYEAzlcEZuKkC46xB+dNew8pMTUwSKZVm53BfPKD\n"
  183. "44QRN6imFbBjU9mAaJnwQbfp6dWKs834cGPolyM4++MeVfB42iZ88ksesgmZdUMD\n"
  184. "szkl6O0pOJs0I+HQZVdjRbadDZvD22MHQ3+oST1dJ3FVXz3Cdo9qPuT8esMO6f4r\n"
  185. "qfDH2s8CgYAXC/lWWHQ//PGP0pH4oiEXisx1K0X1u0xMGgrChxBRGRiKZUwNMIvJ\n"
  186. "TqUu7IKizK19cLHF/NBvxHYHFw+m7puNjn6T1RtRCUjRZT7Dx1VHfVosL9ih5DA8\n"
  187. "tpbZA5KGKcvHtB5DDgT0MHwzBZnb4Q//Rhovzn+HXZPsJTTgHHy3NQ==\n"
  188. "-----END RSA PRIVATE KEY-----\n");
  189. const QString newKeyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  190. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n"
  191. "NhAAAAAwEAAQAAAQEAsCHtJicDPWnvHSIKbnTZaJkIB9vgE0pmLdK580JUqBuonVbBy1QT\n"
  192. "y0ZQ7/TtqvLPgwPK88TR46OLO/QGCzo2+XxgJ85uy0xfuyUYRmSuw0drsErNmH8vU91lSB\n"
  193. "xsGDp9LtBbgHKoR23vMWZ34IxFRc55XphrIH48ijsMaL6bXBwF/3tD9T3lm2MpP1huyVNn\n"
  194. "IY9+GRRWCy4f9LMj/UGu/n4RtwwfpOZBBRwYkq5QkzA9lPm/VzF3MP1rKTMkvAw+Nfb383\n"
  195. "mkmc6MRnsa6uh6iDa9aVB7naegM13UJQX/PY1Ks6pOXDpy/MQ7iCh+HmYNq5dRmARyaNl9\n"
  196. "xIXJNhz1cQAAA8DLsKINy7CiDQAAAAdzc2gtcnNhAAABAQCwIe0mJwM9ae8dIgpudNlomQ\n"
  197. "gH2+ATSmYt0rnzQlSoG6idVsHLVBPLRlDv9O2q8s+DA8rzxNHjo4s79AYLOjb5fGAnzm7L\n"
  198. "TF+7JRhGZK7DR2uwSs2Yfy9T3WVIHGwYOn0u0FuAcqhHbe8xZnfgjEVFznlemGsgfjyKOw\n"
  199. "xovptcHAX/e0P1PeWbYyk/WG7JU2chj34ZFFYLLh/0syP9Qa7+fhG3DB+k5kEFHBiSrlCT\n"
  200. "MD2U+b9XMXcw/WspMyS8DD419vfzeaSZzoxGexrq6HqINr1pUHudp6AzXdQlBf89jUqzqk\n"
  201. "5cOnL8xDuIKH4eZg2rl1GYBHJo2X3Ehck2HPVxAAAAAwEAAQAAAQEApxFHNS1EMXjOSsAD\n"
  202. "TQqhPkoKCApT3Xhwu35qy4dbbanuom+smwVBUUt9cl7NIZ33n7p1RAypWlfCtjedlADALJ\n"
  203. "4BR0DUbxoepBFnmT3fV3PjffE2WzQo3E/gxinPjpvMKh+Q66HWZQquHBmqE+B5xOE41rWU\n"
  204. "x9l161hfSOujyhVn9O9EeOJ78lXL2mYuKQtmJlEUT7hheitYinR/MzOhxxtVBrtluoSzZ/\n"
  205. "itNSLpRtC2/HljWjWDJrUFmscqeyNiFpJHnFLN5wrokW8hTqKJgo3YfK/cmRb8MYxlIYLZ\n"
  206. "ACzfRglNDML3vrNdSAdoHr67jfqvf0Ho28n3ZiJYCwHk0QAAAIAXC/lWWHQ//PGP0pH4oi\n"
  207. "EXisx1K0X1u0xMGgrChxBRGRiKZUwNMIvJTqUu7IKizK19cLHF/NBvxHYHFw+m7puNjn6T\n"
  208. "1RtRCUjRZT7Dx1VHfVosL9ih5DA8tpbZA5KGKcvHtB5DDgT0MHwzBZnb4Q//Rhovzn+HXZ\n"
  209. "PsJTTgHHy3NQAAAIEA1FxXNb0Jh6hsJ/5T2EokUQ66vxc74naZMxoQsDQSNalMkUB4hPsp\n"
  210. "5GkJEbj+85KSXHFEXq8/UQAIDhn7kGU34VOKkcez5tISCqQ9mKIA0Mftmi3kiq/WrR9HKV\n"
  211. "01Fk1krsNanTwE81VYYD8ScS4omJRHGfEFrE1dtTIwJ2PG8y8AAACBANRTutbrqS/bAa/D\n"
  212. "cHKn3V6DRqBl3TDOfvCNjiKC84a67F2uXgzLIdMktr4d1NyCZVJd7/zVgWORLIdg1eAi6r\n"
  213. "YGoOvNV39wwga7CF+m9sBY0wAaKYCELe6L26r4aQHVCX6nrnIgUv+4o4itmU2iP0r3wlmD\n"
  214. "C9pDRQP82vfvQPlfAAAABmlkX3JzYQECAwQ=\n"
  215. "-----END OPENSSH PRIVATE KEY-----\n");
  216. const QByteArray oldKeyData = oldKeyString.toLatin1();
  217. const QByteArray newKeyData = newKeyString.toLatin1();
  218. OpenSSHKey newKey, oldKey;
  219. QByteArray oldPrivateKey, newPrivateKey;
  220. BinaryStream oldPrivateStream(&oldPrivateKey), newPrivateStream(&newPrivateKey);
  221. QVERIFY(oldKey.parsePKCS1PEM(oldKeyData));
  222. QVERIFY(newKey.parsePKCS1PEM(newKeyData));
  223. // comment is not part of the old format and writePrivate() includes it
  224. oldKey.setComment("id_rsa");
  225. QVERIFY(oldKey.writePrivate(oldPrivateStream));
  226. QVERIFY(newKey.writePrivate(newPrivateStream));
  227. QCOMPARE(oldKey.type(), newKey.type());
  228. QCOMPARE(oldKey.fingerprint(), newKey.fingerprint());
  229. QCOMPARE(oldPrivateKey, newPrivateKey);
  230. QCOMPARE(newKeyString, newKey.privateKey());
  231. }
  232. void TestOpenSSHKey::testParseECDSA256()
  233. {
  234. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  235. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAaAAAABNlY2RzYS\n"
  236. "1zaGEyLW5pc3RwMjU2AAAACG5pc3RwMjU2AAAAQQT461x/QlaUUc+H7BxfI5CFXvcMGXA7\n"
  237. "Wp/U/2sfTMuKWUHumBJyjGM4/wJ9V1EldWp3e4MqH2oztQBDoXNlUsn9AAAAwP2/iHH9v4\n"
  238. "hxAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPjrXH9CVpRRz4fs\n"
  239. "HF8jkIVe9wwZcDtan9T/ax9My4pZQe6YEnKMYzj/An1XUSV1and7gyofajO1AEOhc2VSyf\n"
  240. "0AAAAhAIS/QBNpB92hLjYQjpfjguDRkRDYqL6mMbNqX9/5o9fsAAAAIm9wZW5zc2hrZXkt\n"
  241. "dGVzdC1lY2RzYTI1NkBrZWVwYXNzeGMBAgMEBQ==\n"
  242. "-----END OPENSSH PRIVATE KEY-----\n");
  243. const QByteArray keyData = keyString.toLatin1();
  244. OpenSSHKey key;
  245. QVERIFY(key.parsePKCS1PEM(keyData));
  246. QVERIFY(!key.encrypted());
  247. QCOMPARE(key.cipherName(), QString("none"));
  248. QCOMPARE(key.type(), QString("ecdsa-sha2-nistp256"));
  249. QCOMPARE(key.comment(), QString("opensshkey-test-ecdsa256@keepassxc"));
  250. QCOMPARE(key.fingerprint(), QString("SHA256:nwwovZmQbBeiR3GZRpK4OWHgCUE7E0wFtCN7Ng7eX5g"));
  251. QCOMPARE(keyString, key.privateKey());
  252. }
  253. void TestOpenSSHKey::testParseECDSA384()
  254. {
  255. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  256. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAiAAAABNlY2RzYS\n"
  257. "1zaGEyLW5pc3RwMzg0AAAACG5pc3RwMzg0AAAAYQSLw/MlwQSW/y+mD9KpoXkoHLK88uKJ\n"
  258. "hD8HLTNpJ+fdIP24Z6w4vJeddJo/dmsl945UwMzIaHA5DPQmUyAIAcId8wTZRF9xqRpaQI\n"
  259. "uegjFVkxyusj5edC4qNaRKF4V6tTcAAADwdh56A3YeegMAAAATZWNkc2Etc2hhMi1uaXN0\n"
  260. "cDM4NAAAAAhuaXN0cDM4NAAAAGEEi8PzJcEElv8vpg/SqaF5KByyvPLiiYQ/By0zaSfn3S\n"
  261. "D9uGesOLyXnXSaP3ZrJfeOVMDMyGhwOQz0JlMgCAHCHfME2URfcakaWkCLnoIxVZMcrrI+\n"
  262. "XnQuKjWkSheFerU3AAAAMCECw8BmZ1isLTJnOVcHoohmtfXr4lzCbSOWkQH5tPlo2tntUd\n"
  263. "5u1XXrWlo9+5nrAgAAACJvcGVuc3Noa2V5LXRlc3QtZWNkc2EzODRAa2VlcGFzc3hjAQID\n"
  264. "BAUG\n"
  265. "-----END OPENSSH PRIVATE KEY-----\n");
  266. const QByteArray keyData = keyString.toLatin1();
  267. OpenSSHKey key;
  268. QVERIFY(key.parsePKCS1PEM(keyData));
  269. QVERIFY(!key.encrypted());
  270. QCOMPARE(key.cipherName(), QString("none"));
  271. QCOMPARE(key.type(), QString("ecdsa-sha2-nistp384"));
  272. QCOMPARE(key.comment(), QString("opensshkey-test-ecdsa384@keepassxc"));
  273. QCOMPARE(key.fingerprint(), QString("SHA256:B5tLMG976BZ6nyi/oRUmKaTJcaEaFagEjBfOAgru0OY"));
  274. QCOMPARE(keyString, key.privateKey());
  275. }
  276. void TestOpenSSHKey::testParseECDSA521()
  277. {
  278. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  279. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAArAAAABNlY2RzYS\n"
  280. "1zaGEyLW5pc3RwNTIxAAAACG5pc3RwNTIxAAAAhQQBIxaAOfN2yDEHakGVzGfTTzhqwLYf\n"
  281. "7lcOgVpSSbjsDylAV9l+Pd0yBNmf/WqLWN9nzmDaSf2KqGm1HjSKgF+kt60BOyMqNIY1g/\n"
  282. "o6jg4lgKnGiAsIo3bePzYyHBH9EC6aX2mLnCm6v/bJL4AEKuzamRlj+R/juQYFIolLJ6OS\n"
  283. "rg6Wn/UAAAEg4p6+WOKevlgAAAATZWNkc2Etc2hhMi1uaXN0cDUyMQAAAAhuaXN0cDUyMQ\n"
  284. "AAAIUEASMWgDnzdsgxB2pBlcxn0084asC2H+5XDoFaUkm47A8pQFfZfj3dMgTZn/1qi1jf\n"
  285. "Z85g2kn9iqhptR40ioBfpLetATsjKjSGNYP6Oo4OJYCpxogLCKN23j82MhwR/RAuml9pi5\n"
  286. "wpur/2yS+ABCrs2pkZY/kf47kGBSKJSyejkq4Olp/1AAAAQgC4lKZk989FOK7axlAsF3Da\n"
  287. "H8/Ejk2o+aGOGIxe4UU3nw1QnWG0RhBsIkSir10ZBcKklg0coqcBqPQrwYc8GHBoxgAAAC\n"
  288. "JvcGVuc3Noa2V5LXRlc3QtZWNkc2E1MjFAa2VlcGFzc3hj\n"
  289. "-----END OPENSSH PRIVATE KEY-----\n");
  290. const QByteArray keyData = keyString.toLatin1();
  291. OpenSSHKey key;
  292. QVERIFY(key.parsePKCS1PEM(keyData));
  293. QVERIFY(!key.encrypted());
  294. QCOMPARE(key.cipherName(), QString("none"));
  295. QCOMPARE(key.type(), QString("ecdsa-sha2-nistp521"));
  296. QCOMPARE(key.comment(), QString("opensshkey-test-ecdsa521@keepassxc"));
  297. QCOMPARE(key.fingerprint(), QString("SHA256:m3LtA9MtZW8FN0R3vwA0AAI+YtegbggGCy3EGKWya+s"));
  298. QCOMPARE(keyString, key.privateKey());
  299. }
  300. void TestOpenSSHKey::testDecryptOpenSSHAES256CBC()
  301. {
  302. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  303. "b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABD2A0agtd\n"
  304. "oGtJiI9JvIxYbTAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIDPvDXmi0w1rdMoX\n"
  305. "fOeyZ0Q/v+wqq/tPFgJwxnW5ADtfAAAAsC3UPsf035hrF5SgZ48p55iDFPiyGfZC/C3vQx\n"
  306. "+THzpQo8DTUmFokdPn8wvDYGQoIcr9q0RzJuKV87eMQf3zzvZfJthtLYBlt330Deivv9AQ\n"
  307. "MbKdhPZ4SfwRvv0grgT2EVId3GQAPgSVBhXYQTOf2CdmbXV4kieFLTmSsBMy+v6Qn5Rqur\n"
  308. "PDWBwuLQgamcVDZuhrkUEqIVJZU2zAiRU2oAXsw/XOgFV6+Y5UZmLwWJQZ\n"
  309. "-----END OPENSSH PRIVATE KEY-----\n");
  310. const QByteArray keyData = keyString.toLatin1();
  311. OpenSSHKey key;
  312. QVERIFY(key.parsePKCS1PEM(keyData));
  313. QVERIFY(key.encrypted());
  314. QCOMPARE(key.cipherName(), QString("aes256-cbc"));
  315. QVERIFY(!key.openKey("incorrectpassphrase"));
  316. QVERIFY(key.openKey("correctpassphrase"));
  317. QCOMPARE(key.type(), QString("ssh-ed25519"));
  318. QCOMPARE(key.comment(), QString("opensshkey-test-aes256cbc@keepassxc"));
  319. QByteArray publicKey, privateKey;
  320. BinaryStream publicStream(&publicKey), privateStream(&privateKey);
  321. QVERIFY(key.writePublic(publicStream));
  322. QVERIFY(key.writePrivate(privateStream));
  323. QVERIFY(publicKey.length() == 51);
  324. QVERIFY(privateKey.length() == 158);
  325. }
  326. void TestOpenSSHKey::testDecryptRSAAES256CBC()
  327. {
  328. const QString keyString = QString("-----BEGIN RSA PRIVATE KEY-----\n"
  329. "Proc-Type: 4,ENCRYPTED\n"
  330. "DEK-Info: AES-256-CBC,D51E3F558B621BD9384627762CBD16AC\n"
  331. "\n"
  332. "b6nr/06Gj8/Nw3ZFMePFyZeuBodExvZZtZPSH3t/2ArcxXOkoqUhLmlcY/JrvnBF\n"
  333. "JHc34wx/6Yng7mqtUMuk2iMemTzOj3JRx8zHUhwPLnjM/tmeOm0wBUb3WB4+rFZW\n"
  334. "s1PaIgeKywKgFK0UkcSRpMuSaxheWmHrtJkBsHTF7Tg3ogPL8Dc+nhQlbe/ZGaQb\n"
  335. "vMdSYcBMaXngS5ZiOafXeY8+l+IMMOZwy5vPTFQGqKHIzOxFhShs1hSExnwOXy69\n"
  336. "wxrA/QftjNEy5ixIeGT7iQfRB04tEVg0DjYphTPmI2ophzFlwJVBjhj2cmmnsMZg\n"
  337. "a2TdT/78KZsw2cA5ieMcU6d7Yz5p5nu5dyTbZonn6qWficdZRJwZnVb5ikPnJYbZ\n"
  338. "1YJRHHND+RWtpanxz7WhStscTCLeI9w9j2gqBJSjKDPgJaoMiA+tyEoakNlPYg+9\n"
  339. "DadJkBGP0g5E9zw0n4niqQ7eCxk7qolmW6Wtn2zL4UyeJKGi9NWFSGW9x/PmAIse\n"
  340. "E2KVodiJMRNa8/qUZcW58ZG2uRnFTsW4BXdmzOy/Zp53TVGWStBVLDcldSD03ItD\n"
  341. "JIWQWDgWp5xyVqPl+8mkW7xDY0GRVSJCyRkctQeGTGysy0BcNjgQQtiA3lPC0rY5\n"
  342. "m2VxrCYU1KuyHsAjs/V8THcW4a1UdPcVBg1QbCh29bMoM6u4MuXVt7rkwxAV9HJa\n"
  343. "VbwPsKy7V6G60KaAFIiOs0wdOzBZBoPGd9vBQOEzATh2FYJruDo2OfzEnhv25RxE\n"
  344. "1q+C/Jds9cWqaNY8kNtUG799XIKkjrC6KvnoV6UA4BkGs2DAcO9rnwtl/hToEoBe\n"
  345. "ZVj72dlTuS6l9rHqKaz2GI0k0SEt/ZoakPHeDRgPNcDvEZWitV8MuD6Mwb47Y88u\n"
  346. "sjBmS5k4sJOtB4bLg/UShcqYfkv2OTsK90qGQtba9vMk04Xh1FuxB4fHa5VoKrsX\n"
  347. "Th/LB34xoYugd16NPmLuawhSo70o4bT70GYpxnb4brGfjWiuthRdegAG9ESSX+M6\n"
  348. "rNKQPnn2GSroIpkoA4k0PaflcE5tpzeIiJdv0h65N3vw6MFnCaWy8sRSy9fMyRim\n"
  349. "U8QZB2jcp+YjUU/eny3scuh0Vqt6g1tfFbI84pCC5bArBirf63MeMtwDU/IVImax\n"
  350. "xzKOzl7k8ropA+rhAJ4Z9X35EmUncBXhf8g39w6nFuSlqjE6rMxCrsrehljQ1Iuz\n"
  351. "bujaJ2PKpf98OejHDKnMDOfBBq0DdeERCYWlCcqWSgrEgHh4vB5dEQAPP5bAkdZj\n"
  352. "m0Dq+gF99yadioxf3/MUZVTa1dHklBJJkXTYVPeyH07Th5j7bGCcVb9Zd2Ao/Dia\n"
  353. "MPWf6xViCC6d0njCLQY2R8mOR5OMVsdlFrsKZMQ/lqjS/WSM6URDkuGb0Cq94TQd\n"
  354. "7DoblcA50FTwYrVXMygWygbjzJxhcoJDHztzwoqLT/ghh+6zRg6R/fY222tHHbhz\n"
  355. "nePf421NILzfxnuW+GOwRCM5+IHE3OBS/PYDGijjRFHU4ky0rRRDE64m9CeFzeBh\n"
  356. "CnFvW6Yx3Hrh5tXBP7kRZ6KjyrPP7tI4ciVSJceSBLRzFmoBr10kRMm+VsUh2xZH\n"
  357. "-----END RSA PRIVATE KEY-----\n");
  358. const QByteArray keyData = keyString.toLatin1();
  359. OpenSSHKey key;
  360. QVERIFY(key.parsePKCS1PEM(keyData));
  361. QVERIFY(key.encrypted());
  362. QCOMPARE(key.cipherName(), QString("AES-256-CBC"));
  363. QVERIFY(!key.openKey("incorrectpassphrase"));
  364. QVERIFY(key.openKey("correctpassphrase"));
  365. QCOMPARE(key.type(), QString("ssh-rsa"));
  366. QCOMPARE(key.comment(), QString(""));
  367. QCOMPARE(key.fingerprint(), QString("SHA256:1Hsebt2WWnmc72FERsUOgvaajIGHkrMONxXylcmk87U"));
  368. }
  369. void TestOpenSSHKey::testDecryptOpenSSHAES256CTR()
  370. {
  371. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  372. "b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABAMhIAypt\n"
  373. "WP4tZJBmMwq0tTAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIErNsS8ROy43XoWC\n"
  374. "nO9Sn2lEFBJYcDVtRPM1t6WB7W7OAAAAsFKXMOlPILoTmMj2JmcqzjaYAhaCezx18HDp76\n"
  375. "VrNxaZTd0T28EGFSkzrReeewpJWy/bWlhLoXR5fRyOSSto+iMg/pibIvIJMrD5sqxlxr/e\n"
  376. "c5lSeSZUzIK8Rv+ou/3EFDcY5jp8hVXqA4qNtoM/3fV52vmwlNje5d1V5Gsr4U8443+i+p\n"
  377. "swqksozfatkynk51uR/9QFoOJKlsL/Z3LkK1S/apYz/K331iU1f5ozFELf\n"
  378. "-----END OPENSSH PRIVATE KEY-----\n");
  379. const QByteArray keyData = keyString.toLatin1();
  380. OpenSSHKey key;
  381. QVERIFY(key.parsePKCS1PEM(keyData));
  382. QVERIFY(key.encrypted());
  383. QCOMPARE(key.cipherName(), QString("aes256-ctr"));
  384. QVERIFY(!key.openKey("incorrectpassphrase"));
  385. QVERIFY(key.openKey("correctpassphrase"));
  386. QCOMPARE(key.type(), QString("ssh-ed25519"));
  387. QCOMPARE(key.comment(), QString("opensshkey-test-aes256ctr@keepassxc"));
  388. QByteArray publicKey, privateKey;
  389. BinaryStream publicStream(&publicKey), privateStream(&privateKey);
  390. QVERIFY(key.writePublic(publicStream));
  391. QVERIFY(key.writePrivate(privateStream));
  392. QVERIFY(publicKey.length() == 51);
  393. QVERIFY(privateKey.length() == 158);
  394. }
  395. void TestOpenSSHKey::testDecryptRSAAES256CTR()
  396. {
  397. const QString keyString = QString("-----BEGIN RSA PRIVATE KEY-----\n"
  398. "Proc-Type: 4,ENCRYPTED\n"
  399. "DEK-Info: AES-256-CTR,192421854316290DFA8F469A1E8CB9BB\n"
  400. "\n"
  401. "3h7gUWua+jcvhYj1vUusbMdOG9j8SmNWFV5Hfersi8nF4ddsWEQDnMrRuhtIn4tU\n"
  402. "GcLY+SXguim5XXwF8gG1tmvpvFMhudTfX+0cIAX7eAVmqLy2RTA18DWqDwWokVP0\n"
  403. "RJPgRJJSorjMtu2F0YGVVjElW7pHIal7luNk3BDgYUMlgSg0BGOWb+9BkXcEnfc8\n"
  404. "KEwsJw2onoR2eXo6rYnczGaqPhAPu+I+PfUn0J8PFiffWc1KebRntLdRWeNsBS4p\n"
  405. "oxtqByzMYIu/WPSJJ5iFoNdKaWQPiZJB+juwI1wNLEtpzKkhpc7/6mOy87h+0eGV\n"
  406. "fF7javrbHv37eE+k2iZXrcLfvRpiBqt5+uhhCaM8TivBeUho5J38ru/wt/dk+OvY\n"
  407. "tzXboWA4zVnaYmqta1CkXYKOmb5a8TWEwtxmAuE6kCz/n3pPa6gwkwsyGI65IEyX\n"
  408. "ycJsbwUilAzXTcz5bIruGx38Sa9fndAN9llOQMS/hdyNs5W5dO1XZ5gU+ARPce+j\n"
  409. "+A2R8oCUv+2ciEu8z3F++U9aTRmTlD3xeIM0IWUFXKt8Y9fSRC5XoPCbZYNxnV6/\n"
  410. "hn9NPKCb890Faxies3MABOB5IZ0aTPWkx9ntxFhMaXyfkX2YthNO0GzAENPP9Knt\n"
  411. "DYhQePlKQ7sNi8+wzsHNeDxNuL/+Rib2MN3ankDtHIsqFz/Em+rD0+3ya8bLy3pP\n"
  412. "eeUiNpezL+uxI5llq/pikzK4sOgvH1r5YEkMxt9I09grkBwxR7DMBo0vgRE2MLiL\n"
  413. "nlri8TDwArC1+0gE8NspkkClsBOHXuVlGZo5lup2tn5MzERQcLvuFnAby/GnaVXQ\n"
  414. "Hm76teb1wMdL58FrdZsKR6e80E+F6JpTsz0a3XJqptgAwGsoxqizkUNJG5hRP8bi\n"
  415. "NBCFQZPeYi/GxgN5O2UkxhgRkKAcrHg+G87nhLk1ipsc214rb6iOspNizP6fGDuv\n"
  416. "/bsNTpYRgMNxCLh5Nv0HSUqckoNKOcIVe/9nF5/LLFGfhz95agjKTbBygThFK28N\n"
  417. "bnHq5fO9yKCMrGCRBQ6No1wwexyS4IAq17LcQP3k4w4n+Wt2GjO5HIldGOEyGqCE\n"
  418. "zeHYrPpGXF/yf3XTm00XghdQtVtRJptdddXVGZN3EN2w7/ghOSIIlsJO9C4IRgU3\n"
  419. "WkhX7oOpSE4wmXd5Ada+D1U46snW5nWANWko2NmQNVDeJcvuymL6t2ccNYeFWiA+\n"
  420. "Hlv0avBnqng7ZWPxYacqZI3+vU0rN9usN1pzwY/4NsBa34o3M7u6KvzEkyewbyUT\n"
  421. "VfXLJ8XRzb2u4NqQv0WiTBIRxvVB1sRPcrwB4HWKHwRFT8T7f1fefteROrKV7aKm\n"
  422. "Q48pckidDM0ORh1yIET8u24Mreo5eeWXjVJ9MHoM0486VySYxMwk8yp4tnaHx5kd\n"
  423. "fGlBbbwFOifhzjAk0u3KJRAG85t2GZhfTMo1IHS2kdu4Xs1N00ZmK0hjeGG+DCwy\n"
  424. "06ZKHOF5BHWU3SpQEjCsPDwfIpOINWGAJJnp6NIVf7FkHwViV50GWWGSZal4NqZy\n"
  425. "kR19buHiOb7KnGoPCw8MUmIym8v30FePhM4YQ7ASmRtsXlAhQNRX\n"
  426. "-----END RSA PRIVATE KEY-----\n");
  427. const QByteArray keyData = keyString.toLatin1();
  428. OpenSSHKey key;
  429. QVERIFY(key.parsePKCS1PEM(keyData));
  430. QVERIFY(key.encrypted());
  431. QCOMPARE(key.cipherName(), QString("AES-256-CTR"));
  432. QVERIFY(!key.openKey("incorrectpassphrase"));
  433. QVERIFY(key.openKey("correctpassphrase"));
  434. QCOMPARE(key.type(), QString("ssh-rsa"));
  435. QCOMPARE(key.comment(), QString(""));
  436. QCOMPARE(key.fingerprint(), QString("SHA256:1Hsebt2WWnmc72FERsUOgvaajIGHkrMONxXylcmk87U"));
  437. }
  438. void TestOpenSSHKey::testDecryptUTF8()
  439. {
  440. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  441. "b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDtSl4OvT\n"
  442. "H/wHay2dvjOnpIAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIIhrBrn6rb+d3GwF\n"
  443. "ifpJ6gYut95lXvwypiQmu9ZpA8H9AAAAsD85Gpn2mbVEWq3ygx11wBnN5mUQXnMuP48rLv\n"
  444. "0qwm12IihOkrR925ledwN2Sa5mkkL0XjDz6SsKfIFhFa84hUHQdw5zPR8yVGRWLzkNDmo7\n"
  445. "WXNpnoE4ebsX2j0TsBNjP80RUcJdjSXidkt3+aZjaCfquO8cBQn4GJJSDSPwFJYlJeSD/h\n"
  446. "vpb72MEQchOD3NNMORYTJ5sOJ73RayhhmwjTVlrG+zYAw6fXW0YXX3+5LE\n"
  447. "-----END OPENSSH PRIVATE KEY-----\n");
  448. const QByteArray keyData = keyString.toLatin1();
  449. OpenSSHKey key;
  450. QVERIFY(key.parsePKCS1PEM(keyData));
  451. QVERIFY(key.encrypted());
  452. QCOMPARE(key.cipherName(), QString("aes256-ctr"));
  453. QVERIFY(!key.openKey("incorrectpassphrase"));
  454. QVERIFY(key.openKey("äåéëþüúíóö"));
  455. QCOMPARE(key.fingerprint(), QString("SHA256:EfUXwvH4rOoys+AlbznCqjMwzIVW8KuhoWu9uT03FYA"));
  456. QCOMPARE(key.type(), QString("ssh-ed25519"));
  457. QCOMPARE(key.comment(), QString("opensshkey-test-utf8@keepassxc"));
  458. }
  459. void TestOpenSSHKey::testParseECDSASecurityKey()
  460. {
  461. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  462. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAfwAAACJzay1lY2\n"
  463. "RzYS1zaGEyLW5pc3RwMjU2QG9wZW5zc2guY29tAAAACG5pc3RwMjU2AAAAQQQ2Pr1d6zUa\n"
  464. "qcmYgjTGQUF9QPkFEo2Q7aQbvyL/0KL9FObuOfzqxs8mDqswXEsXR4g5L6P7vEe6nPqzSW\n"
  465. "X9/jJfAAAABHNzaDoAAAD4kyJ795Mie/cAAAAic2stZWNkc2Etc2hhMi1uaXN0cDI1NkBv\n"
  466. "cGVuc3NoLmNvbQAAAAhuaXN0cDI1NgAAAEEENj69Xes1GqnJmII0xkFBfUD5BRKNkO2kG7\n"
  467. "8i/9Ci/RTm7jn86sbPJg6rMFxLF0eIOS+j+7xHupz6s0ll/f4yXwAAAARzc2g6AQAAAEA4\n"
  468. "Dbqd2ub7R1QQRm8nBZWDGJSiNIh58vvJ4EuAh0FnJsRvvASsSDiGuuXqh56wT5xmlnYvbb\n"
  469. "nLWO4/1+Mp5PaDAAAAAAAAACJvcGVuc3Noa2V5LXRlc3QtZWNkc2Etc2tAa2VlcGFzc3hj\n"
  470. "AQI=\n"
  471. "-----END OPENSSH PRIVATE KEY-----\n");
  472. const QByteArray keyData = keyString.toLatin1();
  473. OpenSSHKey key;
  474. QVERIFY(key.parsePKCS1PEM(keyData));
  475. QVERIFY(!key.encrypted());
  476. QCOMPARE(key.cipherName(), QString("none"));
  477. QCOMPARE(key.type(), QString("sk-ecdsa-sha2-nistp256@openssh.com"));
  478. QCOMPARE(key.comment(), QString("opensshkey-test-ecdsa-sk@keepassxc"));
  479. QCOMPARE(key.fingerprint(), QString("SHA256:ctOtAsPMqbtumGI41o2oeWfGDah4m1ACILRj+x0gx0E"));
  480. QCOMPARE(keyString, key.privateKey());
  481. }
  482. void TestOpenSSHKey::testParseED25519SecurityKey()
  483. {
  484. const QString keyString = QString("-----BEGIN OPENSSH PRIVATE KEY-----\n"
  485. "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAASgAAABpzay1zc2\n"
  486. "gtZWQyNTUxOUBvcGVuc3NoLmNvbQAAACCSIfzsjUBlhsVBfHHlQCUpj1Yt+404RetvfTnd\n"
  487. "DJIIqgAAAARzc2g6AAABCN1MUOzdTFDsAAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY2\n"
  488. "9tAAAAIJIh/OyNQGWGxUF8ceVAJSmPVi37jThF6299Od0MkgiqAAAABHNzaDoBAAAAgF+0\n"
  489. "UB3uNf48T/u9eSHmhfTfqgZZZxQ81UQmlw9Xw1eNZ2F+y+JwbQYK3gLMxro2cv2PHgYqIW\n"
  490. "MAHFxdJjUn62D88bywmHaFT7ftu8/4bh38G+aQsmTFW38li97FiLz+Ytz0X9oSCo1jerkC\n"
  491. "fYe8pcZZ7zWWSMzRnZKP11QMEkEQAAAAAAAAACRvcGVuc3Noa2V5LXRlc3QtZWQyNTUxOS\n"
  492. "1za0BrZWVwYXNzeGMBAgMEBQ==\n"
  493. "-----END OPENSSH PRIVATE KEY-----\n");
  494. const QByteArray keyData = keyString.toLatin1();
  495. OpenSSHKey key;
  496. QVERIFY(key.parsePKCS1PEM(keyData));
  497. QVERIFY(!key.encrypted());
  498. QCOMPARE(key.cipherName(), QString("none"));
  499. QCOMPARE(key.type(), QString("sk-ssh-ed25519@openssh.com"));
  500. QCOMPARE(key.comment(), QString("opensshkey-test-ed25519-sk@keepassxc"));
  501. QCOMPARE(key.fingerprint(), QString("SHA256:PGtS5WvbnYmNqFIeRbzO6cVP9GLh8eEzENgkHp02XIA"));
  502. QCOMPARE(keyString, key.privateKey());
  503. }