verify.c 25 KB

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