pgp.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2013 Free Software Foundation, Inc.
  4. *
  5. * GRUB is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * GRUB is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <grub/types.h>
  19. #include <grub/misc.h>
  20. #include <grub/mm.h>
  21. #include <grub/err.h>
  22. #include <grub/dl.h>
  23. #include <grub/file.h>
  24. #include <grub/command.h>
  25. #include <grub/crypto.h>
  26. #include <grub/i18n.h>
  27. #include <grub/gcrypt/gcrypt.h>
  28. #include <grub/pubkey.h>
  29. #include <grub/env.h>
  30. #include <grub/kernel.h>
  31. #include <grub/extcmd.h>
  32. #include <grub/verify.h>
  33. GRUB_MOD_LICENSE ("GPLv3+");
  34. enum
  35. {
  36. OPTION_SKIP_SIG = 0
  37. };
  38. static const struct grub_arg_option options[] =
  39. {
  40. {"skip-sig", 's', 0,
  41. N_("Skip signature-checking of the public key file."), 0, ARG_TYPE_NONE},
  42. {0, 0, 0, 0, 0, 0}
  43. };
  44. static grub_err_t
  45. read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len)
  46. {
  47. grub_uint8_t type;
  48. grub_uint8_t l;
  49. grub_uint16_t l16;
  50. grub_uint32_t l32;
  51. /* New format. */
  52. switch (grub_file_read (sig, &type, sizeof (type)))
  53. {
  54. case 1:
  55. break;
  56. case 0:
  57. {
  58. *out_type = 0xff;
  59. return 0;
  60. }
  61. default:
  62. if (grub_errno)
  63. return grub_errno;
  64. /* TRANSLATORS: it's about GNUPG signatures. */
  65. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  66. }
  67. if (type == 0)
  68. {
  69. *out_type = 0xfe;
  70. return 0;
  71. }
  72. if (!(type & 0x80))
  73. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  74. if (type & 0x40)
  75. {
  76. *out_type = (type & 0x3f);
  77. if (grub_file_read (sig, &l, sizeof (l)) != 1)
  78. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  79. if (l < 192)
  80. {
  81. *len = l;
  82. return 0;
  83. }
  84. if (l < 224)
  85. {
  86. *len = (l - 192) << GRUB_CHAR_BIT;
  87. if (grub_file_read (sig, &l, sizeof (l)) != 1)
  88. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  89. *len |= l;
  90. return 0;
  91. }
  92. if (l == 255)
  93. {
  94. if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32))
  95. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  96. *len = grub_be_to_cpu32 (l32);
  97. return 0;
  98. }
  99. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  100. }
  101. *out_type = ((type >> 2) & 0xf);
  102. switch (type & 0x3)
  103. {
  104. case 0:
  105. if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
  106. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  107. *len = l;
  108. return 0;
  109. case 1:
  110. if (grub_file_read (sig, &l16, sizeof (l16)) != sizeof (l16))
  111. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  112. *len = grub_be_to_cpu16 (l16);
  113. return 0;
  114. case 2:
  115. if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32))
  116. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  117. *len = grub_be_to_cpu32 (l32);
  118. return 0;
  119. }
  120. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  121. }
  122. struct signature_v4_header
  123. {
  124. grub_uint8_t type;
  125. grub_uint8_t pkeyalgo;
  126. grub_uint8_t hash;
  127. grub_uint16_t hashed_sub;
  128. } GRUB_PACKED;
  129. const char *hashes[] = {
  130. [0x01] = "md5",
  131. [0x02] = "sha1",
  132. [0x03] = "ripemd160",
  133. [0x08] = "sha256",
  134. [0x09] = "sha384",
  135. [0x0a] = "sha512",
  136. [0x0b] = "sha224"
  137. };
  138. struct gcry_pk_spec *grub_crypto_pk_dsa;
  139. struct gcry_pk_spec *grub_crypto_pk_ecdsa;
  140. struct gcry_pk_spec *grub_crypto_pk_rsa;
  141. static int
  142. dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
  143. const gcry_md_spec_t *hash, struct grub_public_subkey *sk);
  144. static int
  145. rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
  146. const gcry_md_spec_t *hash, struct grub_public_subkey *sk);
  147. struct
  148. {
  149. const char *name;
  150. grub_size_t nmpisig;
  151. grub_size_t nmpipub;
  152. struct gcry_pk_spec **algo;
  153. int (*pad) (gcry_mpi_t *hmpi, grub_uint8_t *hval,
  154. const gcry_md_spec_t *hash, struct grub_public_subkey *sk);
  155. const char *module;
  156. } pkalgos[] =
  157. {
  158. [1] = { "rsa", 1, 2, &grub_crypto_pk_rsa, rsa_pad, "gcry_rsa" },
  159. [3] = { "rsa", 1, 2, &grub_crypto_pk_rsa, rsa_pad, "gcry_rsa" },
  160. [17] = { "dsa", 2, 4, &grub_crypto_pk_dsa, dsa_pad, "gcry_dsa" },
  161. };
  162. struct grub_public_key
  163. {
  164. struct grub_public_key *next;
  165. struct grub_public_subkey *subkeys;
  166. };
  167. struct grub_public_subkey
  168. {
  169. struct grub_public_subkey *next;
  170. grub_uint8_t type;
  171. grub_uint32_t fingerprint[5];
  172. gcry_mpi_t mpis[10];
  173. };
  174. static void
  175. free_pk (struct grub_public_key *pk)
  176. {
  177. struct grub_public_subkey *nsk, *sk;
  178. for (sk = pk->subkeys; sk; sk = nsk)
  179. {
  180. grub_size_t i;
  181. for (i = 0; i < ARRAY_SIZE (sk->mpis); i++)
  182. if (sk->mpis[i])
  183. gcry_mpi_release (sk->mpis[i]);
  184. nsk = sk->next;
  185. grub_free (sk);
  186. }
  187. grub_free (pk);
  188. }
  189. #define READBUF_SIZE 4096
  190. struct grub_public_key *
  191. grub_load_public_key (grub_file_t f)
  192. {
  193. grub_err_t err;
  194. struct grub_public_key *ret;
  195. struct grub_public_subkey **last = 0;
  196. void *fingerprint_context = NULL;
  197. grub_uint8_t *buffer = NULL;
  198. ret = grub_zalloc (sizeof (*ret));
  199. if (!ret)
  200. {
  201. grub_free (fingerprint_context);
  202. return NULL;
  203. }
  204. buffer = grub_zalloc (READBUF_SIZE);
  205. fingerprint_context = grub_zalloc (GRUB_MD_SHA1->contextsize);
  206. if (!buffer || !fingerprint_context)
  207. goto fail;
  208. last = &ret->subkeys;
  209. while (1)
  210. {
  211. grub_uint8_t type;
  212. grub_size_t len;
  213. grub_uint8_t v, pk;
  214. grub_uint32_t creation_time;
  215. grub_off_t pend;
  216. struct grub_public_subkey *sk;
  217. grub_size_t i;
  218. grub_uint16_t len_be;
  219. err = read_packet_header (f, &type, &len);
  220. if (err)
  221. goto fail;
  222. if (type == 0xfe)
  223. continue;
  224. if (type == 0xff)
  225. {
  226. grub_free (fingerprint_context);
  227. grub_free (buffer);
  228. return ret;
  229. }
  230. grub_dprintf ("crypt", "len = %x\n", (int) len);
  231. pend = grub_file_tell (f) + len;
  232. if (type != 6 && type != 14
  233. && type != 5 && type != 7)
  234. {
  235. grub_file_seek (f, pend);
  236. continue;
  237. }
  238. if (grub_file_read (f, &v, sizeof (v)) != sizeof (v))
  239. {
  240. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  241. goto fail;
  242. }
  243. grub_dprintf ("crypt", "v = %x\n", v);
  244. if (v != 4)
  245. {
  246. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  247. goto fail;
  248. }
  249. if (grub_file_read (f, &creation_time, sizeof (creation_time)) != sizeof (creation_time))
  250. {
  251. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  252. goto fail;
  253. }
  254. grub_dprintf ("crypt", "time = %x\n", creation_time);
  255. if (grub_file_read (f, &pk, sizeof (pk)) != sizeof (pk))
  256. {
  257. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  258. goto fail;
  259. }
  260. grub_dprintf ("crypt", "pk = %x\n", pk);
  261. if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
  262. {
  263. grub_file_seek (f, pend);
  264. continue;
  265. }
  266. sk = grub_zalloc (sizeof (struct grub_public_subkey));
  267. if (!sk)
  268. goto fail;
  269. grub_memset (fingerprint_context, 0, GRUB_MD_SHA1->contextsize);
  270. GRUB_MD_SHA1->init (fingerprint_context);
  271. GRUB_MD_SHA1->write (fingerprint_context, "\x99", 1);
  272. len_be = grub_cpu_to_be16 (len);
  273. GRUB_MD_SHA1->write (fingerprint_context, &len_be, sizeof (len_be));
  274. GRUB_MD_SHA1->write (fingerprint_context, &v, sizeof (v));
  275. GRUB_MD_SHA1->write (fingerprint_context, &creation_time, sizeof (creation_time));
  276. GRUB_MD_SHA1->write (fingerprint_context, &pk, sizeof (pk));
  277. for (i = 0; i < pkalgos[pk].nmpipub; i++)
  278. {
  279. grub_uint16_t l;
  280. grub_size_t lb;
  281. if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
  282. {
  283. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  284. break;
  285. }
  286. lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
  287. if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
  288. {
  289. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  290. break;
  291. }
  292. if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
  293. {
  294. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  295. break;
  296. }
  297. grub_memcpy (buffer, &l, sizeof (l));
  298. GRUB_MD_SHA1->write (fingerprint_context, buffer, lb + sizeof (grub_uint16_t));
  299. if (gcry_mpi_scan (&sk->mpis[i], GCRYMPI_FMT_PGP,
  300. buffer, lb + sizeof (grub_uint16_t), 0))
  301. {
  302. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  303. break;
  304. }
  305. }
  306. if (i < pkalgos[pk].nmpipub)
  307. {
  308. grub_free (sk);
  309. goto fail;
  310. }
  311. GRUB_MD_SHA1->final (fingerprint_context);
  312. grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20);
  313. *last = sk;
  314. last = &sk->next;
  315. grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f), (int)pend);
  316. grub_file_seek (f, pend);
  317. }
  318. fail:
  319. free_pk (ret);
  320. grub_free (fingerprint_context);
  321. grub_free (buffer);
  322. return NULL;
  323. }
  324. struct grub_public_key *grub_pk_trusted;
  325. struct grub_public_subkey *
  326. grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey)
  327. {
  328. struct grub_public_subkey *sk;
  329. for (sk = pkey->subkeys; sk; sk = sk->next)
  330. if (grub_memcmp (sk->fingerprint + 3, &keyid, 8) == 0)
  331. return sk;
  332. return 0;
  333. }
  334. struct grub_public_subkey *
  335. grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid)
  336. {
  337. struct grub_public_key *pkey;
  338. struct grub_public_subkey *sk;
  339. for (pkey = grub_pk_trusted; pkey; pkey = pkey->next)
  340. {
  341. sk = grub_crypto_pk_locate_subkey (keyid, pkey);
  342. if (sk)
  343. return sk;
  344. }
  345. return 0;
  346. }
  347. static int
  348. dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
  349. const gcry_md_spec_t *hash, struct grub_public_subkey *sk)
  350. {
  351. unsigned nbits = gcry_mpi_get_nbits (sk->mpis[1]);
  352. grub_dprintf ("crypt", "must be %u bits got %d bits\n", nbits,
  353. (int)(8 * hash->mdlen));
  354. return gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, hval,
  355. nbits / 8 < (unsigned) hash->mdlen ? nbits / 8
  356. : (unsigned) hash->mdlen, 0);
  357. }
  358. static int
  359. rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
  360. const gcry_md_spec_t *hash, struct grub_public_subkey *sk)
  361. {
  362. grub_size_t tlen, emlen, fflen;
  363. grub_uint8_t *em, *emptr;
  364. unsigned nbits = gcry_mpi_get_nbits (sk->mpis[0]);
  365. int ret;
  366. tlen = hash->mdlen + hash->asnlen;
  367. emlen = (nbits + 7) / 8;
  368. if (emlen < tlen + 11)
  369. return 1;
  370. em = grub_malloc (emlen);
  371. if (!em)
  372. return 1;
  373. em[0] = 0x00;
  374. em[1] = 0x01;
  375. fflen = emlen - tlen - 3;
  376. for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
  377. *emptr = 0xff;
  378. *emptr++ = 0x00;
  379. grub_memcpy (emptr, hash->asnoid, hash->asnlen);
  380. emptr += hash->asnlen;
  381. grub_memcpy (emptr, hval, hash->mdlen);
  382. ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
  383. grub_free (em);
  384. return ret;
  385. }
  386. struct grub_pubkey_context
  387. {
  388. grub_file_t sig;
  389. struct signature_v4_header v4;
  390. grub_uint8_t v;
  391. const gcry_md_spec_t *hash;
  392. void *hash_context;
  393. };
  394. static grub_err_t
  395. grub_verify_signature_init (struct grub_pubkey_context *ctxt, grub_file_t sig)
  396. {
  397. grub_size_t len;
  398. grub_uint8_t h;
  399. grub_uint8_t t;
  400. grub_uint8_t pk;
  401. grub_err_t err;
  402. grub_uint8_t type = 0;
  403. grub_memset (ctxt, 0, sizeof (*ctxt));
  404. err = read_packet_header (sig, &type, &len);
  405. if (err)
  406. return err;
  407. if (type != 0x2)
  408. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  409. if (grub_file_read (sig, &ctxt->v, sizeof (ctxt->v)) != sizeof (ctxt->v))
  410. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  411. if (ctxt->v != 4)
  412. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  413. if (grub_file_read (sig, &ctxt->v4, sizeof (ctxt->v4)) != sizeof (ctxt->v4))
  414. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  415. h = ctxt->v4.hash;
  416. t = ctxt->v4.type;
  417. pk = ctxt->v4.pkeyalgo;
  418. if (t != 0)
  419. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  420. if (h >= ARRAY_SIZE (hashes) || hashes[h] == NULL)
  421. return grub_error (GRUB_ERR_BAD_SIGNATURE, "unknown hash");
  422. if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
  423. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  424. ctxt->hash = grub_crypto_lookup_md_by_name (hashes[h]);
  425. if (!ctxt->hash)
  426. return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]);
  427. grub_dprintf ("crypt", "alive\n");
  428. ctxt->hash_context = grub_zalloc (ctxt->hash->contextsize);
  429. if (!ctxt->hash_context)
  430. return grub_errno;
  431. ctxt->hash->init (ctxt->hash_context);
  432. ctxt->sig = sig;
  433. return GRUB_ERR_NONE;
  434. }
  435. static grub_err_t
  436. grub_pubkey_write (void *ctxt_, void *buf, grub_size_t size)
  437. {
  438. struct grub_pubkey_context *ctxt = ctxt_;
  439. ctxt->hash->write (ctxt->hash_context, buf, size);
  440. return GRUB_ERR_NONE;
  441. }
  442. static grub_err_t
  443. grub_verify_signature_real (struct grub_pubkey_context *ctxt,
  444. struct grub_public_key *pkey)
  445. {
  446. gcry_mpi_t mpis[10];
  447. grub_uint8_t pk = ctxt->v4.pkeyalgo;
  448. grub_size_t i;
  449. grub_uint8_t *readbuf = NULL;
  450. unsigned char *hval;
  451. grub_ssize_t rem = grub_be_to_cpu16 (ctxt->v4.hashed_sub);
  452. grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
  453. grub_uint8_t s;
  454. grub_uint16_t unhashed_sub;
  455. grub_ssize_t r;
  456. grub_uint8_t hash_start[2];
  457. gcry_mpi_t hmpi;
  458. grub_uint64_t keyid = 0;
  459. struct grub_public_subkey *sk;
  460. readbuf = grub_malloc (READBUF_SIZE);
  461. if (!readbuf)
  462. goto fail;
  463. ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
  464. ctxt->hash->write (ctxt->hash_context, &ctxt->v4, sizeof (ctxt->v4));
  465. while (rem)
  466. {
  467. r = grub_file_read (ctxt->sig, readbuf,
  468. rem < READBUF_SIZE ? rem : READBUF_SIZE);
  469. if (r < 0)
  470. goto fail;
  471. if (r == 0)
  472. break;
  473. ctxt->hash->write (ctxt->hash_context, readbuf, r);
  474. rem -= r;
  475. }
  476. ctxt->hash->write (ctxt->hash_context, &ctxt->v, sizeof (ctxt->v));
  477. s = 0xff;
  478. ctxt->hash->write (ctxt->hash_context, &s, sizeof (s));
  479. ctxt->hash->write (ctxt->hash_context, &headlen, sizeof (headlen));
  480. r = grub_file_read (ctxt->sig, &unhashed_sub, sizeof (unhashed_sub));
  481. if (r != sizeof (unhashed_sub))
  482. goto fail;
  483. {
  484. grub_uint8_t *ptr;
  485. grub_uint32_t l;
  486. rem = grub_be_to_cpu16 (unhashed_sub);
  487. if (rem > READBUF_SIZE)
  488. goto fail;
  489. r = grub_file_read (ctxt->sig, readbuf, rem);
  490. if (r != rem)
  491. goto fail;
  492. for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
  493. {
  494. if (*ptr < 192)
  495. l = *ptr++;
  496. else if (*ptr < 255)
  497. {
  498. if (ptr + 1 >= readbuf + rem)
  499. break;
  500. l = (((ptr[0] & ~192) << GRUB_CHAR_BIT) | ptr[1]) + 192;
  501. ptr += 2;
  502. }
  503. else
  504. {
  505. if (ptr + 5 >= readbuf + rem)
  506. break;
  507. l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
  508. ptr += 5;
  509. }
  510. if (*ptr == 0x10 && l >= 8)
  511. keyid = grub_get_unaligned64 (ptr + 1);
  512. }
  513. }
  514. ctxt->hash->final (ctxt->hash_context);
  515. grub_dprintf ("crypt", "alive\n");
  516. hval = ctxt->hash->read (ctxt->hash_context);
  517. if (grub_file_read (ctxt->sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
  518. goto fail;
  519. if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
  520. goto fail;
  521. grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (ctxt->sig));
  522. for (i = 0; i < pkalgos[pk].nmpisig; i++)
  523. {
  524. grub_uint16_t l;
  525. grub_size_t lb;
  526. grub_dprintf ("crypt", "alive\n");
  527. if (grub_file_read (ctxt->sig, &l, sizeof (l)) != sizeof (l))
  528. goto fail;
  529. grub_dprintf ("crypt", "alive\n");
  530. lb = (grub_be_to_cpu16 (l) + 7) / 8;
  531. grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
  532. if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
  533. goto fail;
  534. grub_dprintf ("crypt", "alive\n");
  535. if (grub_file_read (ctxt->sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
  536. goto fail;
  537. grub_dprintf ("crypt", "alive\n");
  538. grub_memcpy (readbuf, &l, sizeof (l));
  539. grub_dprintf ("crypt", "alive\n");
  540. if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
  541. readbuf, lb + sizeof (grub_uint16_t), 0))
  542. goto fail;
  543. grub_dprintf ("crypt", "alive\n");
  544. }
  545. if (pkey)
  546. sk = grub_crypto_pk_locate_subkey (keyid, pkey);
  547. else
  548. sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
  549. if (!sk)
  550. {
  551. /* TRANSLATORS: %08x is 32-bit key id. */
  552. grub_error (GRUB_ERR_BAD_SIGNATURE,
  553. N_("public key %08" PRIxGRUB_UINT64_T " not found"), keyid);
  554. goto fail;
  555. }
  556. if (pkalgos[pk].pad (&hmpi, hval, ctxt->hash, sk))
  557. goto fail;
  558. if (!*pkalgos[pk].algo)
  559. {
  560. grub_dl_load (pkalgos[pk].module);
  561. grub_errno = GRUB_ERR_NONE;
  562. }
  563. if (!*pkalgos[pk].algo)
  564. {
  565. grub_error (GRUB_ERR_BAD_SIGNATURE, N_("module `%s' isn't loaded"),
  566. pkalgos[pk].module);
  567. goto fail;
  568. }
  569. if ((*pkalgos[pk].algo)->verify (0, hmpi, mpis, sk->mpis, 0, 0))
  570. goto fail;
  571. grub_free (readbuf);
  572. return GRUB_ERR_NONE;
  573. fail:
  574. grub_free (readbuf);
  575. if (!grub_errno)
  576. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
  577. return grub_errno;
  578. }
  579. static void
  580. grub_pubkey_close_real (struct grub_pubkey_context *ctxt)
  581. {
  582. if (ctxt->sig)
  583. grub_file_close (ctxt->sig);
  584. if (ctxt->hash_context)
  585. grub_free (ctxt->hash_context);
  586. }
  587. static void
  588. grub_pubkey_close (void *ctxt)
  589. {
  590. grub_pubkey_close_real (ctxt);
  591. grub_free (ctxt);
  592. }
  593. grub_err_t
  594. grub_verify_signature (grub_file_t f, const char *fsig,
  595. struct grub_public_key *pkey)
  596. {
  597. grub_file_t sig;
  598. grub_err_t err;
  599. struct grub_pubkey_context ctxt;
  600. grub_uint8_t *readbuf = NULL;
  601. sig = grub_file_open (fsig,
  602. GRUB_FILE_TYPE_SIGNATURE
  603. | GRUB_FILE_TYPE_NO_DECOMPRESS);
  604. if (!sig)
  605. return grub_errno;
  606. err = grub_verify_signature_init (&ctxt, sig);
  607. if (err)
  608. {
  609. grub_file_close (sig);
  610. return err;
  611. }
  612. readbuf = grub_zalloc (READBUF_SIZE);
  613. if (!readbuf)
  614. goto fail;
  615. while (1)
  616. {
  617. grub_ssize_t r;
  618. r = grub_file_read (f, readbuf, READBUF_SIZE);
  619. if (r < 0)
  620. goto fail;
  621. if (r == 0)
  622. break;
  623. err = grub_pubkey_write (&ctxt, readbuf, r);
  624. if (err)
  625. return err;
  626. }
  627. grub_verify_signature_real (&ctxt, pkey);
  628. fail:
  629. grub_pubkey_close_real (&ctxt);
  630. return grub_errno;
  631. }
  632. static grub_err_t
  633. grub_cmd_trust (grub_extcmd_context_t ctxt,
  634. int argc, char **args)
  635. {
  636. grub_file_t pkf;
  637. struct grub_public_key *pk = NULL;
  638. if (argc < 1)
  639. return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
  640. pkf = grub_file_open (args[0],
  641. GRUB_FILE_TYPE_PUBLIC_KEY_TRUST
  642. | GRUB_FILE_TYPE_NO_DECOMPRESS
  643. | (ctxt->state[OPTION_SKIP_SIG].set
  644. ? GRUB_FILE_TYPE_SKIP_SIGNATURE
  645. : GRUB_FILE_TYPE_NONE));
  646. if (!pkf)
  647. return grub_errno;
  648. pk = grub_load_public_key (pkf);
  649. if (!pk)
  650. {
  651. grub_file_close (pkf);
  652. return grub_errno;
  653. }
  654. grub_file_close (pkf);
  655. pk->next = grub_pk_trusted;
  656. grub_pk_trusted = pk;
  657. return GRUB_ERR_NONE;
  658. }
  659. static grub_err_t
  660. grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
  661. int argc __attribute__ ((unused)),
  662. char **args __attribute__ ((unused)))
  663. {
  664. struct grub_public_key *pk = NULL;
  665. struct grub_public_subkey *sk = NULL;
  666. for (pk = grub_pk_trusted; pk; pk = pk->next)
  667. for (sk = pk->subkeys; sk; sk = sk->next)
  668. {
  669. unsigned i;
  670. for (i = 0; i < 20; i += 2)
  671. grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i],
  672. ((grub_uint8_t *) sk->fingerprint)[i + 1]);
  673. grub_printf ("\n");
  674. }
  675. return GRUB_ERR_NONE;
  676. }
  677. static grub_err_t
  678. grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)),
  679. int argc, char **args)
  680. {
  681. grub_uint32_t keyid, keyid_be;
  682. struct grub_public_key **pkey;
  683. struct grub_public_subkey *sk;
  684. if (argc < 1)
  685. return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
  686. keyid = grub_strtoull (args[0], 0, 16);
  687. if (grub_errno)
  688. return grub_errno;
  689. keyid_be = grub_cpu_to_be32 (keyid);
  690. for (pkey = &grub_pk_trusted; *pkey; pkey = &((*pkey)->next))
  691. {
  692. struct grub_public_key *next;
  693. for (sk = (*pkey)->subkeys; sk; sk = sk->next)
  694. if (grub_memcmp (sk->fingerprint + 4, &keyid_be, 4) == 0)
  695. break;
  696. if (!sk)
  697. continue;
  698. next = (*pkey)->next;
  699. free_pk (*pkey);
  700. *pkey = next;
  701. return GRUB_ERR_NONE;
  702. }
  703. /* TRANSLATORS: %08x is 32-bit key id. */
  704. return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("public key %08x not found"), keyid);
  705. }
  706. static grub_err_t
  707. grub_cmd_verify_signature (grub_extcmd_context_t ctxt,
  708. int argc, char **args)
  709. {
  710. grub_file_t f = NULL;
  711. grub_err_t err = GRUB_ERR_NONE;
  712. struct grub_public_key *pk = NULL;
  713. grub_dprintf ("crypt", "alive\n");
  714. if (argc < 2)
  715. return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two arguments expected"));
  716. grub_dprintf ("crypt", "alive\n");
  717. if (argc > 2)
  718. {
  719. grub_file_t pkf;
  720. pkf = grub_file_open (args[2],
  721. GRUB_FILE_TYPE_PUBLIC_KEY
  722. | GRUB_FILE_TYPE_NO_DECOMPRESS
  723. | (ctxt->state[OPTION_SKIP_SIG].set
  724. ? GRUB_FILE_TYPE_SKIP_SIGNATURE
  725. : GRUB_FILE_TYPE_NONE));
  726. if (!pkf)
  727. return grub_errno;
  728. pk = grub_load_public_key (pkf);
  729. if (!pk)
  730. {
  731. grub_file_close (pkf);
  732. return grub_errno;
  733. }
  734. grub_file_close (pkf);
  735. }
  736. f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
  737. if (!f)
  738. {
  739. err = grub_errno;
  740. goto fail;
  741. }
  742. err = grub_verify_signature (f, args[1], pk);
  743. fail:
  744. if (f)
  745. grub_file_close (f);
  746. if (pk)
  747. free_pk (pk);
  748. return err;
  749. }
  750. static int sec = 0;
  751. static grub_err_t
  752. grub_pubkey_init (grub_file_t io, enum grub_file_type type __attribute__ ((unused)),
  753. void **context, enum grub_verify_flags *flags)
  754. {
  755. grub_file_t sig;
  756. char *fsuf, *ptr;
  757. grub_err_t err;
  758. struct grub_pubkey_context *ctxt;
  759. if (!sec)
  760. {
  761. *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
  762. return GRUB_ERR_NONE;
  763. }
  764. fsuf = grub_malloc (grub_strlen (io->name) + sizeof (".sig"));
  765. if (!fsuf)
  766. return grub_errno;
  767. ptr = grub_stpcpy (fsuf, io->name);
  768. grub_memcpy (ptr, ".sig", sizeof (".sig"));
  769. sig = grub_file_open (fsuf, GRUB_FILE_TYPE_SIGNATURE);
  770. grub_free (fsuf);
  771. if (!sig)
  772. return grub_errno;
  773. ctxt = grub_malloc (sizeof (*ctxt));
  774. if (!ctxt)
  775. {
  776. grub_file_close (sig);
  777. return grub_errno;
  778. }
  779. err = grub_verify_signature_init (ctxt, sig);
  780. if (err)
  781. {
  782. grub_free (ctxt);
  783. grub_file_close (sig);
  784. return err;
  785. }
  786. *context = ctxt;
  787. return GRUB_ERR_NONE;
  788. }
  789. static grub_err_t
  790. grub_pubkey_fini (void *ctxt)
  791. {
  792. return grub_verify_signature_real (ctxt, NULL);
  793. }
  794. static char *
  795. grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
  796. const char *val)
  797. {
  798. sec = (*val == '1') || (*val == 'e');
  799. return grub_strdup (sec ? "enforce" : "no");
  800. }
  801. static grub_ssize_t
  802. pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
  803. {
  804. grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
  805. return len;
  806. }
  807. /* Filesystem descriptor. */
  808. struct grub_fs pseudo_fs =
  809. {
  810. .name = "pseudo",
  811. .fs_read = pseudo_read
  812. };
  813. struct grub_file_verifier grub_pubkey_verifier =
  814. {
  815. .name = "pgp",
  816. .init = grub_pubkey_init,
  817. .fini = grub_pubkey_fini,
  818. .write = grub_pubkey_write,
  819. .close = grub_pubkey_close,
  820. };
  821. static grub_extcmd_t cmd, cmd_trust;
  822. static grub_command_t cmd_distrust, cmd_list;
  823. GRUB_MOD_INIT(pgp)
  824. {
  825. const char *val;
  826. struct grub_module_header *header;
  827. val = grub_env_get ("check_signatures");
  828. if (val && (val[0] == '1' || val[0] == 'e'))
  829. sec = 1;
  830. else
  831. sec = 0;
  832. grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
  833. grub_env_export ("check_signatures");
  834. grub_pk_trusted = 0;
  835. FOR_MODULES (header)
  836. {
  837. struct grub_file pseudo_file;
  838. struct grub_public_key *pk = NULL;
  839. grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
  840. /* Not an ELF module, skip. */
  841. if (header->type != OBJ_TYPE_PUBKEY)
  842. continue;
  843. pseudo_file.fs = &pseudo_fs;
  844. pseudo_file.size = (header->size - sizeof (struct grub_module_header));
  845. pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
  846. pk = grub_load_public_key (&pseudo_file);
  847. if (!pk)
  848. grub_fatal ("error loading initial key: %s\n", grub_errmsg);
  849. pk->next = grub_pk_trusted;
  850. grub_pk_trusted = pk;
  851. }
  852. if (!val)
  853. grub_env_set ("check_signatures", grub_pk_trusted ? "enforce" : "no");
  854. cmd = grub_register_extcmd ("verify_detached", grub_cmd_verify_signature, 0,
  855. N_("[-s|--skip-sig] FILE SIGNATURE_FILE [PUBKEY_FILE]"),
  856. N_("Verify detached signature."),
  857. options);
  858. cmd_trust = grub_register_extcmd ("trust", grub_cmd_trust, 0,
  859. N_("[-s|--skip-sig] PUBKEY_FILE"),
  860. N_("Add PUBKEY_FILE to trusted keys."),
  861. options);
  862. cmd_list = grub_register_command ("list_trusted", grub_cmd_list,
  863. 0,
  864. N_("Show the list of trusted keys."));
  865. cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust,
  866. N_("PUBKEY_ID"),
  867. N_("Remove PUBKEY_ID from trusted keys."));
  868. grub_verifier_register (&grub_pubkey_verifier);
  869. }
  870. GRUB_MOD_FINI(pgp)
  871. {
  872. grub_verifier_unregister (&grub_pubkey_verifier);
  873. grub_unregister_extcmd (cmd);
  874. grub_unregister_extcmd (cmd_trust);
  875. grub_unregister_command (cmd_list);
  876. grub_unregister_command (cmd_distrust);
  877. }