libssh2-1.10.0-upstream_fix-1.patch 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755
  1. Submitted by: Xi Ruoyao <xry111 at xry111 dot site>
  2. Date: 2022-09-01
  3. Initial Package Version: 1.10.0
  4. Upstream Status: Applied
  5. Origin:
  6. - https://github.com/libssh2/libssh2/pull/626
  7. - https://github.com/libssh2/libssh2/pull/656
  8. Description: Fix incompatibility with latest OpenSSH.
  9. From 5d31fc6daeb5202df32cf560345cce3e735b49e2 Mon Sep 17 00:00:00 2001
  10. From: Will Cosgrove <will@everydaysoftware.net>
  11. Date: Mon, 30 Aug 2021 17:45:20 +0000
  12. Subject: [PATCH 01/16] Host Key RSA 256/512 support #536
  13. ---
  14. src/hostkey.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++
  15. 1 file changed, 161 insertions(+)
  16. diff --git a/src/hostkey.c b/src/hostkey.c
  17. index d87a4c744..ddf13c365 100644
  18. --- a/src/hostkey.c
  19. +++ b/src/hostkey.c
  20. @@ -227,6 +227,139 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
  21. #endif
  22. }
  23. +/*
  24. + * hostkey_method_ssh_rsa_sha2_256_sig_verify
  25. + *
  26. + * Verify signature created by remote
  27. + */
  28. +
  29. +static int
  30. +hostkey_method_ssh_rsa_sha2_256_sig_verify(LIBSSH2_SESSION * session,
  31. + const unsigned char *sig,
  32. + size_t sig_len,
  33. + const unsigned char *m,
  34. + size_t m_len, void **abstract)
  35. +{
  36. + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
  37. + (void) session;
  38. +
  39. + /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-256"} + signature_len(4) */
  40. + if(sig_len < 20)
  41. + return -1;
  42. +
  43. + sig += 20;
  44. + sig_len -= 20;
  45. + return _libssh2_rsa_sha2_verify(rsactx, SHA256_DIGEST_LENGTH, sig, sig_len, m, m_len);
  46. +}
  47. +
  48. +/*
  49. + * hostkey_method_ssh_rsa_sha2_256_signv
  50. + *
  51. + * Construct a signature from an array of vectors
  52. + */
  53. +
  54. +static int
  55. +hostkey_method_ssh_rsa_sha2_256_signv(LIBSSH2_SESSION * session,
  56. + unsigned char **signature,
  57. + size_t *signature_len,
  58. + int veccount,
  59. + const struct iovec datavec[],
  60. + void **abstract)
  61. +{
  62. + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
  63. +
  64. +#ifdef _libssh2_rsa_sha2_256_signv
  65. + return _libssh2_rsa_sha2_256_signv(session, signature, signature_len,
  66. + veccount, datavec, rsactx);
  67. +#else
  68. + int ret;
  69. + int i;
  70. + unsigned char hash[SHA256_DIGEST_LENGTH];
  71. + libssh2_sha256_ctx ctx;
  72. +
  73. + libssh2_sha256_init(&ctx);
  74. + for(i = 0; i < veccount; i++) {
  75. + libssh2_sha256_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
  76. + }
  77. + libssh2_sha256_final(ctx, hash);
  78. +
  79. + ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA256_DIGEST_LENGTH,
  80. + signature, signature_len);
  81. + if(ret) {
  82. + return -1;
  83. + }
  84. +
  85. + return 0;
  86. +#endif
  87. +}
  88. +
  89. +/*
  90. + * hostkey_method_ssh_rsa_sha2_512_sig_verify
  91. + *
  92. + * Verify signature created by remote
  93. + */
  94. +
  95. +static int
  96. +hostkey_method_ssh_rsa_sha2_512_sig_verify(LIBSSH2_SESSION * session,
  97. + const unsigned char *sig,
  98. + size_t sig_len,
  99. + const unsigned char *m,
  100. + size_t m_len, void **abstract)
  101. +{
  102. + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
  103. + (void) session;
  104. +
  105. + /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-512"} + signature_len(4) */
  106. + if(sig_len < 20)
  107. + return -1;
  108. +
  109. + sig += 20;
  110. + sig_len -= 20;
  111. + return _libssh2_rsa_sha2_verify(rsactx, SHA512_DIGEST_LENGTH, sig, sig_len, m, m_len);
  112. +}
  113. +
  114. +
  115. +/*
  116. + * hostkey_method_ssh_rsa_sha2_512_signv
  117. + *
  118. + * Construct a signature from an array of vectors
  119. + */
  120. +static int
  121. +hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session,
  122. + unsigned char **signature,
  123. + size_t *signature_len,
  124. + int veccount,
  125. + const struct iovec datavec[],
  126. + void **abstract)
  127. +{
  128. + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
  129. +
  130. +#ifdef _libssh2_rsa_sha2_512_signv
  131. + return _libssh2_rsa_sha2_512_signv(session, signature, signature_len,
  132. + veccount, datavec, rsactx);
  133. +#else
  134. + int ret;
  135. + int i;
  136. + unsigned char hash[SHA512_DIGEST_LENGTH];
  137. + libssh2_sha512_ctx ctx;
  138. +
  139. + libssh2_sha512_init(&ctx);
  140. + for(i = 0; i < veccount; i++) {
  141. + libssh2_sha512_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
  142. + }
  143. + libssh2_sha512_final(ctx, hash);
  144. +
  145. + ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA512_DIGEST_LENGTH,
  146. + signature, signature_len);
  147. + if(ret) {
  148. + return -1;
  149. + }
  150. +
  151. + return 0;
  152. +#endif
  153. +}
  154. +
  155. +
  156. /*
  157. * hostkey_method_ssh_rsa_dtor
  158. *
  159. @@ -260,6 +393,32 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
  160. NULL, /* encrypt */
  161. hostkey_method_ssh_rsa_dtor,
  162. };
  163. +
  164. +
  165. +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_256 = {
  166. + "rsa-sha2-256",
  167. + SHA256_DIGEST_LENGTH,
  168. + hostkey_method_ssh_rsa_init,
  169. + hostkey_method_ssh_rsa_initPEM,
  170. + hostkey_method_ssh_rsa_initPEMFromMemory,
  171. + hostkey_method_ssh_rsa_sha2_256_sig_verify,
  172. + hostkey_method_ssh_rsa_sha2_256_signv,
  173. + NULL, /* encrypt */
  174. + hostkey_method_ssh_rsa_dtor,
  175. +};
  176. +
  177. +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_512 = {
  178. + "rsa-sha2-512",
  179. + SHA512_DIGEST_LENGTH,
  180. + hostkey_method_ssh_rsa_init,
  181. + hostkey_method_ssh_rsa_initPEM,
  182. + hostkey_method_ssh_rsa_initPEMFromMemory,
  183. + hostkey_method_ssh_rsa_sha2_512_sig_verify,
  184. + hostkey_method_ssh_rsa_sha2_512_signv,
  185. + NULL, /* encrypt */
  186. + hostkey_method_ssh_rsa_dtor,
  187. +};
  188. +
  189. #endif /* LIBSSH2_RSA */
  190. #if LIBSSH2_DSA
  191. @@ -1043,6 +1202,8 @@ static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
  192. &hostkey_method_ssh_ed25519,
  193. #endif
  194. #if LIBSSH2_RSA
  195. + &hostkey_method_ssh_rsa_sha2_512,
  196. + &hostkey_method_ssh_rsa_sha2_256,
  197. &hostkey_method_ssh_rsa,
  198. #endif /* LIBSSH2_RSA */
  199. #if LIBSSH2_DSA
  200. From b10ccc7633932207cf406d022b125251fe86b466 Mon Sep 17 00:00:00 2001
  201. From: Will Cosgrove <will@everydaysoftware.net>
  202. Date: Mon, 30 Aug 2021 23:05:56 +0000
  203. Subject: [PATCH 02/16] Host Key RSA 256/512 support libssh2 #536
  204. ---
  205. docs/HACKING-CRYPTO | 26 ++++++++++++
  206. src/crypto.h | 13 ++++++
  207. src/hostkey.c | 8 ++++
  208. src/libgcrypt.h | 1 +
  209. src/mbedtls.h | 1 +
  210. src/openssl.c | 99 ++++++++++++++++++++++++++++++++++++++++++---
  211. src/openssl.h | 2 +
  212. src/wincng.h | 1 +
  213. 9 files changed, 146 insertions(+), 6 deletions(-)
  214. diff --git a/docs/HACKING-CRYPTO b/docs/HACKING-CRYPTO
  215. index ca9477286..d0173553f 100644
  216. --- a/docs/HACKING-CRYPTO
  217. +++ b/docs/HACKING-CRYPTO
  218. @@ -637,6 +637,32 @@ Note: this procedure is not used if macro _libssh2_rsa_sha1_signv() is defined.
  219. void _libssh2_rsa_free(libssh2_rsa_ctx *rsactx);
  220. Releases the RSA computation context at rsactx.
  221. +LIBSSH2_RSA_SHA2
  222. +#define as 1 if the crypto library supports RSA SHA2 256/512, else 0.
  223. +If defined as 0, the rest of this section can be omitted.
  224. +
  225. +int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
  226. + libssh2_rsa_ctx * rsactx,
  227. + const unsigned char *hash,
  228. + size_t hash_len,
  229. + unsigned char **signature,
  230. + size_t *signature_len);
  231. +RSA signs the (hash, hashlen) SHA-2 hash bytes based on hash length and stores
  232. +the allocated signature at (signature, signature_len).
  233. +Signature buffer must be allocated from the given session.
  234. +Returns 0 if OK, else -1.
  235. +This procedure is already prototyped in crypto.h.
  236. +Note: this procedure is not used if macro _libssh2_rsa_sha1_signv() is defined.
  237. +
  238. +int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa,
  239. + size_t hash_len,
  240. + const unsigned char *sig,
  241. + unsigned long sig_len,
  242. + const unsigned char *m, unsigned long m_len);
  243. +Verify (sig, sig_len) signature of (m, m_len) using an SHA-2 hash based on
  244. +hash length and the RSA context.
  245. +Return 0 if OK, else -1.
  246. +This procedure is already prototyped in crypto.h.
  247. 7.2) DSA
  248. LIBSSH2_DSA
  249. diff --git a/src/crypto.h b/src/crypto.h
  250. index f512d6039..efaf15646 100644
  251. --- a/src/crypto.h
  252. +++ b/src/crypto.h
  253. @@ -93,6 +93,19 @@ int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
  254. size_t hash_len,
  255. unsigned char **signature,
  256. size_t *signature_len);
  257. +#if LIBSSH2_RSA_SHA2
  258. +int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
  259. + libssh2_rsa_ctx * rsactx,
  260. + const unsigned char *hash,
  261. + size_t hash_len,
  262. + unsigned char **signature,
  263. + size_t *signature_len);
  264. +int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa,
  265. + size_t hash_len,
  266. + const unsigned char *sig,
  267. + unsigned long sig_len,
  268. + const unsigned char *m, unsigned long m_len);
  269. +#endif
  270. int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
  271. LIBSSH2_SESSION * session,
  272. const char *filedata,
  273. diff --git a/src/hostkey.c b/src/hostkey.c
  274. index ddf13c365..8040a4ea1 100644
  275. --- a/src/hostkey.c
  276. +++ b/src/hostkey.c
  277. @@ -232,6 +232,7 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
  278. *
  279. * Verify signature created by remote
  280. */
  281. +#if LIBSSH2_RSA_SHA2
  282. static int
  283. hostkey_method_ssh_rsa_sha2_256_sig_verify(LIBSSH2_SESSION * session,
  284. @@ -359,6 +360,8 @@ hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session,
  285. #endif
  286. }
  287. +#endif /* LIBSSH2_RSA_SHA2 */
  288. +
  289. /*
  290. * hostkey_method_ssh_rsa_dtor
  291. @@ -394,6 +397,7 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = {
  292. hostkey_method_ssh_rsa_dtor,
  293. };
  294. +#if LIBSSH2_RSA_SHA2
  295. static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_256 = {
  296. "rsa-sha2-256",
  297. @@ -419,6 +423,8 @@ static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa_sha2_512 = {
  298. hostkey_method_ssh_rsa_dtor,
  299. };
  300. +#endif /* LIBSSH2_RSA_SHA2 */
  301. +
  302. #endif /* LIBSSH2_RSA */
  303. #if LIBSSH2_DSA
  304. @@ -1202,8 +1208,10 @@ static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = {
  305. &hostkey_method_ssh_ed25519,
  306. #endif
  307. #if LIBSSH2_RSA
  308. +#if LIBSSH2_RSA_SHA2
  309. &hostkey_method_ssh_rsa_sha2_512,
  310. &hostkey_method_ssh_rsa_sha2_256,
  311. +#endif /* LIBSSH2_RSA_SHA2 */
  312. &hostkey_method_ssh_rsa,
  313. #endif /* LIBSSH2_RSA */
  314. #if LIBSSH2_DSA
  315. diff --git a/src/libgcrypt.h b/src/libgcrypt.h
  316. index 298c65ed0..95876b96d 100644
  317. --- a/src/libgcrypt.h
  318. +++ b/src/libgcrypt.h
  319. @@ -55,6 +55,7 @@
  320. #define LIBSSH2_3DES 1
  321. #define LIBSSH2_RSA 1
  322. +#define LIBSSH2_RSA_SHA2 0
  323. #define LIBSSH2_DSA 1
  324. #define LIBSSH2_ECDSA 0
  325. #define LIBSSH2_ED25519 0
  326. diff --git a/src/mbedtls.h b/src/mbedtls.h
  327. index 671932c58..0450113f0 100644
  328. --- a/src/mbedtls.h
  329. +++ b/src/mbedtls.h
  330. @@ -71,6 +71,7 @@
  331. #define LIBSSH2_3DES 1
  332. #define LIBSSH2_RSA 1
  333. +#define LIBSSH2_RSA_SHA2 0
  334. #define LIBSSH2_DSA 0
  335. #ifdef MBEDTLS_ECDSA_C
  336. # define LIBSSH2_ECDSA 1
  337. diff --git a/src/openssl.c b/src/openssl.c
  338. index 7a6810f13..8b5327d44 100644
  339. --- a/src/openssl.c
  340. +++ b/src/openssl.c
  341. @@ -154,21 +154,57 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
  342. }
  343. int
  344. -_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
  345. +_libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
  346. + size_t hash_len,
  347. const unsigned char *sig,
  348. unsigned long sig_len,
  349. const unsigned char *m, unsigned long m_len)
  350. {
  351. - unsigned char hash[SHA_DIGEST_LENGTH];
  352. int ret;
  353. + int nid_type;
  354. + unsigned char *hash = malloc(hash_len);
  355. + if (hash == NULL)
  356. + return -1;
  357. - if(_libssh2_sha1(m, m_len, hash))
  358. + if(hash_len == SHA_DIGEST_LENGTH) {
  359. + nid_type = NID_sha1;
  360. + ret = _libssh2_sha1(m, m_len, hash);
  361. + }
  362. + else if(hash_len == SHA256_DIGEST_LENGTH) {
  363. + nid_type = NID_sha256;
  364. + ret = _libssh2_sha256(m, m_len, hash);
  365. +
  366. + }
  367. + else if(hash_len == SHA512_DIGEST_LENGTH) {
  368. + nid_type = NID_sha512;
  369. + ret = _libssh2_sha512(m, m_len, hash);
  370. + }
  371. + else
  372. + ret = -1; /* unsupported digest */
  373. +
  374. + if(ret != 0)
  375. + {
  376. + free(hash);
  377. return -1; /* failure */
  378. - ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH,
  379. + }
  380. +
  381. + ret = RSA_verify(nid_type, hash, hash_len,
  382. (unsigned char *) sig, sig_len, rsactx);
  383. +
  384. + free(hash);
  385. +
  386. return (ret == 1) ? 0 : -1;
  387. }
  388. +int
  389. +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
  390. + const unsigned char *sig,
  391. + unsigned long sig_len,
  392. + const unsigned char *m, unsigned long m_len)
  393. +{
  394. + return _libssh2_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, sig, sig_len, m, m_len);
  395. +}
  396. +
  397. #if LIBSSH2_DSA
  398. int
  399. _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
  400. @@ -1876,7 +1912,7 @@ _libssh2_ed25519_new_public(libssh2_ed25519_ctx ** ed_ctx,
  401. int
  402. -_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
  403. +_libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
  404. libssh2_rsa_ctx * rsactx,
  405. const unsigned char *hash,
  406. size_t hash_len,
  407. @@ -1893,7 +1929,17 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
  408. return -1;
  409. }
  410. - ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
  411. + if(hash_len == SHA_DIGEST_LENGTH)
  412. + ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx);
  413. + else if(hash_len == SHA256_DIGEST_LENGTH)
  414. + ret = RSA_sign(NID_sha256, hash, hash_len, sig, &sig_len, rsactx);
  415. + else if(hash_len == SHA512_DIGEST_LENGTH)
  416. + ret = RSA_sign(NID_sha512, hash, hash_len, sig, &sig_len, rsactx);
  417. + else {
  418. + _libssh2_error(session, LIBSSH2_ERROR_PROTO,
  419. + "Unsupported hash digest length");
  420. + ret = -1;
  421. + }
  422. if(!ret) {
  423. LIBSSH2_FREE(session, sig);
  424. @@ -1906,6 +1952,19 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
  425. return 0;
  426. }
  427. +
  428. +int
  429. +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
  430. + libssh2_rsa_ctx * rsactx,
  431. + const unsigned char *hash,
  432. + size_t hash_len,
  433. + unsigned char **signature, size_t *signature_len)
  434. + {
  435. + return _libssh2_rsa_sha2_sign(session, rsactx, hash, hash_len,
  436. + signature, signature_len);
  437. + }
  438. +
  439. +
  440. #if LIBSSH2_DSA
  441. int
  442. _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
  443. @@ -3283,4 +3342,32 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
  444. *dhctx = NULL;
  445. }
  446. +#pragma mark PANIC
  447. +
  448. +int
  449. +_libssh2_cipher_crypt_buffer(_libssh2_cipher_ctx * ctx,
  450. + _libssh2_cipher_type(algo),
  451. + int encrypt, unsigned int seqno, unsigned char *buf,
  452. + size_t buf_len, unsigned char *out_buf, int blocksize)
  453. +{
  454. + int ret = 0;
  455. +
  456. + while (buf_len >= blocksize) {
  457. +
  458. +#ifdef HAVE_OPAQUE_STRUCTS
  459. + ret = EVP_Cipher(*ctx, out_buf, buf, blocksize);
  460. +#else
  461. + ret = EVP_Cipher(ctx, out_buf, buf, blocksize);
  462. +#endif
  463. +
  464. + buf_len -= blocksize; /* less bytes left */
  465. + out_buf += blocksize; /* advance write pointer */
  466. + buf += blocksize; /* advance read pointer */
  467. + }
  468. +
  469. + return ret == 1 ? 0 : 1;
  470. +}
  471. +
  472. +#pragma mark END PANIC
  473. +
  474. #endif /* LIBSSH2_OPENSSL */
  475. diff --git a/src/openssl.h b/src/openssl.h
  476. index 658b040d6..2a002b41e 100644
  477. --- a/src/openssl.h
  478. +++ b/src/openssl.h
  479. @@ -64,8 +64,10 @@
  480. #ifdef OPENSSL_NO_RSA
  481. # define LIBSSH2_RSA 0
  482. +# define LIBSSH2_RSA_SHA2 0
  483. #else
  484. # define LIBSSH2_RSA 1
  485. +# define LIBSSH2_RSA_SHA2 1
  486. #endif
  487. #ifdef OPENSSL_NO_DSA
  488. diff --git a/src/wincng.h b/src/wincng.h
  489. index eaf6f9051..538cc4314 100755
  490. --- a/src/wincng.h
  491. +++ b/src/wincng.h
  492. @@ -63,6 +63,7 @@
  493. #define LIBSSH2_3DES 1
  494. #define LIBSSH2_RSA 1
  495. +#define LIBSSH2_RSA_SHA2 0
  496. #define LIBSSH2_DSA 1
  497. #define LIBSSH2_ECDSA 0
  498. #define LIBSSH2_ED25519 0
  499. From 33e98c4595ea82efe2d796ebdb2bbaf4a63f4f04 Mon Sep 17 00:00:00 2001
  500. From: Will Cosgrove <will@everydaysoftware.net>
  501. Date: Mon, 30 Aug 2021 23:07:49 +0000
  502. Subject: [PATCH 03/16] Remove unnecessary code
  503. ---
  504. src/openssl.c | 28 ----------------------------
  505. 1 file changed, 28 deletions(-)
  506. diff --git a/src/openssl.c b/src/openssl.c
  507. index 8b5327d44..60f715ada 100644
  508. --- a/src/openssl.c
  509. +++ b/src/openssl.c
  510. @@ -3342,32 +3342,4 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
  511. *dhctx = NULL;
  512. }
  513. -#pragma mark PANIC
  514. -
  515. -int
  516. -_libssh2_cipher_crypt_buffer(_libssh2_cipher_ctx * ctx,
  517. - _libssh2_cipher_type(algo),
  518. - int encrypt, unsigned int seqno, unsigned char *buf,
  519. - size_t buf_len, unsigned char *out_buf, int blocksize)
  520. -{
  521. - int ret = 0;
  522. -
  523. - while (buf_len >= blocksize) {
  524. -
  525. -#ifdef HAVE_OPAQUE_STRUCTS
  526. - ret = EVP_Cipher(*ctx, out_buf, buf, blocksize);
  527. -#else
  528. - ret = EVP_Cipher(ctx, out_buf, buf, blocksize);
  529. -#endif
  530. -
  531. - buf_len -= blocksize; /* less bytes left */
  532. - out_buf += blocksize; /* advance write pointer */
  533. - buf += blocksize; /* advance read pointer */
  534. - }
  535. -
  536. - return ret == 1 ? 0 : 1;
  537. -}
  538. -
  539. -#pragma mark END PANIC
  540. -
  541. #endif /* LIBSSH2_OPENSSL */
  542. From f8db95b1d2502dd2729a1d3f14cee913ae7db962 Mon Sep 17 00:00:00 2001
  543. From: Will Cosgrove <will@everydaysoftware.net>
  544. Date: Thu, 2 Sep 2021 20:28:42 +0000
  545. Subject: [PATCH 04/16] formatting
  546. ---
  547. src/hostkey.c | 12 ++++++++----
  548. src/openssl.c | 16 ++++++++--------
  549. 2 files changed, 16 insertions(+), 12 deletions(-)
  550. diff --git a/src/hostkey.c b/src/hostkey.c
  551. index 8040a4ea1..5939ffc9e 100644
  552. --- a/src/hostkey.c
  553. +++ b/src/hostkey.c
  554. @@ -244,13 +244,15 @@ hostkey_method_ssh_rsa_sha2_256_sig_verify(LIBSSH2_SESSION * session,
  555. libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
  556. (void) session;
  557. - /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-256"} + signature_len(4) */
  558. + /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-256"} +
  559. + signature_len(4) */
  560. if(sig_len < 20)
  561. return -1;
  562. sig += 20;
  563. sig_len -= 20;
  564. - return _libssh2_rsa_sha2_verify(rsactx, SHA256_DIGEST_LENGTH, sig, sig_len, m, m_len);
  565. + return _libssh2_rsa_sha2_verify(rsactx, SHA256_DIGEST_LENGTH, sig, sig_len,
  566. + m, m_len);
  567. }
  568. /*
  569. @@ -310,13 +312,15 @@ hostkey_method_ssh_rsa_sha2_512_sig_verify(LIBSSH2_SESSION * session,
  570. libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract);
  571. (void) session;
  572. - /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-512"} + signature_len(4) */
  573. + /* Skip past keyname_len(4) + keyname(12){"rsa-sha2-512"} +
  574. + signature_len(4) */
  575. if(sig_len < 20)
  576. return -1;
  577. sig += 20;
  578. sig_len -= 20;
  579. - return _libssh2_rsa_sha2_verify(rsactx, SHA512_DIGEST_LENGTH, sig, sig_len, m, m_len);
  580. + return _libssh2_rsa_sha2_verify(rsactx, SHA512_DIGEST_LENGTH, sig,
  581. + sig_len, m, m_len);
  582. }
  583. diff --git a/src/openssl.c b/src/openssl.c
  584. index 60f715ada..537031e1d 100644
  585. --- a/src/openssl.c
  586. +++ b/src/openssl.c
  587. @@ -163,7 +163,7 @@ _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
  588. int ret;
  589. int nid_type;
  590. unsigned char *hash = malloc(hash_len);
  591. - if (hash == NULL)
  592. + if(hash == NULL)
  593. return -1;
  594. if(hash_len == SHA_DIGEST_LENGTH) {
  595. @@ -182,8 +182,7 @@ _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
  596. else
  597. ret = -1; /* unsupported digest */
  598. - if(ret != 0)
  599. - {
  600. + if(ret != 0) {
  601. free(hash);
  602. return -1; /* failure */
  603. }
  604. @@ -202,7 +201,8 @@ _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx,
  605. unsigned long sig_len,
  606. const unsigned char *m, unsigned long m_len)
  607. {
  608. - return _libssh2_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, sig, sig_len, m, m_len);
  609. + return _libssh2_rsa_sha2_verify(rsactx, SHA_DIGEST_LENGTH, sig, sig_len, m,
  610. + m_len);
  611. }
  612. #if LIBSSH2_DSA
  613. @@ -1959,10 +1959,10 @@ _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
  614. const unsigned char *hash,
  615. size_t hash_len,
  616. unsigned char **signature, size_t *signature_len)
  617. - {
  618. - return _libssh2_rsa_sha2_sign(session, rsactx, hash, hash_len,
  619. - signature, signature_len);
  620. - }
  621. +{
  622. + return _libssh2_rsa_sha2_sign(session, rsactx, hash, hash_len,
  623. + signature, signature_len);
  624. +}
  625. #if LIBSSH2_DSA
  626. From 428c54c9ce41de0cdd5cedf8bae1a808755bbe23 Mon Sep 17 00:00:00 2001
  627. From: Will Cosgrove <will@everydaysoftware.net>
  628. Date: Mon, 8 Nov 2021 19:32:37 +0000
  629. Subject: [PATCH 05/16] Client side key hash upgrading for RFC 8332
  630. ---
  631. docs/HACKING-CRYPTO | 11 +++
  632. docs/libssh2_session_methods.3 | 7 +-
  633. include/libssh2.h | 1 +
  634. src/crypto.h | 19 ++++
  635. src/kex.c | 10 ++
  636. src/libssh2_priv.h | 8 ++
  637. src/mbedtls.c | 15 +++
  638. src/openssl.c | 21 +++++
  639. src/packet.c | 69 ++++++++++++++
  640. src/userauth.c | 161 +++++++++++++++++++++++++++++++--
  641. src/wincng.c | 14 +++
  642. 12 files changed, 338 insertions(+), 12 deletions(-)
  643. diff --git a/docs/HACKING-CRYPTO b/docs/HACKING-CRYPTO
  644. index d0173553f..7352d193c 100644
  645. --- a/docs/HACKING-CRYPTO
  646. +++ b/docs/HACKING-CRYPTO
  647. @@ -926,3 +926,14 @@ If this is not needed, it should be defined as an empty macro.
  648. int _libssh2_random(unsigned char *buf, int len);
  649. Store len random bytes at buf.
  650. Returns 0 if OK, else -1.
  651. +
  652. +char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  653. + unsigned char *key_method,
  654. + size_t key_method_len);
  655. +
  656. +This function is for implementing key hash upgrading as defined in RFC 8332.
  657. +
  658. +Based on the incoming key_method value, this function will return a
  659. +list of supported algorithms that can upgrade the original key method algorithm
  660. +as a comma seperated list, if there is no upgrade option this function should
  661. +return NULL.
  662. diff --git a/docs/libssh2_session_methods.3 b/docs/libssh2_session_methods.3
  663. index cc4f6d49f..0e7f79fa9 100644
  664. --- a/docs/libssh2_session_methods.3
  665. +++ b/docs/libssh2_session_methods.3
  666. @@ -1,4 +1,4 @@
  667. -.TH libssh2_session_methods 3 "1 Jun 2007" "libssh2 0.15" "libssh2 manual"
  668. +.TH libssh2_session_methods 3 "8 Nov 2021" "libssh2 1.11" "libssh2 manual"
  669. .SH NAME
  670. libssh2_session_methods - return the currently active algorithms
  671. .SH SYNOPSIS
  672. @@ -8,13 +8,14 @@ const char *
  673. libssh2_session_methods(LIBSSH2_SESSION *session, int method_type);
  674. .SH DESCRIPTION
  675. -\fIsession\fP - Session instance as returned by
  676. +\fIsession\fP - Session instance as returned by
  677. .BR libssh2_session_init_ex(3)
  678. \fImethod_type\fP - one of the method type constants: LIBSSH2_METHOD_KEX,
  679. LIBSSH2_METHOD_HOSTKEY, LIBSSH2_METHOD_CRYPT_CS, LIBSSH2_METHOD_CRYPT_SC,
  680. LIBSSH2_METHOD_MAC_CS, LIBSSH2_METHOD_MAC_SC, LIBSSH2_METHOD_COMP_CS,
  681. -LIBSSH2_METHOD_COMP_SC, LIBSSH2_METHOD_LANG_CS, LIBSSH2_METHOD_LANG_SC.
  682. +LIBSSH2_METHOD_COMP_SC, LIBSSH2_METHOD_LANG_CS, LIBSSH2_METHOD_LANG_SC,
  683. +LIBSSH2_METHOD_SIGN_ALGO.
  684. Returns the actual method negotiated for a particular transport parameter.
  685. .SH RETURN VALUE
  686. diff --git a/include/libssh2.h b/include/libssh2.h
  687. index f17b502e0..7a2103c9e 100644
  688. --- a/include/libssh2.h
  689. +++ b/include/libssh2.h
  690. @@ -356,6 +356,7 @@ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE
  691. #define LIBSSH2_METHOD_COMP_SC 7
  692. #define LIBSSH2_METHOD_LANG_CS 8
  693. #define LIBSSH2_METHOD_LANG_SC 9
  694. +#define LIBSSH2_METHOD_SIGN_ALGO 10
  695. /* flags */
  696. #define LIBSSH2_FLAG_SIGPIPE 1
  697. diff --git a/src/crypto.h b/src/crypto.h
  698. index efaf15646..66e501791 100644
  699. --- a/src/crypto.h
  700. +++ b/src/crypto.h
  701. @@ -258,4 +258,23 @@ int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
  702. size_t privatekeydata_len,
  703. const char *passphrase);
  704. +
  705. +/**
  706. + * @function _libssh2_supported_key_sign_algorithms
  707. + * @abstract Returns supported algorithms used for upgrading public
  708. + * key signing RFC 8332
  709. + * @discussion Based on the incoming key_method value, this function
  710. + * will return supported algorithms that can upgrade the key method
  711. + * @related _libssh2_key_sign_algorithm()
  712. + * @param key_method current key method, usually the default key sig method
  713. + * @param key_method_len length of the key method buffer
  714. + * @result comma seperated list of supported upgrade options per RFC 8332, if
  715. + * there is no upgrade option return NULL
  716. + */
  717. +
  718. +char *
  719. +_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  720. + unsigned char *key_method,
  721. + size_t key_method_len);
  722. +
  723. #endif /* __LIBSSH2_CRYPTO_H */
  724. diff --git a/src/kex.c b/src/kex.c
  725. index 9f3ef7992..432a4f470 100644
  726. --- a/src/kex.c
  727. +++ b/src/kex.c
  728. @@ -3978,6 +3978,11 @@ libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type,
  729. mlist = NULL;
  730. break;
  731. + case LIBSSH2_METHOD_SIGN_ALGO:
  732. + prefvar = &session->sign_algo_prefs;
  733. + mlist = NULL;
  734. + break;
  735. +
  736. default:
  737. return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
  738. "Invalid parameter specified for method_type");
  739. @@ -4073,6 +4078,11 @@ LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session,
  740. _libssh2_comp_methods(session);
  741. break;
  742. + case LIBSSH2_METHOD_SIGN_ALGO:
  743. + /* no built-in supported list due to backend support */
  744. + mlist = NULL;
  745. + break;
  746. +
  747. default:
  748. return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
  749. "Unknown method type");
  750. diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
  751. index da488b744..aff791e7c 100644
  752. --- a/src/libssh2_priv.h
  753. +++ b/src/libssh2_priv.h
  754. @@ -640,6 +640,13 @@ struct _LIBSSH2_SESSION
  755. unsigned char server_hostkey_sha256[SHA256_DIGEST_LENGTH];
  756. int server_hostkey_sha256_valid;
  757. + /* public key algorithms accepted as comma separated list */
  758. + char *server_sign_algorithms;
  759. + size_t server_sign_algorithms_len;
  760. +
  761. + /* key signing algorithm preferences -- NULL yields server order */
  762. + char *sign_algo_prefs;
  763. +
  764. /* (remote as source of data -- packet_read ) */
  765. libssh2_endpoint_data remote;
  766. @@ -1006,6 +1013,7 @@ _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
  767. #define SSH_MSG_DEBUG 4
  768. #define SSH_MSG_SERVICE_REQUEST 5
  769. #define SSH_MSG_SERVICE_ACCEPT 6
  770. +#define SSH_MSG_EXT_INFO 7
  771. #define SSH_MSG_KEXINIT 20
  772. #define SSH_MSG_NEWKEYS 21
  773. diff --git a/src/mbedtls.c b/src/mbedtls.c
  774. index 4629ce4a9..4ae10acf4 100644
  775. --- a/src/mbedtls.c
  776. +++ b/src/mbedtls.c
  777. @@ -1247,5 +1247,20 @@ _libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx)
  778. mbedtls_free(ctx);
  779. }
  780. +
  781. +/* _libssh2_supported_key_sign_algorithms
  782. + *
  783. + * Return supported key hash algo upgrades, see crypto.h
  784. + *
  785. + */
  786. +
  787. +char *
  788. +_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  789. + unsigned char *key_method,
  790. + size_t key_method_len)
  791. +{
  792. + return NULL;
  793. +}
  794. +
  795. #endif /* LIBSSH2_ECDSA */
  796. #endif /* LIBSSH2_MBEDTLS */
  797. diff --git a/src/openssl.c b/src/openssl.c
  798. index 537031e1d..836470924 100644
  799. --- a/src/openssl.c
  800. +++ b/src/openssl.c
  801. @@ -3342,4 +3342,25 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
  802. *dhctx = NULL;
  803. }
  804. +/* _libssh2_supported_key_sign_algorithms
  805. + *
  806. + * Return supported key hash algo upgrades, see crypto.h
  807. + *
  808. + */
  809. +
  810. +char *
  811. +_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  812. + unsigned char *key_method,
  813. + size_t key_method_len)
  814. +{
  815. +#if LIBSSH2_RSA_SHA2
  816. + if (key_method_len == 7 && memcmp(key_method, "ssh-rsa", key_method_len) == 0)
  817. + {
  818. + return "rsa-sha2-512,rsa-sha2-256,ssh-rsa";
  819. + }
  820. +#endif
  821. +
  822. + return NULL;
  823. +}
  824. +
  825. #endif /* LIBSSH2_OPENSSL */
  826. diff --git a/src/packet.c b/src/packet.c
  827. index 04937d62a..7b24fb60c 100644
  828. --- a/src/packet.c
  829. +++ b/src/packet.c
  830. @@ -615,6 +615,75 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
  831. session->packAdd_state = libssh2_NB_state_idle;
  832. return 0;
  833. + /*
  834. + byte SSH_MSG_EXT_INFO
  835. + uint32 nr-extensions
  836. + [repeat "nr-extensions" times]
  837. + string extension-name [RFC8308]
  838. + string extension-value (binary)
  839. + */
  840. +
  841. + case SSH_MSG_EXT_INFO:
  842. + if(datalen >= 5) {
  843. + struct string_buf buf;
  844. + buf.data = (unsigned char *)data;
  845. + buf.dataptr = buf.data;
  846. + buf.len = datalen;
  847. + buf.dataptr += 1; /* advance past type */
  848. +
  849. + uint32_t nr_extensions = 0;
  850. + if(_libssh2_get_u32(&buf, &nr_extensions) != 0 ) {
  851. + rc = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
  852. + "Invalid extension info received");
  853. + }
  854. +
  855. + while(rc == 0 && nr_extensions > 0) {
  856. +
  857. + size_t name_len = 0;
  858. + size_t value_len = 0;
  859. + unsigned char *name = NULL;
  860. + unsigned char *value = NULL;
  861. +
  862. + nr_extensions -= 1;
  863. +
  864. + _libssh2_get_string(&buf, &name, &name_len);
  865. + _libssh2_get_string(&buf, &value, &value_len);
  866. +
  867. + if(name != NULL && value != NULL) {
  868. + _libssh2_debug(session,
  869. + LIBSSH2_TRACE_KEX,
  870. + "Server to Client extension %.*s: %.*s",
  871. + name_len, name, value_len, value);
  872. + }
  873. +
  874. + if(name_len == 15 &&
  875. + memcmp(name, "server-sig-algs", 15) == 0) {
  876. + if(session->server_sign_algorithms) {
  877. + LIBSSH2_FREE(session,
  878. + session->server_sign_algorithms);
  879. + }
  880. +
  881. + session->server_sign_algorithms =
  882. + LIBSSH2_ALLOC(session,
  883. + value_len);
  884. +
  885. + if(session->server_sign_algorithms) {
  886. + session->server_sign_algorithms_len = value_len;
  887. + memcpy(session->server_sign_algorithms,
  888. + value, value_len);
  889. + }
  890. + else {
  891. + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
  892. + "memory for server sign algo");
  893. + }
  894. + }
  895. + }
  896. + }
  897. +
  898. + LIBSSH2_FREE(session, data);
  899. + session->packAdd_state = libssh2_NB_state_idle;
  900. + return rc;
  901. +
  902. /*
  903. byte SSH_MSG_GLOBAL_REQUEST
  904. string request name in US-ASCII only
  905. diff --git a/src/userauth.c b/src/userauth.c
  906. index 40ef9153a..86dd95e87 100644
  907. --- a/src/userauth.c
  908. +++ b/src/userauth.c
  909. @@ -1086,6 +1086,150 @@ static int plain_method_len(const char *method, size_t method_len)
  910. return method_len;
  911. }
  912. +/**
  913. + * @function _libssh2_key_sign_algorithm
  914. + * @abstract Upgrades the algorithm used for public key signing RFC 8332
  915. + * @discussion Based on the incoming key_method value, this function
  916. + * will upgrade the key method input based on user preferences,
  917. + * server support algos and crypto backend support
  918. + * @related _libssh2_supported_key_sign_algorithms()
  919. + * @param key_method current key method, usually the default key sig method
  920. + * @param key_method_len length of the key method buffer
  921. + * @result error code or zero on success
  922. + */
  923. +
  924. +static int
  925. +_libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  926. + unsigned char **key_method,
  927. + size_t *key_method_len)
  928. +{
  929. + char *s = NULL;
  930. + char *p = NULL;
  931. + char *f = NULL;
  932. + char *a = NULL;
  933. + char *i = NULL;
  934. + int p_len = 0;
  935. + int f_len = 0;
  936. + int rc = 0;
  937. + char *match = NULL;
  938. + int match_len = 0;
  939. +
  940. + char *supported_algs =
  941. + _libssh2_supported_key_sign_algorithms(session,
  942. + *key_method,
  943. + *key_method_len);
  944. +
  945. + if(supported_algs == NULL || session->server_sign_algorithms == NULL) {
  946. + /* no upgrading key algorithm supported, do nothing */
  947. + return LIBSSH2_ERROR_NONE;
  948. + }
  949. +
  950. + char *filtered_algs = LIBSSH2_ALLOC(session, strlen(supported_algs) + 1);
  951. + if(!filtered_algs) {
  952. + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
  953. + "Unable to allocate filtered algs");
  954. + return rc;
  955. + }
  956. +
  957. + s = session->server_sign_algorithms;
  958. + i = filtered_algs;
  959. +
  960. + /* this walks the server algo list and the supported algo list and creates
  961. + a filtered list that includes matches */
  962. +
  963. + while(s && *s) {
  964. + p = strchr(s, ',');
  965. + p_len = p ? (p - s) : (int) strlen(s);
  966. + a = supported_algs;
  967. +
  968. + while(a && *a) {
  969. + f = strchr(a, ',');
  970. + f_len = f ? (f - a) : (int) strlen(a);
  971. +
  972. + if(memmem(a, f_len, s, p_len)) {
  973. +
  974. + if(i != filtered_algs) {
  975. + memcpy(i, ",", 1);
  976. + i += 1;
  977. + }
  978. +
  979. + memcpy(i, s, p_len);
  980. + i += p_len;
  981. + }
  982. +
  983. + a = f ? (f + 1) : NULL;
  984. + }
  985. +
  986. + s = p ? (p + 1) : NULL;
  987. + }
  988. +
  989. + filtered_algs[i - filtered_algs] = '\0';
  990. +
  991. + if(session->sign_algo_prefs) {
  992. + s = session->sign_algo_prefs;
  993. + }
  994. + else {
  995. + s = supported_algs;
  996. + }
  997. +
  998. + /* now that we have the possible supported algos, match based on the prefs
  999. + or what is supported by the crypto backend, look for a match */
  1000. +
  1001. + while(s && *s && !match) {
  1002. + p = strchr(s, ',');
  1003. + p_len = p ? (p - s) : (int) strlen(s);
  1004. + a = filtered_algs;
  1005. +
  1006. + while(a && *a && !match) {
  1007. + f = strchr(a, ',');
  1008. + f_len = f ? (f - a) : (int) strlen(a);
  1009. +
  1010. + if(memmem(a, f_len, s, p_len)) {
  1011. +
  1012. + //found a match, upgrade key method
  1013. + match = s;
  1014. + match_len = p_len;
  1015. + }
  1016. + else {
  1017. + a = f ? (f + 1) : NULL;
  1018. + }
  1019. + }
  1020. +
  1021. + s = p ? (p + 1) : NULL;
  1022. + }
  1023. +
  1024. + if(match != NULL)
  1025. + {
  1026. + if(*key_method)
  1027. + LIBSSH2_FREE(session, *key_method);
  1028. +
  1029. + *key_method = LIBSSH2_ALLOC(session, match_len);
  1030. + if(key_method)
  1031. + {
  1032. + memcpy(*key_method, match, match_len);
  1033. + *key_method_len = match_len;
  1034. +
  1035. + _libssh2_debug(session, LIBSSH2_TRACE_KEX,
  1036. + "Signing using %.*s", match_len, match);
  1037. + }
  1038. + else {
  1039. + *key_method_len = 0;
  1040. + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
  1041. + "Unable to allocate key method upgrade");
  1042. + }
  1043. + }
  1044. + else {
  1045. + /* no match was found */
  1046. + rc = _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
  1047. + "No signing signature matched");
  1048. + }
  1049. +
  1050. + if(filtered_algs)
  1051. + LIBSSH2_FREE(session, filtered_algs);
  1052. +
  1053. + return rc;
  1054. +}
  1055. +
  1056. int
  1057. _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
  1058. const char *username,
  1059. @@ -1144,15 +1288,14 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
  1060. memcpy(session->userauth_pblc_method, pubkeydata + 4,
  1061. session->userauth_pblc_method_len);
  1062. }
  1063. - /*
  1064. - * The length of the method name read from plaintext prefix in the
  1065. - * file must match length embedded in the key.
  1066. - * TODO: The data should match too but we don't check that. Should we?
  1067. - */
  1068. - else if(session->userauth_pblc_method_len !=
  1069. - _libssh2_ntohu32(pubkeydata))
  1070. - return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED,
  1071. - "Invalid public key");
  1072. +
  1073. + /* upgrade key key signing algo needed */
  1074. + rc = _libssh2_key_sign_algorithm(session,
  1075. + &session->userauth_pblc_method,
  1076. + &session->userauth_pblc_method_len);
  1077. +
  1078. + if(rc)
  1079. + return rc;
  1080. /*
  1081. * 45 = packet_type(1) + username_len(4) + servicename_len(4) +
  1082. diff --git a/src/wincng.c b/src/wincng.c
  1083. index cbb2b61cb..08fbc76eb 100644
  1084. --- a/src/wincng.c
  1085. +++ b/src/wincng.c
  1086. @@ -2590,4 +2590,18 @@ _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
  1087. return _libssh2_wincng_bignum_mod_exp(secret, f, dhctx->bn, p);
  1088. }
  1089. +/* _libssh2_supported_key_sign_algorithms
  1090. + *
  1091. + * Return supported key hash algo upgrades, see crypto.h
  1092. + *
  1093. + */
  1094. +
  1095. +char *
  1096. +_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1097. + unsigned char *key_method,
  1098. + size_t key_method_len)
  1099. +{
  1100. + return NULL;
  1101. +}
  1102. +
  1103. #endif /* LIBSSH2_WINCNG */
  1104. From 6427e9fe4d0d4c460b9e77f48f6f55a49ef82413 Mon Sep 17 00:00:00 2001
  1105. From: Will Cosgrove <will@everydaysoftware.net>
  1106. Date: Mon, 8 Nov 2021 19:40:33 +0000
  1107. Subject: [PATCH 06/16] style points
  1108. ---
  1109. src/openssl.c | 4 ++--
  1110. src/packet.c | 2 +-
  1111. src/userauth.c | 9 +++------
  1112. 3 files changed, 6 insertions(+), 9 deletions(-)
  1113. diff --git a/src/openssl.c b/src/openssl.c
  1114. index 836470924..175b170e9 100644
  1115. --- a/src/openssl.c
  1116. +++ b/src/openssl.c
  1117. @@ -3354,8 +3354,8 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1118. size_t key_method_len)
  1119. {
  1120. #if LIBSSH2_RSA_SHA2
  1121. - if (key_method_len == 7 && memcmp(key_method, "ssh-rsa", key_method_len) == 0)
  1122. - {
  1123. + if(key_method_len == 7 &&
  1124. + memcmp(key_method, "ssh-rsa", key_method_len) == 0) {
  1125. return "rsa-sha2-512,rsa-sha2-256,ssh-rsa";
  1126. }
  1127. #endif
  1128. diff --git a/src/packet.c b/src/packet.c
  1129. index 7b24fb60c..a42515846 100644
  1130. --- a/src/packet.c
  1131. +++ b/src/packet.c
  1132. @@ -632,7 +632,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
  1133. buf.dataptr += 1; /* advance past type */
  1134. uint32_t nr_extensions = 0;
  1135. - if(_libssh2_get_u32(&buf, &nr_extensions) != 0 ) {
  1136. + if(_libssh2_get_u32(&buf, &nr_extensions) != 0) {
  1137. rc = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
  1138. "Invalid extension info received");
  1139. }
  1140. diff --git a/src/userauth.c b/src/userauth.c
  1141. index 86dd95e87..395cf34ab 100644
  1142. --- a/src/userauth.c
  1143. +++ b/src/userauth.c
  1144. @@ -1185,8 +1185,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1145. f_len = f ? (f - a) : (int) strlen(a);
  1146. if(memmem(a, f_len, s, p_len)) {
  1147. -
  1148. - //found a match, upgrade key method
  1149. + /* found a match, upgrade key method */
  1150. match = s;
  1151. match_len = p_len;
  1152. }
  1153. @@ -1198,14 +1197,12 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1154. s = p ? (p + 1) : NULL;
  1155. }
  1156. - if(match != NULL)
  1157. - {
  1158. + if(match != NULL) {
  1159. if(*key_method)
  1160. LIBSSH2_FREE(session, *key_method);
  1161. *key_method = LIBSSH2_ALLOC(session, match_len);
  1162. - if(key_method)
  1163. - {
  1164. + if(key_method) {
  1165. memcpy(*key_method, match, match_len);
  1166. *key_method_len = match_len;
  1167. From 26c3ce1f00146d979ae350d58e4bb7a1bc3f44d9 Mon Sep 17 00:00:00 2001
  1168. From: Will Cosgrove <will@everydaysoftware.net>
  1169. Date: Mon, 8 Nov 2021 19:47:52 +0000
  1170. Subject: [PATCH 07/16] =?UTF-8?q?don=E2=80=99t=20use=20memmem?=
  1171. MIME-Version: 1.0
  1172. Content-Type: text/plain; charset=UTF-8
  1173. Content-Transfer-Encoding: 8bit
  1174. ---
  1175. src/userauth.c | 4 ++--
  1176. 1 file changed, 2 insertions(+), 2 deletions(-)
  1177. diff --git a/src/userauth.c b/src/userauth.c
  1178. index 395cf34ab..fa9e7ca8f 100644
  1179. --- a/src/userauth.c
  1180. +++ b/src/userauth.c
  1181. @@ -1146,7 +1146,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1182. f = strchr(a, ',');
  1183. f_len = f ? (f - a) : (int) strlen(a);
  1184. - if(memmem(a, f_len, s, p_len)) {
  1185. + if(f_len == p_len && memcmp(a, s, p_len)) {
  1186. if(i != filtered_algs) {
  1187. memcpy(i, ",", 1);
  1188. @@ -1184,7 +1184,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1189. f = strchr(a, ',');
  1190. f_len = f ? (f - a) : (int) strlen(a);
  1191. - if(memmem(a, f_len, s, p_len)) {
  1192. + if(f_len == p_len && memcmp(a, s, p_len)) {
  1193. /* found a match, upgrade key method */
  1194. match = s;
  1195. match_len = p_len;
  1196. From 3841799a9b145be6d1eba29266b1f8301839543f Mon Sep 17 00:00:00 2001
  1197. From: Will Cosgrove <will@everydaysoftware.net>
  1198. Date: Mon, 8 Nov 2021 19:51:25 +0000
  1199. Subject: [PATCH 08/16] more ci building fixes
  1200. ---
  1201. src/libgcrypt.c | 14 ++++++++++++++
  1202. src/packet.c | 2 +-
  1203. 2 files changed, 15 insertions(+), 1 deletion(-)
  1204. diff --git a/src/libgcrypt.c b/src/libgcrypt.c
  1205. index 0aff176a6..fba5c9dc6 100644
  1206. --- a/src/libgcrypt.c
  1207. +++ b/src/libgcrypt.c
  1208. @@ -664,4 +664,18 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
  1209. *dhctx = NULL;
  1210. }
  1211. +/* _libssh2_supported_key_sign_algorithms
  1212. + *
  1213. + * Return supported key hash algo upgrades, see crypto.h
  1214. + *
  1215. + */
  1216. +
  1217. +char *
  1218. +_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1219. + unsigned char *key_method,
  1220. + size_t key_method_len)
  1221. +{
  1222. + return NULL;
  1223. +}
  1224. +
  1225. #endif /* LIBSSH2_LIBGCRYPT */
  1226. diff --git a/src/packet.c b/src/packet.c
  1227. index a42515846..686be5cc7 100644
  1228. --- a/src/packet.c
  1229. +++ b/src/packet.c
  1230. @@ -625,13 +625,13 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
  1231. case SSH_MSG_EXT_INFO:
  1232. if(datalen >= 5) {
  1233. + uint32_t nr_extensions = 0;
  1234. struct string_buf buf;
  1235. buf.data = (unsigned char *)data;
  1236. buf.dataptr = buf.data;
  1237. buf.len = datalen;
  1238. buf.dataptr += 1; /* advance past type */
  1239. - uint32_t nr_extensions = 0;
  1240. if(_libssh2_get_u32(&buf, &nr_extensions) != 0) {
  1241. rc = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
  1242. "Invalid extension info received");
  1243. From 9267a1afa4d3a6468a141d357aee742c937d10ff Mon Sep 17 00:00:00 2001
  1244. From: Will Cosgrove <will@everydaysoftware.net>
  1245. Date: Mon, 8 Nov 2021 19:56:37 +0000
  1246. Subject: [PATCH 09/16] CI fixes
  1247. ---
  1248. src/libgcrypt.c | 4 ++++
  1249. src/mbedtls.c | 4 ++++
  1250. src/openssl.c | 2 ++
  1251. src/wincng.c | 4 ++++
  1252. 5 files changed, 18 insertions(+)
  1253. diff --git a/src/libgcrypt.c b/src/libgcrypt.c
  1254. index fba5c9dc6..97541aa8a 100644
  1255. --- a/src/libgcrypt.c
  1256. +++ b/src/libgcrypt.c
  1257. @@ -675,6 +675,10 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1258. unsigned char *key_method,
  1259. size_t key_method_len)
  1260. {
  1261. + (void)session;
  1262. + (void)key_method;
  1263. + (void)key_method_len;
  1264. +
  1265. return NULL;
  1266. }
  1267. diff --git a/src/mbedtls.c b/src/mbedtls.c
  1268. index 4ae10acf4..658533ea8 100644
  1269. --- a/src/mbedtls.c
  1270. +++ b/src/mbedtls.c
  1271. @@ -1259,6 +1259,10 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1272. unsigned char *key_method,
  1273. size_t key_method_len)
  1274. {
  1275. + (void)session;
  1276. + (void)key_method;
  1277. + (void)key_method_len;
  1278. +
  1279. return NULL;
  1280. }
  1281. diff --git a/src/openssl.c b/src/openssl.c
  1282. index 175b170e9..b667059c0 100644
  1283. --- a/src/openssl.c
  1284. +++ b/src/openssl.c
  1285. @@ -3353,6 +3353,8 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1286. unsigned char *key_method,
  1287. size_t key_method_len)
  1288. {
  1289. + (void)session;
  1290. +
  1291. #if LIBSSH2_RSA_SHA2
  1292. if(key_method_len == 7 &&
  1293. memcmp(key_method, "ssh-rsa", key_method_len) == 0) {
  1294. diff --git a/src/wincng.c b/src/wincng.c
  1295. index 08fbc76eb..e4151ec88 100644
  1296. --- a/src/wincng.c
  1297. +++ b/src/wincng.c
  1298. @@ -2601,6 +2601,10 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1299. unsigned char *key_method,
  1300. size_t key_method_len)
  1301. {
  1302. + (void)session;
  1303. + (void)key_method;
  1304. + (void)key_method_len;
  1305. +
  1306. return NULL;
  1307. }
  1308. From 4ec7ca7d827369e02f0d258eebb09c87eadc3434 Mon Sep 17 00:00:00 2001
  1309. From: Will Cosgrove <will@everydaysoftware.net>
  1310. Date: Mon, 8 Nov 2021 20:03:35 +0000
  1311. Subject: [PATCH 10/16] made _libssh2_supported_key_sign_algorithms() const
  1312. ---
  1313. src/crypto.h | 2 +-
  1314. src/libgcrypt.c | 2 +-
  1315. src/mbedtls.c | 2 +-
  1316. src/openssl.c | 2 +-
  1317. src/userauth.c | 12 ++++++------
  1318. src/wincng.c | 2 +-
  1319. 7 files changed, 12 insertions(+), 12 deletions(-)
  1320. diff --git a/src/crypto.h b/src/crypto.h
  1321. index 66e501791..809aef7e9 100644
  1322. --- a/src/crypto.h
  1323. +++ b/src/crypto.h
  1324. @@ -272,7 +272,7 @@ int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
  1325. * there is no upgrade option return NULL
  1326. */
  1327. -char *
  1328. +const char *
  1329. _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1330. unsigned char *key_method,
  1331. size_t key_method_len);
  1332. diff --git a/src/libgcrypt.c b/src/libgcrypt.c
  1333. index 97541aa8a..f6e9b64a3 100644
  1334. --- a/src/libgcrypt.c
  1335. +++ b/src/libgcrypt.c
  1336. @@ -670,7 +670,7 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
  1337. *
  1338. */
  1339. -char *
  1340. +const char *
  1341. _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1342. unsigned char *key_method,
  1343. size_t key_method_len)
  1344. diff --git a/src/mbedtls.c b/src/mbedtls.c
  1345. index 658533ea8..dc76ef59a 100644
  1346. --- a/src/mbedtls.c
  1347. +++ b/src/mbedtls.c
  1348. @@ -1254,7 +1254,7 @@ _libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx)
  1349. *
  1350. */
  1351. -char *
  1352. +const char *
  1353. _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1354. unsigned char *key_method,
  1355. size_t key_method_len)
  1356. diff --git a/src/openssl.c b/src/openssl.c
  1357. index b667059c0..72a85b3b6 100644
  1358. --- a/src/openssl.c
  1359. +++ b/src/openssl.c
  1360. @@ -3348,7 +3348,7 @@ _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
  1361. *
  1362. */
  1363. -char *
  1364. +const char *
  1365. _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1366. unsigned char *key_method,
  1367. size_t key_method_len)
  1368. diff --git a/src/userauth.c b/src/userauth.c
  1369. index fa9e7ca8f..8a5adf690 100644
  1370. --- a/src/userauth.c
  1371. +++ b/src/userauth.c
  1372. @@ -1103,18 +1103,18 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1373. unsigned char **key_method,
  1374. size_t *key_method_len)
  1375. {
  1376. - char *s = NULL;
  1377. - char *p = NULL;
  1378. - char *f = NULL;
  1379. - char *a = NULL;
  1380. + const char *s = NULL;
  1381. + const char *a = NULL;
  1382. + const char *match = NULL;
  1383. + const char *p = NULL;
  1384. + const char *f = NULL;
  1385. char *i = NULL;
  1386. int p_len = 0;
  1387. int f_len = 0;
  1388. int rc = 0;
  1389. - char *match = NULL;
  1390. int match_len = 0;
  1391. - char *supported_algs =
  1392. + const char *supported_algs =
  1393. _libssh2_supported_key_sign_algorithms(session,
  1394. *key_method,
  1395. *key_method_len);
  1396. diff --git a/src/wincng.c b/src/wincng.c
  1397. index e4151ec88..654f50db0 100644
  1398. --- a/src/wincng.c
  1399. +++ b/src/wincng.c
  1400. @@ -2596,7 +2596,7 @@ _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
  1401. *
  1402. */
  1403. -char *
  1404. +const char *
  1405. _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1406. unsigned char *key_method,
  1407. size_t key_method_len)
  1408. From 2cee98cb8379a883b62d1be3f4bde31509689ab6 Mon Sep 17 00:00:00 2001
  1409. From: Will Cosgrove <will@everydaysoftware.net>
  1410. Date: Mon, 8 Nov 2021 20:09:38 +0000
  1411. Subject: [PATCH 11/16] ci build warning
  1412. ---
  1413. src/userauth.c | 3 ++-
  1414. 1 file changed, 2 insertions(+), 1 deletion(-)
  1415. diff --git a/src/userauth.c b/src/userauth.c
  1416. index 8a5adf690..d56c5eb17 100644
  1417. --- a/src/userauth.c
  1418. +++ b/src/userauth.c
  1419. @@ -1113,6 +1113,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1420. int f_len = 0;
  1421. int rc = 0;
  1422. int match_len = 0;
  1423. + char *filtered_algs = NULL;
  1424. const char *supported_algs =
  1425. _libssh2_supported_key_sign_algorithms(session,
  1426. @@ -1124,7 +1125,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1427. return LIBSSH2_ERROR_NONE;
  1428. }
  1429. - char *filtered_algs = LIBSSH2_ALLOC(session, strlen(supported_algs) + 1);
  1430. + filtered_algs = LIBSSH2_ALLOC(session, strlen(supported_algs) + 1);
  1431. if(!filtered_algs) {
  1432. rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
  1433. "Unable to allocate filtered algs");
  1434. From 10beabd2e29ea74c621380bb3d2ddb31fccff67f Mon Sep 17 00:00:00 2001
  1435. From: Will Cosgrove <will@everydaysoftware.net>
  1436. Date: Mon, 8 Nov 2021 20:46:38 +0000
  1437. Subject: [PATCH 12/16] updated docs
  1438. ---
  1439. docs/HACKING-CRYPTO | 6 +++---
  1440. 1 file changed, 3 insertions(+), 3 deletions(-)
  1441. diff --git a/docs/HACKING-CRYPTO b/docs/HACKING-CRYPTO
  1442. index 7352d193c..85d813aa6 100644
  1443. --- a/docs/HACKING-CRYPTO
  1444. +++ b/docs/HACKING-CRYPTO
  1445. @@ -927,9 +927,9 @@ int _libssh2_random(unsigned char *buf, int len);
  1446. Store len random bytes at buf.
  1447. Returns 0 if OK, else -1.
  1448. -char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1449. - unsigned char *key_method,
  1450. - size_t key_method_len);
  1451. +const char * _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
  1452. + unsigned char *key_method,
  1453. + size_t key_method_len);
  1454. This function is for implementing key hash upgrading as defined in RFC 8332.
  1455. From 9d1a3a5189ef2531978695aeee8a1322ab984cf3 Mon Sep 17 00:00:00 2001
  1456. From: Will Cosgrove <will@everydaysoftware.net>
  1457. Date: Tue, 9 Nov 2021 16:33:12 +0000
  1458. Subject: [PATCH 13/16] Added missing ext-info-c to commit
  1459. ---
  1460. src/kex.c | 12 ++++++++++++
  1461. 1 file changed, 12 insertions(+)
  1462. diff --git a/src/kex.c b/src/kex.c
  1463. index 432a4f470..f45d48a2b 100644
  1464. --- a/src/kex.c
  1465. +++ b/src/kex.c
  1466. @@ -3026,6 +3026,17 @@ kex_method_ssh_curve25519_sha256 = {
  1467. };
  1468. #endif
  1469. +/* this kex method signals that client can receive extensions
  1470. + * as described in https://datatracker.ietf.org/doc/html/rfc8308
  1471. +*/
  1472. +
  1473. +static const LIBSSH2_KEX_METHOD
  1474. +kex_method_extension_negotiation = {
  1475. + "ext-info-c",
  1476. + NULL,
  1477. + 0,
  1478. +};
  1479. +
  1480. static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
  1481. #if LIBSSH2_ED25519
  1482. &kex_method_ssh_curve25519_sha256,
  1483. @@ -3043,6 +3054,7 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
  1484. &kex_method_diffie_helman_group14_sha1,
  1485. &kex_method_diffie_helman_group1_sha1,
  1486. &kex_method_diffie_helman_group_exchange_sha1,
  1487. + &kex_method_extension_negotiation,
  1488. NULL
  1489. };
  1490. From 7e5b537a01a623f97f651378d6f09b3d76107eca Mon Sep 17 00:00:00 2001
  1491. From: Will Cosgrove <will@everydaysoftware.net>
  1492. Date: Tue, 30 Nov 2021 10:07:43 -0800
  1493. Subject: [PATCH 14/16] added rsa-sha2-256/512 rsa key init support
  1494. ---
  1495. src/hostkey.c | 22 +++++++++++++++++++---
  1496. 1 file changed, 19 insertions(+), 3 deletions(-)
  1497. diff --git a/src/hostkey.c b/src/hostkey.c
  1498. index 5939ffc9e..3874eaafa 100644
  1499. --- a/src/hostkey.c
  1500. +++ b/src/hostkey.c
  1501. @@ -64,8 +64,8 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
  1502. void **abstract)
  1503. {
  1504. libssh2_rsa_ctx *rsactx;
  1505. - unsigned char *e, *n;
  1506. - size_t e_len, n_len;
  1507. + unsigned char *e, *n, *type;
  1508. + size_t e_len, n_len, type_len;
  1509. struct string_buf buf;
  1510. if(*abstract) {
  1511. @@ -83,8 +83,24 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
  1512. buf.dataptr = buf.data;
  1513. buf.len = hostkey_data_len;
  1514. - if(_libssh2_match_string(&buf, "ssh-rsa"))
  1515. + if(_libssh2_get_string(&buf, &type, &type_len)) {
  1516. return -1;
  1517. + }
  1518. +
  1519. + // we accept one of 3 header types
  1520. + if(type_len == 7 && strncmp("ssh-rsa", (char*)type, 7) == 0) {
  1521. + }
  1522. +#if LIBSSH2_RSA_SHA2
  1523. + else if(type_len == 12 && strncmp("rsa-sha2-256", (char*)type, 12) == 0) {
  1524. + }
  1525. + else if(type_len == 12 && strncmp("rsa-sha2-512", (char*)type, 12) == 0) {
  1526. + }
  1527. +#endif
  1528. + else {
  1529. + _libssh2_debug(session, LIBSSH2_TRACE_ERROR,
  1530. + "unexpected rsa type: %.*s", type_len, type);
  1531. + return -1;
  1532. + }
  1533. if(_libssh2_get_string(&buf, &e, &e_len))
  1534. return -1;
  1535. From 2b48eaf41701ddd4f5056eea7f135434abfdcc2f Mon Sep 17 00:00:00 2001
  1536. From: Will Cosgrove <will@everydaysoftware.net>
  1537. Date: Tue, 30 Nov 2021 10:09:46 -0800
  1538. Subject: [PATCH 15/16] formatting
  1539. ---
  1540. src/hostkey.c | 8 ++++----
  1541. 1 file changed, 4 insertions(+), 4 deletions(-)
  1542. diff --git a/src/hostkey.c b/src/hostkey.c
  1543. index 3874eaafa..7d1ef2f2e 100644
  1544. --- a/src/hostkey.c
  1545. +++ b/src/hostkey.c
  1546. @@ -87,13 +87,13 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
  1547. return -1;
  1548. }
  1549. - // we accept one of 3 header types
  1550. - if(type_len == 7 && strncmp("ssh-rsa", (char*)type, 7) == 0) {
  1551. + /* we accept one of 3 header types */
  1552. + if(type_len == 7 && strncmp("ssh-rsa", (char *)type, 7) == 0) {
  1553. }
  1554. #if LIBSSH2_RSA_SHA2
  1555. - else if(type_len == 12 && strncmp("rsa-sha2-256", (char*)type, 12) == 0) {
  1556. + else if(type_len == 12 && strncmp("rsa-sha2-256", (char *)type, 12) == 0) {
  1557. }
  1558. - else if(type_len == 12 && strncmp("rsa-sha2-512", (char*)type, 12) == 0) {
  1559. + else if(type_len == 12 && strncmp("rsa-sha2-512", (char *)type, 12) == 0) {
  1560. }
  1561. #endif
  1562. else {
  1563. From d007d4d4a2a98ed0eedf9c4ee57ff6ee45532673 Mon Sep 17 00:00:00 2001
  1564. From: Will Cosgrove <will@everydaysoftware.net>
  1565. Date: Tue, 30 Nov 2021 10:17:12 -0800
  1566. Subject: [PATCH 16/16] making style checker happy, maybe
  1567. ---
  1568. src/hostkey.c | 3 +++
  1569. 1 file changed, 3 insertions(+)
  1570. diff --git a/src/hostkey.c b/src/hostkey.c
  1571. index 7d1ef2f2e..eeb9e579e 100644
  1572. --- a/src/hostkey.c
  1573. +++ b/src/hostkey.c
  1574. @@ -89,11 +89,14 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
  1575. /* we accept one of 3 header types */
  1576. if(type_len == 7 && strncmp("ssh-rsa", (char *)type, 7) == 0) {
  1577. + /* ssh-rsa */
  1578. }
  1579. #if LIBSSH2_RSA_SHA2
  1580. else if(type_len == 12 && strncmp("rsa-sha2-256", (char *)type, 12) == 0) {
  1581. + /* rsa-sha2-256 */
  1582. }
  1583. else if(type_len == 12 && strncmp("rsa-sha2-512", (char *)type, 12) == 0) {
  1584. + /* rsa-sha2-512 */
  1585. }
  1586. #endif
  1587. else {
  1588. From af077e2ce706f4a7c5f821f79d185b8908a060a7 Mon Sep 17 00:00:00 2001
  1589. From: Michael Buckley <michael@buckleyisms.com>
  1590. Date: Thu, 6 Jan 2022 12:58:05 -0800
  1591. Subject: [PATCH] Fix a couple memcmp errors in code that was changed from
  1592. memmem to memcmp
  1593. ---
  1594. src/userauth.c | 4 ++--
  1595. 1 file changed, 2 insertions(+), 2 deletions(-)
  1596. diff --git a/src/userauth.c b/src/userauth.c
  1597. index 988dc17ff..29f58bab9 100644
  1598. --- a/src/userauth.c
  1599. +++ b/src/userauth.c
  1600. @@ -1147,7 +1147,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1601. f = strchr(a, ',');
  1602. f_len = f ? (f - a) : (int) strlen(a);
  1603. - if(f_len == p_len && memcmp(a, s, p_len)) {
  1604. + if(f_len == p_len && memcmp(a, s, p_len) == 0) {
  1605. if(i != filtered_algs) {
  1606. memcpy(i, ",", 1);
  1607. @@ -1185,7 +1185,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
  1608. f = strchr(a, ',');
  1609. f_len = f ? (f - a) : (int) strlen(a);
  1610. - if(f_len == p_len && memcmp(a, s, p_len)) {
  1611. + if(f_len == p_len && memcmp(a, s, p_len) == 0) {
  1612. /* found a match, upgrade key method */
  1613. match = s;
  1614. match_len = p_len;