summaryrefslogtreecommitdiff
path: root/ssh-keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'ssh-keygen.c')
-rw-r--r--ssh-keygen.c140
1 files changed, 115 insertions, 25 deletions
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 22860ad90..46b3af5a8 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.319 2018/08/08 01:16:01 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.322 2018/09/14 04:17:44 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -450,7 +450,10 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
450 u_int magic, i1, i2, i3, i4; 450 u_int magic, i1, i2, i3, i4;
451 size_t slen; 451 size_t slen;
452 u_long e; 452 u_long e;
453 453 BIGNUM *dsa_p = NULL, *dsa_q = NULL, *dsa_g = NULL;
454 BIGNUM *dsa_pub_key = NULL, *dsa_priv_key = NULL;
455 BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL;
456 BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL;
454 if ((b = sshbuf_from(blob, blen)) == NULL) 457 if ((b = sshbuf_from(blob, blen)) == NULL)
455 fatal("%s: sshbuf_from failed", __func__); 458 fatal("%s: sshbuf_from failed", __func__);
456 if ((r = sshbuf_get_u32(b, &magic)) != 0) 459 if ((r = sshbuf_get_u32(b, &magic)) != 0)
@@ -488,17 +491,29 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
488 free(type); 491 free(type);
489 return NULL; 492 return NULL;
490 } 493 }
491 if ((key = sshkey_new_private(ktype)) == NULL) 494 if ((key = sshkey_new(ktype)) == NULL)
492 fatal("sshkey_new_private failed"); 495 fatal("sshkey_new failed");
493 free(type); 496 free(type);
494 497
495 switch (key->type) { 498 switch (key->type) {
496 case KEY_DSA: 499 case KEY_DSA:
497 buffer_get_bignum_bits(b, key->dsa->p); 500 if ((dsa_p = BN_new()) == NULL ||
498 buffer_get_bignum_bits(b, key->dsa->g); 501 (dsa_q = BN_new()) == NULL ||
499 buffer_get_bignum_bits(b, key->dsa->q); 502 (dsa_g = BN_new()) == NULL ||
500 buffer_get_bignum_bits(b, key->dsa->pub_key); 503 (dsa_pub_key = BN_new()) == NULL ||
501 buffer_get_bignum_bits(b, key->dsa->priv_key); 504 (dsa_priv_key = BN_new()) == NULL)
505 fatal("%s: BN_new", __func__);
506 buffer_get_bignum_bits(b, dsa_p);
507 buffer_get_bignum_bits(b, dsa_g);
508 buffer_get_bignum_bits(b, dsa_q);
509 buffer_get_bignum_bits(b, dsa_pub_key);
510 buffer_get_bignum_bits(b, dsa_priv_key);
511 if (!DSA_set0_pqg(key->dsa, dsa_p, dsa_q, dsa_g))
512 fatal("%s: DSA_set0_pqg failed", __func__);
513 dsa_p = dsa_q = dsa_g = NULL; /* transferred */
514 if (!DSA_set0_key(key->dsa, dsa_pub_key, dsa_priv_key))
515 fatal("%s: DSA_set0_key failed", __func__);
516 dsa_pub_key = dsa_priv_key = NULL; /* transferred */
502 break; 517 break;
503 case KEY_RSA: 518 case KEY_RSA:
504 if ((r = sshbuf_get_u8(b, &e1)) != 0 || 519 if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
@@ -515,18 +530,34 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
515 e += e3; 530 e += e3;
516 debug("e %lx", e); 531 debug("e %lx", e);
517 } 532 }
518 if (!BN_set_word(key->rsa->e, e)) { 533 if ((rsa_e = BN_new()) == NULL)
534 fatal("%s: BN_new", __func__);
535 if (!BN_set_word(rsa_e, e)) {
536 BN_clear_free(rsa_e);
519 sshbuf_free(b); 537 sshbuf_free(b);
520 sshkey_free(key); 538 sshkey_free(key);
521 return NULL; 539 return NULL;
522 } 540 }
523 buffer_get_bignum_bits(b, key->rsa->d); 541 if ((rsa_n = BN_new()) == NULL ||
524 buffer_get_bignum_bits(b, key->rsa->n); 542 (rsa_d = BN_new()) == NULL ||
525 buffer_get_bignum_bits(b, key->rsa->iqmp); 543 (rsa_p = BN_new()) == NULL ||
526 buffer_get_bignum_bits(b, key->rsa->q); 544 (rsa_q = BN_new()) == NULL ||
527 buffer_get_bignum_bits(b, key->rsa->p); 545 (rsa_iqmp = BN_new()) == NULL)
528 if ((r = ssh_rsa_generate_additional_parameters(key)) != 0) 546 fatal("%s: BN_new", __func__);
547 buffer_get_bignum_bits(b, rsa_d);
548 buffer_get_bignum_bits(b, rsa_n);
549 buffer_get_bignum_bits(b, rsa_iqmp);
550 buffer_get_bignum_bits(b, rsa_q);
551 buffer_get_bignum_bits(b, rsa_p);
552 if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d))
553 fatal("%s: RSA_set0_key failed", __func__);
554 rsa_n = rsa_e = rsa_d = NULL; /* transferred */
555 if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q))
556 fatal("%s: RSA_set0_factors failed", __func__);
557 rsa_p = rsa_q = NULL; /* transferred */
558 if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0)
529 fatal("generate RSA parameters failed: %s", ssh_err(r)); 559 fatal("generate RSA parameters failed: %s", ssh_err(r));
560 BN_clear_free(rsa_iqmp);
530 break; 561 break;
531 } 562 }
532 rlen = sshbuf_len(b); 563 rlen = sshbuf_len(b);
@@ -634,7 +665,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
634 identity_file); 665 identity_file);
635 } 666 }
636 fclose(fp); 667 fclose(fp);
637 switch (EVP_PKEY_type(pubkey->type)) { 668 switch (EVP_PKEY_base_id(pubkey)) {
638 case EVP_PKEY_RSA: 669 case EVP_PKEY_RSA:
639 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) 670 if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
640 fatal("sshkey_new failed"); 671 fatal("sshkey_new failed");
@@ -658,7 +689,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
658#endif 689#endif
659 default: 690 default:
660 fatal("%s: unsupported pubkey type %d", __func__, 691 fatal("%s: unsupported pubkey type %d", __func__,
661 EVP_PKEY_type(pubkey->type)); 692 EVP_PKEY_base_id(pubkey));
662 } 693 }
663 EVP_PKEY_free(pubkey); 694 EVP_PKEY_free(pubkey);
664 return; 695 return;
@@ -2080,15 +2111,51 @@ load_krl(const char *path, struct ssh_krl **krlp)
2080} 2111}
2081 2112
2082static void 2113static void
2114hash_to_blob(const char *cp, u_char **blobp, size_t *lenp,
2115 const char *file, u_long lnum)
2116{
2117 char *tmp;
2118 size_t tlen;
2119 struct sshbuf *b;
2120 int r;
2121
2122 if (strncmp(cp, "SHA256:", 7) != 0)
2123 fatal("%s:%lu: unsupported hash algorithm", file, lnum);
2124 cp += 7;
2125
2126 /*
2127 * OpenSSH base64 hashes omit trailing '='
2128 * characters; put them back for decode.
2129 */
2130 tlen = strlen(cp);
2131 tmp = xmalloc(tlen + 4 + 1);
2132 strlcpy(tmp, cp, tlen + 1);
2133 while ((tlen % 4) != 0) {
2134 tmp[tlen++] = '=';
2135 tmp[tlen] = '\0';
2136 }
2137 if ((b = sshbuf_new()) == NULL)
2138 fatal("%s: sshbuf_new failed", __func__);
2139 if ((r = sshbuf_b64tod(b, tmp)) != 0)
2140 fatal("%s:%lu: decode hash failed: %s", file, lnum, ssh_err(r));
2141 free(tmp);
2142 *lenp = sshbuf_len(b);
2143 *blobp = xmalloc(*lenp);
2144 memcpy(*blobp, sshbuf_ptr(b), *lenp);
2145 sshbuf_free(b);
2146}
2147
2148static void
2083update_krl_from_file(struct passwd *pw, const char *file, int wild_ca, 2149update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2084 const struct sshkey *ca, struct ssh_krl *krl) 2150 const struct sshkey *ca, struct ssh_krl *krl)
2085{ 2151{
2086 struct sshkey *key = NULL; 2152 struct sshkey *key = NULL;
2087 u_long lnum = 0; 2153 u_long lnum = 0;
2088 char *path, *cp, *ep, *line = NULL; 2154 char *path, *cp, *ep, *line = NULL;
2089 size_t linesize = 0; 2155 u_char *blob = NULL;
2156 size_t blen = 0, linesize = 0;
2090 unsigned long long serial, serial2; 2157 unsigned long long serial, serial2;
2091 int i, was_explicit_key, was_sha1, r; 2158 int i, was_explicit_key, was_sha1, was_sha256, was_hash, r;
2092 FILE *krl_spec; 2159 FILE *krl_spec;
2093 2160
2094 path = tilde_expand_filename(file, pw->pw_uid); 2161 path = tilde_expand_filename(file, pw->pw_uid);
@@ -2103,7 +2170,7 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2103 printf("Revoking from %s\n", path); 2170 printf("Revoking from %s\n", path);
2104 while (getline(&line, &linesize, krl_spec) != -1) { 2171 while (getline(&line, &linesize, krl_spec) != -1) {
2105 lnum++; 2172 lnum++;
2106 was_explicit_key = was_sha1 = 0; 2173 was_explicit_key = was_sha1 = was_sha256 = was_hash = 0;
2107 cp = line + strspn(line, " \t"); 2174 cp = line + strspn(line, " \t");
2108 /* Trim trailing space, comments and strip \n */ 2175 /* Trim trailing space, comments and strip \n */
2109 for (i = 0, r = -1; cp[i] != '\0'; i++) { 2176 for (i = 0, r = -1; cp[i] != '\0'; i++) {
@@ -2168,6 +2235,11 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2168 cp = cp + strspn(cp, " \t"); 2235 cp = cp + strspn(cp, " \t");
2169 if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0) 2236 if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
2170 fatal("%s: revoke key ID failed", __func__); 2237 fatal("%s: revoke key ID failed", __func__);
2238 } else if (strncasecmp(cp, "hash:", 5) == 0) {
2239 cp += 5;
2240 cp = cp + strspn(cp, " \t");
2241 hash_to_blob(cp, &blob, &blen, file, lnum);
2242 r = ssh_krl_revoke_key_sha256(krl, blob, blen);
2171 } else { 2243 } else {
2172 if (strncasecmp(cp, "key:", 4) == 0) { 2244 if (strncasecmp(cp, "key:", 4) == 0) {
2173 cp += 4; 2245 cp += 4;
@@ -2177,7 +2249,10 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2177 cp += 5; 2249 cp += 5;
2178 cp = cp + strspn(cp, " \t"); 2250 cp = cp + strspn(cp, " \t");
2179 was_sha1 = 1; 2251 was_sha1 = 1;
2180 } else { 2252 } else if (strncasecmp(cp, "sha256:", 7) == 0) {
2253 cp += 7;
2254 cp = cp + strspn(cp, " \t");
2255 was_sha256 = 1;
2181 /* 2256 /*
2182 * Just try to process the line as a key. 2257 * Just try to process the line as a key.
2183 * Parsing will fail if it isn't. 2258 * Parsing will fail if it isn't.
@@ -2190,13 +2265,28 @@ update_krl_from_file(struct passwd *pw, const char *file, int wild_ca,
2190 path, lnum, ssh_err(r)); 2265 path, lnum, ssh_err(r));
2191 if (was_explicit_key) 2266 if (was_explicit_key)
2192 r = ssh_krl_revoke_key_explicit(krl, key); 2267 r = ssh_krl_revoke_key_explicit(krl, key);
2193 else if (was_sha1) 2268 else if (was_sha1) {
2194 r = ssh_krl_revoke_key_sha1(krl, key); 2269 if (sshkey_fingerprint_raw(key,
2195 else 2270 SSH_DIGEST_SHA1, &blob, &blen) != 0) {
2271 fatal("%s:%lu: fingerprint failed",
2272 file, lnum);
2273 }
2274 r = ssh_krl_revoke_key_sha1(krl, blob, blen);
2275 } else if (was_sha256) {
2276 if (sshkey_fingerprint_raw(key,
2277 SSH_DIGEST_SHA256, &blob, &blen) != 0) {
2278 fatal("%s:%lu: fingerprint failed",
2279 file, lnum);
2280 }
2281 r = ssh_krl_revoke_key_sha256(krl, blob, blen);
2282 } else
2196 r = ssh_krl_revoke_key(krl, key); 2283 r = ssh_krl_revoke_key(krl, key);
2197 if (r != 0) 2284 if (r != 0)
2198 fatal("%s: revoke key failed: %s", 2285 fatal("%s: revoke key failed: %s",
2199 __func__, ssh_err(r)); 2286 __func__, ssh_err(r));
2287 freezero(blob, blen);
2288 blob = NULL;
2289 blen = 0;
2200 sshkey_free(key); 2290 sshkey_free(key);
2201 } 2291 }
2202 } 2292 }