import.c 82 KB

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