sshsig.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. /* $OpenBSD: sshsig.c,v 1.17 2020/08/31 00:17:41 djm Exp $ */
  2. /*
  3. * Copyright (c) 2019 Google LLC
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include "includes.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <errno.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include "authfd.h"
  25. #include "authfile.h"
  26. #include "log.h"
  27. #include "misc.h"
  28. #include "sshbuf.h"
  29. #include "sshsig.h"
  30. #include "ssherr.h"
  31. #include "sshkey.h"
  32. #include "match.h"
  33. #include "digest.h"
  34. #define SIG_VERSION 0x01
  35. #define MAGIC_PREAMBLE "SSHSIG"
  36. #define MAGIC_PREAMBLE_LEN (sizeof(MAGIC_PREAMBLE) - 1)
  37. #define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----\n"
  38. #define END_SIGNATURE "-----END SSH SIGNATURE-----"
  39. #define RSA_SIGN_ALG "rsa-sha2-512" /* XXX maybe make configurable */
  40. #define RSA_SIGN_ALLOWED "rsa-sha2-512,rsa-sha2-256"
  41. #define HASHALG_DEFAULT "sha512" /* XXX maybe make configurable */
  42. #define HASHALG_ALLOWED "sha256,sha512"
  43. int
  44. sshsig_armor(const struct sshbuf *blob, struct sshbuf **out)
  45. {
  46. struct sshbuf *buf = NULL;
  47. int r = SSH_ERR_INTERNAL_ERROR;
  48. *out = NULL;
  49. if ((buf = sshbuf_new()) == NULL) {
  50. error("%s: sshbuf_new failed", __func__);
  51. r = SSH_ERR_ALLOC_FAIL;
  52. goto out;
  53. }
  54. if ((r = sshbuf_put(buf, BEGIN_SIGNATURE,
  55. sizeof(BEGIN_SIGNATURE)-1)) != 0) {
  56. error("%s: sshbuf_putf failed: %s", __func__, ssh_err(r));
  57. goto out;
  58. }
  59. if ((r = sshbuf_dtob64(blob, buf, 1)) != 0) {
  60. error("%s: Couldn't base64 encode signature blob: %s",
  61. __func__, ssh_err(r));
  62. goto out;
  63. }
  64. if ((r = sshbuf_put(buf, END_SIGNATURE,
  65. sizeof(END_SIGNATURE)-1)) != 0 ||
  66. (r = sshbuf_put_u8(buf, '\n')) != 0) {
  67. error("%s: sshbuf_put failed: %s", __func__, ssh_err(r));
  68. goto out;
  69. }
  70. /* success */
  71. *out = buf;
  72. buf = NULL; /* transferred */
  73. r = 0;
  74. out:
  75. sshbuf_free(buf);
  76. return r;
  77. }
  78. int
  79. sshsig_dearmor(struct sshbuf *sig, struct sshbuf **out)
  80. {
  81. int r;
  82. size_t eoffset = 0;
  83. struct sshbuf *buf = NULL;
  84. struct sshbuf *sbuf = NULL;
  85. char *b64 = NULL;
  86. if ((sbuf = sshbuf_fromb(sig)) == NULL) {
  87. error("%s: sshbuf_fromb failed", __func__);
  88. return SSH_ERR_ALLOC_FAIL;
  89. }
  90. if ((r = sshbuf_cmp(sbuf, 0,
  91. BEGIN_SIGNATURE, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
  92. error("Couldn't parse signature: missing header");
  93. goto done;
  94. }
  95. if ((r = sshbuf_consume(sbuf, sizeof(BEGIN_SIGNATURE)-1)) != 0) {
  96. error("%s: sshbuf_consume failed: %s", __func__, ssh_err(r));
  97. goto done;
  98. }
  99. if ((r = sshbuf_find(sbuf, 0, "\n" END_SIGNATURE,
  100. sizeof("\n" END_SIGNATURE)-1, &eoffset)) != 0) {
  101. error("Couldn't parse signature: missing footer");
  102. goto done;
  103. }
  104. if ((r = sshbuf_consume_end(sbuf, sshbuf_len(sbuf)-eoffset)) != 0) {
  105. error("%s: sshbuf_consume failed: %s", __func__, ssh_err(r));
  106. goto done;
  107. }
  108. if ((b64 = sshbuf_dup_string(sbuf)) == NULL) {
  109. error("%s: sshbuf_dup_string failed", __func__);
  110. r = SSH_ERR_ALLOC_FAIL;
  111. goto done;
  112. }
  113. if ((buf = sshbuf_new()) == NULL) {
  114. error("%s: sshbuf_new() failed", __func__);
  115. r = SSH_ERR_ALLOC_FAIL;
  116. goto done;
  117. }
  118. if ((r = sshbuf_b64tod(buf, b64)) != 0) {
  119. error("Couldn't decode signature: %s", ssh_err(r));
  120. goto done;
  121. }
  122. /* success */
  123. *out = buf;
  124. r = 0;
  125. buf = NULL; /* transferred */
  126. done:
  127. sshbuf_free(buf);
  128. sshbuf_free(sbuf);
  129. free(b64);
  130. return r;
  131. }
  132. static int
  133. sshsig_wrap_sign(struct sshkey *key, const char *hashalg,
  134. const char *sk_provider, const char *sk_pin, const struct sshbuf *h_message,
  135. const char *sig_namespace, struct sshbuf **out,
  136. sshsig_signer *signer, void *signer_ctx)
  137. {
  138. int r;
  139. size_t slen = 0;
  140. u_char *sig = NULL;
  141. struct sshbuf *blob = NULL;
  142. struct sshbuf *tosign = NULL;
  143. const char *sign_alg = NULL;
  144. if ((tosign = sshbuf_new()) == NULL ||
  145. (blob = sshbuf_new()) == NULL) {
  146. error("%s: sshbuf_new failed", __func__);
  147. r = SSH_ERR_ALLOC_FAIL;
  148. goto done;
  149. }
  150. if ((r = sshbuf_put(tosign, MAGIC_PREAMBLE, MAGIC_PREAMBLE_LEN)) != 0 ||
  151. (r = sshbuf_put_cstring(tosign, sig_namespace)) != 0 ||
  152. (r = sshbuf_put_string(tosign, NULL, 0)) != 0 || /* reserved */
  153. (r = sshbuf_put_cstring(tosign, hashalg)) != 0 ||
  154. (r = sshbuf_put_stringb(tosign, h_message)) != 0) {
  155. error("Couldn't construct message to sign: %s", ssh_err(r));
  156. goto done;
  157. }
  158. /* If using RSA keys then default to a good signature algorithm */
  159. if (sshkey_type_plain(key->type) == KEY_RSA)
  160. sign_alg = RSA_SIGN_ALG;
  161. if (signer != NULL) {
  162. if ((r = signer(key, &sig, &slen,
  163. sshbuf_ptr(tosign), sshbuf_len(tosign),
  164. sign_alg, sk_provider, sk_pin, 0, signer_ctx)) != 0) {
  165. error("Couldn't sign message: %s", ssh_err(r));
  166. goto done;
  167. }
  168. } else {
  169. if ((r = sshkey_sign(key, &sig, &slen,
  170. sshbuf_ptr(tosign), sshbuf_len(tosign),
  171. sign_alg, sk_provider, sk_pin, 0)) != 0) {
  172. error("Couldn't sign message: %s", ssh_err(r));
  173. goto done;
  174. }
  175. }
  176. if ((r = sshbuf_put(blob, MAGIC_PREAMBLE, MAGIC_PREAMBLE_LEN)) != 0 ||
  177. (r = sshbuf_put_u32(blob, SIG_VERSION)) != 0 ||
  178. (r = sshkey_puts(key, blob)) != 0 ||
  179. (r = sshbuf_put_cstring(blob, sig_namespace)) != 0 ||
  180. (r = sshbuf_put_string(blob, NULL, 0)) != 0 || /* reserved */
  181. (r = sshbuf_put_cstring(blob, hashalg)) != 0 ||
  182. (r = sshbuf_put_string(blob, sig, slen)) != 0) {
  183. error("Couldn't populate blob: %s", ssh_err(r));
  184. goto done;
  185. }
  186. if (out != NULL) {
  187. *out = blob;
  188. blob = NULL;
  189. }
  190. r = 0;
  191. done:
  192. free(sig);
  193. sshbuf_free(blob);
  194. sshbuf_free(tosign);
  195. return r;
  196. }
  197. /* Check preamble and version. */
  198. static int
  199. sshsig_parse_preamble(struct sshbuf *buf)
  200. {
  201. int r = SSH_ERR_INTERNAL_ERROR;
  202. uint32_t sversion;
  203. if ((r = sshbuf_cmp(buf, 0, MAGIC_PREAMBLE, MAGIC_PREAMBLE_LEN)) != 0 ||
  204. (r = sshbuf_consume(buf, (sizeof(MAGIC_PREAMBLE)-1))) != 0 ||
  205. (r = sshbuf_get_u32(buf, &sversion)) != 0) {
  206. error("Couldn't verify signature: invalid format");
  207. return r;
  208. }
  209. if (sversion > SIG_VERSION) {
  210. error("Signature version %lu is larger than supported "
  211. "version %u", (unsigned long)sversion, SIG_VERSION);
  212. return SSH_ERR_INVALID_FORMAT;
  213. }
  214. return 0;
  215. }
  216. static int
  217. sshsig_check_hashalg(const char *hashalg)
  218. {
  219. if (hashalg == NULL ||
  220. match_pattern_list(hashalg, HASHALG_ALLOWED, 0) == 1)
  221. return 0;
  222. error("%s: unsupported hash algorithm \"%.100s\"", __func__, hashalg);
  223. return SSH_ERR_SIGN_ALG_UNSUPPORTED;
  224. }
  225. static int
  226. sshsig_peek_hashalg(struct sshbuf *signature, char **hashalgp)
  227. {
  228. struct sshbuf *buf = NULL;
  229. char *hashalg = NULL;
  230. int r = SSH_ERR_INTERNAL_ERROR;
  231. if (hashalgp != NULL)
  232. *hashalgp = NULL;
  233. if ((buf = sshbuf_fromb(signature)) == NULL)
  234. return SSH_ERR_ALLOC_FAIL;
  235. if ((r = sshsig_parse_preamble(buf)) != 0)
  236. goto done;
  237. if ((r = sshbuf_get_string_direct(buf, NULL, NULL)) != 0 ||
  238. (r = sshbuf_get_string_direct(buf, NULL, NULL)) != 0 ||
  239. (r = sshbuf_get_string(buf, NULL, NULL)) != 0 ||
  240. (r = sshbuf_get_cstring(buf, &hashalg, NULL)) != 0 ||
  241. (r = sshbuf_get_string_direct(buf, NULL, NULL)) != 0) {
  242. error("Couldn't parse signature blob: %s", ssh_err(r));
  243. goto done;
  244. }
  245. /* success */
  246. r = 0;
  247. *hashalgp = hashalg;
  248. hashalg = NULL;
  249. done:
  250. free(hashalg);
  251. sshbuf_free(buf);
  252. return r;
  253. }
  254. static int
  255. sshsig_wrap_verify(struct sshbuf *signature, const char *hashalg,
  256. const struct sshbuf *h_message, const char *expect_namespace,
  257. struct sshkey **sign_keyp, struct sshkey_sig_details **sig_details)
  258. {
  259. int r = SSH_ERR_INTERNAL_ERROR;
  260. struct sshbuf *buf = NULL, *toverify = NULL;
  261. struct sshkey *key = NULL;
  262. const u_char *sig;
  263. char *got_namespace = NULL, *sigtype = NULL, *sig_hashalg = NULL;
  264. size_t siglen;
  265. debug("%s: verify message length %zu", __func__, sshbuf_len(h_message));
  266. if (sig_details != NULL)
  267. *sig_details = NULL;
  268. if (sign_keyp != NULL)
  269. *sign_keyp = NULL;
  270. if ((toverify = sshbuf_new()) == NULL) {
  271. error("%s: sshbuf_new failed", __func__);
  272. r = SSH_ERR_ALLOC_FAIL;
  273. goto done;
  274. }
  275. if ((r = sshbuf_put(toverify, MAGIC_PREAMBLE,
  276. MAGIC_PREAMBLE_LEN)) != 0 ||
  277. (r = sshbuf_put_cstring(toverify, expect_namespace)) != 0 ||
  278. (r = sshbuf_put_string(toverify, NULL, 0)) != 0 || /* reserved */
  279. (r = sshbuf_put_cstring(toverify, hashalg)) != 0 ||
  280. (r = sshbuf_put_stringb(toverify, h_message)) != 0) {
  281. error("Couldn't construct message to verify: %s", ssh_err(r));
  282. goto done;
  283. }
  284. if ((r = sshsig_parse_preamble(signature)) != 0)
  285. goto done;
  286. if ((r = sshkey_froms(signature, &key)) != 0 ||
  287. (r = sshbuf_get_cstring(signature, &got_namespace, NULL)) != 0 ||
  288. (r = sshbuf_get_string(signature, NULL, NULL)) != 0 ||
  289. (r = sshbuf_get_cstring(signature, &sig_hashalg, NULL)) != 0 ||
  290. (r = sshbuf_get_string_direct(signature, &sig, &siglen)) != 0) {
  291. error("Couldn't parse signature blob: %s", ssh_err(r));
  292. goto done;
  293. }
  294. if (sshbuf_len(signature) != 0) {
  295. error("Signature contains trailing data");
  296. r = SSH_ERR_INVALID_FORMAT;
  297. goto done;
  298. }
  299. if (strcmp(expect_namespace, got_namespace) != 0) {
  300. error("Couldn't verify signature: namespace does not match");
  301. debug("%s: expected namespace \"%s\" received \"%s\"",
  302. __func__, expect_namespace, got_namespace);
  303. r = SSH_ERR_SIGNATURE_INVALID;
  304. goto done;
  305. }
  306. if (strcmp(hashalg, sig_hashalg) != 0) {
  307. error("Couldn't verify signature: hash algorithm mismatch");
  308. debug("%s: expected algorithm \"%s\" received \"%s\"",
  309. __func__, hashalg, sig_hashalg);
  310. r = SSH_ERR_SIGNATURE_INVALID;
  311. goto done;
  312. }
  313. /* Ensure that RSA keys use an acceptable signature algorithm */
  314. if (sshkey_type_plain(key->type) == KEY_RSA) {
  315. if ((r = sshkey_get_sigtype(sig, siglen, &sigtype)) != 0) {
  316. error("Couldn't verify signature: unable to get "
  317. "signature type: %s", ssh_err(r));
  318. goto done;
  319. }
  320. if (match_pattern_list(sigtype, RSA_SIGN_ALLOWED, 0) != 1) {
  321. error("Couldn't verify signature: unsupported RSA "
  322. "signature algorithm %s", sigtype);
  323. r = SSH_ERR_SIGN_ALG_UNSUPPORTED;
  324. goto done;
  325. }
  326. }
  327. if ((r = sshkey_verify(key, sig, siglen, sshbuf_ptr(toverify),
  328. sshbuf_len(toverify), NULL, 0, sig_details)) != 0) {
  329. error("Signature verification failed: %s", ssh_err(r));
  330. goto done;
  331. }
  332. /* success */
  333. r = 0;
  334. if (sign_keyp != NULL) {
  335. *sign_keyp = key;
  336. key = NULL; /* transferred */
  337. }
  338. done:
  339. free(got_namespace);
  340. free(sigtype);
  341. free(sig_hashalg);
  342. sshbuf_free(buf);
  343. sshbuf_free(toverify);
  344. sshkey_free(key);
  345. return r;
  346. }
  347. static int
  348. hash_buffer(const struct sshbuf *m, const char *hashalg, struct sshbuf **bp)
  349. {
  350. char *hex, hash[SSH_DIGEST_MAX_LENGTH];
  351. int alg, r = SSH_ERR_INTERNAL_ERROR;
  352. struct sshbuf *b = NULL;
  353. *bp = NULL;
  354. memset(hash, 0, sizeof(hash));
  355. if ((r = sshsig_check_hashalg(hashalg)) != 0)
  356. return r;
  357. if ((alg = ssh_digest_alg_by_name(hashalg)) == -1) {
  358. error("%s: can't look up hash algorithm %s",
  359. __func__, hashalg);
  360. return SSH_ERR_INTERNAL_ERROR;
  361. }
  362. if ((r = ssh_digest_buffer(alg, m, hash, sizeof(hash))) != 0) {
  363. error("%s: ssh_digest_buffer failed: %s", __func__, ssh_err(r));
  364. return r;
  365. }
  366. if ((hex = tohex(hash, ssh_digest_bytes(alg))) != NULL) {
  367. debug3("%s: final hash: %s", __func__, hex);
  368. freezero(hex, strlen(hex));
  369. }
  370. if ((b = sshbuf_new()) == NULL) {
  371. r = SSH_ERR_ALLOC_FAIL;
  372. goto out;
  373. }
  374. if ((r = sshbuf_put(b, hash, ssh_digest_bytes(alg))) != 0) {
  375. error("%s: sshbuf_put: %s", __func__, ssh_err(r));
  376. goto out;
  377. }
  378. *bp = b;
  379. b = NULL; /* transferred */
  380. /* success */
  381. r = 0;
  382. out:
  383. sshbuf_free(b);
  384. explicit_bzero(hash, sizeof(hash));
  385. return r;
  386. }
  387. int
  388. sshsig_signb(struct sshkey *key, const char *hashalg,
  389. const char *sk_provider, const char *sk_pin,
  390. const struct sshbuf *message, const char *sig_namespace,
  391. struct sshbuf **out, sshsig_signer *signer, void *signer_ctx)
  392. {
  393. struct sshbuf *b = NULL;
  394. int r = SSH_ERR_INTERNAL_ERROR;
  395. if (hashalg == NULL)
  396. hashalg = HASHALG_DEFAULT;
  397. if (out != NULL)
  398. *out = NULL;
  399. if ((r = hash_buffer(message, hashalg, &b)) != 0) {
  400. error("%s: hash_buffer failed: %s", __func__, ssh_err(r));
  401. goto out;
  402. }
  403. if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
  404. sig_namespace, out, signer, signer_ctx)) != 0)
  405. goto out;
  406. /* success */
  407. r = 0;
  408. out:
  409. sshbuf_free(b);
  410. return r;
  411. }
  412. int
  413. sshsig_verifyb(struct sshbuf *signature, const struct sshbuf *message,
  414. const char *expect_namespace, struct sshkey **sign_keyp,
  415. struct sshkey_sig_details **sig_details)
  416. {
  417. struct sshbuf *b = NULL;
  418. int r = SSH_ERR_INTERNAL_ERROR;
  419. char *hashalg = NULL;
  420. if (sig_details != NULL)
  421. *sig_details = NULL;
  422. if (sign_keyp != NULL)
  423. *sign_keyp = NULL;
  424. if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
  425. return r;
  426. debug("%s: signature made with hash \"%s\"", __func__, hashalg);
  427. if ((r = hash_buffer(message, hashalg, &b)) != 0) {
  428. error("%s: hash_buffer failed: %s", __func__, ssh_err(r));
  429. goto out;
  430. }
  431. if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
  432. sign_keyp, sig_details)) != 0)
  433. goto out;
  434. /* success */
  435. r = 0;
  436. out:
  437. sshbuf_free(b);
  438. free(hashalg);
  439. return r;
  440. }
  441. static int
  442. hash_file(int fd, const char *hashalg, struct sshbuf **bp)
  443. {
  444. char *hex, rbuf[8192], hash[SSH_DIGEST_MAX_LENGTH];
  445. ssize_t n, total = 0;
  446. struct ssh_digest_ctx *ctx;
  447. int alg, oerrno, r = SSH_ERR_INTERNAL_ERROR;
  448. struct sshbuf *b = NULL;
  449. *bp = NULL;
  450. memset(hash, 0, sizeof(hash));
  451. if ((r = sshsig_check_hashalg(hashalg)) != 0)
  452. return r;
  453. if ((alg = ssh_digest_alg_by_name(hashalg)) == -1) {
  454. error("%s: can't look up hash algorithm %s",
  455. __func__, hashalg);
  456. return SSH_ERR_INTERNAL_ERROR;
  457. }
  458. if ((ctx = ssh_digest_start(alg)) == NULL) {
  459. error("%s: ssh_digest_start failed", __func__);
  460. return SSH_ERR_INTERNAL_ERROR;
  461. }
  462. for (;;) {
  463. if ((n = read(fd, rbuf, sizeof(rbuf))) == -1) {
  464. if (errno == EINTR || errno == EAGAIN)
  465. continue;
  466. oerrno = errno;
  467. error("%s: read: %s", __func__, strerror(errno));
  468. ssh_digest_free(ctx);
  469. errno = oerrno;
  470. r = SSH_ERR_SYSTEM_ERROR;
  471. goto out;
  472. } else if (n == 0) {
  473. debug2("%s: hashed %zu bytes", __func__, total);
  474. break; /* EOF */
  475. }
  476. total += (size_t)n;
  477. if ((r = ssh_digest_update(ctx, rbuf, (size_t)n)) != 0) {
  478. error("%s: ssh_digest_update: %s",
  479. __func__, ssh_err(r));
  480. goto out;
  481. }
  482. }
  483. if ((r = ssh_digest_final(ctx, hash, sizeof(hash))) != 0) {
  484. error("%s: ssh_digest_final: %s", __func__, ssh_err(r));
  485. goto out;
  486. }
  487. if ((hex = tohex(hash, ssh_digest_bytes(alg))) != NULL) {
  488. debug3("%s: final hash: %s", __func__, hex);
  489. freezero(hex, strlen(hex));
  490. }
  491. if ((b = sshbuf_new()) == NULL) {
  492. r = SSH_ERR_ALLOC_FAIL;
  493. goto out;
  494. }
  495. if ((r = sshbuf_put(b, hash, ssh_digest_bytes(alg))) != 0) {
  496. error("%s: sshbuf_put: %s", __func__, ssh_err(r));
  497. goto out;
  498. }
  499. *bp = b;
  500. b = NULL; /* transferred */
  501. /* success */
  502. r = 0;
  503. out:
  504. sshbuf_free(b);
  505. ssh_digest_free(ctx);
  506. explicit_bzero(hash, sizeof(hash));
  507. return r;
  508. }
  509. int
  510. sshsig_sign_fd(struct sshkey *key, const char *hashalg,
  511. const char *sk_provider, const char *sk_pin,
  512. int fd, const char *sig_namespace, struct sshbuf **out,
  513. sshsig_signer *signer, void *signer_ctx)
  514. {
  515. struct sshbuf *b = NULL;
  516. int r = SSH_ERR_INTERNAL_ERROR;
  517. if (hashalg == NULL)
  518. hashalg = HASHALG_DEFAULT;
  519. if (out != NULL)
  520. *out = NULL;
  521. if ((r = hash_file(fd, hashalg, &b)) != 0) {
  522. error("%s: hash_file failed: %s", __func__, ssh_err(r));
  523. return r;
  524. }
  525. if ((r = sshsig_wrap_sign(key, hashalg, sk_provider, sk_pin, b,
  526. sig_namespace, out, signer, signer_ctx)) != 0)
  527. goto out;
  528. /* success */
  529. r = 0;
  530. out:
  531. sshbuf_free(b);
  532. return r;
  533. }
  534. int
  535. sshsig_verify_fd(struct sshbuf *signature, int fd,
  536. const char *expect_namespace, struct sshkey **sign_keyp,
  537. struct sshkey_sig_details **sig_details)
  538. {
  539. struct sshbuf *b = NULL;
  540. int r = SSH_ERR_INTERNAL_ERROR;
  541. char *hashalg = NULL;
  542. if (sig_details != NULL)
  543. *sig_details = NULL;
  544. if (sign_keyp != NULL)
  545. *sign_keyp = NULL;
  546. if ((r = sshsig_peek_hashalg(signature, &hashalg)) != 0)
  547. return r;
  548. debug("%s: signature made with hash \"%s\"", __func__, hashalg);
  549. if ((r = hash_file(fd, hashalg, &b)) != 0) {
  550. error("%s: hash_file failed: %s", __func__, ssh_err(r));
  551. goto out;
  552. }
  553. if ((r = sshsig_wrap_verify(signature, hashalg, b, expect_namespace,
  554. sign_keyp, sig_details)) != 0)
  555. goto out;
  556. /* success */
  557. r = 0;
  558. out:
  559. sshbuf_free(b);
  560. free(hashalg);
  561. return r;
  562. }
  563. struct sshsigopt {
  564. int ca;
  565. char *namespaces;
  566. };
  567. struct sshsigopt *
  568. sshsigopt_parse(const char *opts, const char *path, u_long linenum,
  569. const char **errstrp)
  570. {
  571. struct sshsigopt *ret;
  572. int r;
  573. const char *errstr = NULL;
  574. if ((ret = calloc(1, sizeof(*ret))) == NULL)
  575. return NULL;
  576. if (opts == NULL || *opts == '\0')
  577. return ret; /* Empty options yields empty options :) */
  578. while (*opts && *opts != ' ' && *opts != '\t') {
  579. /* flag options */
  580. if ((r = opt_flag("cert-authority", 0, &opts)) != -1) {
  581. ret->ca = 1;
  582. } else if (opt_match(&opts, "namespaces")) {
  583. if (ret->namespaces != NULL) {
  584. errstr = "multiple \"namespaces\" clauses";
  585. goto fail;
  586. }
  587. ret->namespaces = opt_dequote(&opts, &errstr);
  588. if (ret->namespaces == NULL)
  589. goto fail;
  590. }
  591. /*
  592. * Skip the comma, and move to the next option
  593. * (or break out if there are no more).
  594. */
  595. if (*opts == '\0' || *opts == ' ' || *opts == '\t')
  596. break; /* End of options. */
  597. /* Anything other than a comma is an unknown option */
  598. if (*opts != ',') {
  599. errstr = "unknown key option";
  600. goto fail;
  601. }
  602. opts++;
  603. if (*opts == '\0') {
  604. errstr = "unexpected end-of-options";
  605. goto fail;
  606. }
  607. }
  608. /* success */
  609. return ret;
  610. fail:
  611. if (errstrp != NULL)
  612. *errstrp = errstr;
  613. sshsigopt_free(ret);
  614. return NULL;
  615. }
  616. void
  617. sshsigopt_free(struct sshsigopt *opts)
  618. {
  619. if (opts == NULL)
  620. return;
  621. free(opts->namespaces);
  622. free(opts);
  623. }
  624. static int
  625. parse_principals_key_and_options(const char *path, u_long linenum, char *line,
  626. const char *required_principal, char **principalsp, struct sshkey **keyp,
  627. struct sshsigopt **sigoptsp)
  628. {
  629. char *opts = NULL, *tmp, *cp, *principals = NULL;
  630. const char *reason = NULL;
  631. struct sshsigopt *sigopts = NULL;
  632. struct sshkey *key = NULL;
  633. int r = SSH_ERR_INTERNAL_ERROR;
  634. if (principalsp != NULL)
  635. *principalsp = NULL;
  636. if (sigoptsp != NULL)
  637. *sigoptsp = NULL;
  638. if (keyp != NULL)
  639. *keyp = NULL;
  640. cp = line;
  641. cp = cp + strspn(cp, " \t"); /* skip leading whitespace */
  642. if (*cp == '#' || *cp == '\0')
  643. return SSH_ERR_KEY_NOT_FOUND; /* blank or all-comment line */
  644. /* format: identity[,identity...] [option[,option...]] key */
  645. if ((tmp = strdelimw(&cp)) == NULL) {
  646. error("%s:%lu: invalid line", path, linenum);
  647. r = SSH_ERR_INVALID_FORMAT;
  648. goto out;
  649. }
  650. if ((principals = strdup(tmp)) == NULL) {
  651. error("%s: strdup failed", __func__);
  652. r = SSH_ERR_ALLOC_FAIL;
  653. goto out;
  654. }
  655. /*
  656. * Bail out early if we're looking for a particular principal and this
  657. * line does not list it.
  658. */
  659. if (required_principal != NULL) {
  660. if (match_pattern_list(required_principal,
  661. principals, 0) != 1) {
  662. /* principal didn't match */
  663. r = SSH_ERR_KEY_NOT_FOUND;
  664. goto out;
  665. }
  666. debug("%s: %s:%lu: matched principal \"%s\"",
  667. __func__, path, linenum, required_principal);
  668. }
  669. if ((key = sshkey_new(KEY_UNSPEC)) == NULL) {
  670. error("%s: sshkey_new failed", __func__);
  671. r = SSH_ERR_ALLOC_FAIL;
  672. goto out;
  673. }
  674. if (sshkey_read(key, &cp) != 0) {
  675. /* no key? Check for options */
  676. opts = cp;
  677. if (sshkey_advance_past_options(&cp) != 0) {
  678. error("%s:%lu: invalid options", path, linenum);
  679. r = SSH_ERR_INVALID_FORMAT;
  680. goto out;
  681. }
  682. *cp++ = '\0';
  683. skip_space(&cp);
  684. if (sshkey_read(key, &cp) != 0) {
  685. error("%s:%lu: invalid key", path, linenum);
  686. r = SSH_ERR_INVALID_FORMAT;
  687. goto out;
  688. }
  689. }
  690. debug3("%s:%lu: options %s", path, linenum, opts == NULL ? "" : opts);
  691. if ((sigopts = sshsigopt_parse(opts, path, linenum, &reason)) == NULL) {
  692. error("%s:%lu: bad options: %s", path, linenum, reason);
  693. r = SSH_ERR_INVALID_FORMAT;
  694. goto out;
  695. }
  696. /* success */
  697. if (principalsp != NULL) {
  698. *principalsp = principals;
  699. principals = NULL; /* transferred */
  700. }
  701. if (sigoptsp != NULL) {
  702. *sigoptsp = sigopts;
  703. sigopts = NULL; /* transferred */
  704. }
  705. if (keyp != NULL) {
  706. *keyp = key;
  707. key = NULL; /* transferred */
  708. }
  709. r = 0;
  710. out:
  711. free(principals);
  712. sshsigopt_free(sigopts);
  713. sshkey_free(key);
  714. return r;
  715. }
  716. static int
  717. check_allowed_keys_line(const char *path, u_long linenum, char *line,
  718. const struct sshkey *sign_key, const char *principal,
  719. const char *sig_namespace)
  720. {
  721. struct sshkey *found_key = NULL;
  722. int r, found = 0;
  723. const char *reason = NULL;
  724. struct sshsigopt *sigopts = NULL;
  725. /* Parse the line */
  726. if ((r = parse_principals_key_and_options(path, linenum, line,
  727. principal, NULL, &found_key, &sigopts)) != 0) {
  728. /* error already logged */
  729. goto done;
  730. }
  731. /* Check whether options preclude the use of this key */
  732. if (sigopts->namespaces != NULL &&
  733. match_pattern_list(sig_namespace, sigopts->namespaces, 0) != 1) {
  734. error("%s:%lu: key is not permitted for use in signature "
  735. "namespace \"%s\"", path, linenum, sig_namespace);
  736. goto done;
  737. }
  738. if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {
  739. /* Exact match of key */
  740. debug("%s:%lu: matched key and principal", path, linenum);
  741. /* success */
  742. found = 1;
  743. } else if (sigopts->ca && sshkey_is_cert(sign_key) &&
  744. sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
  745. /* Match of certificate's CA key */
  746. if ((r = sshkey_cert_check_authority(sign_key, 0, 1, 0,
  747. principal, &reason)) != 0) {
  748. error("%s:%lu: certificate not authorized: %s",
  749. path, linenum, reason);
  750. goto done;
  751. }
  752. debug("%s:%lu: matched certificate CA key", path, linenum);
  753. /* success */
  754. found = 1;
  755. } else {
  756. /* Principal matched but key didn't */
  757. goto done;
  758. }
  759. done:
  760. sshkey_free(found_key);
  761. sshsigopt_free(sigopts);
  762. return found ? 0 : SSH_ERR_KEY_NOT_FOUND;
  763. }
  764. int
  765. sshsig_check_allowed_keys(const char *path, const struct sshkey *sign_key,
  766. const char *principal, const char *sig_namespace)
  767. {
  768. FILE *f = NULL;
  769. char *line = NULL;
  770. size_t linesize = 0;
  771. u_long linenum = 0;
  772. int r = SSH_ERR_INTERNAL_ERROR, oerrno;
  773. /* Check key and principal against file */
  774. if ((f = fopen(path, "r")) == NULL) {
  775. oerrno = errno;
  776. error("Unable to open allowed keys file \"%s\": %s",
  777. path, strerror(errno));
  778. errno = oerrno;
  779. return SSH_ERR_SYSTEM_ERROR;
  780. }
  781. while (getline(&line, &linesize, f) != -1) {
  782. linenum++;
  783. r = check_allowed_keys_line(path, linenum, line, sign_key,
  784. principal, sig_namespace);
  785. free(line);
  786. line = NULL;
  787. linesize = 0;
  788. if (r == SSH_ERR_KEY_NOT_FOUND)
  789. continue;
  790. else if (r == 0) {
  791. /* success */
  792. fclose(f);
  793. return 0;
  794. } else
  795. break;
  796. }
  797. /* Either we hit an error parsing or we simply didn't find the key */
  798. fclose(f);
  799. free(line);
  800. return r == 0 ? SSH_ERR_KEY_NOT_FOUND : r;
  801. }
  802. static int
  803. cert_filter_principals(const char *path, u_long linenum,
  804. char **principalsp, const struct sshkey *cert)
  805. {
  806. char *cp, *oprincipals, *principals;
  807. const char *reason;
  808. struct sshbuf *nprincipals;
  809. int r = SSH_ERR_INTERNAL_ERROR, success = 0;
  810. oprincipals = principals = *principalsp;
  811. *principalsp = NULL;
  812. if ((nprincipals = sshbuf_new()) == NULL) {
  813. r = SSH_ERR_ALLOC_FAIL;
  814. goto out;
  815. }
  816. while ((cp = strsep(&principals, ",")) != NULL && *cp != '\0') {
  817. if (strcspn(cp, "!?*") != strlen(cp)) {
  818. debug("%s:%lu: principal \"%s\" not authorized: "
  819. "contains wildcards", path, linenum, cp);
  820. continue;
  821. }
  822. /* Check against principals list in certificate */
  823. if ((r = sshkey_cert_check_authority(cert, 0, 1, 0,
  824. cp, &reason)) != 0) {
  825. debug("%s:%lu: principal \"%s\" not authorized: %s",
  826. path, linenum, cp, reason);
  827. continue;
  828. }
  829. if ((r = sshbuf_putf(nprincipals, "%s%s",
  830. sshbuf_len(nprincipals) != 0 ? "," : "", cp)) != 0) {
  831. error("%s: buffer error", __func__);
  832. goto out;
  833. }
  834. }
  835. if (sshbuf_len(nprincipals) == 0) {
  836. error("%s:%lu: no valid principals found", path, linenum);
  837. r = SSH_ERR_KEY_CERT_INVALID;
  838. goto out;
  839. }
  840. if ((principals = sshbuf_dup_string(nprincipals)) == NULL) {
  841. error("%s: buffer error", __func__);
  842. goto out;
  843. }
  844. /* success */
  845. success = 1;
  846. *principalsp = principals;
  847. out:
  848. sshbuf_free(nprincipals);
  849. free(oprincipals);
  850. return success ? 0 : r;
  851. }
  852. static int
  853. get_matching_principals_from_line(const char *path, u_long linenum, char *line,
  854. const struct sshkey *sign_key, char **principalsp)
  855. {
  856. struct sshkey *found_key = NULL;
  857. char *principals = NULL;
  858. int r, found = 0;
  859. struct sshsigopt *sigopts = NULL;
  860. if (principalsp != NULL)
  861. *principalsp = NULL;
  862. /* Parse the line */
  863. if ((r = parse_principals_key_and_options(path, linenum, line,
  864. NULL, &principals, &found_key, &sigopts)) != 0) {
  865. /* error already logged */
  866. goto done;
  867. }
  868. if (!sigopts->ca && sshkey_equal(found_key, sign_key)) {
  869. /* Exact match of key */
  870. debug("%s:%lu: matched key", path, linenum);
  871. /* success */
  872. found = 1;
  873. } else if (sigopts->ca && sshkey_is_cert(sign_key) &&
  874. sshkey_equal_public(sign_key->cert->signature_key, found_key)) {
  875. /* Remove principals listed in file but not allowed by cert */
  876. if ((r = cert_filter_principals(path, linenum,
  877. &principals, sign_key)) != 0) {
  878. /* error already displayed */
  879. debug("%s:%lu: cert_filter_principals: %s",
  880. path, linenum, ssh_err(r));
  881. goto done;
  882. }
  883. debug("%s:%lu: matched certificate CA key", path, linenum);
  884. /* success */
  885. found = 1;
  886. } else {
  887. /* Key didn't match */
  888. goto done;
  889. }
  890. done:
  891. if (found && principalsp != NULL) {
  892. *principalsp = principals;
  893. principals = NULL; /* transferred */
  894. }
  895. free(principals);
  896. sshkey_free(found_key);
  897. sshsigopt_free(sigopts);
  898. return found ? 0 : SSH_ERR_KEY_NOT_FOUND;
  899. }
  900. int
  901. sshsig_find_principals(const char *path, const struct sshkey *sign_key,
  902. char **principals)
  903. {
  904. FILE *f = NULL;
  905. char *line = NULL;
  906. size_t linesize = 0;
  907. u_long linenum = 0;
  908. int r = SSH_ERR_INTERNAL_ERROR, oerrno;
  909. if ((f = fopen(path, "r")) == NULL) {
  910. oerrno = errno;
  911. error("Unable to open allowed keys file \"%s\": %s",
  912. path, strerror(errno));
  913. errno = oerrno;
  914. return SSH_ERR_SYSTEM_ERROR;
  915. }
  916. while (getline(&line, &linesize, f) != -1) {
  917. linenum++;
  918. r = get_matching_principals_from_line(path, linenum, line,
  919. sign_key, principals);
  920. free(line);
  921. line = NULL;
  922. linesize = 0;
  923. if (r == SSH_ERR_KEY_NOT_FOUND)
  924. continue;
  925. else if (r == 0) {
  926. /* success */
  927. fclose(f);
  928. return 0;
  929. } else
  930. break;
  931. }
  932. free(line);
  933. /* Either we hit an error parsing or we simply didn't find the key */
  934. if (ferror(f) != 0) {
  935. oerrno = errno;
  936. fclose(f);
  937. error("Unable to read allowed keys file \"%s\": %s",
  938. path, strerror(errno));
  939. errno = oerrno;
  940. return SSH_ERR_SYSTEM_ERROR;
  941. }
  942. fclose(f);
  943. return r == 0 ? SSH_ERR_KEY_NOT_FOUND : r;
  944. }
  945. int
  946. sshsig_get_pubkey(struct sshbuf *signature, struct sshkey **pubkey)
  947. {
  948. struct sshkey *pk = NULL;
  949. int r = SSH_ERR_SIGNATURE_INVALID;
  950. if (pubkey == NULL)
  951. return SSH_ERR_INTERNAL_ERROR;
  952. if ((r = sshsig_parse_preamble(signature)) != 0)
  953. return r;
  954. if ((r = sshkey_froms(signature, &pk)) != 0)
  955. return r;
  956. *pubkey = pk;
  957. pk = NULL;
  958. return 0;
  959. }