import.c 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701
  1. /*
  2. * Code for PuTTY to import and export private key files in other
  3. * SSH clients' formats.
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <assert.h>
  8. #include <ctype.h>
  9. #include "putty.h"
  10. #include "ssh.h"
  11. #include "misc.h"
  12. int openssh_pem_encrypted(const Filename *filename);
  13. int openssh_new_encrypted(const Filename *filename);
  14. struct ssh2_userkey *openssh_pem_read(const Filename *filename,
  15. char *passphrase,
  16. const char **errmsg_p);
  17. struct ssh2_userkey *openssh_new_read(const Filename *filename,
  18. char *passphrase,
  19. const char **errmsg_p);
  20. int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
  21. char *passphrase);
  22. int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
  23. char *passphrase);
  24. int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
  25. char *passphrase);
  26. int sshcom_encrypted(const Filename *filename, char **comment);
  27. struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
  28. const char **errmsg_p);
  29. int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
  30. char *passphrase);
  31. /*
  32. * Given a key type, determine whether we know how to import it.
  33. */
  34. int import_possible(int type)
  35. {
  36. if (type == SSH_KEYTYPE_OPENSSH_PEM)
  37. return 1;
  38. if (type == SSH_KEYTYPE_OPENSSH_NEW)
  39. return 1;
  40. if (type == SSH_KEYTYPE_SSHCOM)
  41. return 1;
  42. return 0;
  43. }
  44. /*
  45. * Given a key type, determine what native key type
  46. * (SSH_KEYTYPE_SSH1 or SSH_KEYTYPE_SSH2) it will come out as once
  47. * we've imported it.
  48. */
  49. int import_target_type(int type)
  50. {
  51. /*
  52. * There are no known foreign SSH-1 key formats.
  53. */
  54. return SSH_KEYTYPE_SSH2;
  55. }
  56. /*
  57. * Determine whether a foreign key is encrypted.
  58. */
  59. int import_encrypted(const Filename *filename, int type, char **comment)
  60. {
  61. if (type == SSH_KEYTYPE_OPENSSH_PEM) {
  62. /* OpenSSH PEM format doesn't contain a key comment at all */
  63. *comment = dupstr(filename_to_str(filename));
  64. return openssh_pem_encrypted(filename);
  65. } else if (type == SSH_KEYTYPE_OPENSSH_NEW) {
  66. /* OpenSSH new format does, but it's inside the encrypted
  67. * section for some reason */
  68. *comment = dupstr(filename_to_str(filename));
  69. return openssh_new_encrypted(filename);
  70. } else if (type == SSH_KEYTYPE_SSHCOM) {
  71. return sshcom_encrypted(filename, comment);
  72. }
  73. return 0;
  74. }
  75. /*
  76. * Import an SSH-1 key.
  77. */
  78. int import_ssh1(const Filename *filename, int type,
  79. struct RSAKey *key, char *passphrase, const char **errmsg_p)
  80. {
  81. return 0;
  82. }
  83. /*
  84. * Import an SSH-2 key.
  85. */
  86. struct ssh2_userkey *import_ssh2(const Filename *filename, int type,
  87. char *passphrase, const char **errmsg_p)
  88. {
  89. if (type == SSH_KEYTYPE_OPENSSH_PEM)
  90. return openssh_pem_read(filename, passphrase, errmsg_p);
  91. else if (type == SSH_KEYTYPE_OPENSSH_NEW)
  92. return openssh_new_read(filename, passphrase, errmsg_p);
  93. if (type == SSH_KEYTYPE_SSHCOM)
  94. return sshcom_read(filename, passphrase, errmsg_p);
  95. return NULL;
  96. }
  97. /*
  98. * Export an SSH-1 key.
  99. */
  100. int export_ssh1(const Filename *filename, int type, struct RSAKey *key,
  101. char *passphrase)
  102. {
  103. return 0;
  104. }
  105. /*
  106. * Export an SSH-2 key.
  107. */
  108. int export_ssh2(const Filename *filename, int type,
  109. struct ssh2_userkey *key, char *passphrase)
  110. {
  111. if (type == SSH_KEYTYPE_OPENSSH_AUTO)
  112. return openssh_auto_write(filename, key, passphrase);
  113. if (type == SSH_KEYTYPE_OPENSSH_NEW)
  114. return openssh_new_write(filename, key, passphrase);
  115. if (type == SSH_KEYTYPE_SSHCOM)
  116. return sshcom_write(filename, key, passphrase);
  117. return 0;
  118. }
  119. /*
  120. * Strip trailing CRs and LFs at the end of a line of text.
  121. */
  122. void strip_crlf(char *str)
  123. {
  124. char *p = str + strlen(str);
  125. while (p > str && (p[-1] == '\r' || p[-1] == '\n'))
  126. *--p = '\0';
  127. }
  128. /* ----------------------------------------------------------------------
  129. * Helper routines. (The base64 ones are defined in sshpubk.c.)
  130. */
  131. #define isbase64(c) ( ((c) >= 'A' && (c) <= 'Z') || \
  132. ((c) >= 'a' && (c) <= 'z') || \
  133. ((c) >= '0' && (c) <= '9') || \
  134. (c) == '+' || (c) == '/' || (c) == '=' \
  135. )
  136. /*
  137. * Read an ASN.1/BER identifier and length pair.
  138. *
  139. * Flags are a combination of the #defines listed below.
  140. *
  141. * Returns -1 if unsuccessful; otherwise returns the number of
  142. * bytes used out of the source data.
  143. */
  144. /* ASN.1 tag classes. */
  145. #define ASN1_CLASS_UNIVERSAL (0 << 6)
  146. #define ASN1_CLASS_APPLICATION (1 << 6)
  147. #define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6)
  148. #define ASN1_CLASS_PRIVATE (3 << 6)
  149. #define ASN1_CLASS_MASK (3 << 6)
  150. /* Primitive versus constructed bit. */
  151. #define ASN1_CONSTRUCTED (1 << 5)
  152. static int ber_read_id_len(void *source, int sourcelen,
  153. int *id, int *length, int *flags)
  154. {
  155. unsigned char *p = (unsigned char *) source;
  156. if (sourcelen == 0)
  157. return -1;
  158. *flags = (*p & 0xE0);
  159. if ((*p & 0x1F) == 0x1F) {
  160. *id = 0;
  161. while (*p & 0x80) {
  162. p++, sourcelen--;
  163. if (sourcelen == 0)
  164. return -1;
  165. *id = (*id << 7) | (*p & 0x7F);
  166. }
  167. p++, sourcelen--;
  168. } else {
  169. *id = *p & 0x1F;
  170. p++, sourcelen--;
  171. }
  172. if (sourcelen == 0)
  173. return -1;
  174. if (*p & 0x80) {
  175. unsigned len;
  176. int n = *p & 0x7F;
  177. p++, sourcelen--;
  178. if (sourcelen < n)
  179. return -1;
  180. len = 0;
  181. while (n--)
  182. len = (len << 8) | (*p++);
  183. sourcelen -= n;
  184. *length = toint(len);
  185. } else {
  186. *length = *p;
  187. p++, sourcelen--;
  188. }
  189. return p - (unsigned char *) source;
  190. }
  191. /*
  192. * Write an ASN.1/BER identifier and length pair. Returns the
  193. * number of bytes consumed. Assumes dest contains enough space.
  194. * Will avoid writing anything if dest is NULL, but still return
  195. * amount of space required.
  196. */
  197. static int ber_write_id_len(void *dest, int id, int length, int flags)
  198. {
  199. unsigned char *d = (unsigned char *)dest;
  200. int len = 0;
  201. if (id <= 30) {
  202. /*
  203. * Identifier is one byte.
  204. */
  205. len++;
  206. if (d) *d++ = id | flags;
  207. } else {
  208. int n;
  209. /*
  210. * Identifier is multiple bytes: the first byte is 11111
  211. * plus the flags, and subsequent bytes encode the value of
  212. * the identifier, 7 bits at a time, with the top bit of
  213. * each byte 1 except the last one which is 0.
  214. */
  215. len++;
  216. if (d) *d++ = 0x1F | flags;
  217. for (n = 1; (id >> (7*n)) > 0; n++)
  218. continue; /* count the bytes */
  219. while (n--) {
  220. len++;
  221. if (d) *d++ = (n ? 0x80 : 0) | ((id >> (7*n)) & 0x7F);
  222. }
  223. }
  224. if (length < 128) {
  225. /*
  226. * Length is one byte.
  227. */
  228. len++;
  229. if (d) *d++ = length;
  230. } else {
  231. int n;
  232. /*
  233. * Length is multiple bytes. The first is 0x80 plus the
  234. * number of subsequent bytes, and the subsequent bytes
  235. * encode the actual length.
  236. */
  237. for (n = 1; (length >> (8*n)) > 0; n++)
  238. continue; /* count the bytes */
  239. len++;
  240. if (d) *d++ = 0x80 | n;
  241. while (n--) {
  242. len++;
  243. if (d) *d++ = (length >> (8*n)) & 0xFF;
  244. }
  245. }
  246. return len;
  247. }
  248. static int put_uint32(void *target, unsigned val)
  249. {
  250. unsigned char *d = (unsigned char *)target;
  251. PUT_32BIT(d, val);
  252. return 4;
  253. }
  254. static int put_string(void *target, const void *data, int len)
  255. {
  256. unsigned char *d = (unsigned char *)target;
  257. PUT_32BIT(d, len);
  258. memcpy(d+4, data, len);
  259. return len+4;
  260. }
  261. static int put_string_z(void *target, const char *string)
  262. {
  263. return put_string(target, string, strlen(string));
  264. }
  265. static int put_mp(void *target, void *data, int len)
  266. {
  267. unsigned char *d = (unsigned char *)target;
  268. unsigned char *i = (unsigned char *)data;
  269. if (*i & 0x80) {
  270. PUT_32BIT(d, len+1);
  271. d[4] = 0;
  272. memcpy(d+5, data, len);
  273. return len+5;
  274. } else {
  275. PUT_32BIT(d, len);
  276. memcpy(d+4, data, len);
  277. return len+4;
  278. }
  279. }
  280. /* Simple structure to point to an mp-int within a blob. */
  281. struct mpint_pos { void *start; int bytes; };
  282. static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
  283. {
  284. int bytes;
  285. unsigned char *d = (unsigned char *) data;
  286. if (len < 4)
  287. goto error;
  288. bytes = toint(GET_32BIT(d));
  289. if (bytes < 0 || len-4 < bytes)
  290. goto error;
  291. ret->start = d + 4;
  292. ret->bytes = bytes;
  293. return bytes+4;
  294. error:
  295. ret->start = NULL;
  296. ret->bytes = -1;
  297. return len; /* ensure further calls fail as well */
  298. }
  299. /* ----------------------------------------------------------------------
  300. * Code to read and write OpenSSH private keys, in the old-style PEM
  301. * format.
  302. */
  303. typedef enum {
  304. OP_DSA, OP_RSA, OP_ECDSA
  305. } openssh_pem_keytype;
  306. typedef enum {
  307. OP_E_3DES, OP_E_AES
  308. } openssh_pem_enc;
  309. struct openssh_pem_key {
  310. openssh_pem_keytype keytype;
  311. int encrypted;
  312. openssh_pem_enc encryption;
  313. char iv[32];
  314. unsigned char *keyblob;
  315. int keyblob_len, keyblob_size;
  316. };
  317. static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename,
  318. const char **errmsg_p)
  319. {
  320. struct openssh_pem_key *ret;
  321. FILE *fp = NULL;
  322. char *line = NULL;
  323. const char *errmsg;
  324. char *p;
  325. int headers_done;
  326. char base64_bit[4];
  327. int base64_chars = 0;
  328. ret = snew(struct openssh_pem_key);
  329. ret->keyblob = NULL;
  330. ret->keyblob_len = ret->keyblob_size = 0;
  331. fp = f_open(filename, "r", FALSE);
  332. if (!fp) {
  333. errmsg = "unable to open key file";
  334. goto error;
  335. }
  336. if (!(line = fgetline(fp))) {
  337. errmsg = "unexpected end of file";
  338. goto error;
  339. }
  340. strip_crlf(line);
  341. if (!strstartswith(line, "-----BEGIN ") ||
  342. !strendswith(line, "PRIVATE KEY-----")) {
  343. errmsg = "file does not begin with OpenSSH key header";
  344. goto error;
  345. }
  346. /*
  347. * Parse the BEGIN line. For old-format keys, this tells us the
  348. * type of the key; for new-format keys, all it tells us is the
  349. * format, and we'll find out the key type once we parse the
  350. * base64.
  351. */
  352. if (!strcmp(line, "-----BEGIN RSA PRIVATE KEY-----")) {
  353. ret->keytype = OP_RSA;
  354. } else if (!strcmp(line, "-----BEGIN DSA PRIVATE KEY-----")) {
  355. ret->keytype = OP_DSA;
  356. } else if (!strcmp(line, "-----BEGIN EC PRIVATE KEY-----")) {
  357. ret->keytype = OP_ECDSA;
  358. } else if (!strcmp(line, "-----BEGIN OPENSSH PRIVATE KEY-----")) {
  359. errmsg = "this is a new-style OpenSSH key";
  360. goto error;
  361. } else {
  362. errmsg = "unrecognised key type";
  363. goto error;
  364. }
  365. smemclr(line, strlen(line));
  366. sfree(line);
  367. line = NULL;
  368. ret->encrypted = FALSE;
  369. memset(ret->iv, 0, sizeof(ret->iv));
  370. headers_done = 0;
  371. while (1) {
  372. if (!(line = fgetline(fp))) {
  373. errmsg = "unexpected end of file";
  374. goto error;
  375. }
  376. strip_crlf(line);
  377. if (strstartswith(line, "-----END ") &&
  378. strendswith(line, "PRIVATE KEY-----")) {
  379. sfree(line);
  380. line = NULL;
  381. break; /* done */
  382. }
  383. if ((p = strchr(line, ':')) != NULL) {
  384. if (headers_done) {
  385. errmsg = "header found in body of key data";
  386. goto error;
  387. }
  388. *p++ = '\0';
  389. while (*p && isspace((unsigned char)*p)) p++;
  390. if (!strcmp(line, "Proc-Type")) {
  391. if (p[0] != '4' || p[1] != ',') {
  392. errmsg = "Proc-Type is not 4 (only 4 is supported)";
  393. goto error;
  394. }
  395. p += 2;
  396. if (!strcmp(p, "ENCRYPTED"))
  397. ret->encrypted = TRUE;
  398. } else if (!strcmp(line, "DEK-Info")) {
  399. int i, j, ivlen;
  400. if (!strncmp(p, "DES-EDE3-CBC,", 13)) {
  401. ret->encryption = OP_E_3DES;
  402. ivlen = 8;
  403. } else if (!strncmp(p, "AES-128-CBC,", 12)) {
  404. ret->encryption = OP_E_AES;
  405. ivlen = 16;
  406. } else {
  407. errmsg = "unsupported cipher";
  408. goto error;
  409. }
  410. p = strchr(p, ',') + 1;/* always non-NULL, by above checks */
  411. for (i = 0; i < ivlen; i++) {
  412. if (1 != sscanf(p, "%2x", &j)) {
  413. errmsg = "expected more iv data in DEK-Info";
  414. goto error;
  415. }
  416. ret->iv[i] = j;
  417. p += 2;
  418. }
  419. if (*p) {
  420. errmsg = "more iv data than expected in DEK-Info";
  421. goto error;
  422. }
  423. }
  424. } else {
  425. headers_done = 1;
  426. p = line;
  427. while (isbase64(*p)) {
  428. base64_bit[base64_chars++] = *p;
  429. if (base64_chars == 4) {
  430. unsigned char out[3];
  431. int len;
  432. base64_chars = 0;
  433. len = base64_decode_atom(base64_bit, out);
  434. if (len <= 0) {
  435. errmsg = "invalid base64 encoding";
  436. goto error;
  437. }
  438. if (ret->keyblob_len + len > ret->keyblob_size) {
  439. ret->keyblob_size = ret->keyblob_len + len + 256;
  440. ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
  441. unsigned char);
  442. }
  443. memcpy(ret->keyblob + ret->keyblob_len, out, len);
  444. ret->keyblob_len += len;
  445. smemclr(out, sizeof(out));
  446. }
  447. p++;
  448. }
  449. }
  450. smemclr(line, strlen(line));
  451. sfree(line);
  452. line = NULL;
  453. }
  454. fclose(fp);
  455. fp = NULL;
  456. if (ret->keyblob_len == 0 || !ret->keyblob) {
  457. errmsg = "key body not present";
  458. goto error;
  459. }
  460. if (ret->encrypted && ret->keyblob_len % 8 != 0) {
  461. errmsg = "encrypted key blob is not a multiple of "
  462. "cipher block size";
  463. goto error;
  464. }
  465. smemclr(base64_bit, sizeof(base64_bit));
  466. if (errmsg_p) *errmsg_p = NULL;
  467. return ret;
  468. error:
  469. if (line) {
  470. smemclr(line, strlen(line));
  471. sfree(line);
  472. line = NULL;
  473. }
  474. smemclr(base64_bit, sizeof(base64_bit));
  475. if (ret) {
  476. if (ret->keyblob) {
  477. smemclr(ret->keyblob, ret->keyblob_size);
  478. sfree(ret->keyblob);
  479. }
  480. smemclr(ret, sizeof(*ret));
  481. sfree(ret);
  482. }
  483. if (errmsg_p) *errmsg_p = errmsg;
  484. if (fp) fclose(fp);
  485. return NULL;
  486. }
  487. int openssh_pem_encrypted(const Filename *filename)
  488. {
  489. struct openssh_pem_key *key = load_openssh_pem_key(filename, NULL);
  490. int ret;
  491. if (!key)
  492. return 0;
  493. ret = key->encrypted;
  494. smemclr(key->keyblob, key->keyblob_size);
  495. sfree(key->keyblob);
  496. smemclr(key, sizeof(*key));
  497. sfree(key);
  498. return ret;
  499. }
  500. struct ssh2_userkey *openssh_pem_read(const Filename *filename,
  501. char *passphrase,
  502. const char **errmsg_p)
  503. {
  504. struct openssh_pem_key *key = load_openssh_pem_key(filename, errmsg_p);
  505. struct ssh2_userkey *retkey;
  506. unsigned char *p, *q;
  507. int ret, id, len, flags;
  508. int i, num_integers;
  509. struct ssh2_userkey *retval = NULL;
  510. const char *errmsg;
  511. unsigned char *blob;
  512. int blobsize = 0, blobptr, privptr;
  513. char *modptr = NULL;
  514. int modlen = 0;
  515. blob = NULL;
  516. if (!key)
  517. return NULL;
  518. if (key->encrypted) {
  519. /*
  520. * Derive encryption key from passphrase and iv/salt:
  521. *
  522. * - let block A equal MD5(passphrase || iv)
  523. * - let block B equal MD5(A || passphrase || iv)
  524. * - block C would be MD5(B || passphrase || iv) and so on
  525. * - encryption key is the first N bytes of A || B
  526. *
  527. * (Note that only 8 bytes of the iv are used for key
  528. * derivation, even when the key is encrypted with AES and
  529. * hence there are 16 bytes available.)
  530. */
  531. struct MD5Context md5c;
  532. unsigned char keybuf[32];
  533. MD5Init(&md5c);
  534. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  535. MD5Update(&md5c, (unsigned char *)key->iv, 8);
  536. MD5Final(keybuf, &md5c);
  537. MD5Init(&md5c);
  538. MD5Update(&md5c, keybuf, 16);
  539. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  540. MD5Update(&md5c, (unsigned char *)key->iv, 8);
  541. MD5Final(keybuf+16, &md5c);
  542. /*
  543. * Now decrypt the key blob.
  544. */
  545. if (key->encryption == OP_E_3DES)
  546. des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,
  547. key->keyblob, key->keyblob_len);
  548. else {
  549. void *ctx;
  550. assert(key->encryption == OP_E_AES);
  551. ctx = aes_make_context();
  552. aes128_key(ctx, keybuf);
  553. aes_iv(ctx, (unsigned char *)key->iv);
  554. aes_ssh2_decrypt_blk(ctx, key->keyblob, key->keyblob_len);
  555. aes_free_context(ctx);
  556. }
  557. smemclr(&md5c, sizeof(md5c));
  558. smemclr(keybuf, sizeof(keybuf));
  559. }
  560. /*
  561. * Now we have a decrypted key blob, which contains an ASN.1
  562. * encoded private key. We must now untangle the ASN.1.
  563. *
  564. * We expect the whole key blob to be formatted as a SEQUENCE
  565. * (0x30 followed by a length code indicating that the rest of
  566. * the blob is part of the sequence). Within that SEQUENCE we
  567. * expect to see a bunch of INTEGERs. What those integers mean
  568. * depends on the key type:
  569. *
  570. * - For RSA, we expect the integers to be 0, n, e, d, p, q,
  571. * dmp1, dmq1, iqmp in that order. (The last three are d mod
  572. * (p-1), d mod (q-1), inverse of q mod p respectively.)
  573. *
  574. * - For DSA, we expect them to be 0, p, q, g, y, x in that
  575. * order.
  576. *
  577. * - In ECDSA the format is totally different: we see the
  578. * SEQUENCE, but beneath is an INTEGER 1, OCTET STRING priv
  579. * EXPLICIT [0] OID curve, EXPLICIT [1] BIT STRING pubPoint
  580. */
  581. p = key->keyblob;
  582. /* Expect the SEQUENCE header. Take its absence as a failure to
  583. * decrypt, if the key was encrypted. */
  584. ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
  585. p += ret;
  586. if (ret < 0 || id != 16 || len < 0 ||
  587. key->keyblob+key->keyblob_len-p < len) {
  588. errmsg = "ASN.1 decoding failure";
  589. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  590. goto error;
  591. }
  592. /* Expect a load of INTEGERs. */
  593. if (key->keytype == OP_RSA)
  594. num_integers = 9;
  595. else if (key->keytype == OP_DSA)
  596. num_integers = 6;
  597. else
  598. num_integers = 0; /* placate compiler warnings */
  599. if (key->keytype == OP_ECDSA) {
  600. /* And now for something completely different */
  601. unsigned char *priv;
  602. int privlen;
  603. const struct ssh_signkey *alg;
  604. const struct ec_curve *curve;
  605. int algnamelen, curvenamelen;
  606. /* Read INTEGER 1 */
  607. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  608. &id, &len, &flags);
  609. p += ret;
  610. if (ret < 0 || id != 2 || len != 1 ||
  611. key->keyblob+key->keyblob_len-p < len || p[0] != 1) {
  612. errmsg = "ASN.1 decoding failure";
  613. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  614. goto error;
  615. }
  616. p += 1;
  617. /* Read private key OCTET STRING */
  618. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  619. &id, &len, &flags);
  620. p += ret;
  621. if (ret < 0 || id != 4 || len < 0 ||
  622. key->keyblob+key->keyblob_len-p < len) {
  623. errmsg = "ASN.1 decoding failure";
  624. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  625. goto error;
  626. }
  627. priv = p;
  628. privlen = len;
  629. p += len;
  630. /* Read curve OID */
  631. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  632. &id, &len, &flags);
  633. p += ret;
  634. if (ret < 0 || id != 0 || len < 0 ||
  635. key->keyblob+key->keyblob_len-p < len) {
  636. errmsg = "ASN.1 decoding failure";
  637. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  638. goto error;
  639. }
  640. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  641. &id, &len, &flags);
  642. p += ret;
  643. if (ret < 0 || id != 6 || len < 0 ||
  644. key->keyblob+key->keyblob_len-p < len) {
  645. errmsg = "ASN.1 decoding failure";
  646. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  647. goto error;
  648. }
  649. alg = ec_alg_by_oid(len, p, &curve);
  650. if (!alg) {
  651. errmsg = "Unsupported ECDSA curve.";
  652. retval = NULL;
  653. goto error;
  654. }
  655. p += len;
  656. /* Read BIT STRING point */
  657. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  658. &id, &len, &flags);
  659. p += ret;
  660. if (ret < 0 || id != 1 || len < 0 ||
  661. key->keyblob+key->keyblob_len-p < len) {
  662. errmsg = "ASN.1 decoding failure";
  663. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  664. goto error;
  665. }
  666. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  667. &id, &len, &flags);
  668. p += ret;
  669. if (ret < 0 || id != 3 || len < 0 ||
  670. key->keyblob+key->keyblob_len-p < len ||
  671. len != ((((curve->fieldBits + 7) / 8) * 2) + 2)) {
  672. errmsg = "ASN.1 decoding failure";
  673. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  674. goto error;
  675. }
  676. p += 1; len -= 1; /* Skip 0x00 before point */
  677. /* Construct the key */
  678. retkey = snew(struct ssh2_userkey);
  679. if (!retkey) {
  680. errmsg = "out of memory";
  681. goto error;
  682. }
  683. retkey->alg = alg;
  684. blob = snewn((4+19 + 4+8 + 4+len) + (4+1+privlen), unsigned char);
  685. if (!blob) {
  686. sfree(retkey);
  687. errmsg = "out of memory";
  688. goto error;
  689. }
  690. q = blob;
  691. algnamelen = strlen(alg->name);
  692. PUT_32BIT(q, algnamelen); q += 4;
  693. memcpy(q, alg->name, algnamelen); q += algnamelen;
  694. curvenamelen = strlen(curve->name);
  695. PUT_32BIT(q, curvenamelen); q += 4;
  696. memcpy(q, curve->name, curvenamelen); q += curvenamelen;
  697. PUT_32BIT(q, len); q += 4;
  698. memcpy(q, p, len); q += len;
  699. /*
  700. * To be acceptable to our createkey(), the private blob must
  701. * contain a valid mpint, i.e. without the top bit set. But
  702. * the input private string may have the top bit set, so we
  703. * prefix a zero byte to ensure createkey() doesn't fail for
  704. * that reason.
  705. */
  706. PUT_32BIT(q, privlen+1);
  707. q[4] = 0;
  708. memcpy(q+5, priv, privlen);
  709. retkey->data = retkey->alg->createkey(retkey->alg,
  710. blob, q-blob,
  711. q, 5+privlen);
  712. if (!retkey->data) {
  713. sfree(retkey);
  714. errmsg = "unable to create key data structure";
  715. goto error;
  716. }
  717. } else if (key->keytype == OP_RSA || key->keytype == OP_DSA) {
  718. /*
  719. * Space to create key blob in.
  720. */
  721. blobsize = 256+key->keyblob_len;
  722. blob = snewn(blobsize, unsigned char);
  723. PUT_32BIT(blob, 7);
  724. if (key->keytype == OP_DSA)
  725. memcpy(blob+4, "ssh-dss", 7);
  726. else if (key->keytype == OP_RSA)
  727. memcpy(blob+4, "ssh-rsa", 7);
  728. blobptr = 4+7;
  729. privptr = -1;
  730. for (i = 0; i < num_integers; i++) {
  731. ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
  732. &id, &len, &flags);
  733. p += ret;
  734. if (ret < 0 || id != 2 || len < 0 ||
  735. key->keyblob+key->keyblob_len-p < len) {
  736. errmsg = "ASN.1 decoding failure";
  737. retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL;
  738. goto error;
  739. }
  740. if (i == 0) {
  741. /*
  742. * The first integer should be zero always (I think
  743. * this is some sort of version indication).
  744. */
  745. if (len != 1 || p[0] != 0) {
  746. errmsg = "version number mismatch";
  747. goto error;
  748. }
  749. } else if (key->keytype == OP_RSA) {
  750. /*
  751. * Integers 1 and 2 go into the public blob but in the
  752. * opposite order; integers 3, 4, 5 and 8 go into the
  753. * private blob. The other two (6 and 7) are ignored.
  754. */
  755. if (i == 1) {
  756. /* Save the details for after we deal with number 2. */
  757. modptr = (char *)p;
  758. modlen = len;
  759. } else if (i != 6 && i != 7) {
  760. PUT_32BIT(blob+blobptr, len);
  761. memcpy(blob+blobptr+4, p, len);
  762. blobptr += 4+len;
  763. if (i == 2) {
  764. PUT_32BIT(blob+blobptr, modlen);
  765. memcpy(blob+blobptr+4, modptr, modlen);
  766. blobptr += 4+modlen;
  767. privptr = blobptr;
  768. }
  769. }
  770. } else if (key->keytype == OP_DSA) {
  771. /*
  772. * Integers 1-4 go into the public blob; integer 5 goes
  773. * into the private blob.
  774. */
  775. PUT_32BIT(blob+blobptr, len);
  776. memcpy(blob+blobptr+4, p, len);
  777. blobptr += 4+len;
  778. if (i == 4)
  779. privptr = blobptr;
  780. }
  781. /* Skip past the number. */
  782. p += len;
  783. }
  784. /*
  785. * Now put together the actual key. Simplest way to do this is
  786. * to assemble our own key blobs and feed them to the createkey
  787. * functions; this is a bit faffy but it does mean we get all
  788. * the sanity checks for free.
  789. */
  790. assert(privptr > 0); /* should have bombed by now if not */
  791. retkey = snew(struct ssh2_userkey);
  792. retkey->alg = (key->keytype == OP_RSA ? &ssh_rsa : &ssh_dss);
  793. retkey->data = retkey->alg->createkey(retkey->alg, blob, privptr,
  794. blob+privptr,
  795. blobptr-privptr);
  796. if (!retkey->data) {
  797. sfree(retkey);
  798. errmsg = "unable to create key data structure";
  799. goto error;
  800. }
  801. } else {
  802. assert(0 && "Bad key type from load_openssh_pem_key");
  803. errmsg = "Bad key type from load_openssh_pem_key";
  804. goto error;
  805. }
  806. /*
  807. * The old key format doesn't include a comment in the private
  808. * key file.
  809. */
  810. retkey->comment = dupstr("imported-openssh-key");
  811. errmsg = NULL; /* no error */
  812. retval = retkey;
  813. error:
  814. if (blob) {
  815. smemclr(blob, blobsize);
  816. sfree(blob);
  817. }
  818. smemclr(key->keyblob, key->keyblob_size);
  819. sfree(key->keyblob);
  820. smemclr(key, sizeof(*key));
  821. sfree(key);
  822. if (errmsg_p) *errmsg_p = errmsg;
  823. return retval;
  824. }
  825. int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
  826. char *passphrase)
  827. {
  828. unsigned char *pubblob, *privblob, *spareblob;
  829. int publen, privlen, sparelen = 0;
  830. unsigned char *outblob;
  831. int outlen;
  832. struct mpint_pos numbers[9];
  833. int nnumbers, pos, len, seqlen, i;
  834. const char *header, *footer;
  835. char zero[1];
  836. unsigned char iv[8];
  837. int ret = 0;
  838. FILE *fp;
  839. /*
  840. * Fetch the key blobs.
  841. */
  842. pubblob = key->alg->public_blob(key->data, &publen);
  843. privblob = key->alg->private_blob(key->data, &privlen);
  844. spareblob = outblob = NULL;
  845. outblob = NULL;
  846. len = 0;
  847. /*
  848. * Encode the OpenSSH key blob, and also decide on the header
  849. * line.
  850. */
  851. if (key->alg == &ssh_rsa || key->alg == &ssh_dss) {
  852. /*
  853. * The RSA and DSS handlers share some code because the two
  854. * key types have very similar ASN.1 representations, as a
  855. * plain SEQUENCE of big integers. So we set up a list of
  856. * bignums per key type and then construct the actual blob in
  857. * common code after that.
  858. */
  859. if (key->alg == &ssh_rsa) {
  860. int pos;
  861. struct mpint_pos n, e, d, p, q, iqmp, dmp1, dmq1;
  862. Bignum bd, bp, bq, bdmp1, bdmq1;
  863. /*
  864. * These blobs were generated from inside PuTTY, so we needn't
  865. * treat them as untrusted.
  866. */
  867. pos = 4 + GET_32BIT(pubblob);
  868. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
  869. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
  870. pos = 0;
  871. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
  872. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
  873. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
  874. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
  875. assert(e.start && iqmp.start); /* can't go wrong */
  876. /* We also need d mod (p-1) and d mod (q-1). */
  877. bd = bignum_from_bytes(d.start, d.bytes);
  878. bp = bignum_from_bytes(p.start, p.bytes);
  879. bq = bignum_from_bytes(q.start, q.bytes);
  880. decbn(bp);
  881. decbn(bq);
  882. bdmp1 = bigmod(bd, bp);
  883. bdmq1 = bigmod(bd, bq);
  884. freebn(bd);
  885. freebn(bp);
  886. freebn(bq);
  887. dmp1.bytes = (bignum_bitcount(bdmp1)+8)/8;
  888. dmq1.bytes = (bignum_bitcount(bdmq1)+8)/8;
  889. sparelen = dmp1.bytes + dmq1.bytes;
  890. spareblob = snewn(sparelen, unsigned char);
  891. dmp1.start = spareblob;
  892. dmq1.start = spareblob + dmp1.bytes;
  893. for (i = 0; i < dmp1.bytes; i++)
  894. spareblob[i] = bignum_byte(bdmp1, dmp1.bytes-1 - i);
  895. for (i = 0; i < dmq1.bytes; i++)
  896. spareblob[i+dmp1.bytes] = bignum_byte(bdmq1, dmq1.bytes-1 - i);
  897. freebn(bdmp1);
  898. freebn(bdmq1);
  899. numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0';
  900. numbers[1] = n;
  901. numbers[2] = e;
  902. numbers[3] = d;
  903. numbers[4] = p;
  904. numbers[5] = q;
  905. numbers[6] = dmp1;
  906. numbers[7] = dmq1;
  907. numbers[8] = iqmp;
  908. nnumbers = 9;
  909. header = "-----BEGIN RSA PRIVATE KEY-----\n";
  910. footer = "-----END RSA PRIVATE KEY-----\n";
  911. } else { /* ssh-dss */
  912. int pos;
  913. struct mpint_pos p, q, g, y, x;
  914. /*
  915. * These blobs were generated from inside PuTTY, so we needn't
  916. * treat them as untrusted.
  917. */
  918. pos = 4 + GET_32BIT(pubblob);
  919. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
  920. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
  921. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
  922. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
  923. pos = 0;
  924. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
  925. assert(y.start && x.start); /* can't go wrong */
  926. numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0';
  927. numbers[1] = p;
  928. numbers[2] = q;
  929. numbers[3] = g;
  930. numbers[4] = y;
  931. numbers[5] = x;
  932. nnumbers = 6;
  933. header = "-----BEGIN DSA PRIVATE KEY-----\n";
  934. footer = "-----END DSA PRIVATE KEY-----\n";
  935. }
  936. /*
  937. * Now count up the total size of the ASN.1 encoded integers,
  938. * so as to determine the length of the containing SEQUENCE.
  939. */
  940. len = 0;
  941. for (i = 0; i < nnumbers; i++) {
  942. len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0);
  943. len += numbers[i].bytes;
  944. }
  945. seqlen = len;
  946. /* Now add on the SEQUENCE header. */
  947. len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED);
  948. /*
  949. * Now we know how big outblob needs to be. Allocate it.
  950. */
  951. outblob = snewn(len, unsigned char);
  952. /*
  953. * And write the data into it.
  954. */
  955. pos = 0;
  956. pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED);
  957. for (i = 0; i < nnumbers; i++) {
  958. pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0);
  959. memcpy(outblob+pos, numbers[i].start, numbers[i].bytes);
  960. pos += numbers[i].bytes;
  961. }
  962. } else if (key->alg == &ssh_ecdsa_nistp256 ||
  963. key->alg == &ssh_ecdsa_nistp384 ||
  964. key->alg == &ssh_ecdsa_nistp521) {
  965. const unsigned char *oid;
  966. int oidlen;
  967. int pointlen;
  968. /*
  969. * Structure of asn1:
  970. * SEQUENCE
  971. * INTEGER 1
  972. * OCTET STRING (private key)
  973. * [0]
  974. * OID (curve)
  975. * [1]
  976. * BIT STRING (0x00 public key point)
  977. */
  978. oid = ec_alg_oid(key->alg, &oidlen);
  979. pointlen = (((struct ec_key *)key->data)->publicKey.curve->fieldBits
  980. + 7) / 8 * 2;
  981. len = ber_write_id_len(NULL, 2, 1, 0);
  982. len += 1;
  983. len += ber_write_id_len(NULL, 4, privlen - 4, 0);
  984. len+= privlen - 4;
  985. len += ber_write_id_len(NULL, 0, oidlen +
  986. ber_write_id_len(NULL, 6, oidlen, 0),
  987. ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
  988. len += ber_write_id_len(NULL, 6, oidlen, 0);
  989. len += oidlen;
  990. len += ber_write_id_len(NULL, 1, 2 + pointlen +
  991. ber_write_id_len(NULL, 3, 2 + pointlen, 0),
  992. ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
  993. len += ber_write_id_len(NULL, 3, 2 + pointlen, 0);
  994. len += 2 + pointlen;
  995. seqlen = len;
  996. len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED);
  997. outblob = snewn(len, unsigned char);
  998. assert(outblob);
  999. pos = 0;
  1000. pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED);
  1001. pos += ber_write_id_len(outblob+pos, 2, 1, 0);
  1002. outblob[pos++] = 1;
  1003. pos += ber_write_id_len(outblob+pos, 4, privlen - 4, 0);
  1004. memcpy(outblob+pos, privblob + 4, privlen - 4);
  1005. pos += privlen - 4;
  1006. pos += ber_write_id_len(outblob+pos, 0, oidlen +
  1007. ber_write_id_len(NULL, 6, oidlen, 0),
  1008. ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
  1009. pos += ber_write_id_len(outblob+pos, 6, oidlen, 0);
  1010. memcpy(outblob+pos, oid, oidlen);
  1011. pos += oidlen;
  1012. pos += ber_write_id_len(outblob+pos, 1, 2 + pointlen +
  1013. ber_write_id_len(NULL, 3, 2 + pointlen, 0),
  1014. ASN1_CLASS_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED);
  1015. pos += ber_write_id_len(outblob+pos, 3, 2 + pointlen, 0);
  1016. outblob[pos++] = 0;
  1017. memcpy(outblob+pos, pubblob+39, 1 + pointlen);
  1018. pos += 1 + pointlen;
  1019. header = "-----BEGIN EC PRIVATE KEY-----\n";
  1020. footer = "-----END EC PRIVATE KEY-----\n";
  1021. } else {
  1022. assert(0); /* zoinks! */
  1023. exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
  1024. }
  1025. /*
  1026. * Encrypt the key.
  1027. *
  1028. * For the moment, we still encrypt our OpenSSH keys using
  1029. * old-style 3DES.
  1030. */
  1031. if (passphrase) {
  1032. struct MD5Context md5c;
  1033. unsigned char keybuf[32];
  1034. /*
  1035. * Round up to the cipher block size, ensuring we have at
  1036. * least one byte of padding (see below).
  1037. */
  1038. outlen = (len+8) &~ 7;
  1039. {
  1040. unsigned char *tmp = snewn(outlen, unsigned char);
  1041. memcpy(tmp, outblob, len);
  1042. smemclr(outblob, len);
  1043. sfree(outblob);
  1044. outblob = tmp;
  1045. }
  1046. /*
  1047. * Padding on OpenSSH keys is deterministic. The number of
  1048. * padding bytes is always more than zero, and always at most
  1049. * the cipher block length. The value of each padding byte is
  1050. * equal to the number of padding bytes. So a plaintext that's
  1051. * an exact multiple of the block size will be padded with 08
  1052. * 08 08 08 08 08 08 08 (assuming a 64-bit block cipher); a
  1053. * plaintext one byte less than a multiple of the block size
  1054. * will be padded with just 01.
  1055. *
  1056. * This enables the OpenSSL key decryption function to strip
  1057. * off the padding algorithmically and return the unpadded
  1058. * plaintext to the next layer: it looks at the final byte, and
  1059. * then expects to find that many bytes at the end of the data
  1060. * with the same value. Those are all removed and the rest is
  1061. * returned.
  1062. */
  1063. assert(pos == len);
  1064. while (pos < outlen) {
  1065. outblob[pos++] = outlen - len;
  1066. }
  1067. /*
  1068. * Invent an iv. Then derive encryption key from passphrase
  1069. * and iv/salt:
  1070. *
  1071. * - let block A equal MD5(passphrase || iv)
  1072. * - let block B equal MD5(A || passphrase || iv)
  1073. * - block C would be MD5(B || passphrase || iv) and so on
  1074. * - encryption key is the first N bytes of A || B
  1075. */
  1076. for (i = 0; i < 8; i++) iv[i] = random_byte();
  1077. MD5Init(&md5c);
  1078. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  1079. MD5Update(&md5c, iv, 8);
  1080. MD5Final(keybuf, &md5c);
  1081. MD5Init(&md5c);
  1082. MD5Update(&md5c, keybuf, 16);
  1083. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  1084. MD5Update(&md5c, iv, 8);
  1085. MD5Final(keybuf+16, &md5c);
  1086. /*
  1087. * Now encrypt the key blob.
  1088. */
  1089. des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
  1090. smemclr(&md5c, sizeof(md5c));
  1091. smemclr(keybuf, sizeof(keybuf));
  1092. } else {
  1093. /*
  1094. * If no encryption, the blob has exactly its original
  1095. * cleartext size.
  1096. */
  1097. outlen = len;
  1098. }
  1099. /*
  1100. * And save it. We'll use Unix line endings just in case it's
  1101. * subsequently transferred in binary mode.
  1102. */
  1103. fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
  1104. if (!fp)
  1105. goto error;
  1106. fputs(header, fp);
  1107. if (passphrase) {
  1108. fprintf(fp, "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,");
  1109. for (i = 0; i < 8; i++)
  1110. fprintf(fp, "%02X", iv[i]);
  1111. fprintf(fp, "\n\n");
  1112. }
  1113. base64_encode(fp, outblob, outlen, 64);
  1114. fputs(footer, fp);
  1115. fclose(fp);
  1116. ret = 1;
  1117. error:
  1118. if (outblob) {
  1119. smemclr(outblob, outlen);
  1120. sfree(outblob);
  1121. }
  1122. if (spareblob) {
  1123. smemclr(spareblob, sparelen);
  1124. sfree(spareblob);
  1125. }
  1126. if (privblob) {
  1127. smemclr(privblob, privlen);
  1128. sfree(privblob);
  1129. }
  1130. if (pubblob) {
  1131. smemclr(pubblob, publen);
  1132. sfree(pubblob);
  1133. }
  1134. return ret;
  1135. }
  1136. /* ----------------------------------------------------------------------
  1137. * Code to read and write OpenSSH private keys in the new-style format.
  1138. */
  1139. typedef enum {
  1140. ON_E_NONE, ON_E_AES256CBC
  1141. } openssh_new_cipher;
  1142. typedef enum {
  1143. ON_K_NONE, ON_K_BCRYPT
  1144. } openssh_new_kdf;
  1145. struct openssh_new_key {
  1146. openssh_new_cipher cipher;
  1147. openssh_new_kdf kdf;
  1148. union {
  1149. struct {
  1150. int rounds;
  1151. /* This points to a position within keyblob, not a
  1152. * separately allocated thing */
  1153. const unsigned char *salt;
  1154. int saltlen;
  1155. } bcrypt;
  1156. } kdfopts;
  1157. int nkeys, key_wanted;
  1158. /* This too points to a position within keyblob */
  1159. unsigned char *privatestr;
  1160. int privatelen;
  1161. unsigned char *keyblob;
  1162. int keyblob_len, keyblob_size;
  1163. };
  1164. static struct openssh_new_key *load_openssh_new_key(const Filename *filename,
  1165. const char **errmsg_p)
  1166. {
  1167. struct openssh_new_key *ret;
  1168. FILE *fp = NULL;
  1169. char *line = NULL;
  1170. const char *errmsg;
  1171. char *p;
  1172. char base64_bit[4];
  1173. int base64_chars = 0;
  1174. const void *filedata;
  1175. int filelen;
  1176. const void *string, *kdfopts, *bcryptsalt, *pubkey;
  1177. int stringlen, kdfoptlen, bcryptsaltlen, pubkeylen;
  1178. unsigned bcryptrounds, nkeys, key_index;
  1179. ret = snew(struct openssh_new_key);
  1180. ret->keyblob = NULL;
  1181. ret->keyblob_len = ret->keyblob_size = 0;
  1182. fp = f_open(filename, "r", FALSE);
  1183. if (!fp) {
  1184. errmsg = "unable to open key file";
  1185. goto error;
  1186. }
  1187. if (!(line = fgetline(fp))) {
  1188. errmsg = "unexpected end of file";
  1189. goto error;
  1190. }
  1191. strip_crlf(line);
  1192. if (0 != strcmp(line, "-----BEGIN OPENSSH PRIVATE KEY-----")) {
  1193. errmsg = "file does not begin with OpenSSH new-style key header";
  1194. goto error;
  1195. }
  1196. smemclr(line, strlen(line));
  1197. sfree(line);
  1198. line = NULL;
  1199. while (1) {
  1200. if (!(line = fgetline(fp))) {
  1201. errmsg = "unexpected end of file";
  1202. goto error;
  1203. }
  1204. strip_crlf(line);
  1205. if (0 == strcmp(line, "-----END OPENSSH PRIVATE KEY-----")) {
  1206. sfree(line);
  1207. line = NULL;
  1208. break; /* done */
  1209. }
  1210. p = line;
  1211. while (isbase64(*p)) {
  1212. base64_bit[base64_chars++] = *p;
  1213. if (base64_chars == 4) {
  1214. unsigned char out[3];
  1215. int len;
  1216. base64_chars = 0;
  1217. len = base64_decode_atom(base64_bit, out);
  1218. if (len <= 0) {
  1219. errmsg = "invalid base64 encoding";
  1220. goto error;
  1221. }
  1222. if (ret->keyblob_len + len > ret->keyblob_size) {
  1223. ret->keyblob_size = ret->keyblob_len + len + 256;
  1224. ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
  1225. unsigned char);
  1226. }
  1227. memcpy(ret->keyblob + ret->keyblob_len, out, len);
  1228. ret->keyblob_len += len;
  1229. smemclr(out, sizeof(out));
  1230. }
  1231. p++;
  1232. }
  1233. smemclr(line, strlen(line));
  1234. sfree(line);
  1235. line = NULL;
  1236. }
  1237. fclose(fp);
  1238. fp = NULL;
  1239. if (ret->keyblob_len == 0 || !ret->keyblob) {
  1240. errmsg = "key body not present";
  1241. goto error;
  1242. }
  1243. filedata = ret->keyblob;
  1244. filelen = ret->keyblob_len;
  1245. if (filelen < 15 || 0 != memcmp(filedata, "openssh-key-v1\0", 15)) {
  1246. errmsg = "new-style OpenSSH magic number missing\n";
  1247. goto error;
  1248. }
  1249. filedata = (const char *)filedata + 15;
  1250. filelen -= 15;
  1251. if (!(string = get_ssh_string(&filelen, &filedata, &stringlen))) {
  1252. errmsg = "encountered EOF before cipher name\n";
  1253. goto error;
  1254. }
  1255. if (match_ssh_id(stringlen, string, "none")) {
  1256. ret->cipher = ON_E_NONE;
  1257. } else if (match_ssh_id(stringlen, string, "aes256-cbc")) {
  1258. ret->cipher = ON_E_AES256CBC;
  1259. } else {
  1260. errmsg = "unrecognised cipher name\n";
  1261. goto error;
  1262. }
  1263. if (!(string = get_ssh_string(&filelen, &filedata, &stringlen))) {
  1264. errmsg = "encountered EOF before kdf name\n";
  1265. goto error;
  1266. }
  1267. if (match_ssh_id(stringlen, string, "none")) {
  1268. ret->kdf = ON_K_NONE;
  1269. } else if (match_ssh_id(stringlen, string, "bcrypt")) {
  1270. ret->kdf = ON_K_BCRYPT;
  1271. } else {
  1272. errmsg = "unrecognised kdf name\n";
  1273. goto error;
  1274. }
  1275. if (!(kdfopts = get_ssh_string(&filelen, &filedata, &kdfoptlen))) {
  1276. errmsg = "encountered EOF before kdf options\n";
  1277. goto error;
  1278. }
  1279. switch (ret->kdf) {
  1280. case ON_K_NONE:
  1281. if (kdfoptlen != 0) {
  1282. errmsg = "expected empty options string for 'none' kdf";
  1283. goto error;
  1284. }
  1285. break;
  1286. case ON_K_BCRYPT:
  1287. if (!(bcryptsalt = get_ssh_string(&kdfoptlen, &kdfopts,
  1288. &bcryptsaltlen))) {
  1289. errmsg = "bcrypt options string did not contain salt\n";
  1290. goto error;
  1291. }
  1292. if (!get_ssh_uint32(&kdfoptlen, &kdfopts, &bcryptrounds)) {
  1293. errmsg = "bcrypt options string did not contain round count\n";
  1294. goto error;
  1295. }
  1296. ret->kdfopts.bcrypt.salt = bcryptsalt;
  1297. ret->kdfopts.bcrypt.saltlen = bcryptsaltlen;
  1298. ret->kdfopts.bcrypt.rounds = bcryptrounds;
  1299. break;
  1300. }
  1301. /*
  1302. * At this point we expect a uint32 saying how many keys are
  1303. * stored in this file. OpenSSH new-style key files can
  1304. * contain more than one. Currently we don't have any user
  1305. * interface to specify which one we're trying to extract, so
  1306. * we just bomb out with an error if more than one is found in
  1307. * the file. However, I've put in all the mechanism here to
  1308. * extract the nth one for a given n, in case we later connect
  1309. * up some UI to that mechanism. Just arrange that the
  1310. * 'key_wanted' field is set to a value in the range [0,
  1311. * nkeys) by some mechanism.
  1312. */
  1313. if (!get_ssh_uint32(&filelen, &filedata, &nkeys)) {
  1314. errmsg = "encountered EOF before key count\n";
  1315. goto error;
  1316. }
  1317. if (nkeys != 1) {
  1318. errmsg = "multiple keys in new-style OpenSSH key file "
  1319. "not supported\n";
  1320. goto error;
  1321. }
  1322. ret->nkeys = nkeys;
  1323. ret->key_wanted = 0;
  1324. for (key_index = 0; key_index < nkeys; key_index++) {
  1325. if (!(pubkey = get_ssh_string(&filelen, &filedata, &pubkeylen))) {
  1326. errmsg = "encountered EOF before kdf options\n";
  1327. goto error;
  1328. }
  1329. }
  1330. /*
  1331. * Now we expect a string containing the encrypted part of the
  1332. * key file.
  1333. */
  1334. if (!(string = get_ssh_string(&filelen, &filedata, &stringlen))) {
  1335. errmsg = "encountered EOF before private key container\n";
  1336. goto error;
  1337. }
  1338. ret->privatestr = (unsigned char *)string;
  1339. ret->privatelen = stringlen;
  1340. /*
  1341. * And now we're done, until asked to actually decrypt.
  1342. */
  1343. smemclr(base64_bit, sizeof(base64_bit));
  1344. if (errmsg_p) *errmsg_p = NULL;
  1345. return ret;
  1346. error:
  1347. if (line) {
  1348. smemclr(line, strlen(line));
  1349. sfree(line);
  1350. line = NULL;
  1351. }
  1352. smemclr(base64_bit, sizeof(base64_bit));
  1353. if (ret) {
  1354. if (ret->keyblob) {
  1355. smemclr(ret->keyblob, ret->keyblob_size);
  1356. sfree(ret->keyblob);
  1357. }
  1358. smemclr(ret, sizeof(*ret));
  1359. sfree(ret);
  1360. }
  1361. if (errmsg_p) *errmsg_p = errmsg;
  1362. if (fp) fclose(fp);
  1363. return NULL;
  1364. }
  1365. int openssh_new_encrypted(const Filename *filename)
  1366. {
  1367. struct openssh_new_key *key = load_openssh_new_key(filename, NULL);
  1368. int ret;
  1369. if (!key)
  1370. return 0;
  1371. ret = (key->cipher != ON_E_NONE);
  1372. smemclr(key->keyblob, key->keyblob_size);
  1373. sfree(key->keyblob);
  1374. smemclr(key, sizeof(*key));
  1375. sfree(key);
  1376. return ret;
  1377. }
  1378. struct ssh2_userkey *openssh_new_read(const Filename *filename,
  1379. char *passphrase,
  1380. const char **errmsg_p)
  1381. {
  1382. struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p);
  1383. struct ssh2_userkey *retkey;
  1384. int i;
  1385. struct ssh2_userkey *retval = NULL;
  1386. const char *errmsg;
  1387. unsigned char *blob;
  1388. int blobsize = 0;
  1389. unsigned checkint0, checkint1;
  1390. const void *priv, *string;
  1391. int privlen, stringlen, key_index;
  1392. const struct ssh_signkey *alg;
  1393. blob = NULL;
  1394. if (!key)
  1395. return NULL;
  1396. if (key->cipher != ON_E_NONE) {
  1397. unsigned char keybuf[48];
  1398. int keysize;
  1399. /*
  1400. * Construct the decryption key, and decrypt the string.
  1401. */
  1402. switch (key->cipher) {
  1403. case ON_E_NONE:
  1404. keysize = 0;
  1405. break;
  1406. case ON_E_AES256CBC:
  1407. keysize = 48; /* 32 byte key + 16 byte IV */
  1408. break;
  1409. default:
  1410. assert(0 && "Bad cipher enumeration value");
  1411. }
  1412. assert(keysize <= sizeof(keybuf));
  1413. switch (key->kdf) {
  1414. case ON_K_NONE:
  1415. memset(keybuf, 0, keysize);
  1416. break;
  1417. case ON_K_BCRYPT:
  1418. openssh_bcrypt(passphrase,
  1419. key->kdfopts.bcrypt.salt,
  1420. key->kdfopts.bcrypt.saltlen,
  1421. key->kdfopts.bcrypt.rounds,
  1422. keybuf, keysize);
  1423. break;
  1424. default:
  1425. assert(0 && "Bad kdf enumeration value");
  1426. }
  1427. switch (key->cipher) {
  1428. case ON_E_NONE:
  1429. break;
  1430. case ON_E_AES256CBC:
  1431. if (key->privatelen % 16 != 0) {
  1432. errmsg = "private key container length is not a"
  1433. " multiple of AES block size\n";
  1434. goto error;
  1435. }
  1436. {
  1437. void *ctx = aes_make_context();
  1438. aes256_key(ctx, keybuf);
  1439. aes_iv(ctx, keybuf + 32);
  1440. aes_ssh2_decrypt_blk(ctx, key->privatestr,
  1441. key->privatelen);
  1442. aes_free_context(ctx);
  1443. }
  1444. break;
  1445. default:
  1446. assert(0 && "Bad cipher enumeration value");
  1447. }
  1448. }
  1449. /*
  1450. * Now parse the entire encrypted section, and extract the key
  1451. * identified by key_wanted.
  1452. */
  1453. priv = key->privatestr;
  1454. privlen = key->privatelen;
  1455. if (!get_ssh_uint32(&privlen, &priv, &checkint0) ||
  1456. !get_ssh_uint32(&privlen, &priv, &checkint1) ||
  1457. checkint0 != checkint1) {
  1458. errmsg = "decryption check failed";
  1459. goto error;
  1460. }
  1461. retkey = NULL;
  1462. for (key_index = 0; key_index < key->nkeys; key_index++) {
  1463. const unsigned char *thiskey;
  1464. int thiskeylen;
  1465. /*
  1466. * Read the key type, which will tell us how to scan over
  1467. * the key to get to the next one.
  1468. */
  1469. if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
  1470. errmsg = "expected key type in private string";
  1471. goto error;
  1472. }
  1473. /*
  1474. * Preliminary key type identification, and decide how
  1475. * many pieces of key we expect to see. Currently
  1476. * (conveniently) all key types can be seen as some number
  1477. * of strings, so we just need to know how many of them to
  1478. * skip over. (The numbers below exclude the key comment.)
  1479. */
  1480. {
  1481. /* find_pubkey_alg needs a zero-terminated copy of the
  1482. * algorithm name */
  1483. char *name_zt = dupprintf("%.*s", stringlen, (char *)string);
  1484. alg = find_pubkey_alg(name_zt);
  1485. sfree(name_zt);
  1486. }
  1487. if (!alg) {
  1488. errmsg = "private key type not recognised\n";
  1489. goto error;
  1490. }
  1491. thiskey = priv;
  1492. /*
  1493. * Skip over the pieces of key.
  1494. */
  1495. for (i = 0; i < alg->openssh_private_npieces; i++) {
  1496. if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
  1497. errmsg = "ran out of data in mid-private-key";
  1498. goto error;
  1499. }
  1500. }
  1501. thiskeylen = (int)((const unsigned char *)priv -
  1502. (const unsigned char *)thiskey);
  1503. if (key_index == key->key_wanted) {
  1504. retkey = snew(struct ssh2_userkey);
  1505. retkey->alg = alg;
  1506. retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
  1507. if (!retkey->data) {
  1508. sfree(retkey);
  1509. errmsg = "unable to create key data structure";
  1510. goto error;
  1511. }
  1512. }
  1513. /*
  1514. * Read the key comment.
  1515. */
  1516. if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
  1517. errmsg = "ran out of data at key comment";
  1518. goto error;
  1519. }
  1520. if (key_index == key->key_wanted) {
  1521. assert(retkey);
  1522. retkey->comment = dupprintf("%.*s", stringlen,
  1523. (const char *)string);
  1524. }
  1525. }
  1526. if (!retkey) {
  1527. errmsg = "key index out of range";
  1528. goto error;
  1529. }
  1530. /*
  1531. * Now we expect nothing left but padding.
  1532. */
  1533. for (i = 0; i < privlen; i++) {
  1534. if (((const unsigned char *)priv)[i] != (unsigned char)(i+1)) {
  1535. errmsg = "padding at end of private string did not match";
  1536. goto error;
  1537. }
  1538. }
  1539. errmsg = NULL; /* no error */
  1540. retval = retkey;
  1541. error:
  1542. if (blob) {
  1543. smemclr(blob, blobsize);
  1544. sfree(blob);
  1545. }
  1546. smemclr(key->keyblob, key->keyblob_size);
  1547. sfree(key->keyblob);
  1548. smemclr(key, sizeof(*key));
  1549. sfree(key);
  1550. if (errmsg_p) *errmsg_p = errmsg;
  1551. return retval;
  1552. }
  1553. int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
  1554. char *passphrase)
  1555. {
  1556. unsigned char *pubblob, *privblob, *outblob, *p;
  1557. unsigned char *private_section_start, *private_section_length_field;
  1558. int publen, privlen, commentlen, maxsize, padvalue, i;
  1559. unsigned checkint;
  1560. int ret = 0;
  1561. unsigned char bcrypt_salt[16];
  1562. const int bcrypt_rounds = 16;
  1563. FILE *fp;
  1564. /*
  1565. * Fetch the key blobs and find out the lengths of things.
  1566. */
  1567. pubblob = key->alg->public_blob(key->data, &publen);
  1568. i = key->alg->openssh_fmtkey(key->data, NULL, 0);
  1569. privblob = snewn(i, unsigned char);
  1570. privlen = key->alg->openssh_fmtkey(key->data, privblob, i);
  1571. assert(privlen == i);
  1572. commentlen = strlen(key->comment);
  1573. /*
  1574. * Allocate enough space for the full binary key format. No need
  1575. * to be absolutely precise here.
  1576. */
  1577. maxsize = (16 + /* magic number */
  1578. 32 + /* cipher name string */
  1579. 32 + /* kdf name string */
  1580. 64 + /* kdf options string */
  1581. 4 + /* key count */
  1582. 4+publen + /* public key string */
  1583. 4 + /* string header for private section */
  1584. 8 + /* checkint x 2 */
  1585. 4+strlen(key->alg->name) + /* key type string */
  1586. privlen + /* private blob */
  1587. 4+commentlen + /* comment string */
  1588. 16); /* padding at end of private section */
  1589. outblob = snewn(maxsize, unsigned char);
  1590. /*
  1591. * Construct the cleartext version of the blob.
  1592. */
  1593. p = outblob;
  1594. /* Magic number. */
  1595. memcpy(p, "openssh-key-v1\0", 15);
  1596. p += 15;
  1597. /* Cipher and kdf names, and kdf options. */
  1598. if (!passphrase) {
  1599. memset(bcrypt_salt, 0, sizeof(bcrypt_salt)); /* prevent warnings */
  1600. p += put_string_z(p, "none");
  1601. p += put_string_z(p, "none");
  1602. p += put_string_z(p, "");
  1603. } else {
  1604. unsigned char *q;
  1605. for (i = 0; i < (int)sizeof(bcrypt_salt); i++)
  1606. bcrypt_salt[i] = random_byte();
  1607. p += put_string_z(p, "aes256-cbc");
  1608. p += put_string_z(p, "bcrypt");
  1609. q = p;
  1610. p += 4;
  1611. p += put_string(p, bcrypt_salt, sizeof(bcrypt_salt));
  1612. p += put_uint32(p, bcrypt_rounds);
  1613. PUT_32BIT_MSB_FIRST(q, (unsigned)(p - (q+4)));
  1614. }
  1615. /* Number of keys. */
  1616. p += put_uint32(p, 1);
  1617. /* Public blob. */
  1618. p += put_string(p, pubblob, publen);
  1619. /* Begin private section. */
  1620. private_section_length_field = p;
  1621. p += 4;
  1622. private_section_start = p;
  1623. /* checkint. */
  1624. checkint = 0;
  1625. for (i = 0; i < 4; i++)
  1626. checkint = (checkint << 8) + random_byte();
  1627. p += put_uint32(p, checkint);
  1628. p += put_uint32(p, checkint);
  1629. /* Private key. The main private blob goes inline, with no string
  1630. * wrapper. */
  1631. p += put_string_z(p, key->alg->name);
  1632. memcpy(p, privblob, privlen);
  1633. p += privlen;
  1634. /* Comment. */
  1635. p += put_string_z(p, key->comment);
  1636. /* Pad out the encrypted section. */
  1637. padvalue = 1;
  1638. do {
  1639. *p++ = padvalue++;
  1640. } while ((p - private_section_start) & 15);
  1641. assert(p - outblob < maxsize);
  1642. /* Go back and fill in the length field for the private section. */
  1643. PUT_32BIT_MSB_FIRST(private_section_length_field,
  1644. p - private_section_start);
  1645. if (passphrase) {
  1646. /*
  1647. * Encrypt the private section. We need 48 bytes of key
  1648. * material: 32 bytes AES key + 16 bytes iv.
  1649. */
  1650. unsigned char keybuf[48];
  1651. void *ctx;
  1652. openssh_bcrypt(passphrase,
  1653. bcrypt_salt, sizeof(bcrypt_salt), bcrypt_rounds,
  1654. keybuf, sizeof(keybuf));
  1655. ctx = aes_make_context();
  1656. aes256_key(ctx, keybuf);
  1657. aes_iv(ctx, keybuf + 32);
  1658. aes_ssh2_encrypt_blk(ctx, private_section_start,
  1659. p - private_section_start);
  1660. aes_free_context(ctx);
  1661. smemclr(keybuf, sizeof(keybuf));
  1662. }
  1663. /*
  1664. * And save it. We'll use Unix line endings just in case it's
  1665. * subsequently transferred in binary mode.
  1666. */
  1667. fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
  1668. if (!fp)
  1669. goto error;
  1670. fputs("-----BEGIN OPENSSH PRIVATE KEY-----\n", fp);
  1671. base64_encode(fp, outblob, p - outblob, 64);
  1672. fputs("-----END OPENSSH PRIVATE KEY-----\n", fp);
  1673. fclose(fp);
  1674. ret = 1;
  1675. error:
  1676. if (outblob) {
  1677. smemclr(outblob, maxsize);
  1678. sfree(outblob);
  1679. }
  1680. if (privblob) {
  1681. smemclr(privblob, privlen);
  1682. sfree(privblob);
  1683. }
  1684. if (pubblob) {
  1685. smemclr(pubblob, publen);
  1686. sfree(pubblob);
  1687. }
  1688. return ret;
  1689. }
  1690. /* ----------------------------------------------------------------------
  1691. * The switch function openssh_auto_write(), which chooses one of the
  1692. * concrete OpenSSH output formats based on the key type.
  1693. */
  1694. int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
  1695. char *passphrase)
  1696. {
  1697. /*
  1698. * The old OpenSSH format supports a fixed list of key types. We
  1699. * assume that anything not in that fixed list is newer, and hence
  1700. * will use the new format.
  1701. */
  1702. if (key->alg == &ssh_dss ||
  1703. key->alg == &ssh_rsa ||
  1704. key->alg == &ssh_ecdsa_nistp256 ||
  1705. key->alg == &ssh_ecdsa_nistp384 ||
  1706. key->alg == &ssh_ecdsa_nistp521)
  1707. return openssh_pem_write(filename, key, passphrase);
  1708. else
  1709. return openssh_new_write(filename, key, passphrase);
  1710. }
  1711. /* ----------------------------------------------------------------------
  1712. * Code to read ssh.com private keys.
  1713. */
  1714. /*
  1715. * The format of the base64 blob is largely SSH-2-packet-formatted,
  1716. * except that mpints are a bit different: they're more like the
  1717. * old SSH-1 mpint. You have a 32-bit bit count N, followed by
  1718. * (N+7)/8 bytes of data.
  1719. *
  1720. * So. The blob contains:
  1721. *
  1722. * - uint32 0x3f6ff9eb (magic number)
  1723. * - uint32 size (total blob size)
  1724. * - string key-type (see below)
  1725. * - string cipher-type (tells you if key is encrypted)
  1726. * - string encrypted-blob
  1727. *
  1728. * (The first size field includes the size field itself and the
  1729. * magic number before it. All other size fields are ordinary SSH-2
  1730. * strings, so the size field indicates how much data is to
  1731. * _follow_.)
  1732. *
  1733. * The encrypted blob, once decrypted, contains a single string
  1734. * which in turn contains the payload. (This allows padding to be
  1735. * added after that string while still making it clear where the
  1736. * real payload ends. Also it probably makes for a reasonable
  1737. * decryption check.)
  1738. *
  1739. * The payload blob, for an RSA key, contains:
  1740. * - mpint e
  1741. * - mpint d
  1742. * - mpint n (yes, the public and private stuff is intermixed)
  1743. * - mpint u (presumably inverse of p mod q)
  1744. * - mpint p (p is the smaller prime)
  1745. * - mpint q (q is the larger)
  1746. *
  1747. * For a DSA key, the payload blob contains:
  1748. * - uint32 0
  1749. * - mpint p
  1750. * - mpint g
  1751. * - mpint q
  1752. * - mpint y
  1753. * - mpint x
  1754. *
  1755. * Alternatively, if the parameters are `predefined', that
  1756. * (0,p,g,q) sequence can be replaced by a uint32 1 and a string
  1757. * containing some predefined parameter specification. *shudder*,
  1758. * but I doubt we'll encounter this in real life.
  1759. *
  1760. * The key type strings are ghastly. The RSA key I looked at had a
  1761. * type string of
  1762. *
  1763. * `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
  1764. *
  1765. * and the DSA key wasn't much better:
  1766. *
  1767. * `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
  1768. *
  1769. * It isn't clear that these will always be the same. I think it
  1770. * might be wise just to look at the `if-modn{sign{rsa' and
  1771. * `dl-modp{sign{dsa' prefixes.
  1772. *
  1773. * Finally, the encryption. The cipher-type string appears to be
  1774. * either `none' or `3des-cbc'. Looks as if this is SSH-2-style
  1775. * 3des-cbc (i.e. outer cbc rather than inner). The key is created
  1776. * from the passphrase by means of yet another hashing faff:
  1777. *
  1778. * - first 16 bytes are MD5(passphrase)
  1779. * - next 16 bytes are MD5(passphrase || first 16 bytes)
  1780. * - if there were more, they'd be MD5(passphrase || first 32),
  1781. * and so on.
  1782. */
  1783. #define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb
  1784. struct sshcom_key {
  1785. char comment[256]; /* allowing any length is overkill */
  1786. unsigned char *keyblob;
  1787. int keyblob_len, keyblob_size;
  1788. };
  1789. static struct sshcom_key *load_sshcom_key(const Filename *filename,
  1790. const char **errmsg_p)
  1791. {
  1792. struct sshcom_key *ret;
  1793. FILE *fp;
  1794. char *line = NULL;
  1795. int hdrstart, len;
  1796. const char *errmsg;
  1797. char *p;
  1798. int headers_done;
  1799. char base64_bit[4];
  1800. int base64_chars = 0;
  1801. ret = snew(struct sshcom_key);
  1802. ret->comment[0] = '\0';
  1803. ret->keyblob = NULL;
  1804. ret->keyblob_len = ret->keyblob_size = 0;
  1805. fp = f_open(filename, "r", FALSE);
  1806. if (!fp) {
  1807. errmsg = "unable to open key file";
  1808. goto error;
  1809. }
  1810. if (!(line = fgetline(fp))) {
  1811. errmsg = "unexpected end of file";
  1812. goto error;
  1813. }
  1814. strip_crlf(line);
  1815. if (0 != strcmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) {
  1816. errmsg = "file does not begin with ssh.com key header";
  1817. goto error;
  1818. }
  1819. smemclr(line, strlen(line));
  1820. sfree(line);
  1821. line = NULL;
  1822. headers_done = 0;
  1823. while (1) {
  1824. if (!(line = fgetline(fp))) {
  1825. errmsg = "unexpected end of file";
  1826. goto error;
  1827. }
  1828. strip_crlf(line);
  1829. if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) {
  1830. sfree(line);
  1831. line = NULL;
  1832. break; /* done */
  1833. }
  1834. if ((p = strchr(line, ':')) != NULL) {
  1835. if (headers_done) {
  1836. errmsg = "header found in body of key data";
  1837. goto error;
  1838. }
  1839. *p++ = '\0';
  1840. while (*p && isspace((unsigned char)*p)) p++;
  1841. hdrstart = p - line;
  1842. /*
  1843. * Header lines can end in a trailing backslash for
  1844. * continuation.
  1845. */
  1846. len = hdrstart + strlen(line+hdrstart);
  1847. assert(!line[len]);
  1848. while (line[len-1] == '\\') {
  1849. char *line2;
  1850. int line2len;
  1851. line2 = fgetline(fp);
  1852. if (!line2) {
  1853. errmsg = "unexpected end of file";
  1854. goto error;
  1855. }
  1856. strip_crlf(line2);
  1857. line2len = strlen(line2);
  1858. line = sresize(line, len + line2len + 1, char);
  1859. strcpy(line + len - 1, line2);
  1860. len += line2len - 1;
  1861. assert(!line[len]);
  1862. smemclr(line2, strlen(line2));
  1863. sfree(line2);
  1864. line2 = NULL;
  1865. }
  1866. p = line + hdrstart;
  1867. strip_crlf(p);
  1868. if (!strcmp(line, "Comment")) {
  1869. /* Strip quotes in comment if present. */
  1870. if (p[0] == '"' && p[strlen(p)-1] == '"') {
  1871. p++;
  1872. p[strlen(p)-1] = '\0';
  1873. }
  1874. strncpy(ret->comment, p, sizeof(ret->comment));
  1875. ret->comment[sizeof(ret->comment)-1] = '\0';
  1876. }
  1877. } else {
  1878. headers_done = 1;
  1879. p = line;
  1880. while (isbase64(*p)) {
  1881. base64_bit[base64_chars++] = *p;
  1882. if (base64_chars == 4) {
  1883. unsigned char out[3];
  1884. base64_chars = 0;
  1885. len = base64_decode_atom(base64_bit, out);
  1886. if (len <= 0) {
  1887. errmsg = "invalid base64 encoding";
  1888. goto error;
  1889. }
  1890. if (ret->keyblob_len + len > ret->keyblob_size) {
  1891. ret->keyblob_size = ret->keyblob_len + len + 256;
  1892. ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
  1893. unsigned char);
  1894. }
  1895. memcpy(ret->keyblob + ret->keyblob_len, out, len);
  1896. ret->keyblob_len += len;
  1897. }
  1898. p++;
  1899. }
  1900. }
  1901. smemclr(line, strlen(line));
  1902. sfree(line);
  1903. line = NULL;
  1904. }
  1905. if (ret->keyblob_len == 0 || !ret->keyblob) {
  1906. errmsg = "key body not present";
  1907. goto error;
  1908. }
  1909. fclose(fp);
  1910. if (errmsg_p) *errmsg_p = NULL;
  1911. return ret;
  1912. error:
  1913. if (fp)
  1914. fclose(fp);
  1915. if (line) {
  1916. smemclr(line, strlen(line));
  1917. sfree(line);
  1918. line = NULL;
  1919. }
  1920. if (ret) {
  1921. if (ret->keyblob) {
  1922. smemclr(ret->keyblob, ret->keyblob_size);
  1923. sfree(ret->keyblob);
  1924. }
  1925. smemclr(ret, sizeof(*ret));
  1926. sfree(ret);
  1927. }
  1928. if (errmsg_p) *errmsg_p = errmsg;
  1929. return NULL;
  1930. }
  1931. int sshcom_encrypted(const Filename *filename, char **comment)
  1932. {
  1933. struct sshcom_key *key = load_sshcom_key(filename, NULL);
  1934. int pos, len, answer;
  1935. answer = 0;
  1936. *comment = NULL;
  1937. if (!key)
  1938. goto done;
  1939. /*
  1940. * Check magic number.
  1941. */
  1942. if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) {
  1943. goto done; /* key is invalid */
  1944. }
  1945. /*
  1946. * Find the cipher-type string.
  1947. */
  1948. pos = 8;
  1949. if (key->keyblob_len < pos+4)
  1950. goto done; /* key is far too short */
  1951. len = toint(GET_32BIT(key->keyblob + pos));
  1952. if (len < 0 || len > key->keyblob_len - pos - 4)
  1953. goto done; /* key is far too short */
  1954. pos += 4 + len; /* skip key type */
  1955. len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */
  1956. if (len < 0 || len > key->keyblob_len - pos - 4)
  1957. goto done; /* cipher type string is incomplete */
  1958. if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
  1959. answer = 1;
  1960. done:
  1961. if (key) {
  1962. *comment = dupstr(key->comment);
  1963. smemclr(key->keyblob, key->keyblob_size);
  1964. sfree(key->keyblob);
  1965. smemclr(key, sizeof(*key));
  1966. sfree(key);
  1967. } else {
  1968. *comment = dupstr("");
  1969. }
  1970. return answer;
  1971. }
  1972. static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
  1973. {
  1974. unsigned bits, bytes;
  1975. unsigned char *d = (unsigned char *) data;
  1976. if (len < 4)
  1977. goto error;
  1978. bits = GET_32BIT(d);
  1979. bytes = (bits + 7) / 8;
  1980. if (len < 4+bytes)
  1981. goto error;
  1982. ret->start = d + 4;
  1983. ret->bytes = bytes;
  1984. return bytes+4;
  1985. error:
  1986. ret->start = NULL;
  1987. ret->bytes = -1;
  1988. return len; /* ensure further calls fail as well */
  1989. }
  1990. static int sshcom_put_mpint(void *target, void *data, int len)
  1991. {
  1992. unsigned char *d = (unsigned char *)target;
  1993. unsigned char *i = (unsigned char *)data;
  1994. int bits = len * 8 - 1;
  1995. while (bits > 0) {
  1996. if (*i & (1 << (bits & 7)))
  1997. break;
  1998. if (!(bits-- & 7))
  1999. i++, len--;
  2000. }
  2001. PUT_32BIT(d, bits+1);
  2002. memcpy(d+4, i, len);
  2003. return len+4;
  2004. }
  2005. struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
  2006. const char **errmsg_p)
  2007. {
  2008. struct sshcom_key *key = load_sshcom_key(filename, errmsg_p);
  2009. const char *errmsg;
  2010. int pos, len;
  2011. const char prefix_rsa[] = "if-modn{sign{rsa";
  2012. const char prefix_dsa[] = "dl-modp{sign{dsa";
  2013. enum { RSA, DSA } type;
  2014. int encrypted;
  2015. char *ciphertext;
  2016. int cipherlen;
  2017. struct ssh2_userkey *ret = NULL, *retkey;
  2018. const struct ssh_signkey *alg;
  2019. unsigned char *blob = NULL;
  2020. int blobsize = 0, publen, privlen;
  2021. if (!key)
  2022. return NULL;
  2023. /*
  2024. * Check magic number.
  2025. */
  2026. if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
  2027. errmsg = "key does not begin with magic number";
  2028. goto error;
  2029. }
  2030. /*
  2031. * Determine the key type.
  2032. */
  2033. pos = 8;
  2034. if (key->keyblob_len < pos+4 ||
  2035. (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
  2036. len > key->keyblob_len - pos - 4) {
  2037. errmsg = "key blob does not contain a key type string";
  2038. goto error;
  2039. }
  2040. if (len > sizeof(prefix_rsa) - 1 &&
  2041. !memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) {
  2042. type = RSA;
  2043. } else if (len > sizeof(prefix_dsa) - 1 &&
  2044. !memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
  2045. type = DSA;
  2046. } else {
  2047. errmsg = "key is of unknown type";
  2048. goto error;
  2049. }
  2050. pos += 4+len;
  2051. /*
  2052. * Determine the cipher type.
  2053. */
  2054. if (key->keyblob_len < pos+4 ||
  2055. (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
  2056. len > key->keyblob_len - pos - 4) {
  2057. errmsg = "key blob does not contain a cipher type string";
  2058. goto error;
  2059. }
  2060. if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
  2061. encrypted = 0;
  2062. else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
  2063. encrypted = 1;
  2064. else {
  2065. errmsg = "key encryption is of unknown type";
  2066. goto error;
  2067. }
  2068. pos += 4+len;
  2069. /*
  2070. * Get hold of the encrypted part of the key.
  2071. */
  2072. if (key->keyblob_len < pos+4 ||
  2073. (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
  2074. len > key->keyblob_len - pos - 4) {
  2075. errmsg = "key blob does not contain actual key data";
  2076. goto error;
  2077. }
  2078. ciphertext = (char *)key->keyblob + pos + 4;
  2079. cipherlen = len;
  2080. if (cipherlen == 0) {
  2081. errmsg = "length of key data is zero";
  2082. goto error;
  2083. }
  2084. /*
  2085. * Decrypt it if necessary.
  2086. */
  2087. if (encrypted) {
  2088. /*
  2089. * Derive encryption key from passphrase and iv/salt:
  2090. *
  2091. * - let block A equal MD5(passphrase)
  2092. * - let block B equal MD5(passphrase || A)
  2093. * - block C would be MD5(passphrase || A || B) and so on
  2094. * - encryption key is the first N bytes of A || B
  2095. */
  2096. struct MD5Context md5c;
  2097. unsigned char keybuf[32], iv[8];
  2098. if (cipherlen % 8 != 0) {
  2099. errmsg = "encrypted part of key is not a multiple of cipher block"
  2100. " size";
  2101. goto error;
  2102. }
  2103. MD5Init(&md5c);
  2104. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2105. MD5Final(keybuf, &md5c);
  2106. MD5Init(&md5c);
  2107. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2108. MD5Update(&md5c, keybuf, 16);
  2109. MD5Final(keybuf+16, &md5c);
  2110. /*
  2111. * Now decrypt the key blob.
  2112. */
  2113. memset(iv, 0, sizeof(iv));
  2114. des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
  2115. cipherlen);
  2116. smemclr(&md5c, sizeof(md5c));
  2117. smemclr(keybuf, sizeof(keybuf));
  2118. /*
  2119. * Hereafter we return WRONG_PASSPHRASE for any parsing
  2120. * error. (But only if we've just tried to decrypt it!
  2121. * Returning WRONG_PASSPHRASE for an unencrypted key is
  2122. * automatic doom.)
  2123. */
  2124. if (encrypted)
  2125. ret = SSH2_WRONG_PASSPHRASE;
  2126. }
  2127. /*
  2128. * Strip away the containing string to get to the real meat.
  2129. */
  2130. len = toint(GET_32BIT(ciphertext));
  2131. if (len < 0 || len > cipherlen-4) {
  2132. errmsg = "containing string was ill-formed";
  2133. goto error;
  2134. }
  2135. ciphertext += 4;
  2136. cipherlen = len;
  2137. /*
  2138. * Now we break down into RSA versus DSA. In either case we'll
  2139. * construct public and private blobs in our own format, and
  2140. * end up feeding them to alg->createkey().
  2141. */
  2142. blobsize = cipherlen + 256;
  2143. blob = snewn(blobsize, unsigned char);
  2144. privlen = 0;
  2145. if (type == RSA) {
  2146. struct mpint_pos n, e, d, u, p, q;
  2147. int pos = 0;
  2148. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);
  2149. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);
  2150. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);
  2151. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);
  2152. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
  2153. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
  2154. if (!q.start) {
  2155. errmsg = "key data did not contain six integers";
  2156. goto error;
  2157. }
  2158. alg = &ssh_rsa;
  2159. pos = 0;
  2160. pos += put_string(blob+pos, "ssh-rsa", 7);
  2161. pos += put_mp(blob+pos, e.start, e.bytes);
  2162. pos += put_mp(blob+pos, n.start, n.bytes);
  2163. publen = pos;
  2164. pos += put_string(blob+pos, d.start, d.bytes);
  2165. pos += put_mp(blob+pos, q.start, q.bytes);
  2166. pos += put_mp(blob+pos, p.start, p.bytes);
  2167. pos += put_mp(blob+pos, u.start, u.bytes);
  2168. privlen = pos - publen;
  2169. } else {
  2170. struct mpint_pos p, q, g, x, y;
  2171. int pos = 4;
  2172. assert(type == DSA); /* the only other option from the if above */
  2173. if (GET_32BIT(ciphertext) != 0) {
  2174. errmsg = "predefined DSA parameters not supported";
  2175. goto error;
  2176. }
  2177. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
  2178. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);
  2179. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
  2180. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);
  2181. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);
  2182. if (!x.start) {
  2183. errmsg = "key data did not contain five integers";
  2184. goto error;
  2185. }
  2186. alg = &ssh_dss;
  2187. pos = 0;
  2188. pos += put_string(blob+pos, "ssh-dss", 7);
  2189. pos += put_mp(blob+pos, p.start, p.bytes);
  2190. pos += put_mp(blob+pos, q.start, q.bytes);
  2191. pos += put_mp(blob+pos, g.start, g.bytes);
  2192. pos += put_mp(blob+pos, y.start, y.bytes);
  2193. publen = pos;
  2194. pos += put_mp(blob+pos, x.start, x.bytes);
  2195. privlen = pos - publen;
  2196. }
  2197. assert(privlen > 0); /* should have bombed by now if not */
  2198. retkey = snew(struct ssh2_userkey);
  2199. retkey->alg = alg;
  2200. retkey->data = alg->createkey(alg, blob, publen, blob+publen, privlen);
  2201. if (!retkey->data) {
  2202. sfree(retkey);
  2203. errmsg = "unable to create key data structure";
  2204. goto error;
  2205. }
  2206. retkey->comment = dupstr(key->comment);
  2207. errmsg = NULL; /* no error */
  2208. ret = retkey;
  2209. error:
  2210. if (blob) {
  2211. smemclr(blob, blobsize);
  2212. sfree(blob);
  2213. }
  2214. smemclr(key->keyblob, key->keyblob_size);
  2215. sfree(key->keyblob);
  2216. smemclr(key, sizeof(*key));
  2217. sfree(key);
  2218. if (errmsg_p) *errmsg_p = errmsg;
  2219. return ret;
  2220. }
  2221. int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
  2222. char *passphrase)
  2223. {
  2224. unsigned char *pubblob, *privblob;
  2225. int publen, privlen;
  2226. unsigned char *outblob;
  2227. int outlen;
  2228. struct mpint_pos numbers[6];
  2229. int nnumbers, initial_zero, pos, lenpos, i;
  2230. const char *type;
  2231. char *ciphertext;
  2232. int cipherlen;
  2233. int ret = 0;
  2234. FILE *fp;
  2235. /*
  2236. * Fetch the key blobs.
  2237. */
  2238. pubblob = key->alg->public_blob(key->data, &publen);
  2239. privblob = key->alg->private_blob(key->data, &privlen);
  2240. outblob = NULL;
  2241. /*
  2242. * Find the sequence of integers to be encoded into the OpenSSH
  2243. * key blob, and also decide on the header line.
  2244. */
  2245. if (key->alg == &ssh_rsa) {
  2246. int pos;
  2247. struct mpint_pos n, e, d, p, q, iqmp;
  2248. /*
  2249. * These blobs were generated from inside PuTTY, so we needn't
  2250. * treat them as untrusted.
  2251. */
  2252. pos = 4 + GET_32BIT(pubblob);
  2253. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
  2254. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
  2255. pos = 0;
  2256. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
  2257. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
  2258. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
  2259. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
  2260. assert(e.start && iqmp.start); /* can't go wrong */
  2261. numbers[0] = e;
  2262. numbers[1] = d;
  2263. numbers[2] = n;
  2264. numbers[3] = iqmp;
  2265. numbers[4] = q;
  2266. numbers[5] = p;
  2267. nnumbers = 6;
  2268. initial_zero = 0;
  2269. type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";
  2270. } else if (key->alg == &ssh_dss) {
  2271. int pos;
  2272. struct mpint_pos p, q, g, y, x;
  2273. /*
  2274. * These blobs were generated from inside PuTTY, so we needn't
  2275. * treat them as untrusted.
  2276. */
  2277. pos = 4 + GET_32BIT(pubblob);
  2278. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
  2279. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
  2280. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
  2281. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
  2282. pos = 0;
  2283. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
  2284. assert(y.start && x.start); /* can't go wrong */
  2285. numbers[0] = p;
  2286. numbers[1] = g;
  2287. numbers[2] = q;
  2288. numbers[3] = y;
  2289. numbers[4] = x;
  2290. nnumbers = 5;
  2291. initial_zero = 1;
  2292. type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}";
  2293. } else {
  2294. assert(0); /* zoinks! */
  2295. exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
  2296. }
  2297. /*
  2298. * Total size of key blob will be somewhere under 512 plus
  2299. * combined length of integers. We'll calculate the more
  2300. * precise size as we construct the blob.
  2301. */
  2302. outlen = 512;
  2303. for (i = 0; i < nnumbers; i++)
  2304. outlen += 4 + numbers[i].bytes;
  2305. outblob = snewn(outlen, unsigned char);
  2306. /*
  2307. * Create the unencrypted key blob.
  2308. */
  2309. pos = 0;
  2310. PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4;
  2311. pos += 4; /* length field, fill in later */
  2312. pos += put_string(outblob+pos, type, strlen(type));
  2313. {
  2314. const char *ciphertype = passphrase ? "3des-cbc" : "none";
  2315. pos += put_string(outblob+pos, ciphertype, strlen(ciphertype));
  2316. }
  2317. lenpos = pos; /* remember this position */
  2318. pos += 4; /* encrypted-blob size */
  2319. pos += 4; /* encrypted-payload size */
  2320. if (initial_zero) {
  2321. PUT_32BIT(outblob+pos, 0);
  2322. pos += 4;
  2323. }
  2324. for (i = 0; i < nnumbers; i++)
  2325. pos += sshcom_put_mpint(outblob+pos,
  2326. numbers[i].start, numbers[i].bytes);
  2327. /* Now wrap up the encrypted payload. */
  2328. PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8));
  2329. /* Pad encrypted blob to a multiple of cipher block size. */
  2330. if (passphrase) {
  2331. int padding = -(pos - (lenpos+4)) & 7;
  2332. while (padding--)
  2333. outblob[pos++] = random_byte();
  2334. }
  2335. ciphertext = (char *)outblob+lenpos+4;
  2336. cipherlen = pos - (lenpos+4);
  2337. assert(!passphrase || cipherlen % 8 == 0);
  2338. /* Wrap up the encrypted blob string. */
  2339. PUT_32BIT(outblob+lenpos, cipherlen);
  2340. /* And finally fill in the total length field. */
  2341. PUT_32BIT(outblob+4, pos);
  2342. assert(pos < outlen);
  2343. /*
  2344. * Encrypt the key.
  2345. */
  2346. if (passphrase) {
  2347. /*
  2348. * Derive encryption key from passphrase and iv/salt:
  2349. *
  2350. * - let block A equal MD5(passphrase)
  2351. * - let block B equal MD5(passphrase || A)
  2352. * - block C would be MD5(passphrase || A || B) and so on
  2353. * - encryption key is the first N bytes of A || B
  2354. */
  2355. struct MD5Context md5c;
  2356. unsigned char keybuf[32], iv[8];
  2357. MD5Init(&md5c);
  2358. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2359. MD5Final(keybuf, &md5c);
  2360. MD5Init(&md5c);
  2361. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2362. MD5Update(&md5c, keybuf, 16);
  2363. MD5Final(keybuf+16, &md5c);
  2364. /*
  2365. * Now decrypt the key blob.
  2366. */
  2367. memset(iv, 0, sizeof(iv));
  2368. des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
  2369. cipherlen);
  2370. smemclr(&md5c, sizeof(md5c));
  2371. smemclr(keybuf, sizeof(keybuf));
  2372. }
  2373. /*
  2374. * And save it. We'll use Unix line endings just in case it's
  2375. * subsequently transferred in binary mode.
  2376. */
  2377. fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
  2378. if (!fp)
  2379. goto error;
  2380. fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
  2381. fprintf(fp, "Comment: \"");
  2382. /*
  2383. * Comment header is broken with backslash-newline if it goes
  2384. * over 70 chars. Although it's surrounded by quotes, it
  2385. * _doesn't_ escape backslashes or quotes within the string.
  2386. * Don't ask me, I didn't design it.
  2387. */
  2388. {
  2389. int slen = 60; /* starts at 60 due to "Comment: " */
  2390. char *c = key->comment;
  2391. while ((int)strlen(c) > slen) {
  2392. fprintf(fp, "%.*s\\\n", slen, c);
  2393. c += slen;
  2394. slen = 70; /* allow 70 chars on subsequent lines */
  2395. }
  2396. fprintf(fp, "%s\"\n", c);
  2397. }
  2398. base64_encode(fp, outblob, pos, 70);
  2399. fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
  2400. fclose(fp);
  2401. ret = 1;
  2402. error:
  2403. if (outblob) {
  2404. smemclr(outblob, outlen);
  2405. sfree(outblob);
  2406. }
  2407. if (privblob) {
  2408. smemclr(privblob, privlen);
  2409. sfree(privblob);
  2410. }
  2411. if (pubblob) {
  2412. smemclr(pubblob, publen);
  2413. sfree(pubblob);
  2414. }
  2415. return ret;
  2416. }