- djm@cvs.openbsd.org 2013/01/17 23:00:01

[auth.c key.c key.h ssh-keygen.1 ssh-keygen.c sshd_config.5]
     [krl.c krl.h PROTOCOL.krl]
     add support for Key Revocation Lists (KRLs). These are a compact way to
     represent lists of revoked keys and certificates, taking as little as
     a single bit of incremental cost to revoke a certificate by serial number.
     KRLs are loaded via the existing RevokedKeys sshd_config option.
     feedback and ok markus@
This commit is contained in:
Damien Miller 2013-01-18 11:44:04 +11:00
parent b26699bbad
commit f3747bf401
11 changed files with 1884 additions and 34 deletions

View File

@ -1,3 +1,14 @@
20130118
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2013/01/17 23:00:01
[auth.c key.c key.h ssh-keygen.1 ssh-keygen.c sshd_config.5]
[krl.c krl.h PROTOCOL.krl]
add support for Key Revocation Lists (KRLs). These are a compact way to
represent lists of revoked keys and certificates, taking as little as
a single bit of incremental cost to revoke a certificate by serial number.
KRLs are loaded via the existing RevokedKeys sshd_config option.
feedback and ok markus@
20130117
- (djm) [regress/cipher-speed.sh regress/integrity.sh regress/try-ciphers.sh]
check for GCM support before testing GCM ciphers.

View File

@ -1,4 +1,4 @@
# $Id: Makefile.in,v 1.329 2012/12/17 04:59:43 dtucker Exp $
# $Id: Makefile.in,v 1.330 2013/01/18 00:44:04 djm Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
jpake.o schnorr.o ssh-pkcs11.o
jpake.o schnorr.o ssh-pkcs11.o krl.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect1.o sshconnect2.o mux.o \

164
PROTOCOL.krl Normal file
View File

@ -0,0 +1,164 @@
This describes the key/certificate revocation list format for OpenSSH.
1. Overall format
The KRL consists of a header and zero or more sections. The header is:
#define KRL_MAGIC 0x5353484b524c0a00ULL /* "SSHKRL\n\0" */
#define KRL_FORMAT_VERSION 1
uint64 KRL_MAGIC
uint32 KRL_FORMAT_VERSION
uint64 krl_version
uint64 generated_date
uint64 flags
string reserved
string comment
Where "krl_version" is a version number that increases each time the KRL
is modified, "generated_date" is the time in seconds since 1970-01-01
00:00:00 UTC that the KRL was generated, "comment" is an optional comment
and "reserved" an extension field whose contents are currently ignored.
No "flags" are currently defined.
Following the header are zero or more sections, each consisting of:
byte section_type
string section_data
Where "section_type" indicates the type of the "section_data". An exception
to this is the KRL_SECTION_SIGNATURE section, that has a slightly different
format (see below).
The available section types are:
#define KRL_SECTION_CERTIFICATES 1
#define KRL_SECTION_EXPLICIT_KEY 2
#define KRL_SECTION_FINGERPRINT_SHA1 3
#define KRL_SECTION_SIGNATURE 4
3. Certificate serial section
These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by
serial number or key ID. The consist of the CA key that issued the
certificates to be revoked and a reserved field whose contents is currently
ignored.
string ca_key
string reserved
Followed by one or more sections:
byte cert_section_type
string cert_section_data
The certificate section types are:
#define KRL_SECTION_CERT_SERIAL_LIST 0x20
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
#define KRL_SECTION_CERT_KEY_ID 0x23
2.1 Certificate serial list section
This section is identified as KRL_SECTION_CERT_SERIAL_LIST. It revokes
certificates by listing their serial numbers. The cert_section_data in this
case contains:
uint64 revoked_cert_serial
uint64 ...
This section may appear multiple times.
2.2. Certificate serial range section
These sections use type KRL_SECTION_CERT_SERIAL_RANGE and hold
a range of serial numbers of certificates:
uint64 serial_min
uint64 serial_max
All certificates in the range serial_min <= serial <= serial_max are
revoked.
This section may appear multiple times.
2.3. Certificate serial bitmap section
Bitmap sections use type KRL_SECTION_CERT_SERIAL_BITMAP and revoke keys
by listing their serial number in a bitmap.
uint64 serial_offset
mpint revoked_keys_bitmap
A bit set at index N in the bitmap corresponds to revocation of a keys with
serial number (serial_offset + N).
This section may appear multiple times.
2.4. Revoked key ID sections
KRL_SECTION_CERT_KEY_ID sections revoke particular certificate "key
ID" strings. This may be useful in revoking all certificates
associated with a particular identity, e.g. a host or a user.
string key_id[0]
...
This section must contain at least one "key_id". This section may appear
multiple times.
3. Explicit key sections
These sections, identified as KRL_SECTION_EXPLICIT_KEY, revoke keys
(not certificates). They are less space efficient than serial numbers,
but are able to revoke plain keys.
string public_key_blob[0]
....
This section must contain at least one "public_key_blob". The blob
must be a raw key (i.e. not a certificate).
This section may appear multiple times.
4. SHA1 fingerprint sections
These sections, identified as KRL_SECTION_FINGERPRINT_SHA1, revoke
plain keys (i.e. not certificates) by listing their SHA1 hashes:
string public_key_hash[0]
....
This section must contain at least one "public_key_hash". The hash blob
is obtained by taking the SHA1 hash of the public key blob. Hashes in
this section must appear in numeric order, treating each hash as a big-
endian integer.
This section may appear multiple times.
5. KRL signature sections
The KRL_SECTION_SIGNATURE section serves a different purpose to the
preceeding ones: to provide cryptographic authentication of a KRL that
is retrieved over a channel that does not provide integrity protection.
Its format is slightly different to the previously-described sections:
in order to simplify the signature generation, it includes as a "body"
two string components instead of one.
byte KRL_SECTION_SIGNATURE
string signature_key
string signature
The signature is calculated over the entire KRL from the KRL_MAGIC
to this subsection's "signature_key", including both and using the
signature generation rules appropriate for the type of "signature_key".
This section must appear last in the KRL. If multiple signature sections
appear, they must appear consecutively at the end of the KRL file.
Implementations that retrieve KRLs over untrusted channels must verify
signatures. Signature sections are optional for KRLs distributed by
trusted means.
$OpenBSD: PROTOCOL.krl,v 1.2 2013/01/18 00:24:58 djm Exp $

15
auth.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.99 2012/12/14 05:26:43 dtucker Exp $ */
/* $OpenBSD: auth.c,v 1.100 2013/01/17 23:00:01 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -71,6 +71,7 @@
#endif
#include "authfile.h"
#include "monitor_wrap.h"
#include "krl.h"
/* import */
extern ServerOptions options;
@ -640,7 +641,16 @@ auth_key_is_revoked(Key *key)
if (options.revoked_keys_file == NULL)
return 0;
switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) {
case 0:
return 0; /* Not revoked */
case -2:
break; /* Not a KRL */
default:
goto revoked;
}
debug3("%s: treating %s as a key list", __func__,
options.revoked_keys_file);
switch (key_in_file(key, options.revoked_keys_file, 0)) {
case 0:
/* key not revoked */
@ -651,6 +661,7 @@ auth_key_is_revoked(Key *key)
"authentication");
return 1;
case 1:
revoked:
/* Key revoked */
key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
error("WARNING: authentication attempt with a revoked "

40
key.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.c,v 1.99 2012/05/23 03:28:28 djm Exp $ */
/* $OpenBSD: key.c,v 1.100 2013/01/17 23:00:01 djm Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -55,6 +55,8 @@
#include "misc.h"
#include "ssh2.h"
static int to_blob(const Key *, u_char **, u_int *, int);
static struct KeyCert *
cert_new(void)
{
@ -324,14 +326,15 @@ key_equal(const Key *a, const Key *b)
}
u_char*
key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
u_int *dgst_raw_length)
{
const EVP_MD *md = NULL;
EVP_MD_CTX ctx;
u_char *blob = NULL;
u_char *retval = NULL;
u_int len = 0;
int nlen, elen, otype;
int nlen, elen;
*dgst_raw_length = 0;
@ -371,10 +374,7 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
case KEY_ECDSA_CERT:
case KEY_RSA_CERT:
/* We want a fingerprint of the _key_ not of the cert */
otype = k->type;
k->type = key_type_plain(k->type);
key_to_blob(k, &blob, &len);
k->type = otype;
to_blob(k, &blob, &len, 1);
break;
case KEY_UNSPEC:
return retval;
@ -1587,18 +1587,19 @@ key_from_blob(const u_char *blob, u_int blen)
return key;
}
int
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
static int
to_blob(const Key *key, u_char **blobp, u_int *lenp, int force_plain)
{
Buffer b;
int len;
int len, type;
if (key == NULL) {
error("key_to_blob: key == NULL");
return 0;
}
buffer_init(&b);
switch (key->type) {
type = force_plain ? key_type_plain(key->type) : key->type;
switch (type) {
case KEY_DSA_CERT_V00:
case KEY_RSA_CERT_V00:
case KEY_DSA_CERT:
@ -1609,7 +1610,8 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
buffer_len(&key->cert->certblob));
break;
case KEY_DSA:
buffer_put_cstring(&b, key_ssh_name(key));
buffer_put_cstring(&b,
key_ssh_name_from_type_nid(type, key->ecdsa_nid));
buffer_put_bignum2(&b, key->dsa->p);
buffer_put_bignum2(&b, key->dsa->q);
buffer_put_bignum2(&b, key->dsa->g);
@ -1617,14 +1619,16 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
break;
#ifdef OPENSSL_HAS_ECC
case KEY_ECDSA:
buffer_put_cstring(&b, key_ssh_name(key));
buffer_put_cstring(&b,
key_ssh_name_from_type_nid(type, key->ecdsa_nid));
buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid));
buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa),
EC_KEY_get0_public_key(key->ecdsa));
break;
#endif
case KEY_RSA:
buffer_put_cstring(&b, key_ssh_name(key));
buffer_put_cstring(&b,
key_ssh_name_from_type_nid(type, key->ecdsa_nid));
buffer_put_bignum2(&b, key->rsa->e);
buffer_put_bignum2(&b, key->rsa->n);
break;
@ -1645,6 +1649,12 @@ key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
return len;
}
int
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
{
return to_blob(key, blobp, lenp, 0);
}
int
key_sign(
const Key *key,
@ -2024,7 +2034,7 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
}
int
key_cert_is_legacy(Key *k)
key_cert_is_legacy(const Key *k)
{
switch (k->type) {
case KEY_DSA_CERT_V00:

6
key.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: key.h,v 1.34 2012/05/23 03:28:28 djm Exp $ */
/* $OpenBSD: key.h,v 1.35 2013/01/17 23:00:01 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -96,7 +96,7 @@ Key *key_demote(const Key *);
int key_equal_public(const Key *, const Key *);
int key_equal(const Key *, const Key *);
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *);
u_char *key_fingerprint_raw(const Key *, enum fp_type, u_int *);
const char *key_type(const Key *);
const char *key_cert_type(const Key *);
int key_write(const Key *, FILE *);
@ -114,7 +114,7 @@ int key_certify(Key *, Key *);
void key_cert_copy(const Key *, struct Key *);
int key_cert_check_authority(const Key *, int, int, const char *,
const char **);
int key_cert_is_legacy(Key *);
int key_cert_is_legacy(const Key *);
int key_ecdsa_nid_from_name(const char *);
int key_curve_name_to_nid(const char *);

1227
krl.c Normal file

File diff suppressed because it is too large Load Diff

63
krl.h Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2012 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $OpenBSD: krl.h,v 1.2 2013/01/18 00:24:58 djm Exp $ */
#ifndef _KRL_H
#define _KRL_H
/* Functions to manage key revocation lists */
#define KRL_MAGIC "SSHKRL\n\0"
#define KRL_FORMAT_VERSION 1
/* KRL section types */
#define KRL_SECTION_CERTIFICATES 1
#define KRL_SECTION_EXPLICIT_KEY 2
#define KRL_SECTION_FINGERPRINT_SHA1 3
#define KRL_SECTION_SIGNATURE 4
/* KRL_SECTION_CERTIFICATES subsection types */
#define KRL_SECTION_CERT_SERIAL_LIST 0x20
#define KRL_SECTION_CERT_SERIAL_RANGE 0x21
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
#define KRL_SECTION_CERT_KEY_ID 0x23
struct ssh_krl;
struct ssh_krl *ssh_krl_init(void);
void ssh_krl_free(struct ssh_krl *krl);
void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version);
void ssh_krl_set_sign_key(struct ssh_krl *krl, const Key *sign_key);
void ssh_krl_set_comment(struct ssh_krl *krl, const char *comment);
int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key,
u_int64_t serial);
int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const Key *ca_key,
u_int64_t lo, u_int64_t hi);
int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key,
const char *key_id);
int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key);
int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key);
int ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key);
int ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys,
u_int nsign_keys);
int ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
const Key **sign_ca_keys, u_int nsign_ca_keys);
int ssh_krl_check_key(struct ssh_krl *krl, const Key *key);
int ssh_krl_file_contains_key(const char *path, const Key *key);
#endif /* _KRL_H */

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: ssh-keygen.1,v 1.110 2012/08/15 18:25:50 jmc Exp $
.\" $OpenBSD: ssh-keygen.1,v 1.111 2013/01/17 23:00:01 djm Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,7 +35,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: August 15 2012 $
.Dd $Mdocdate: January 17 2013 $
.Dt SSH-KEYGEN 1
.Os
.Sh NAME
@ -122,6 +122,17 @@
.Op Fl f Ar input_keyfile
.Nm ssh-keygen
.Fl A
.Nm ssh-keygen
.Fl k
.Fl f Ar krl_file
.Op Fl u
.Op Fl s ca_public
.Op Fl z version_number
.Ar
.Nm ssh-keygen
.Fl Q
.Fl f Ar krl_file
.Ar
.Ek
.Sh DESCRIPTION
.Nm
@ -144,6 +155,13 @@ See the
.Sx MODULI GENERATION
section for details.
.Pp
Finally,
.Nm
can be used to generate and update Key Revocation Lists, and to test whether
given keys have been revoked by one. See the
.Sx KEY REVOCATION LISTS
section for details.
.Pp
Normally each user wishing to use SSH
with public key authentication runs this once to create the authentication
key in
@ -321,6 +339,17 @@ This option allows importing keys from other software, including several
commercial SSH implementations.
The default import format is
.Dq RFC4716 .
.It Fl k
Generate a KRL file.
In this mode,
.Nm
will generate a KRL file at the location specified via the
.Fl f
flag that revokes every key or certificate presented on the command-line.
Keys/certificates to be revoked may be specified by public key file or
using the format described in the
.Sx KEY REVOCATION LISTS
section.
.It Fl L
Prints the contents of a certificate.
.It Fl l
@ -448,6 +477,14 @@ Certify (sign) a public key using the specified CA key.
Please see the
.Sx CERTIFICATES
section for details.
.Pp
When generating a KRL,
.Fl s
specifies a path to a CA public key file used to revoke certificated directly
by key ID or serial number.
See the
.Sx KEY REVOCATION LISTS
section for details.
.It Fl T Ar output_file
Test DH group exchange candidate primes (generated using the
.Fl G
@ -485,6 +522,12 @@ For example:
(valid from 12:30 PM, January 1st, 2010 to 12:30 PM, January 1st, 2011),
.Dq -1d:20110101
(valid from yesterday to midnight, January 1st, 2011).
.It Fl u
Update a KRL.
When specified with
.Fl k ,
keys listed via the command-line are added to the existing KRL rather than
a new KRL being created.
.It Fl v
Verbose mode.
Causes
@ -504,6 +547,10 @@ OpenSSH format file and print an OpenSSH public key to stdout.
Specifies a serial number to be embedded in the certificate to distinguish
this certificate from others from the same CA.
The default serial number is zero.
.Pp
When generating a KRL, the
.Fl z
flag is used to specify a KRL version number.
.El
.Sh MODULI GENERATION
.Nm
@ -638,6 +685,73 @@ public key must be trusted by
or
.Xr ssh 1 .
Please refer to those manual pages for details.
.Sh KEY REVOCATION LISTS
.Nm
is able to manage OpenSSH format Key Revocation Lists (KRLs).
These binary files specify keys or certificates to be revoked using a
compact format; taking as little a one bit per certificate if they are being
revoked by serial number.
.Pp
KRLs may be generated using the
.Fl k
flag.
This option reads one or more files from the command-line and generates a new
KRL.
The files may either contain a KRL specification (see below) or public keys,
listed one per line.
Plain public keys are revoked by listing their hash or contents in the KRL and
certificates revoked by serial number or key ID (if the serial is zero or
not available).
.Pp
Revoking keys using a KRL specification offers explicit control over the
types of record used to revoke keys and may be used to directly revoke
certificates by serial number or key ID without having the complete original
certificate on hand.
A KRL specification consists of lines containing one of the following directives
followed by a colon and some directive-specific information.
.Bl -tag -width Ds
.It Cm serial : Ar serial_number Op -serial_number
Revokes a certificate with the specified serial number.
Serial numbers are 64 bit values, not including zero and may be expressed
in decimal, hex or octal.
If two serial numbers are specified separated by a hyphen, then the range
of serial numbers including and between each is revoked.
The CA key must have been specified on the
.Nm
command-line using the
.Fl s
option.
.It Cm id : Ar key_id
Revokes a certificate with the specified key ID string.
The CA key must have been specified on the
.Nm
command-line using the
.Fl s
option.
.It Cm key : Ar public_key
Revokes the specified key.
In a certificate is listed, then it is revoked as a plain public key.
.It Cm sha1 : Ar public_key
Revokes the specified key by its SHA1 hash.
.El
.Pp
KRLs may be updated using the
.Fl u
flag in addition to
.Fl k .
When this option is specified, keys listed via the command-line are merged into
the KRL, adding to those already there.
.Pp
It is also possible, given a KRL, to test whether it revokes a particular key
(or keys).
The
.Fl Q
flag will query an existing KRL, testing each key specified on the commandline.
If any key listed on the command-line has been revoked (or an error encountered)
then
.Nm
will exit with a non-zero exit status.
A zero exit status will only be returned if no key was revoked.
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa ~/.ssh/identity

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.222 2013/01/09 05:40:17 djm Exp $ */
/* $OpenBSD: ssh-keygen.c,v 1.223 2013/01/17 23:00:01 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -48,8 +48,11 @@
#include "match.h"
#include "hostfile.h"
#include "dns.h"
#include "ssh.h"
#include "ssh2.h"
#include "ssh-pkcs11.h"
#include "atomicio.h"
#include "krl.h"
/* Number of bits in the RSA/DSA key. This value can be set on the command line. */
#define DEFAULT_BITS 2048
@ -1896,6 +1899,226 @@ do_show_cert(struct passwd *pw)
exit(0);
}
static void
load_krl(const char *path, struct ssh_krl **krlp)
{
Buffer krlbuf;
int fd;
buffer_init(&krlbuf);
if ((fd = open(path, O_RDONLY)) == -1)
fatal("open %s: %s", path, strerror(errno));
if (!key_load_file(fd, path, &krlbuf))
fatal("Unable to load KRL");
close(fd);
/* XXX check sigs */
if (ssh_krl_from_blob(&krlbuf, krlp, NULL, 0) != 0 ||
*krlp == NULL)
fatal("Invalid KRL file");
buffer_free(&krlbuf);
}
static void
update_krl_from_file(struct passwd *pw, const char *file, const Key *ca,
struct ssh_krl *krl)
{
Key *key = NULL;
u_long lnum = 0;
char *path, *cp, *ep, line[SSH_MAX_PUBKEY_BYTES];
unsigned long long serial, serial2;
int i, was_explicit_key, was_sha1, r;
FILE *krl_spec;
path = tilde_expand_filename(file, pw->pw_uid);
if (strcmp(path, "-") == 0) {
krl_spec = stdin;
free(path);
path = xstrdup("(standard input)");
} else if ((krl_spec = fopen(path, "r")) == NULL)
fatal("fopen %s: %s", path, strerror(errno));
if (!quiet)
printf("Revoking from %s\n", path);
while (read_keyfile_line(krl_spec, path, line, sizeof(line),
&lnum) == 0) {
was_explicit_key = was_sha1 = 0;
cp = line + strspn(line, " \t");
/* Trim trailing space, comments and strip \n */
for (i = 0, r = -1; cp[i] != '\0'; i++) {
if (cp[i] == '#' || cp[i] == '\n') {
cp[i] = '\0';
break;
}
if (cp[i] == ' ' || cp[i] == '\t') {
/* Remember the start of a span of whitespace */
if (r == -1)
r = i;
} else
r = -1;
}
if (r != -1)
cp[r] = '\0';
if (*cp == '\0')
continue;
if (strncasecmp(cp, "serial:", 7) == 0) {
if (ca == NULL) {
fatal("revoking certificated by serial number "
"requires specification of a CA key");
}
cp += 7;
cp = cp + strspn(cp, " \t");
errno = 0;
serial = strtoull(cp, &ep, 0);
if (*cp == '\0' || (*ep != '\0' && *ep != '-'))
fatal("%s:%lu: invalid serial \"%s\"",
path, lnum, cp);
if (errno == ERANGE && serial == ULLONG_MAX)
fatal("%s:%lu: serial out of range",
path, lnum);
serial2 = serial;
if (*ep == '-') {
cp = ep + 1;
errno = 0;
serial2 = strtoull(cp, &ep, 0);
if (*cp == '\0' || *ep != '\0')
fatal("%s:%lu: invalid serial \"%s\"",
path, lnum, cp);
if (errno == ERANGE && serial2 == ULLONG_MAX)
fatal("%s:%lu: serial out of range",
path, lnum);
if (serial2 <= serial)
fatal("%s:%lu: invalid serial range "
"%llu:%llu", path, lnum,
(unsigned long long)serial,
(unsigned long long)serial2);
}
if (ssh_krl_revoke_cert_by_serial_range(krl,
ca, serial, serial2) != 0) {
fatal("%s: revoke serial failed",
__func__);
}
} else if (strncasecmp(cp, "id:", 3) == 0) {
if (ca == NULL) {
fatal("revoking certificated by key ID "
"requires specification of a CA key");
}
cp += 3;
cp = cp + strspn(cp, " \t");
if (ssh_krl_revoke_cert_by_key_id(krl, ca, cp) != 0)
fatal("%s: revoke key ID failed", __func__);
} else {
if (strncasecmp(cp, "key:", 4) == 0) {
cp += 4;
cp = cp + strspn(cp, " \t");
was_explicit_key = 1;
} else if (strncasecmp(cp, "sha1:", 5) == 0) {
cp += 5;
cp = cp + strspn(cp, " \t");
was_sha1 = 1;
} else {
/*
* Just try to process the line as a key.
* Parsing will fail if it isn't.
*/
}
if ((key = key_new(KEY_UNSPEC)) == NULL)
fatal("key_new");
if (key_read(key, &cp) != 1)
fatal("%s:%lu: invalid key", path, lnum);
if (was_explicit_key)
r = ssh_krl_revoke_key_explicit(krl, key);
else if (was_sha1)
r = ssh_krl_revoke_key_sha1(krl, key);
else
r = ssh_krl_revoke_key(krl, key);
if (r != 0)
fatal("%s: revoke key failed", __func__);
key_free(key);
}
}
if (strcmp(path, "-") != 0)
fclose(krl_spec);
}
static void
do_gen_krl(struct passwd *pw, int updating, int argc, char **argv)
{
struct ssh_krl *krl;
struct stat sb;
Key *ca = NULL;
int fd, i;
char *tmp;
Buffer kbuf;
if (*identity_file == '\0')
fatal("KRL generation requires an output file");
if (stat(identity_file, &sb) == -1) {
if (errno != ENOENT)
fatal("Cannot access KRL \"%s\": %s",
identity_file, strerror(errno));
if (updating)
fatal("KRL \"%s\" does not exist", identity_file);
}
if (ca_key_path != NULL) {
tmp = tilde_expand_filename(ca_key_path, pw->pw_uid);
if ((ca = key_load_public(tmp, NULL)) == NULL)
fatal("Cannot load CA public key %s", tmp);
xfree(tmp);
}
if (updating)
load_krl(identity_file, &krl);
else if ((krl = ssh_krl_init()) == NULL)
fatal("couldn't create KRL");
if (cert_serial != 0)
ssh_krl_set_version(krl, cert_serial);
if (identity_comment != NULL)
ssh_krl_set_comment(krl, identity_comment);
for (i = 0; i < argc; i++)
update_krl_from_file(pw, argv[i], ca, krl);
buffer_init(&kbuf);
if (ssh_krl_to_blob(krl, &kbuf, NULL, 0) != 0)
fatal("Couldn't generate KRL");
if ((fd = open(identity_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
fatal("open %s: %s", identity_file, strerror(errno));
if (atomicio(vwrite, fd, buffer_ptr(&kbuf), buffer_len(&kbuf)) !=
buffer_len(&kbuf))
fatal("write %s: %s", identity_file, strerror(errno));
close(fd);
buffer_free(&kbuf);
ssh_krl_free(krl);
}
static void
do_check_krl(struct passwd *pw, int argc, char **argv)
{
int i, r, ret = 0;
char *comment;
struct ssh_krl *krl;
Key *k;
if (*identity_file == '\0')
fatal("KRL checking requires an input file");
load_krl(identity_file, &krl);
for (i = 0; i < argc; i++) {
if ((k = key_load_public(argv[i], &comment)) == NULL)
fatal("Cannot load public key %s", argv[i]);
r = ssh_krl_check_key(krl, k);
printf("%s%s%s%s: %s\n", argv[i],
*comment ? " (" : "", comment, *comment ? ")" : "",
r == 0 ? "ok" : "REVOKED");
if (r != 0)
ret = 1;
key_free(k);
free(comment);
}
ssh_krl_free(krl);
exit(ret);
}
static void
usage(void)
{
@ -1922,6 +2145,7 @@ usage(void)
fprintf(stderr, " -J number Screen this number of moduli lines.\n");
fprintf(stderr, " -j number Start screening moduli at specified line.\n");
fprintf(stderr, " -K checkpt Write checkpoints to this file.\n");
fprintf(stderr, " -k Generate a KRL file.\n");
fprintf(stderr, " -L Print the contents of a certificate.\n");
fprintf(stderr, " -l Show fingerprint of key file.\n");
fprintf(stderr, " -M memory Amount of memory (MB) to use for generating DH-GEX moduli.\n");
@ -1931,6 +2155,7 @@ usage(void)
fprintf(stderr, " -O option Specify a certificate option.\n");
fprintf(stderr, " -P phrase Provide old passphrase.\n");
fprintf(stderr, " -p Change passphrase of private key file.\n");
fprintf(stderr, " -Q Test whether key(s) are revoked in KRL.\n");
fprintf(stderr, " -q Quiet.\n");
fprintf(stderr, " -R hostname Remove host from known_hosts file.\n");
fprintf(stderr, " -r hostname Print DNS resource record.\n");
@ -1939,6 +2164,7 @@ usage(void)
fprintf(stderr, " -T file Screen candidates for DH-GEX moduli.\n");
fprintf(stderr, " -t type Specify type of key to create.\n");
fprintf(stderr, " -V from:to Specify certificate validity interval.\n");
fprintf(stderr, " -u Update KRL rather than creating a new one.\n");
fprintf(stderr, " -v Verbose.\n");
fprintf(stderr, " -W gen Generator to use for generating DH-GEX moduli.\n");
fprintf(stderr, " -y Read private key file and print public key.\n");
@ -1955,14 +2181,14 @@ main(int argc, char **argv)
{
char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
char *checkpoint = NULL;
char out_file[MAXPATHLEN], *rr_hostname = NULL, *ep;
char out_file[MAXPATHLEN], *ep, *rr_hostname = NULL;
Key *private, *public;
struct passwd *pw;
struct stat st;
int opt, type, fd;
u_int32_t memory = 0, generator_wanted = 0, trials = 100;
int do_gen_candidates = 0, do_screen_candidates = 0;
int gen_all_hostkeys = 0;
int gen_all_hostkeys = 0, gen_krl = 0, update_krl = 0, check_krl = 0;
unsigned long start_lineno = 0, lines_to_process = 0;
BIGNUM *start = NULL;
FILE *f;
@ -1992,8 +2218,8 @@ main(int argc, char **argv)
exit(1);
}
while ((opt = getopt(argc, argv, "AegiqpclBHLhvxXyF:b:f:t:D:I:J:j:K:P:"
"m:N:n:O:C:r:g:R:T:G:M:S:s:a:V:W:z:")) != -1) {
while ((opt = getopt(argc, argv, "ABHLQXceghiklpquvxy"
"C:D:F:G:I:J:K:M:N:O:P:R:S:T:V:W:a:b:f:g:j:m:n:r:s:t:z:")) != -1) {
switch (opt) {
case 'A':
gen_all_hostkeys = 1;
@ -2072,6 +2298,9 @@ main(int argc, char **argv)
case 'N':
identity_new_passphrase = optarg;
break;
case 'Q':
check_krl = 1;
break;
case 'O':
add_cert_option(optarg);
break;
@ -2090,6 +2319,9 @@ main(int argc, char **argv)
cert_key_type = SSH2_CERT_TYPE_HOST;
certflags_flags = 0;
break;
case 'k':
gen_krl = 1;
break;
case 'i':
case 'X':
/* import key */
@ -2107,6 +2339,9 @@ main(int argc, char **argv)
case 'D':
pkcs11provider = optarg;
break;
case 'u':
update_krl = 1;
break;
case 'v':
if (log_level == SYSLOG_LEVEL_INFO)
log_level = SYSLOG_LEVEL_DEBUG1;
@ -2182,11 +2417,11 @@ main(int argc, char **argv)
argc -= optind;
if (ca_key_path != NULL) {
if (argc < 1) {
if (argc < 1 && !gen_krl) {
printf("Too few arguments.\n");
usage();
}
} else if (argc > 0) {
} else if (argc > 0 && !gen_krl && !check_krl) {
printf("Too many arguments.\n");
usage();
}
@ -2198,6 +2433,14 @@ main(int argc, char **argv)
printf("Cannot use -l with -H or -R.\n");
usage();
}
if (gen_krl) {
do_gen_krl(pw, update_krl, argc, argv);
return (0);
}
if (check_krl) {
do_check_krl(pw, argc, argv);
return (0);
}
if (ca_key_path != NULL) {
if (cert_key_id == NULL)
fatal("Must specify key id (-I) when certifying");

View File

@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.153 2013/01/08 18:49:04 markus Exp $
.Dd $Mdocdate: January 8 2013 $
.\" $OpenBSD: sshd_config.5,v 1.154 2013/01/17 23:00:01 djm Exp $
.Dd $Mdocdate: January 17 2013 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
@ -994,10 +994,17 @@ The default is
.Dq yes .
Note that this option applies to protocol version 2 only.
.It Cm RevokedKeys
Specifies a list of revoked public keys.
Specifies revoked public keys.
Keys listed in this file will be refused for public key authentication.
Note that if this file is not readable, then public key authentication will
be refused for all users.
Keys may be specified as a text file, listing one public key per line, or as
an OpenSSH Key Revocation List (KRL) as generated by
.Xr ssh-keygen 1
For more information on KRLs, see the
.Sx KEY REVOCATION LISTS
section in
.Xr ssh-keygen 1 .
.It Cm RhostsRSAAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together
with successful RSA host authentication is allowed.