summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--ssh-keygen.110
-rw-r--r--ssh-keygen.c115
3 files changed, 114 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index ab7f88fe2..3f0ba4237 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
3 - jmc@cvs.openbsd.org 2010/03/04 12:51:25 3 - jmc@cvs.openbsd.org 2010/03/04 12:51:25
4 [ssh.1 sshd_config.5] 4 [ssh.1 sshd_config.5]
5 tweak previous; 5 tweak previous;
6 - djm@cvs.openbsd.org 2010/03/04 20:35:08
7 [ssh-keygen.1 ssh-keygen.c]
8 Add a -L flag to print the contents of a certificate; ok markus@
6 9
720100304 1020100304
8 - (djm) [ssh-keygen.c] Use correct local variable, instead of 11 - (djm) [ssh-keygen.c] Use correct local variable, instead of
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index d704f0660..dccf5eabc 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-keygen.1,v 1.85 2010/02/26 22:09:28 jmc Exp $ 1.\" $OpenBSD: ssh-keygen.1,v 1.86 2010/03/04 20:35:08 djm Exp $
2.\" 2.\"
3.\" -*- nroff -*- 3.\" -*- nroff -*-
4.\" 4.\"
@@ -37,7 +37,7 @@
37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39.\" 39.\"
40.Dd $Mdocdate: February 26 2010 $ 40.Dd $Mdocdate: March 4 2010 $
41.Dt SSH-KEYGEN 1 41.Dt SSH-KEYGEN 1
42.Os 42.Os
43.Sh NAME 43.Sh NAME
@@ -115,6 +115,10 @@
115.Op Fl O Ar constraint 115.Op Fl O Ar constraint
116.Op Fl V Ar validity_interval 116.Op Fl V Ar validity_interval
117.Ar 117.Ar
118.Nm ssh-keygen
119.Bk -words
120.Fl L
121.Op Fl f Ar input_keyfile
118.Ek 122.Ek
119.Sh DESCRIPTION 123.Sh DESCRIPTION
120.Nm 124.Nm
@@ -275,6 +279,8 @@ also reads the
275RFC 4716 SSH Public Key File Format. 279RFC 4716 SSH Public Key File Format.
276This option allows importing keys from several commercial 280This option allows importing keys from several commercial
277SSH implementations. 281SSH implementations.
282.It Fl L
283Prints the contents of a certificate.
278.It Fl l 284.It Fl l
279Show fingerprint of specified public key file. 285Show fingerprint of specified public key file.
280Private RSA1 keys are also supported. 286Private RSA1 keys are also supported.
diff --git a/ssh-keygen.c b/ssh-keygen.c
index c2120bbc1..492c301d3 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-keygen.c,v 1.181 2010/03/04 10:36:03 djm Exp $ */ 1/* $OpenBSD: ssh-keygen.c,v 1.182 2010/03/04 20:35:08 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
@@ -82,6 +82,9 @@ int find_host = 0;
82/* Flag indicating that we want to delete a host from a known_hosts file */ 82/* Flag indicating that we want to delete a host from a known_hosts file */
83int delete_host = 0; 83int delete_host = 0;
84 84
85/* Flag indicating that we want to show the contents of a certificate */
86int show_cert = 0;
87
85/* Flag indicating that we just want to see the key fingerprint */ 88/* Flag indicating that we just want to see the key fingerprint */
86int print_fingerprint = 0; 89int print_fingerprint = 0;
87int print_bubblebabble = 0; 90int print_bubblebabble = 0;
@@ -1063,7 +1066,7 @@ do_change_comment(struct passwd *pw)
1063} 1066}
1064 1067
1065static const char * 1068static const char *
1066fmt_validity(void) 1069fmt_validity(u_int64_t valid_from, u_int64_t valid_to)
1067{ 1070{
1068 char from[32], to[32]; 1071 char from[32], to[32];
1069 static char ret[64]; 1072 static char ret[64];
@@ -1071,28 +1074,27 @@ fmt_validity(void)
1071 struct tm *tm; 1074 struct tm *tm;
1072 1075
1073 *from = *to = '\0'; 1076 *from = *to = '\0';
1074 if (cert_valid_from == 0 && 1077 if (valid_from == 0 && valid_to == 0xffffffffffffffffULL)
1075 cert_valid_to == 0xffffffffffffffffULL)
1076 return "forever"; 1078 return "forever";
1077 1079
1078 if (cert_valid_from != 0) { 1080 if (valid_from != 0) {
1079 /* XXX revisit INT_MAX in 2038 :) */ 1081 /* XXX revisit INT_MAX in 2038 :) */
1080 tt = cert_valid_from > INT_MAX ? INT_MAX : cert_valid_from; 1082 tt = valid_from > INT_MAX ? INT_MAX : valid_from;
1081 tm = localtime(&tt); 1083 tm = localtime(&tt);
1082 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm); 1084 strftime(from, sizeof(from), "%Y-%m-%dT%H:%M:%S", tm);
1083 } 1085 }
1084 if (cert_valid_to != 0xffffffffffffffffULL) { 1086 if (valid_to != 0xffffffffffffffffULL) {
1085 /* XXX revisit INT_MAX in 2038 :) */ 1087 /* XXX revisit INT_MAX in 2038 :) */
1086 tt = cert_valid_to > INT_MAX ? INT_MAX : cert_valid_to; 1088 tt = valid_to > INT_MAX ? INT_MAX : valid_to;
1087 tm = localtime(&tt); 1089 tm = localtime(&tt);
1088 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm); 1090 strftime(to, sizeof(to), "%Y-%m-%dT%H:%M:%S", tm);
1089 } 1091 }
1090 1092
1091 if (cert_valid_from == 0) { 1093 if (valid_from == 0) {
1092 snprintf(ret, sizeof(ret), "before %s", to); 1094 snprintf(ret, sizeof(ret), "before %s", to);
1093 return ret; 1095 return ret;
1094 } 1096 }
1095 if (cert_valid_to == 0xffffffffffffffffULL) { 1097 if (valid_to == 0xffffffffffffffffULL) {
1096 snprintf(ret, sizeof(ret), "after %s", from); 1098 snprintf(ret, sizeof(ret), "after %s", from);
1097 return ret; 1099 return ret;
1098 } 1100 }
@@ -1216,7 +1218,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
1216 out, cert_key_id, 1218 out, cert_key_id,
1217 cert_principals != NULL ? " for " : "", 1219 cert_principals != NULL ? " for " : "",
1218 cert_principals != NULL ? cert_principals : "", 1220 cert_principals != NULL ? cert_principals : "",
1219 fmt_validity()); 1221 fmt_validity(cert_valid_from, cert_valid_to));
1220 1222
1221 key_free(public); 1223 key_free(public);
1222 xfree(out); 1224 xfree(out);
@@ -1366,6 +1368,89 @@ add_cert_constraint(char *opt)
1366} 1368}
1367 1369
1368static void 1370static void
1371do_show_cert(struct passwd *pw)
1372{
1373 Key *key;
1374 struct stat st;
1375 char *key_fp, *ca_fp;
1376 Buffer constraints, constraint;
1377 u_char *name, *data;
1378 u_int i, dlen;
1379
1380 if (!have_identity)
1381 ask_filename(pw, "Enter file in which the key is");
1382 if (stat(identity_file, &st) < 0) {
1383 perror(identity_file);
1384 exit(1);
1385 }
1386 if ((key = key_load_public(identity_file, NULL)) == NULL)
1387 fatal("%s is not a public key", identity_file);
1388 if (!key_is_cert(key))
1389 fatal("%s is not a certificate", identity_file);
1390
1391 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
1392 ca_fp = key_fingerprint(key->cert->signature_key,
1393 SSH_FP_MD5, SSH_FP_HEX);
1394
1395 printf("%s:\n", identity_file);
1396 printf(" %s certificate %s\n", key_type(key), key_fp);
1397 printf(" Signed by %s CA %s\n",
1398 key_type(key->cert->signature_key), ca_fp);
1399 printf(" Key ID \"%s\"\n", key->cert->key_id);
1400 printf(" Valid: %s\n",
1401 fmt_validity(key->cert->valid_after, key->cert->valid_before));
1402 printf(" Principals: ");
1403 if (key->cert->nprincipals == 0)
1404 printf("(none)\n");
1405 else {
1406 for (i = 0; i < key->cert->nprincipals; i++)
1407 printf("\n %s",
1408 key->cert->principals[i]);
1409 printf("\n");
1410 }
1411 printf(" Constraints: ");
1412 if (buffer_len(&key->cert->constraints) == 0)
1413 printf("(none)\n");
1414 else {
1415 printf("\n");
1416 buffer_init(&constraints);
1417 buffer_append(&constraints,
1418 buffer_ptr(&key->cert->constraints),
1419 buffer_len(&key->cert->constraints));
1420 buffer_init(&constraint);
1421 while (buffer_len(&constraints) != 0) {
1422 name = buffer_get_string(&constraints, NULL);
1423 data = buffer_get_string_ptr(&constraints, &dlen);
1424 buffer_append(&constraint, data, dlen);
1425 printf(" %s", name);
1426 if (strcmp(name, "permit-X11-forwarding") == 0 ||
1427 strcmp(name, "permit-agent-forwarding") == 0 ||
1428 strcmp(name, "permit-port-forwarding") == 0 ||
1429 strcmp(name, "permit-pty") == 0 ||
1430 strcmp(name, "permit-user-rc") == 0)
1431 printf("\n");
1432 else if (strcmp(name, "force-command") == 0 ||
1433 strcmp(name, "source-address") == 0) {
1434 data = buffer_get_string(&constraint, NULL);
1435 printf(" %s\n", data);
1436 xfree(data);
1437 } else {
1438 printf(" UNKNOWN CONSTRAINT (len %u)\n",
1439 buffer_len(&constraint));
1440 buffer_clear(&constraint);
1441 }
1442 xfree(name);
1443 if (buffer_len(&constraint) != 0)
1444 fatal("Constraint corrupt: extra data at end");
1445 }
1446 buffer_free(&constraint);
1447 buffer_free(&constraints);
1448 }
1449
1450 exit(0);
1451}
1452
1453static void
1369usage(void) 1454usage(void)
1370{ 1455{
1371 fprintf(stderr, "usage: %s [options]\n", __progname); 1456 fprintf(stderr, "usage: %s [options]\n", __progname);
@@ -1387,6 +1472,7 @@ usage(void)
1387 fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n"); 1472 fprintf(stderr, " -h Generate host certificate instead of a user certificate.\n");
1388 fprintf(stderr, " -I key_id Key identifier to include in certificate.\n"); 1473 fprintf(stderr, " -I key_id Key identifier to include in certificate.\n");
1389 fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n"); 1474 fprintf(stderr, " -i Convert RFC 4716 to OpenSSH key file.\n");
1475 fprintf(stderr, " -L Print the contents of a certificate.\n");
1390 fprintf(stderr, " -l Show fingerprint of key file.\n"); 1476 fprintf(stderr, " -l Show fingerprint of key file.\n");
1391 fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n"); 1477 fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
1392 fprintf(stderr, " -n name,... User/host principal names to include in certificate\n"); 1478 fprintf(stderr, " -n name,... User/host principal names to include in certificate\n");
@@ -1453,7 +1539,7 @@ main(int argc, char **argv)
1453 exit(1); 1539 exit(1);
1454 } 1540 }
1455 1541
1456 while ((opt = getopt(argc, argv, "degiqpclBHhvxXyF:b:f:t:D:I:P:N:n:" 1542 while ((opt = getopt(argc, argv, "degiqpclBHLhvxXyF:b:f:t:D:I:P:N:n:"
1457 "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) { 1543 "O:C:r:g:R:T:G:M:S:s:a:V:W:")) != -1) {
1458 switch (opt) { 1544 switch (opt) {
1459 case 'b': 1545 case 'b':
@@ -1476,6 +1562,9 @@ main(int argc, char **argv)
1476 delete_host = 1; 1562 delete_host = 1;
1477 rr_hostname = optarg; 1563 rr_hostname = optarg;
1478 break; 1564 break;
1565 case 'L':
1566 show_cert = 1;
1567 break;
1479 case 'l': 1568 case 'l':
1480 print_fingerprint = 1; 1569 print_fingerprint = 1;
1481 break; 1570 break;
@@ -1629,6 +1718,8 @@ main(int argc, char **argv)
1629 fatal("Must specify key id (-I) when certifying"); 1718 fatal("Must specify key id (-I) when certifying");
1630 do_ca_sign(pw, argc, argv); 1719 do_ca_sign(pw, argc, argv);
1631 } 1720 }
1721 if (show_cert)
1722 do_show_cert(pw);
1632 if (delete_host || hash_hosts || find_host) 1723 if (delete_host || hash_hosts || find_host)
1633 do_known_hosts(pw, rr_hostname); 1724 do_known_hosts(pw, rr_hostname);
1634 if (print_fingerprint || print_bubblebabble) 1725 if (print_fingerprint || print_bubblebabble)