import.c 82 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 = NULL;
  1384. int i;
  1385. struct ssh2_userkey *retval = NULL;
  1386. const char *errmsg;
  1387. unsigned checkint0, checkint1;
  1388. const void *priv, *string;
  1389. int privlen, stringlen, key_index;
  1390. const struct ssh_signkey *alg = NULL;
  1391. if (!key)
  1392. return NULL;
  1393. if (key->cipher != ON_E_NONE) {
  1394. unsigned char keybuf[48];
  1395. int keysize;
  1396. /*
  1397. * Construct the decryption key, and decrypt the string.
  1398. */
  1399. switch (key->cipher) {
  1400. case ON_E_NONE:
  1401. keysize = 0;
  1402. break;
  1403. case ON_E_AES256CBC:
  1404. keysize = 48; /* 32 byte key + 16 byte IV */
  1405. break;
  1406. default:
  1407. assert(0 && "Bad cipher enumeration value");
  1408. }
  1409. assert(keysize <= sizeof(keybuf));
  1410. switch (key->kdf) {
  1411. case ON_K_NONE:
  1412. memset(keybuf, 0, keysize);
  1413. break;
  1414. case ON_K_BCRYPT:
  1415. openssh_bcrypt(passphrase,
  1416. key->kdfopts.bcrypt.salt,
  1417. key->kdfopts.bcrypt.saltlen,
  1418. key->kdfopts.bcrypt.rounds,
  1419. keybuf, keysize);
  1420. break;
  1421. default:
  1422. assert(0 && "Bad kdf enumeration value");
  1423. }
  1424. switch (key->cipher) {
  1425. case ON_E_NONE:
  1426. break;
  1427. case ON_E_AES256CBC:
  1428. if (key->privatelen % 16 != 0) {
  1429. errmsg = "private key container length is not a"
  1430. " multiple of AES block size\n";
  1431. goto error;
  1432. }
  1433. {
  1434. void *ctx = aes_make_context();
  1435. aes256_key(ctx, keybuf);
  1436. aes_iv(ctx, keybuf + 32);
  1437. aes_ssh2_decrypt_blk(ctx, key->privatestr,
  1438. key->privatelen);
  1439. aes_free_context(ctx);
  1440. }
  1441. break;
  1442. default:
  1443. assert(0 && "Bad cipher enumeration value");
  1444. }
  1445. }
  1446. /*
  1447. * Now parse the entire encrypted section, and extract the key
  1448. * identified by key_wanted.
  1449. */
  1450. priv = key->privatestr;
  1451. privlen = key->privatelen;
  1452. if (!get_ssh_uint32(&privlen, &priv, &checkint0) ||
  1453. !get_ssh_uint32(&privlen, &priv, &checkint1) ||
  1454. checkint0 != checkint1) {
  1455. errmsg = "decryption check failed";
  1456. goto error;
  1457. }
  1458. retkey = NULL;
  1459. for (key_index = 0; key_index < key->nkeys; key_index++) {
  1460. const unsigned char *thiskey;
  1461. int thiskeylen;
  1462. /*
  1463. * Read the key type, which will tell us how to scan over
  1464. * the key to get to the next one.
  1465. */
  1466. if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
  1467. errmsg = "expected key type in private string";
  1468. goto error;
  1469. }
  1470. /*
  1471. * Preliminary key type identification, and decide how
  1472. * many pieces of key we expect to see. Currently
  1473. * (conveniently) all key types can be seen as some number
  1474. * of strings, so we just need to know how many of them to
  1475. * skip over. (The numbers below exclude the key comment.)
  1476. */
  1477. {
  1478. /* find_pubkey_alg needs a zero-terminated copy of the
  1479. * algorithm name */
  1480. char *name_zt = dupprintf("%.*s", stringlen, (char *)string);
  1481. alg = find_pubkey_alg(name_zt);
  1482. sfree(name_zt);
  1483. }
  1484. if (!alg) {
  1485. errmsg = "private key type not recognised\n";
  1486. goto error;
  1487. }
  1488. thiskey = priv;
  1489. /*
  1490. * Skip over the pieces of key.
  1491. */
  1492. for (i = 0; i < alg->openssh_private_npieces; i++) {
  1493. if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
  1494. errmsg = "ran out of data in mid-private-key";
  1495. goto error;
  1496. }
  1497. }
  1498. thiskeylen = (int)((const unsigned char *)priv -
  1499. (const unsigned char *)thiskey);
  1500. if (key_index == key->key_wanted) {
  1501. retkey = snew(struct ssh2_userkey);
  1502. retkey->comment = NULL;
  1503. retkey->alg = alg;
  1504. retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
  1505. if (!retkey->data) {
  1506. errmsg = "unable to create key data structure";
  1507. goto error;
  1508. }
  1509. }
  1510. /*
  1511. * Read the key comment.
  1512. */
  1513. if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
  1514. errmsg = "ran out of data at key comment";
  1515. goto error;
  1516. }
  1517. if (key_index == key->key_wanted) {
  1518. assert(retkey);
  1519. retkey->comment = dupprintf("%.*s", stringlen,
  1520. (const char *)string);
  1521. }
  1522. }
  1523. if (!retkey) {
  1524. errmsg = "key index out of range";
  1525. goto error;
  1526. }
  1527. /*
  1528. * Now we expect nothing left but padding.
  1529. */
  1530. for (i = 0; i < privlen; i++) {
  1531. if (((const unsigned char *)priv)[i] != (unsigned char)(i+1)) {
  1532. errmsg = "padding at end of private string did not match";
  1533. goto error;
  1534. }
  1535. }
  1536. errmsg = NULL; /* no error */
  1537. retval = retkey;
  1538. retkey = NULL; /* prevent the free */
  1539. error:
  1540. if (retkey) {
  1541. sfree(retkey->comment);
  1542. if (retkey->data) {
  1543. assert(alg);
  1544. alg->freekey(retkey->data);
  1545. }
  1546. sfree(retkey);
  1547. }
  1548. smemclr(key->keyblob, key->keyblob_size);
  1549. sfree(key->keyblob);
  1550. smemclr(key, sizeof(*key));
  1551. sfree(key);
  1552. if (errmsg_p) *errmsg_p = errmsg;
  1553. return retval;
  1554. }
  1555. int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
  1556. char *passphrase)
  1557. {
  1558. unsigned char *pubblob, *privblob, *outblob, *p;
  1559. unsigned char *private_section_start, *private_section_length_field;
  1560. int publen, privlen, commentlen, maxsize, padvalue, i;
  1561. unsigned checkint;
  1562. int ret = 0;
  1563. unsigned char bcrypt_salt[16];
  1564. const int bcrypt_rounds = 16;
  1565. FILE *fp;
  1566. /*
  1567. * Fetch the key blobs and find out the lengths of things.
  1568. */
  1569. pubblob = key->alg->public_blob(key->data, &publen);
  1570. i = key->alg->openssh_fmtkey(key->data, NULL, 0);
  1571. privblob = snewn(i, unsigned char);
  1572. privlen = key->alg->openssh_fmtkey(key->data, privblob, i);
  1573. assert(privlen == i);
  1574. commentlen = strlen(key->comment);
  1575. /*
  1576. * Allocate enough space for the full binary key format. No need
  1577. * to be absolutely precise here.
  1578. */
  1579. maxsize = (16 + /* magic number */
  1580. 32 + /* cipher name string */
  1581. 32 + /* kdf name string */
  1582. 64 + /* kdf options string */
  1583. 4 + /* key count */
  1584. 4+publen + /* public key string */
  1585. 4 + /* string header for private section */
  1586. 8 + /* checkint x 2 */
  1587. 4+strlen(key->alg->name) + /* key type string */
  1588. privlen + /* private blob */
  1589. 4+commentlen + /* comment string */
  1590. 16); /* padding at end of private section */
  1591. outblob = snewn(maxsize, unsigned char);
  1592. /*
  1593. * Construct the cleartext version of the blob.
  1594. */
  1595. p = outblob;
  1596. /* Magic number. */
  1597. memcpy(p, "openssh-key-v1\0", 15);
  1598. p += 15;
  1599. /* Cipher and kdf names, and kdf options. */
  1600. if (!passphrase) {
  1601. memset(bcrypt_salt, 0, sizeof(bcrypt_salt)); /* prevent warnings */
  1602. p += put_string_z(p, "none");
  1603. p += put_string_z(p, "none");
  1604. p += put_string_z(p, "");
  1605. } else {
  1606. unsigned char *q;
  1607. for (i = 0; i < (int)sizeof(bcrypt_salt); i++)
  1608. bcrypt_salt[i] = random_byte();
  1609. p += put_string_z(p, "aes256-cbc");
  1610. p += put_string_z(p, "bcrypt");
  1611. q = p;
  1612. p += 4;
  1613. p += put_string(p, bcrypt_salt, sizeof(bcrypt_salt));
  1614. p += put_uint32(p, bcrypt_rounds);
  1615. PUT_32BIT_MSB_FIRST(q, (unsigned)(p - (q+4)));
  1616. }
  1617. /* Number of keys. */
  1618. p += put_uint32(p, 1);
  1619. /* Public blob. */
  1620. p += put_string(p, pubblob, publen);
  1621. /* Begin private section. */
  1622. private_section_length_field = p;
  1623. p += 4;
  1624. private_section_start = p;
  1625. /* checkint. */
  1626. checkint = 0;
  1627. for (i = 0; i < 4; i++)
  1628. checkint = (checkint << 8) + random_byte();
  1629. p += put_uint32(p, checkint);
  1630. p += put_uint32(p, checkint);
  1631. /* Private key. The main private blob goes inline, with no string
  1632. * wrapper. */
  1633. p += put_string_z(p, key->alg->name);
  1634. memcpy(p, privblob, privlen);
  1635. p += privlen;
  1636. /* Comment. */
  1637. p += put_string_z(p, key->comment);
  1638. /* Pad out the encrypted section. */
  1639. padvalue = 1;
  1640. do {
  1641. *p++ = padvalue++;
  1642. } while ((p - private_section_start) & 15);
  1643. assert(p - outblob < maxsize);
  1644. /* Go back and fill in the length field for the private section. */
  1645. PUT_32BIT_MSB_FIRST(private_section_length_field,
  1646. p - private_section_start);
  1647. if (passphrase) {
  1648. /*
  1649. * Encrypt the private section. We need 48 bytes of key
  1650. * material: 32 bytes AES key + 16 bytes iv.
  1651. */
  1652. unsigned char keybuf[48];
  1653. void *ctx;
  1654. openssh_bcrypt(passphrase,
  1655. bcrypt_salt, sizeof(bcrypt_salt), bcrypt_rounds,
  1656. keybuf, sizeof(keybuf));
  1657. ctx = aes_make_context();
  1658. aes256_key(ctx, keybuf);
  1659. aes_iv(ctx, keybuf + 32);
  1660. aes_ssh2_encrypt_blk(ctx, private_section_start,
  1661. p - private_section_start);
  1662. aes_free_context(ctx);
  1663. smemclr(keybuf, sizeof(keybuf));
  1664. }
  1665. /*
  1666. * And save it. We'll use Unix line endings just in case it's
  1667. * subsequently transferred in binary mode.
  1668. */
  1669. fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
  1670. if (!fp)
  1671. goto error;
  1672. fputs("-----BEGIN OPENSSH PRIVATE KEY-----\n", fp);
  1673. base64_encode(fp, outblob, p - outblob, 64);
  1674. fputs("-----END OPENSSH PRIVATE KEY-----\n", fp);
  1675. fclose(fp);
  1676. ret = 1;
  1677. error:
  1678. if (outblob) {
  1679. smemclr(outblob, maxsize);
  1680. sfree(outblob);
  1681. }
  1682. if (privblob) {
  1683. smemclr(privblob, privlen);
  1684. sfree(privblob);
  1685. }
  1686. if (pubblob) {
  1687. smemclr(pubblob, publen);
  1688. sfree(pubblob);
  1689. }
  1690. return ret;
  1691. }
  1692. /* ----------------------------------------------------------------------
  1693. * The switch function openssh_auto_write(), which chooses one of the
  1694. * concrete OpenSSH output formats based on the key type.
  1695. */
  1696. int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
  1697. char *passphrase)
  1698. {
  1699. /*
  1700. * The old OpenSSH format supports a fixed list of key types. We
  1701. * assume that anything not in that fixed list is newer, and hence
  1702. * will use the new format.
  1703. */
  1704. if (key->alg == &ssh_dss ||
  1705. key->alg == &ssh_rsa ||
  1706. key->alg == &ssh_ecdsa_nistp256 ||
  1707. key->alg == &ssh_ecdsa_nistp384 ||
  1708. key->alg == &ssh_ecdsa_nistp521)
  1709. return openssh_pem_write(filename, key, passphrase);
  1710. else
  1711. return openssh_new_write(filename, key, passphrase);
  1712. }
  1713. /* ----------------------------------------------------------------------
  1714. * Code to read ssh.com private keys.
  1715. */
  1716. /*
  1717. * The format of the base64 blob is largely SSH-2-packet-formatted,
  1718. * except that mpints are a bit different: they're more like the
  1719. * old SSH-1 mpint. You have a 32-bit bit count N, followed by
  1720. * (N+7)/8 bytes of data.
  1721. *
  1722. * So. The blob contains:
  1723. *
  1724. * - uint32 0x3f6ff9eb (magic number)
  1725. * - uint32 size (total blob size)
  1726. * - string key-type (see below)
  1727. * - string cipher-type (tells you if key is encrypted)
  1728. * - string encrypted-blob
  1729. *
  1730. * (The first size field includes the size field itself and the
  1731. * magic number before it. All other size fields are ordinary SSH-2
  1732. * strings, so the size field indicates how much data is to
  1733. * _follow_.)
  1734. *
  1735. * The encrypted blob, once decrypted, contains a single string
  1736. * which in turn contains the payload. (This allows padding to be
  1737. * added after that string while still making it clear where the
  1738. * real payload ends. Also it probably makes for a reasonable
  1739. * decryption check.)
  1740. *
  1741. * The payload blob, for an RSA key, contains:
  1742. * - mpint e
  1743. * - mpint d
  1744. * - mpint n (yes, the public and private stuff is intermixed)
  1745. * - mpint u (presumably inverse of p mod q)
  1746. * - mpint p (p is the smaller prime)
  1747. * - mpint q (q is the larger)
  1748. *
  1749. * For a DSA key, the payload blob contains:
  1750. * - uint32 0
  1751. * - mpint p
  1752. * - mpint g
  1753. * - mpint q
  1754. * - mpint y
  1755. * - mpint x
  1756. *
  1757. * Alternatively, if the parameters are `predefined', that
  1758. * (0,p,g,q) sequence can be replaced by a uint32 1 and a string
  1759. * containing some predefined parameter specification. *shudder*,
  1760. * but I doubt we'll encounter this in real life.
  1761. *
  1762. * The key type strings are ghastly. The RSA key I looked at had a
  1763. * type string of
  1764. *
  1765. * `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
  1766. *
  1767. * and the DSA key wasn't much better:
  1768. *
  1769. * `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
  1770. *
  1771. * It isn't clear that these will always be the same. I think it
  1772. * might be wise just to look at the `if-modn{sign{rsa' and
  1773. * `dl-modp{sign{dsa' prefixes.
  1774. *
  1775. * Finally, the encryption. The cipher-type string appears to be
  1776. * either `none' or `3des-cbc'. Looks as if this is SSH-2-style
  1777. * 3des-cbc (i.e. outer cbc rather than inner). The key is created
  1778. * from the passphrase by means of yet another hashing faff:
  1779. *
  1780. * - first 16 bytes are MD5(passphrase)
  1781. * - next 16 bytes are MD5(passphrase || first 16 bytes)
  1782. * - if there were more, they'd be MD5(passphrase || first 32),
  1783. * and so on.
  1784. */
  1785. #define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb
  1786. struct sshcom_key {
  1787. char comment[256]; /* allowing any length is overkill */
  1788. unsigned char *keyblob;
  1789. int keyblob_len, keyblob_size;
  1790. };
  1791. static struct sshcom_key *load_sshcom_key(const Filename *filename,
  1792. const char **errmsg_p)
  1793. {
  1794. struct sshcom_key *ret;
  1795. FILE *fp;
  1796. char *line = NULL;
  1797. int hdrstart, len;
  1798. const char *errmsg;
  1799. char *p;
  1800. int headers_done;
  1801. char base64_bit[4];
  1802. int base64_chars = 0;
  1803. ret = snew(struct sshcom_key);
  1804. ret->comment[0] = '\0';
  1805. ret->keyblob = NULL;
  1806. ret->keyblob_len = ret->keyblob_size = 0;
  1807. fp = f_open(filename, "r", FALSE);
  1808. if (!fp) {
  1809. errmsg = "unable to open key file";
  1810. goto error;
  1811. }
  1812. if (!(line = fgetline(fp))) {
  1813. errmsg = "unexpected end of file";
  1814. goto error;
  1815. }
  1816. strip_crlf(line);
  1817. if (0 != strcmp(line, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----")) {
  1818. errmsg = "file does not begin with ssh.com key header";
  1819. goto error;
  1820. }
  1821. smemclr(line, strlen(line));
  1822. sfree(line);
  1823. line = NULL;
  1824. headers_done = 0;
  1825. while (1) {
  1826. if (!(line = fgetline(fp))) {
  1827. errmsg = "unexpected end of file";
  1828. goto error;
  1829. }
  1830. strip_crlf(line);
  1831. if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) {
  1832. sfree(line);
  1833. line = NULL;
  1834. break; /* done */
  1835. }
  1836. if ((p = strchr(line, ':')) != NULL) {
  1837. if (headers_done) {
  1838. errmsg = "header found in body of key data";
  1839. goto error;
  1840. }
  1841. *p++ = '\0';
  1842. while (*p && isspace((unsigned char)*p)) p++;
  1843. hdrstart = p - line;
  1844. /*
  1845. * Header lines can end in a trailing backslash for
  1846. * continuation.
  1847. */
  1848. len = hdrstart + strlen(line+hdrstart);
  1849. assert(!line[len]);
  1850. while (line[len-1] == '\\') {
  1851. char *line2;
  1852. int line2len;
  1853. line2 = fgetline(fp);
  1854. if (!line2) {
  1855. errmsg = "unexpected end of file";
  1856. goto error;
  1857. }
  1858. strip_crlf(line2);
  1859. line2len = strlen(line2);
  1860. line = sresize(line, len + line2len + 1, char);
  1861. strcpy(line + len - 1, line2);
  1862. len += line2len - 1;
  1863. assert(!line[len]);
  1864. smemclr(line2, strlen(line2));
  1865. sfree(line2);
  1866. line2 = NULL;
  1867. }
  1868. p = line + hdrstart;
  1869. strip_crlf(p);
  1870. if (!strcmp(line, "Comment")) {
  1871. /* Strip quotes in comment if present. */
  1872. if (p[0] == '"' && p[strlen(p)-1] == '"') {
  1873. p++;
  1874. p[strlen(p)-1] = '\0';
  1875. }
  1876. strncpy(ret->comment, p, sizeof(ret->comment));
  1877. ret->comment[sizeof(ret->comment)-1] = '\0';
  1878. }
  1879. } else {
  1880. headers_done = 1;
  1881. p = line;
  1882. while (isbase64(*p)) {
  1883. base64_bit[base64_chars++] = *p;
  1884. if (base64_chars == 4) {
  1885. unsigned char out[3];
  1886. base64_chars = 0;
  1887. len = base64_decode_atom(base64_bit, out);
  1888. if (len <= 0) {
  1889. errmsg = "invalid base64 encoding";
  1890. goto error;
  1891. }
  1892. if (ret->keyblob_len + len > ret->keyblob_size) {
  1893. ret->keyblob_size = ret->keyblob_len + len + 256;
  1894. ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
  1895. unsigned char);
  1896. }
  1897. memcpy(ret->keyblob + ret->keyblob_len, out, len);
  1898. ret->keyblob_len += len;
  1899. }
  1900. p++;
  1901. }
  1902. }
  1903. smemclr(line, strlen(line));
  1904. sfree(line);
  1905. line = NULL;
  1906. }
  1907. if (ret->keyblob_len == 0 || !ret->keyblob) {
  1908. errmsg = "key body not present";
  1909. goto error;
  1910. }
  1911. fclose(fp);
  1912. if (errmsg_p) *errmsg_p = NULL;
  1913. return ret;
  1914. error:
  1915. if (fp)
  1916. fclose(fp);
  1917. if (line) {
  1918. smemclr(line, strlen(line));
  1919. sfree(line);
  1920. line = NULL;
  1921. }
  1922. if (ret) {
  1923. if (ret->keyblob) {
  1924. smemclr(ret->keyblob, ret->keyblob_size);
  1925. sfree(ret->keyblob);
  1926. }
  1927. smemclr(ret, sizeof(*ret));
  1928. sfree(ret);
  1929. }
  1930. if (errmsg_p) *errmsg_p = errmsg;
  1931. return NULL;
  1932. }
  1933. int sshcom_encrypted(const Filename *filename, char **comment)
  1934. {
  1935. struct sshcom_key *key = load_sshcom_key(filename, NULL);
  1936. int pos, len, answer;
  1937. answer = 0;
  1938. *comment = NULL;
  1939. if (!key)
  1940. goto done;
  1941. /*
  1942. * Check magic number.
  1943. */
  1944. if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) {
  1945. goto done; /* key is invalid */
  1946. }
  1947. /*
  1948. * Find the cipher-type string.
  1949. */
  1950. pos = 8;
  1951. if (key->keyblob_len < pos+4)
  1952. goto done; /* key is far too short */
  1953. len = toint(GET_32BIT(key->keyblob + pos));
  1954. if (len < 0 || len > key->keyblob_len - pos - 4)
  1955. goto done; /* key is far too short */
  1956. pos += 4 + len; /* skip key type */
  1957. len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */
  1958. if (len < 0 || len > key->keyblob_len - pos - 4)
  1959. goto done; /* cipher type string is incomplete */
  1960. if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
  1961. answer = 1;
  1962. done:
  1963. if (key) {
  1964. *comment = dupstr(key->comment);
  1965. smemclr(key->keyblob, key->keyblob_size);
  1966. sfree(key->keyblob);
  1967. smemclr(key, sizeof(*key));
  1968. sfree(key);
  1969. } else {
  1970. *comment = dupstr("");
  1971. }
  1972. return answer;
  1973. }
  1974. static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
  1975. {
  1976. unsigned bits, bytes;
  1977. unsigned char *d = (unsigned char *) data;
  1978. if (len < 4)
  1979. goto error;
  1980. bits = GET_32BIT(d);
  1981. bytes = (bits + 7) / 8;
  1982. if (len < 4+bytes)
  1983. goto error;
  1984. ret->start = d + 4;
  1985. ret->bytes = bytes;
  1986. return bytes+4;
  1987. error:
  1988. ret->start = NULL;
  1989. ret->bytes = -1;
  1990. return len; /* ensure further calls fail as well */
  1991. }
  1992. static int sshcom_put_mpint(void *target, void *data, int len)
  1993. {
  1994. unsigned char *d = (unsigned char *)target;
  1995. unsigned char *i = (unsigned char *)data;
  1996. int bits = len * 8 - 1;
  1997. while (bits > 0) {
  1998. if (*i & (1 << (bits & 7)))
  1999. break;
  2000. if (!(bits-- & 7))
  2001. i++, len--;
  2002. }
  2003. PUT_32BIT(d, bits+1);
  2004. memcpy(d+4, i, len);
  2005. return len+4;
  2006. }
  2007. struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
  2008. const char **errmsg_p)
  2009. {
  2010. struct sshcom_key *key = load_sshcom_key(filename, errmsg_p);
  2011. const char *errmsg;
  2012. int pos, len;
  2013. const char prefix_rsa[] = "if-modn{sign{rsa";
  2014. const char prefix_dsa[] = "dl-modp{sign{dsa";
  2015. enum { RSA, DSA } type;
  2016. int encrypted;
  2017. char *ciphertext;
  2018. int cipherlen;
  2019. struct ssh2_userkey *ret = NULL, *retkey;
  2020. const struct ssh_signkey *alg;
  2021. unsigned char *blob = NULL;
  2022. int blobsize = 0, publen, privlen;
  2023. if (!key)
  2024. return NULL;
  2025. /*
  2026. * Check magic number.
  2027. */
  2028. if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
  2029. errmsg = "key does not begin with magic number";
  2030. goto error;
  2031. }
  2032. /*
  2033. * Determine the key type.
  2034. */
  2035. pos = 8;
  2036. if (key->keyblob_len < pos+4 ||
  2037. (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
  2038. len > key->keyblob_len - pos - 4) {
  2039. errmsg = "key blob does not contain a key type string";
  2040. goto error;
  2041. }
  2042. if (len > sizeof(prefix_rsa) - 1 &&
  2043. !memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) {
  2044. type = RSA;
  2045. } else if (len > sizeof(prefix_dsa) - 1 &&
  2046. !memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
  2047. type = DSA;
  2048. } else {
  2049. errmsg = "key is of unknown type";
  2050. goto error;
  2051. }
  2052. pos += 4+len;
  2053. /*
  2054. * Determine the cipher type.
  2055. */
  2056. if (key->keyblob_len < pos+4 ||
  2057. (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
  2058. len > key->keyblob_len - pos - 4) {
  2059. errmsg = "key blob does not contain a cipher type string";
  2060. goto error;
  2061. }
  2062. if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
  2063. encrypted = 0;
  2064. else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
  2065. encrypted = 1;
  2066. else {
  2067. errmsg = "key encryption is of unknown type";
  2068. goto error;
  2069. }
  2070. pos += 4+len;
  2071. /*
  2072. * Get hold of the encrypted part of the key.
  2073. */
  2074. if (key->keyblob_len < pos+4 ||
  2075. (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
  2076. len > key->keyblob_len - pos - 4) {
  2077. errmsg = "key blob does not contain actual key data";
  2078. goto error;
  2079. }
  2080. ciphertext = (char *)key->keyblob + pos + 4;
  2081. cipherlen = len;
  2082. if (cipherlen == 0) {
  2083. errmsg = "length of key data is zero";
  2084. goto error;
  2085. }
  2086. /*
  2087. * Decrypt it if necessary.
  2088. */
  2089. if (encrypted) {
  2090. /*
  2091. * Derive encryption key from passphrase and iv/salt:
  2092. *
  2093. * - let block A equal MD5(passphrase)
  2094. * - let block B equal MD5(passphrase || A)
  2095. * - block C would be MD5(passphrase || A || B) and so on
  2096. * - encryption key is the first N bytes of A || B
  2097. */
  2098. struct MD5Context md5c;
  2099. unsigned char keybuf[32], iv[8];
  2100. if (cipherlen % 8 != 0) {
  2101. errmsg = "encrypted part of key is not a multiple of cipher block"
  2102. " size";
  2103. goto error;
  2104. }
  2105. MD5Init(&md5c);
  2106. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2107. MD5Final(keybuf, &md5c);
  2108. MD5Init(&md5c);
  2109. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2110. MD5Update(&md5c, keybuf, 16);
  2111. MD5Final(keybuf+16, &md5c);
  2112. /*
  2113. * Now decrypt the key blob.
  2114. */
  2115. memset(iv, 0, sizeof(iv));
  2116. des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
  2117. cipherlen);
  2118. smemclr(&md5c, sizeof(md5c));
  2119. smemclr(keybuf, sizeof(keybuf));
  2120. /*
  2121. * Hereafter we return WRONG_PASSPHRASE for any parsing
  2122. * error. (But only if we've just tried to decrypt it!
  2123. * Returning WRONG_PASSPHRASE for an unencrypted key is
  2124. * automatic doom.)
  2125. */
  2126. if (encrypted)
  2127. ret = SSH2_WRONG_PASSPHRASE;
  2128. }
  2129. /*
  2130. * Strip away the containing string to get to the real meat.
  2131. */
  2132. len = toint(GET_32BIT(ciphertext));
  2133. if (len < 0 || len > cipherlen-4) {
  2134. errmsg = "containing string was ill-formed";
  2135. goto error;
  2136. }
  2137. ciphertext += 4;
  2138. cipherlen = len;
  2139. /*
  2140. * Now we break down into RSA versus DSA. In either case we'll
  2141. * construct public and private blobs in our own format, and
  2142. * end up feeding them to alg->createkey().
  2143. */
  2144. blobsize = cipherlen + 256;
  2145. blob = snewn(blobsize, unsigned char);
  2146. privlen = 0;
  2147. if (type == RSA) {
  2148. struct mpint_pos n, e, d, u, p, q;
  2149. int pos = 0;
  2150. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);
  2151. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);
  2152. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);
  2153. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);
  2154. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
  2155. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
  2156. if (!q.start) {
  2157. errmsg = "key data did not contain six integers";
  2158. goto error;
  2159. }
  2160. alg = &ssh_rsa;
  2161. pos = 0;
  2162. pos += put_string(blob+pos, "ssh-rsa", 7);
  2163. pos += put_mp(blob+pos, e.start, e.bytes);
  2164. pos += put_mp(blob+pos, n.start, n.bytes);
  2165. publen = pos;
  2166. pos += put_string(blob+pos, d.start, d.bytes);
  2167. pos += put_mp(blob+pos, q.start, q.bytes);
  2168. pos += put_mp(blob+pos, p.start, p.bytes);
  2169. pos += put_mp(blob+pos, u.start, u.bytes);
  2170. privlen = pos - publen;
  2171. } else {
  2172. struct mpint_pos p, q, g, x, y;
  2173. int pos = 4;
  2174. assert(type == DSA); /* the only other option from the if above */
  2175. if (GET_32BIT(ciphertext) != 0) {
  2176. errmsg = "predefined DSA parameters not supported";
  2177. goto error;
  2178. }
  2179. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
  2180. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);
  2181. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
  2182. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);
  2183. pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);
  2184. if (!x.start) {
  2185. errmsg = "key data did not contain five integers";
  2186. goto error;
  2187. }
  2188. alg = &ssh_dss;
  2189. pos = 0;
  2190. pos += put_string(blob+pos, "ssh-dss", 7);
  2191. pos += put_mp(blob+pos, p.start, p.bytes);
  2192. pos += put_mp(blob+pos, q.start, q.bytes);
  2193. pos += put_mp(blob+pos, g.start, g.bytes);
  2194. pos += put_mp(blob+pos, y.start, y.bytes);
  2195. publen = pos;
  2196. pos += put_mp(blob+pos, x.start, x.bytes);
  2197. privlen = pos - publen;
  2198. }
  2199. assert(privlen > 0); /* should have bombed by now if not */
  2200. retkey = snew(struct ssh2_userkey);
  2201. retkey->alg = alg;
  2202. retkey->data = alg->createkey(alg, blob, publen, blob+publen, privlen);
  2203. if (!retkey->data) {
  2204. sfree(retkey);
  2205. errmsg = "unable to create key data structure";
  2206. goto error;
  2207. }
  2208. retkey->comment = dupstr(key->comment);
  2209. errmsg = NULL; /* no error */
  2210. ret = retkey;
  2211. error:
  2212. if (blob) {
  2213. smemclr(blob, blobsize);
  2214. sfree(blob);
  2215. }
  2216. smemclr(key->keyblob, key->keyblob_size);
  2217. sfree(key->keyblob);
  2218. smemclr(key, sizeof(*key));
  2219. sfree(key);
  2220. if (errmsg_p) *errmsg_p = errmsg;
  2221. return ret;
  2222. }
  2223. int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
  2224. char *passphrase)
  2225. {
  2226. unsigned char *pubblob, *privblob;
  2227. int publen, privlen;
  2228. unsigned char *outblob;
  2229. int outlen;
  2230. struct mpint_pos numbers[6];
  2231. int nnumbers, initial_zero, pos, lenpos, i;
  2232. const char *type;
  2233. char *ciphertext;
  2234. int cipherlen;
  2235. int ret = 0;
  2236. FILE *fp;
  2237. /*
  2238. * Fetch the key blobs.
  2239. */
  2240. pubblob = key->alg->public_blob(key->data, &publen);
  2241. privblob = key->alg->private_blob(key->data, &privlen);
  2242. outblob = NULL;
  2243. /*
  2244. * Find the sequence of integers to be encoded into the OpenSSH
  2245. * key blob, and also decide on the header line.
  2246. */
  2247. if (key->alg == &ssh_rsa) {
  2248. int pos;
  2249. struct mpint_pos n, e, d, p, q, iqmp;
  2250. /*
  2251. * These blobs were generated from inside PuTTY, so we needn't
  2252. * treat them as untrusted.
  2253. */
  2254. pos = 4 + GET_32BIT(pubblob);
  2255. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
  2256. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
  2257. pos = 0;
  2258. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
  2259. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
  2260. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
  2261. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);
  2262. assert(e.start && iqmp.start); /* can't go wrong */
  2263. numbers[0] = e;
  2264. numbers[1] = d;
  2265. numbers[2] = n;
  2266. numbers[3] = iqmp;
  2267. numbers[4] = q;
  2268. numbers[5] = p;
  2269. nnumbers = 6;
  2270. initial_zero = 0;
  2271. type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";
  2272. } else if (key->alg == &ssh_dss) {
  2273. int pos;
  2274. struct mpint_pos p, q, g, y, x;
  2275. /*
  2276. * These blobs were generated from inside PuTTY, so we needn't
  2277. * treat them as untrusted.
  2278. */
  2279. pos = 4 + GET_32BIT(pubblob);
  2280. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
  2281. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
  2282. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
  2283. pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
  2284. pos = 0;
  2285. pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);
  2286. assert(y.start && x.start); /* can't go wrong */
  2287. numbers[0] = p;
  2288. numbers[1] = g;
  2289. numbers[2] = q;
  2290. numbers[3] = y;
  2291. numbers[4] = x;
  2292. nnumbers = 5;
  2293. initial_zero = 1;
  2294. type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}";
  2295. } else {
  2296. assert(0); /* zoinks! */
  2297. exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
  2298. }
  2299. /*
  2300. * Total size of key blob will be somewhere under 512 plus
  2301. * combined length of integers. We'll calculate the more
  2302. * precise size as we construct the blob.
  2303. */
  2304. outlen = 512;
  2305. for (i = 0; i < nnumbers; i++)
  2306. outlen += 4 + numbers[i].bytes;
  2307. outblob = snewn(outlen, unsigned char);
  2308. /*
  2309. * Create the unencrypted key blob.
  2310. */
  2311. pos = 0;
  2312. PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4;
  2313. pos += 4; /* length field, fill in later */
  2314. pos += put_string(outblob+pos, type, strlen(type));
  2315. {
  2316. const char *ciphertype = passphrase ? "3des-cbc" : "none";
  2317. pos += put_string(outblob+pos, ciphertype, strlen(ciphertype));
  2318. }
  2319. lenpos = pos; /* remember this position */
  2320. pos += 4; /* encrypted-blob size */
  2321. pos += 4; /* encrypted-payload size */
  2322. if (initial_zero) {
  2323. PUT_32BIT(outblob+pos, 0);
  2324. pos += 4;
  2325. }
  2326. for (i = 0; i < nnumbers; i++)
  2327. pos += sshcom_put_mpint(outblob+pos,
  2328. numbers[i].start, numbers[i].bytes);
  2329. /* Now wrap up the encrypted payload. */
  2330. PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8));
  2331. /* Pad encrypted blob to a multiple of cipher block size. */
  2332. if (passphrase) {
  2333. int padding = -(pos - (lenpos+4)) & 7;
  2334. while (padding--)
  2335. outblob[pos++] = random_byte();
  2336. }
  2337. ciphertext = (char *)outblob+lenpos+4;
  2338. cipherlen = pos - (lenpos+4);
  2339. assert(!passphrase || cipherlen % 8 == 0);
  2340. /* Wrap up the encrypted blob string. */
  2341. PUT_32BIT(outblob+lenpos, cipherlen);
  2342. /* And finally fill in the total length field. */
  2343. PUT_32BIT(outblob+4, pos);
  2344. assert(pos < outlen);
  2345. /*
  2346. * Encrypt the key.
  2347. */
  2348. if (passphrase) {
  2349. /*
  2350. * Derive encryption key from passphrase and iv/salt:
  2351. *
  2352. * - let block A equal MD5(passphrase)
  2353. * - let block B equal MD5(passphrase || A)
  2354. * - block C would be MD5(passphrase || A || B) and so on
  2355. * - encryption key is the first N bytes of A || B
  2356. */
  2357. struct MD5Context md5c;
  2358. unsigned char keybuf[32], iv[8];
  2359. MD5Init(&md5c);
  2360. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2361. MD5Final(keybuf, &md5c);
  2362. MD5Init(&md5c);
  2363. MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
  2364. MD5Update(&md5c, keybuf, 16);
  2365. MD5Final(keybuf+16, &md5c);
  2366. /*
  2367. * Now decrypt the key blob.
  2368. */
  2369. memset(iv, 0, sizeof(iv));
  2370. des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
  2371. cipherlen);
  2372. smemclr(&md5c, sizeof(md5c));
  2373. smemclr(keybuf, sizeof(keybuf));
  2374. }
  2375. /*
  2376. * And save it. We'll use Unix line endings just in case it's
  2377. * subsequently transferred in binary mode.
  2378. */
  2379. fp = f_open(filename, "wb", TRUE); /* ensure Unix line endings */
  2380. if (!fp)
  2381. goto error;
  2382. fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
  2383. fprintf(fp, "Comment: \"");
  2384. /*
  2385. * Comment header is broken with backslash-newline if it goes
  2386. * over 70 chars. Although it's surrounded by quotes, it
  2387. * _doesn't_ escape backslashes or quotes within the string.
  2388. * Don't ask me, I didn't design it.
  2389. */
  2390. {
  2391. int slen = 60; /* starts at 60 due to "Comment: " */
  2392. char *c = key->comment;
  2393. while ((int)strlen(c) > slen) {
  2394. fprintf(fp, "%.*s\\\n", slen, c);
  2395. c += slen;
  2396. slen = 70; /* allow 70 chars on subsequent lines */
  2397. }
  2398. fprintf(fp, "%s\"\n", c);
  2399. }
  2400. base64_encode(fp, outblob, pos, 70);
  2401. fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
  2402. fclose(fp);
  2403. ret = 1;
  2404. error:
  2405. if (outblob) {
  2406. smemclr(outblob, outlen);
  2407. sfree(outblob);
  2408. }
  2409. if (privblob) {
  2410. smemclr(privblob, privlen);
  2411. sfree(privblob);
  2412. }
  2413. if (pubblob) {
  2414. smemclr(pubblob, publen);
  2415. sfree(pubblob);
  2416. }
  2417. return ret;
  2418. }