From 992faad1f1f71114f66ea67485606b083f7d722a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 5 Oct 2012 11:38:24 +1000 Subject: - [Makefile umac.c] Add special-case target to build umac128.o. --- Makefile.in | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'Makefile.in') diff --git a/Makefile.in b/Makefile.in index 566f58fe6..a0dc5dcf7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.326 2012/04/04 01:27:57 djm Exp $ +# $Id: Makefile.in,v 1.327 2012/10/05 01:38:25 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -70,8 +70,8 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.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 jpake.o \ - schnorr.o ssh-pkcs11.o + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ + jpake.o schnorr.o ssh-pkcs11.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o \ @@ -195,6 +195,13 @@ $(CONFIGFILES): $(CONFIGFILES_IN) moduli: echo +# special case target for umac128 +umac128.o: umac.c + $(CC) $(CFLAGS) $(CPPFLAGS) -o umac128.o -c $< \ + -DUMAC_OUTPUT_LEN=16 -Dumac_new=umac128_new \ + -Dumac_update=umac128_update -Dumac_final=umac128_final \ + -Dumac_delete=umac128_delete + clean: regressclean rm -f *.o *.a $(TARGETS) logintest config.cache config.log rm -f *.out core survey -- cgit v1.2.3 From cc8e9ffdd18e1ff2b14cc49cc983648f62c9d79a Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 5 Oct 2012 15:41:06 +1000 Subject: - [Makefile.in] "Using $< in a non-suffix rule context is a GNUmake idiom" --- ChangeLog | 1 + Makefile.in | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index eda55cf57..796656601 100644 --- a/ChangeLog +++ b/ChangeLog @@ -48,6 +48,7 @@ less racy and (hopefully) more reliable on slow hardware. - [Makefile umac.c] Add special-case target to build umac128.o. - [umac.c] Enforce allowed umac output sizes. From djm@. + - [Makefile.in] "Using $< in a non-suffix rule context is a GNUmake idiom". 20120917 - (dtucker) OpenBSD CVS Sync diff --git a/Makefile.in b/Makefile.in index a0dc5dcf7..e4f9ee194 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.327 2012/10/05 01:38:25 dtucker Exp $ +# $Id: Makefile.in,v 1.328 2012/10/05 05:41:07 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -197,7 +197,7 @@ moduli: # special case target for umac128 umac128.o: umac.c - $(CC) $(CFLAGS) $(CPPFLAGS) -o umac128.o -c $< \ + $(CC) $(CFLAGS) $(CPPFLAGS) -o umac128.o -c $(srcdir)/umac.c \ -DUMAC_OUTPUT_LEN=16 -Dumac_new=umac128_new \ -Dumac_update=umac128_update -Dumac_final=umac128_final \ -Dumac_delete=umac128_delete -- cgit v1.2.3 From 0fc77297e6825ae83618c5137e190aa9f9dac9da Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 17 Dec 2012 15:59:42 +1100 Subject: - (dtucker) [Makefile.in] Add some scaffolding so that the new regress tests will work with VPATH directories. --- ChangeLog | 4 ++++ Makefile.in | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index 16a6489e5..86f756423 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20121217 + - (dtucker) [Makefile.in] Add some scaffolding so that the new regress + tests will work with VPATH directories. + 20121213 - (djm) OpenBSD CVS Sync - markus@cvs.openbsd.org 2012/12/12 16:45:52 diff --git a/Makefile.in b/Makefile.in index e4f9ee194..8765b7efb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.328 2012/10/05 05:41:07 dtucker Exp $ +# $Id: Makefile.in,v 1.329 2012/12/17 04:59:43 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -384,6 +384,9 @@ tests interop-tests: $(TARGETS) [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile ; \ + [ -f `pwd`/regress/modpipe.c ] || \ + ln -s `cd $(srcdir) && pwd`/regress/modpipe.c `pwd`/regress/modpipe.c; \ + (cd regress && make prereq); \ TEST_SHELL="@TEST_SHELL@"; \ TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ -- cgit v1.2.3 From f3747bf4014a450c9aaf1d88b010f6e579d10072 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 18 Jan 2013 11:44:04 +1100 Subject: - 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@ --- ChangeLog | 11 + Makefile.in | 4 +- PROTOCOL.krl | 164 ++++++++ auth.c | 15 +- key.c | 40 +- key.h | 6 +- krl.c | 1227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ krl.h | 63 +++ ssh-keygen.1 | 118 +++++- ssh-keygen.c | 257 +++++++++++- sshd_config.5 | 13 +- 11 files changed, 1884 insertions(+), 34 deletions(-) create mode 100644 PROTOCOL.krl create mode 100644 krl.c create mode 100644 krl.h (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index 686fe8966..65403d6e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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. diff --git a/Makefile.in b/Makefile.in index 8765b7efb..74eeab574 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 \ diff --git a/PROTOCOL.krl b/PROTOCOL.krl new file mode 100644 index 000000000..e8caa4527 --- /dev/null +++ b/PROTOCOL.krl @@ -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 $ diff --git a/auth.c b/auth.c index f5e2d3d2e..d978f0271 100644 --- a/auth.c +++ b/auth.c @@ -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 " diff --git a/key.c b/key.c index 7e9099703..4cc5c5d35 100644 --- a/key.c +++ b/key.c @@ -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 , 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: diff --git a/key.h b/key.h index 39e5577f6..ebdf45677 100644 --- a/key.h +++ b/key.h @@ -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 *); diff --git a/krl.c b/krl.c new file mode 100644 index 000000000..485057029 --- /dev/null +++ b/krl.c @@ -0,0 +1,1227 @@ +/* + * Copyright (c) 2012 Damien Miller + * + * 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.c,v 1.2 2013/01/18 00:24:58 djm Exp $ */ + +#include "includes.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "buffer.h" +#include "key.h" +#include "authfile.h" +#include "err.h" +#include "misc.h" +#include "log.h" +#include "xmalloc.h" + +#include "krl.h" + +/* #define DEBUG_KRL */ +#ifdef DEBUG_KRL +# define KRL_DBG(x) debug3 x +#else +# define KRL_DBG(x) +#endif + +/* + * Trees of revoked serial numbers, key IDs and keys. This allows + * quick searching, querying and producing lists in canonical order. + */ + +/* Tree of serial numbers. XXX make smarter: really need a real sparse bitmap */ +struct revoked_serial { + u_int64_t lo, hi; + RB_ENTRY(revoked_serial) tree_entry; +}; +static int serial_cmp(struct revoked_serial *a, struct revoked_serial *b); +RB_HEAD(revoked_serial_tree, revoked_serial); +RB_GENERATE_STATIC(revoked_serial_tree, revoked_serial, tree_entry, serial_cmp); + +/* Tree of key IDs */ +struct revoked_key_id { + char *key_id; + RB_ENTRY(revoked_key_id) tree_entry; +}; +static int key_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b); +RB_HEAD(revoked_key_id_tree, revoked_key_id); +RB_GENERATE_STATIC(revoked_key_id_tree, revoked_key_id, tree_entry, key_id_cmp); + +/* Tree of blobs (used for keys and fingerprints) */ +struct revoked_blob { + u_char *blob; + u_int len; + RB_ENTRY(revoked_blob) tree_entry; +}; +static int blob_cmp(struct revoked_blob *a, struct revoked_blob *b); +RB_HEAD(revoked_blob_tree, revoked_blob); +RB_GENERATE_STATIC(revoked_blob_tree, revoked_blob, tree_entry, blob_cmp); + +/* Tracks revoked certs for a single CA */ +struct revoked_certs { + Key *ca_key; + struct revoked_serial_tree revoked_serials; + struct revoked_key_id_tree revoked_key_ids; + TAILQ_ENTRY(revoked_certs) entry; +}; +TAILQ_HEAD(revoked_certs_list, revoked_certs); + +struct ssh_krl { + u_int64_t krl_version; + u_int64_t generated_date; + u_int64_t flags; + char *comment; + struct revoked_blob_tree revoked_keys; + struct revoked_blob_tree revoked_sha1s; + struct revoked_certs_list revoked_certs; +}; + +/* Return equal if a and b overlap */ +static int +serial_cmp(struct revoked_serial *a, struct revoked_serial *b) +{ + if (a->hi >= b->lo && a->lo <= b->hi) + return 0; + return a->lo < b->lo ? -1 : 1; +} + +static int +key_id_cmp(struct revoked_key_id *a, struct revoked_key_id *b) +{ + return strcmp(a->key_id, b->key_id); +} + +static int +blob_cmp(struct revoked_blob *a, struct revoked_blob *b) +{ + int r; + + if (a->len != b->len) { + if ((r = memcmp(a->blob, b->blob, MIN(a->len, b->len))) != 0) + return r; + return a->len > b->len ? 1 : -1; + } else + return memcmp(a->blob, b->blob, a->len); +} + +struct ssh_krl * +ssh_krl_init(void) +{ + struct ssh_krl *krl; + + if ((krl = calloc(1, sizeof(*krl))) == NULL) + return NULL; + RB_INIT(&krl->revoked_keys); + RB_INIT(&krl->revoked_sha1s); + TAILQ_INIT(&krl->revoked_certs); + return krl; +} + +static void +revoked_certs_free(struct revoked_certs *rc) +{ + struct revoked_serial *rs, *trs; + struct revoked_key_id *rki, *trki; + + RB_FOREACH_SAFE(rs, revoked_serial_tree, &rc->revoked_serials, trs) { + RB_REMOVE(revoked_serial_tree, &rc->revoked_serials, rs); + free(rs); + } + RB_FOREACH_SAFE(rki, revoked_key_id_tree, &rc->revoked_key_ids, trki) { + RB_REMOVE(revoked_key_id_tree, &rc->revoked_key_ids, rki); + free(rki->key_id); + free(rki); + } + if (rc->ca_key != NULL) + key_free(rc->ca_key); +} + +void +ssh_krl_free(struct ssh_krl *krl) +{ + struct revoked_blob *rb, *trb; + struct revoked_certs *rc, *trc; + + if (krl == NULL) + return; + + free(krl->comment); + RB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_keys, trb) { + RB_REMOVE(revoked_blob_tree, &krl->revoked_keys, rb); + free(rb->blob); + free(rb); + } + RB_FOREACH_SAFE(rb, revoked_blob_tree, &krl->revoked_sha1s, trb) { + RB_REMOVE(revoked_blob_tree, &krl->revoked_sha1s, rb); + free(rb->blob); + free(rb); + } + TAILQ_FOREACH_SAFE(rc, &krl->revoked_certs, entry, trc) { + TAILQ_REMOVE(&krl->revoked_certs, rc, entry); + revoked_certs_free(rc); + } +} + +void +ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version) +{ + krl->krl_version = version; +} + +void +ssh_krl_set_comment(struct ssh_krl *krl, const char *comment) +{ + free(krl->comment); + if ((krl->comment = strdup(comment)) == NULL) + fatal("%s: strdup", __func__); +} + +/* + * Find the revoked_certs struct for a CA key. If allow_create is set then + * create a new one in the tree if one did not exist already. + */ +static int +revoked_certs_for_ca_key(struct ssh_krl *krl, const Key *ca_key, + struct revoked_certs **rcp, int allow_create) +{ + struct revoked_certs *rc; + + *rcp = NULL; + TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { + if (key_equal(rc->ca_key, ca_key)) { + *rcp = rc; + return 0; + } + } + if (!allow_create) + return 0; + /* If this CA doesn't exist in the list then add it now */ + if ((rc = calloc(1, sizeof(*rc))) == NULL) + return -1; + if ((rc->ca_key = key_from_private(ca_key)) == NULL) { + free(rc); + return -1; + } + RB_INIT(&rc->revoked_serials); + RB_INIT(&rc->revoked_key_ids); + TAILQ_INSERT_TAIL(&krl->revoked_certs, rc, entry); + debug3("%s: new CA %s", __func__, key_type(ca_key)); + *rcp = rc; + return 0; +} + +static int +insert_serial_range(struct revoked_serial_tree *rt, u_int64_t lo, u_int64_t hi) +{ + struct revoked_serial rs, *ers, *crs, *irs; + + KRL_DBG(("%s: insert %llu:%llu", __func__, lo, hi)); + bzero(&rs, sizeof(rs)); + rs.lo = lo; + rs.hi = hi; + ers = RB_NFIND(revoked_serial_tree, rt, &rs); + if (ers == NULL || serial_cmp(ers, &rs) != 0) { + /* No entry matches. Just insert */ + if ((irs = malloc(sizeof(rs))) == NULL) + return -1; + memcpy(irs, &rs, sizeof(*irs)); + ers = RB_INSERT(revoked_serial_tree, rt, irs); + if (ers != NULL) { + KRL_DBG(("%s: bad: ers != NULL", __func__)); + /* Shouldn't happen */ + free(ers); + return -1; + } + ers = irs; + } else { + KRL_DBG(("%s: overlap found %llu:%llu", __func__, + ers->lo, ers->hi)); + /* + * The inserted entry overlaps an existing one. Grow the + * existing entry. + */ + if (ers->lo > lo) + ers->lo = lo; + if (ers->hi < hi) + ers->hi = hi; + } + /* + * The inserted or revised range might overlap or abut adjacent ones; + * coalesce as necessary. + */ + + /* Check predecessors */ + while ((crs = RB_PREV(revoked_serial_tree, rt, ers)) != NULL) { + KRL_DBG(("%s: pred %llu:%llu", __func__, crs->lo, crs->hi)); + if (ers->lo != 0 && crs->hi < ers->lo - 1) + break; + /* This entry overlaps. */ + if (crs->lo < ers->lo) { + ers->lo = crs->lo; + KRL_DBG(("%s: pred extend %llu:%llu", __func__, + ers->lo, ers->hi)); + } + RB_REMOVE(revoked_serial_tree, rt, crs); + free(crs); + } + /* Check successors */ + while ((crs = RB_NEXT(revoked_serial_tree, rt, ers)) != NULL) { + KRL_DBG(("%s: succ %llu:%llu", __func__, crs->lo, crs->hi)); + if (ers->hi != (u_int64_t)-1 && crs->lo > ers->hi + 1) + break; + /* This entry overlaps. */ + if (crs->hi > ers->hi) { + ers->hi = crs->hi; + KRL_DBG(("%s: succ extend %llu:%llu", __func__, + ers->lo, ers->hi)); + } + RB_REMOVE(revoked_serial_tree, rt, crs); + free(crs); + } + KRL_DBG(("%s: done, final %llu:%llu", __func__, ers->lo, ers->hi)); + return 0; +} + +int +ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key, + u_int64_t serial) +{ + return ssh_krl_revoke_cert_by_serial_range(krl, ca_key, serial, 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) +{ + struct revoked_certs *rc; + + if (lo > hi || lo == 0) + return -1; + if (revoked_certs_for_ca_key(krl, ca_key, &rc, 1) != 0) + return -1; + return insert_serial_range(&rc->revoked_serials, lo, hi); +} + +int +ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key, + const char *key_id) +{ + struct revoked_key_id *rki, *erki; + struct revoked_certs *rc; + + if (revoked_certs_for_ca_key(krl, ca_key, &rc, 1) != 0) + return -1; + + debug3("%s: revoke %s", __func__, key_id); + if ((rki = calloc(1, sizeof(*rki))) == NULL || + (rki->key_id = strdup(key_id)) == NULL) { + free(rki); + fatal("%s: strdup", __func__); + } + erki = RB_INSERT(revoked_key_id_tree, &rc->revoked_key_ids, rki); + if (erki != NULL) { + free(rki->key_id); + free(rki); + } + return 0; +} + +/* Convert "key" to a public key blob without any certificate information */ +static int +plain_key_blob(const Key *key, u_char **blob, u_int *blen) +{ + Key *kcopy; + int r; + + if ((kcopy = key_from_private(key)) == NULL) + return -1; + if (key_is_cert(kcopy)) { + if (key_drop_cert(kcopy) != 0) { + error("%s: key_drop_cert", __func__); + key_free(kcopy); + return -1; + } + } + r = key_to_blob(kcopy, blob, blen); + free(kcopy); + return r == 0 ? -1 : 0; +} + +/* Revoke a key blob. Ownership of blob is transferred to the tree */ +static int +revoke_blob(struct revoked_blob_tree *rbt, u_char *blob, u_int len) +{ + struct revoked_blob *rb, *erb; + + if ((rb = calloc(1, sizeof(*rb))) == NULL) + return -1; + rb->blob = blob; + rb->len = len; + erb = RB_INSERT(revoked_blob_tree, rbt, rb); + if (erb != NULL) { + free(rb->blob); + free(rb); + } + return 0; +} + +int +ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key) +{ + u_char *blob; + u_int len; + + debug3("%s: revoke type %s", __func__, key_type(key)); + if (plain_key_blob(key, &blob, &len) != 0) + return -1; + return revoke_blob(&krl->revoked_keys, blob, len); +} + +int +ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key) +{ + u_char *blob; + u_int len; + + debug3("%s: revoke type %s by sha1", __func__, key_type(key)); + if ((blob = key_fingerprint_raw(key, SSH_FP_SHA1, &len)) == NULL) + return -1; + return revoke_blob(&krl->revoked_sha1s, blob, len); +} + +int +ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key) +{ + if (!key_is_cert(key)) + return ssh_krl_revoke_key_sha1(krl, key); + + if (key_cert_is_legacy(key) || key->cert->serial == 0) { + return ssh_krl_revoke_cert_by_key_id(krl, + key->cert->signature_key, + key->cert->key_id); + } else { + return ssh_krl_revoke_cert_by_serial(krl, + key->cert->signature_key, + key->cert->serial); + } +} + +/* + * Select a copact next section type to emit in a KRL based on the + * current section type, the run length of contiguous revoked serial + * numbers and the gaps from the last and to the next revoked serial. + * Applies a mostly-accurate bit cost model to select the section type + * that will minimise the size of the resultant KRL. + */ +static int +choose_next_state(int current_state, u_int64_t contig, int final, + u_int64_t last_gap, u_int64_t next_gap, int *force_new_section) +{ + int new_state; + u_int64_t cost, cost_list, cost_range, cost_bitmap, cost_bitmap_restart; + + /* + * Avoid unsigned overflows. + * The limits are high enough to avoid confusing the calculations. + */ + contig = MIN(contig, 1ULL<<31); + last_gap = MIN(last_gap, 1ULL<<31); + next_gap = MIN(next_gap, 1ULL<<31); + + /* + * Calculate the cost to switch from the current state to candidates. + * NB. range sections only ever contain a single range, so their + * switching cost is independent of the current_state. + */ + cost_list = cost_bitmap = cost_bitmap_restart = 0; + cost_range = 8; + switch (current_state) { + case KRL_SECTION_CERT_SERIAL_LIST: + cost_bitmap_restart = cost_bitmap = 8 + 64; + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + cost_list = 8; + cost_bitmap_restart = 8 + 64; + break; + case KRL_SECTION_CERT_SERIAL_RANGE: + case 0: + cost_bitmap_restart = cost_bitmap = 8 + 64; + cost_list = 8; + } + + /* Estimate base cost in bits of each section type */ + cost_list += 64 * contig + (final ? 0 : 8+64); + cost_range += (2 * 64) + (final ? 0 : 8+64); + cost_bitmap += last_gap + contig + (final ? 0 : MIN(next_gap, 8+64)); + cost_bitmap_restart += contig + (final ? 0 : MIN(next_gap, 8+64)); + + /* Convert to byte costs for actual comparison */ + cost_list = (cost_list + 7) / 8; + cost_bitmap = (cost_bitmap + 7) / 8; + cost_bitmap_restart = (cost_bitmap_restart + 7) / 8; + cost_range = (cost_range + 7) / 8; + + /* Now pick the best choice */ + *force_new_section = 0; + new_state = KRL_SECTION_CERT_SERIAL_BITMAP; + cost = cost_bitmap; + if (cost_range < cost) { + new_state = KRL_SECTION_CERT_SERIAL_RANGE; + cost = cost_range; + } + if (cost_list < cost) { + new_state = KRL_SECTION_CERT_SERIAL_LIST; + cost = cost_list; + } + if (cost_bitmap_restart < cost) { + new_state = KRL_SECTION_CERT_SERIAL_BITMAP; + *force_new_section = 1; + cost = cost_bitmap_restart; + } + debug3("%s: contig %llu last_gap %llu next_gap %llu final %d, costs:" + "list %llu range %llu bitmap %llu new bitmap %llu, " + "selected 0x%02x%s", __func__, contig, last_gap, next_gap, final, + cost_list, cost_range, cost_bitmap, cost_bitmap_restart, new_state, + *force_new_section ? " restart" : ""); + return new_state; +} + +/* Generate a KRL_SECTION_CERTIFICATES KRL section */ +static int +revoked_certs_generate(struct revoked_certs *rc, Buffer *buf) +{ + int final, force_new_sect, r = -1; + u_int64_t i, contig, gap, last = 0, bitmap_start = 0; + struct revoked_serial *rs, *nrs; + struct revoked_key_id *rki; + int next_state, state = 0; + Buffer sect; + u_char *kblob = NULL; + u_int klen; + BIGNUM *bitmap = NULL; + + /* Prepare CA scope key blob if we have one supplied */ + if (key_to_blob(rc->ca_key, &kblob, &klen) == 0) + return -1; + + buffer_init(§); + + /* Store the header */ + buffer_put_string(buf, kblob, klen); + buffer_put_string(buf, NULL, 0); /* Reserved */ + + free(kblob); + + /* Store the revoked serials. */ + for (rs = RB_MIN(revoked_serial_tree, &rc->revoked_serials); + rs != NULL; + rs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs)) { + debug3("%s: serial %llu:%llu state 0x%02x", __func__, + rs->lo, rs->hi, state); + + /* Check contiguous length and gap to next section (if any) */ + nrs = RB_NEXT(revoked_serial_tree, &rc->revoked_serials, rs); + final = nrs == NULL; + gap = nrs == NULL ? 0 : nrs->lo - rs->hi; + contig = 1 + (rs->hi - rs->lo); + + /* Choose next state based on these */ + next_state = choose_next_state(state, contig, final, + state == 0 ? 0 : rs->lo - last, gap, &force_new_sect); + + /* + * If the current section is a range section or has a different + * type to the next section, then finish it off now. + */ + if (state != 0 && (force_new_sect || next_state != state || + state == KRL_SECTION_CERT_SERIAL_RANGE)) { + debug3("%s: finish state 0x%02x", __func__, state); + switch (state) { + case KRL_SECTION_CERT_SERIAL_LIST: + case KRL_SECTION_CERT_SERIAL_RANGE: + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + buffer_put_bignum2(§, bitmap); + BN_free(bitmap); + bitmap = NULL; + break; + } + buffer_put_char(buf, state); + buffer_put_string(buf, + buffer_ptr(§), buffer_len(§)); + } + + /* If we are starting a new section then prepare it now */ + if (next_state != state || force_new_sect) { + debug3("%s: start state 0x%02x", __func__, next_state); + state = next_state; + buffer_clear(§); + switch (state) { + case KRL_SECTION_CERT_SERIAL_LIST: + case KRL_SECTION_CERT_SERIAL_RANGE: + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + if ((bitmap = BN_new()) == NULL) + goto out; + bitmap_start = rs->lo; + buffer_put_int64(§, bitmap_start); + break; + } + } + + /* Perform section-specific processing */ + switch (state) { + case KRL_SECTION_CERT_SERIAL_LIST: + for (i = rs->lo; i < contig; i++) + buffer_put_int64(§, rs->lo + i); + break; + case KRL_SECTION_CERT_SERIAL_RANGE: + buffer_put_int64(§, rs->lo); + buffer_put_int64(§, rs->hi); + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + if (rs->lo - bitmap_start > INT_MAX) { + error("%s: insane bitmap gap", __func__); + goto out; + } + for (i = 0; i < contig; i++) { + if (BN_set_bit(bitmap, + rs->lo + i - bitmap_start) != 1) + goto out; + } + break; + } + last = rs->hi; + } + /* Flush the remaining section, if any */ + if (state != 0) { + debug3("%s: serial final flush for state 0x%02x", + __func__, state); + switch (state) { + case KRL_SECTION_CERT_SERIAL_LIST: + case KRL_SECTION_CERT_SERIAL_RANGE: + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + buffer_put_bignum2(§, bitmap); + BN_free(bitmap); + bitmap = NULL; + break; + } + buffer_put_char(buf, state); + buffer_put_string(buf, + buffer_ptr(§), buffer_len(§)); + } + debug3("%s: serial done ", __func__); + + /* Now output a section for any revocations by key ID */ + buffer_clear(§); + RB_FOREACH(rki, revoked_key_id_tree, &rc->revoked_key_ids) { + debug3("%s: key ID %s", __func__, rki->key_id); + buffer_put_cstring(§, rki->key_id); + } + if (buffer_len(§) != 0) { + buffer_put_char(buf, KRL_SECTION_CERT_KEY_ID); + buffer_put_string(buf, buffer_ptr(§), + buffer_len(§)); + } + r = 0; + out: + if (bitmap != NULL) + BN_free(bitmap); + buffer_free(§); + return r; +} + +int +ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys, + u_int nsign_keys) +{ + int r = -1; + struct revoked_certs *rc; + struct revoked_blob *rb; + Buffer sect; + u_char *kblob = NULL, *sblob = NULL; + u_int klen, slen, i; + + if (krl->generated_date == 0) + krl->generated_date = time(NULL); + + buffer_init(§); + + /* Store the header */ + buffer_append(buf, KRL_MAGIC, sizeof(KRL_MAGIC) - 1); + buffer_put_int(buf, KRL_FORMAT_VERSION); + buffer_put_int64(buf, krl->krl_version); + buffer_put_int64(buf, krl->generated_date); + buffer_put_int64(buf, krl->flags); + buffer_put_string(buf, NULL, 0); + buffer_put_cstring(buf, krl->comment ? krl->comment : ""); + + /* Store sections for revoked certificates */ + TAILQ_FOREACH(rc, &krl->revoked_certs, entry) { + if (revoked_certs_generate(rc, §) != 0) + goto out; + buffer_put_char(buf, KRL_SECTION_CERTIFICATES); + buffer_put_string(buf, buffer_ptr(§), + buffer_len(§)); + } + + /* Finally, output sections for revocations by public key/hash */ + buffer_clear(§); + RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_keys) { + debug3("%s: key len %u ", __func__, rb->len); + buffer_put_string(§, rb->blob, rb->len); + } + if (buffer_len(§) != 0) { + buffer_put_char(buf, KRL_SECTION_EXPLICIT_KEY); + buffer_put_string(buf, buffer_ptr(§), + buffer_len(§)); + } + buffer_clear(§); + RB_FOREACH(rb, revoked_blob_tree, &krl->revoked_sha1s) { + debug3("%s: hash len %u ", __func__, rb->len); + buffer_put_string(§, rb->blob, rb->len); + } + if (buffer_len(§) != 0) { + buffer_put_char(buf, KRL_SECTION_FINGERPRINT_SHA1); + buffer_put_string(buf, buffer_ptr(§), + buffer_len(§)); + } + + for (i = 0; i < nsign_keys; i++) { + if (key_to_blob(sign_keys[i], &kblob, &klen) == 0) + goto out; + + debug3("%s: signature key len %u", __func__, klen); + buffer_put_char(buf, KRL_SECTION_SIGNATURE); + buffer_put_string(buf, kblob, klen); + + if (key_sign(sign_keys[i], &sblob, &slen, + buffer_ptr(buf), buffer_len(buf)) == -1) + goto out; + debug3("%s: signature sig len %u", __func__, slen); + buffer_put_string(buf, sblob, slen); + } + + r = 0; + out: + free(kblob); + free(sblob); + buffer_free(§); + return r; +} + +static void +format_timestamp(u_int64_t timestamp, char *ts, size_t nts) +{ + time_t t; + struct tm *tm; + + t = timestamp; + tm = localtime(&t); + *ts = '\0'; + strftime(ts, nts, "%Y%m%dT%H%M%S", tm); +} + +static int +parse_revoked_certs(Buffer *buf, struct ssh_krl *krl) +{ + int ret = -1, nbits; + u_char type, *blob; + u_int blen; + Buffer subsect; + u_int64_t serial, serial_lo, serial_hi; + BIGNUM *bitmap = NULL; + char *key_id = NULL; + Key *ca_key = NULL; + + buffer_init(&subsect); + + if ((blob = buffer_get_string_ptr_ret(buf, &blen)) == NULL || + buffer_get_string_ptr_ret(buf, NULL) == NULL) { /* reserved */ + error("%s: buffer error", __func__); + goto out; + } + if ((ca_key = key_from_blob(blob, blen)) == NULL) + goto out; + + while (buffer_len(buf) > 0) { + if (buffer_get_char_ret(&type, buf) != 0 || + (blob = buffer_get_string_ptr_ret(buf, &blen)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + buffer_clear(&subsect); + buffer_append(&subsect, blob, blen); + debug3("%s: subsection type 0x%02x", __func__, type); + /* buffer_dump(&subsect); */ + + switch (type) { + case KRL_SECTION_CERT_SERIAL_LIST: + while (buffer_len(&subsect) > 0) { + if (buffer_get_int64_ret(&serial, + &subsect) != 0) { + error("%s: buffer error", __func__); + goto out; + } + if (ssh_krl_revoke_cert_by_serial(krl, ca_key, + serial) != 0) { + error("%s: update failed", __func__); + goto out; + } + } + break; + case KRL_SECTION_CERT_SERIAL_RANGE: + if (buffer_get_int64_ret(&serial_lo, &subsect) != 0 || + buffer_get_int64_ret(&serial_hi, &subsect) != 0) { + error("%s: buffer error", __func__); + goto out; + } + if (ssh_krl_revoke_cert_by_serial_range(krl, ca_key, + serial_lo, serial_hi) != 0) { + error("%s: update failed", __func__); + goto out; + } + break; + case KRL_SECTION_CERT_SERIAL_BITMAP: + if ((bitmap = BN_new()) == NULL) { + error("%s: BN_new", __func__); + goto out; + } + if (buffer_get_int64_ret(&serial_lo, &subsect) != 0 || + buffer_get_bignum2_ret(&subsect, bitmap) != 0) { + error("%s: buffer error", __func__); + goto out; + } + if ((nbits = BN_num_bits(bitmap)) < 0) { + error("%s: bitmap bits < 0", __func__); + goto out; + } + for (serial = 0; serial < (u_int)nbits; serial++) { + if (serial > 0 && serial_lo + serial == 0) { + error("%s: bitmap wraps u64", __func__); + goto out; + } + if (!BN_is_bit_set(bitmap, serial)) + continue; + if (ssh_krl_revoke_cert_by_serial(krl, ca_key, + serial_lo + serial) != 0) { + error("%s: update failed", __func__); + goto out; + } + } + BN_free(bitmap); + bitmap = NULL; + break; + case KRL_SECTION_CERT_KEY_ID: + while (buffer_len(&subsect) > 0) { + if ((key_id = buffer_get_cstring_ret(&subsect, + NULL)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + if (ssh_krl_revoke_cert_by_key_id(krl, ca_key, + key_id) != 0) { + error("%s: update failed", __func__); + goto out; + } + free(key_id); + key_id = NULL; + } + break; + default: + error("Unsupported KRL certificate section %u", type); + goto out; + } + if (buffer_len(&subsect) > 0) { + error("KRL certificate section contains unparsed data"); + goto out; + } + } + + ret = 0; + out: + if (ca_key != NULL) + key_free(ca_key); + if (bitmap != NULL) + BN_free(bitmap); + free(key_id); + buffer_free(&subsect); + return ret; +} + + +/* Attempt to parse a KRL, checking its signature (if any) with sign_ca_keys. */ +int +ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp, + const Key **sign_ca_keys, u_int nsign_ca_keys) +{ + Buffer copy, sect; + struct ssh_krl *krl; + char timestamp[64]; + int ret = -1, r, sig_seen; + Key *key = NULL, **ca_used = NULL; + u_char type, *blob; + u_int i, j, sig_off, sects_off, blen, format_version, nca_used = 0; + + *krlp = NULL; + if (buffer_len(buf) < sizeof(KRL_MAGIC) - 1 || + memcmp(buffer_ptr(buf), KRL_MAGIC, sizeof(KRL_MAGIC) - 1) != 0) { + debug3("%s: not a KRL", __func__); + /* + * Return success but a NULL *krlp here to signal that the + * file might be a simple list of keys. + */ + return 0; + } + + /* Take a copy of the KRL buffer so we can verify its signature later */ + buffer_init(©); + buffer_append(©, buffer_ptr(buf), buffer_len(buf)); + + buffer_init(§); + buffer_consume(©, sizeof(KRL_MAGIC) - 1); + + if ((krl = ssh_krl_init()) == NULL) { + error("%s: alloc failed", __func__); + goto out; + } + + if (buffer_get_int_ret(&format_version, ©) != 0) { + error("%s: KRL truncated", __func__); + goto out; + } + if (format_version != KRL_FORMAT_VERSION) { + error("%s: KRL unsupported format version %u", + __func__, format_version); + goto out; + } + if (buffer_get_int64_ret(&krl->krl_version, ©) != 0 || + buffer_get_int64_ret(&krl->generated_date, ©) != 0 || + buffer_get_int64_ret(&krl->flags, ©) != 0 || + buffer_get_string_ptr_ret(©, NULL) == NULL || /* reserved */ + (krl->comment = buffer_get_cstring_ret(©, NULL)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + + format_timestamp(krl->generated_date, timestamp, sizeof(timestamp)); + debug("KRL version %llu generated at %s%s%s", krl->krl_version, + timestamp, *krl->comment ? ": " : "", krl->comment); + + /* + * 1st pass: verify signatures, if any. This is done to avoid + * detailed parsing of data whose provenance is unverified. + */ + sig_seen = 0; + sects_off = buffer_len(buf) - buffer_len(©); + while (buffer_len(©) > 0) { + if (buffer_get_char_ret(&type, ©) != 0 || + (blob = buffer_get_string_ptr_ret(©, &blen)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + debug3("%s: first pass, section 0x%02x", __func__, type); + if (type != KRL_SECTION_SIGNATURE) { + if (sig_seen) { + error("KRL contains non-signature section " + "after signature"); + goto out; + } + /* Not interested for now. */ + continue; + } + sig_seen = 1; + /* First string component is the signing key */ + if ((key = key_from_blob(blob, blen)) == NULL) { + error("%s: invalid signature key", __func__); + goto out; + } + sig_off = buffer_len(buf) - buffer_len(©); + /* Second string component is the signature itself */ + if ((blob = buffer_get_string_ptr_ret(©, &blen)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + /* Check signature over entire KRL up to this point */ + if (key_verify(key, blob, blen, + buffer_ptr(buf), buffer_len(buf) - sig_off) == -1) { + error("bad signaure on KRL"); + goto out; + } + /* Check if this key has already signed this KRL */ + for (i = 0; i < nca_used; i++) { + if (key_equal(ca_used[i], key)) { + error("KRL signed more than once with " + "the same key"); + goto out; + } + } + /* Record keys used to sign the KRL */ + xrealloc(ca_used, nca_used + 1, sizeof(*ca_used)); + ca_used[nca_used++] = key; + key = NULL; + break; + } + + /* + * 2nd pass: parse and load the KRL, skipping the header to the point + * where the section start. + */ + buffer_append(©, (u_char*)buffer_ptr(buf) + sects_off, + buffer_len(buf) - sects_off); + while (buffer_len(©) > 0) { + if (buffer_get_char_ret(&type, ©) != 0 || + (blob = buffer_get_string_ptr_ret(©, &blen)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + debug3("%s: second pass, section 0x%02x", __func__, type); + buffer_clear(§); + buffer_append(§, blob, blen); + + switch (type) { + case KRL_SECTION_CERTIFICATES: + if ((r = parse_revoked_certs(§, krl)) != 0) + goto out; + break; + case KRL_SECTION_EXPLICIT_KEY: + case KRL_SECTION_FINGERPRINT_SHA1: + while (buffer_len(§) > 0) { + if ((blob = buffer_get_string_ret(§, + &blen)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + if (type == KRL_SECTION_FINGERPRINT_SHA1 && + blen != 20) { + error("%s: bad SHA1 length", __func__); + goto out; + } + if (revoke_blob( + type == KRL_SECTION_EXPLICIT_KEY ? + &krl->revoked_keys : &krl->revoked_sha1s, + blob, blen) != 0) + goto out; /* revoke_blob frees blob */ + } + break; + case KRL_SECTION_SIGNATURE: + /* Handled above, but still need to stay in synch */ + buffer_clear(§); + if ((blob = buffer_get_string_ptr_ret(§, + &blen)) == NULL) { + error("%s: buffer error", __func__); + goto out; + } + break; + default: + error("Unsupported KRL section %u", type); + goto out; + } + if (buffer_len(§) > 0) { + error("KRL section contains unparsed data"); + goto out; + } + } + + /* Check that the key(s) used to sign the KRL weren't revoked */ + sig_seen = 0; + for (i = 0; i < nca_used; i++) { + if (ssh_krl_check_key(krl, ca_used[i]) == 0) + sig_seen = 1; + else { + key_free(ca_used[i]); + ca_used[i] = NULL; + } + } + if (nca_used && !sig_seen) { + error("All keys used to sign KRL were revoked"); + goto out; + } + + /* If we have CA keys, then verify that one was used to sign the KRL */ + if (sig_seen && nsign_ca_keys != 0) { + sig_seen = 0; + for (i = 0; !sig_seen && i < nsign_ca_keys; i++) { + for (j = 0; j < nca_used; j++) { + if (ca_used[j] == NULL) + continue; + if (key_equal(ca_used[j], sign_ca_keys[i])) { + sig_seen = 1; + break; + } + } + } + if (!sig_seen) { + error("KRL not signed with any trusted key"); + goto out; + } + } + + *krlp = krl; + ret = 0; + out: + if (ret != 0) + ssh_krl_free(krl); + for (i = 0; i < nca_used; i++) { + if (ca_used[i] != NULL) + key_free(ca_used[i]); + } + free(ca_used); + if (key != NULL) + key_free(key); + buffer_free(©); + buffer_free(§); + return ret; +} + +/* Checks whether a given key/cert is revoked. Does not check its CA */ +static int +is_key_revoked(struct ssh_krl *krl, const Key *key) +{ + struct revoked_blob rb, *erb; + struct revoked_serial rs, *ers; + struct revoked_key_id rki, *erki; + struct revoked_certs *rc; + + /* Check explicitly revoked hashes first */ + bzero(&rb, sizeof(rb)); + if ((rb.blob = key_fingerprint_raw(key, SSH_FP_SHA1, &rb.len)) == NULL) + return -1; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_sha1s, &rb); + free(rb.blob); + if (erb != NULL) { + debug("%s: revoked by key SHA1", __func__); + return -1; + } + + /* Next, explicit keys */ + bzero(&rb, sizeof(rb)); + if (plain_key_blob(key, &rb.blob, &rb.len) != 0) + return -1; + erb = RB_FIND(revoked_blob_tree, &krl->revoked_keys, &rb); + free(rb.blob); + if (erb != NULL) { + debug("%s: revoked by explicit key", __func__); + return -1; + } + + if (!key_is_cert(key)) + return 0; + + /* Check cert revocation */ + if (revoked_certs_for_ca_key(krl, key->cert->signature_key, + &rc, 0) != 0) + return -1; + if (rc == NULL) + return 0; /* No entry for this CA */ + + /* Check revocation by cert key ID */ + bzero(&rki, sizeof(rki)); + rki.key_id = key->cert->key_id; + erki = RB_FIND(revoked_key_id_tree, &rc->revoked_key_ids, &rki); + if (erki != NULL) { + debug("%s: revoked by key ID", __func__); + return -1; + } + + /* Legacy cert formats lack serial numbers */ + if (key_cert_is_legacy(key)) + return 0; + + bzero(&rs, sizeof(rs)); + rs.lo = rs.hi = key->cert->serial; + ers = RB_FIND(revoked_serial_tree, &rc->revoked_serials, &rs); + if (ers != NULL) { + KRL_DBG(("%s: %llu matched %llu:%llu", __func__, + key->cert->serial, ers->lo, ers->hi)); + debug("%s: revoked by serial", __func__); + return -1; + } + KRL_DBG(("%s: %llu no match", __func__, key->cert->serial)); + + return 0; +} + +int +ssh_krl_check_key(struct ssh_krl *krl, const Key *key) +{ + int r; + + debug2("%s: checking key", __func__); + if ((r = is_key_revoked(krl, key)) != 0) + return r; + if (key_is_cert(key)) { + debug2("%s: checking CA key", __func__); + if ((r = is_key_revoked(krl, key->cert->signature_key)) != 0) + return r; + } + debug3("%s: key okay", __func__); + return 0; +} + +/* Returns 0 on success, -1 on error or key revoked, -2 if path is not a KRL */ +int +ssh_krl_file_contains_key(const char *path, const Key *key) +{ + Buffer krlbuf; + struct ssh_krl *krl; + int revoked, fd; + + if (path == NULL) + return 0; + + if ((fd = open(path, O_RDONLY)) == -1) { + error("open %s: %s", path, strerror(errno)); + error("Revoked keys file not accessible - refusing public key " + "authentication"); + return -1; + } + buffer_init(&krlbuf); + if (!key_load_file(fd, path, &krlbuf)) { + close(fd); + buffer_free(&krlbuf); + error("Revoked keys file not readable - refusing public key " + "authentication"); + return -1; + } + close(fd); + if (ssh_krl_from_blob(&krlbuf, &krl, NULL, 0) != 0) { + buffer_free(&krlbuf); + error("Invalid KRL, refusing public key " + "authentication"); + return -1; + } + buffer_free(&krlbuf); + if (krl == NULL) { + debug3("%s: %s is not a KRL file", __func__, path); + return -2; + } + debug2("%s: checking KRL %s", __func__, path); + revoked = ssh_krl_check_key(krl, key) != 0; + ssh_krl_free(krl); + return revoked ? -1 : 0; +} diff --git a/krl.h b/krl.h new file mode 100644 index 000000000..2c43f5bb2 --- /dev/null +++ b/krl.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2012 Damien Miller + * + * 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 */ + diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 1d5564640..52f4b6ea6 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -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 .\" Copyright (c) 1995 Tatu Ylonen , 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 diff --git a/ssh-keygen.c b/ssh-keygen.c index a19a2b085..861b04e2d 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -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 * Copyright (c) 1994 Tatu Ylonen , 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"); diff --git a/sshd_config.5 b/sshd_config.5 index e7bb0b55f..c8b814da6 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -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. -- cgit v1.2.3 From f0a8ded824a0149940a8c95755da05a9ce5d7f35 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 12 Feb 2013 11:00:34 +1100 Subject: - djm@cvs.openbsd.org 2013/01/26 06:11:05 [Makefile.in acss.c acss.h cipher-acss.c cipher.c] [openbsd-compat/openssl-compat.h] remove ACSS, now that it is gone from libcrypto too --- ChangeLog | 4 + Makefile.in | 6 +- acss.c | 267 ---------------------------------------- acss.h | 47 ------- cipher-acss.c | 86 ------------- cipher.c | 10 +- openbsd-compat/openssl-compat.h | 12 +- 7 files changed, 11 insertions(+), 421 deletions(-) delete mode 100644 acss.c delete mode 100644 acss.h delete mode 100644 cipher-acss.c (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index 428a93ddb..25fb4b680 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,10 @@ redo last commit without the vi-vomit that snuck in: skip serial lookup when cert's serial number is zero (now with 100% better comment) + - djm@cvs.openbsd.org 2013/01/26 06:11:05 + [Makefile.in acss.c acss.h cipher-acss.c cipher.c] + [openbsd-compat/openssl-compat.h] + remove ACSS, now that it is gone from libcrypto too 20130211 - (djm) [configure.ac openbsd-compat/openssl-compat.h] Repair build on old diff --git a/Makefile.in b/Makefile.in index 74eeab574..ec3e1f417 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.330 2013/01/18 00:44:04 djm Exp $ +# $Id: Makefile.in,v 1.331 2013/02/12 00:00:34 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -61,8 +61,8 @@ MANFMT=@MANFMT@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) -LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ - canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \ +LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + canohost.o channels.o cipher.o cipher-aes.o \ cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ log.o match.o md-sha256.o moduli.o nchan.o packet.o \ diff --git a/acss.c b/acss.c deleted file mode 100644 index 86e2c01a8..000000000 --- a/acss.c +++ /dev/null @@ -1,267 +0,0 @@ -/* $Id: acss.c,v 1.4 2006/07/24 04:51:01 djm Exp $ */ -/* - * Copyright (c) 2004 The OpenBSD project - * - * 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. - */ - -#include "includes.h" - -#include - -#include - -#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00906000L) - -#include "acss.h" - -/* decryption sbox */ -static unsigned char sboxdec[] = { - 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, - 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b, - 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96, - 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b, - 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12, - 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f, - 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90, - 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91, - 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74, - 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75, - 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94, - 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95, - 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10, - 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11, - 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92, - 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f, - 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16, - 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b, - 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6, - 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb, - 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72, - 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f, - 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0, - 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1, - 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14, - 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15, - 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4, - 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5, - 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, - 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, - 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2, - 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff -}; - -/* encryption sbox */ -static unsigned char sboxenc[] = { - 0x33, 0x3b, 0x73, 0x15, 0x53, 0x5b, 0x13, 0x75, - 0x3d, 0x35, 0x7d, 0x1b, 0x5d, 0x55, 0x1d, 0x7b, - 0x67, 0x6f, 0x27, 0x81, 0xc7, 0xcf, 0x87, 0x21, - 0x69, 0x61, 0x29, 0x8f, 0xc9, 0xc1, 0x89, 0x2f, - 0xe3, 0xeb, 0xa3, 0x05, 0x43, 0x4b, 0x03, 0xa5, - 0xed, 0xe5, 0xad, 0x0b, 0x4d, 0x45, 0x0d, 0xab, - 0xea, 0xe2, 0xaa, 0x00, 0x4a, 0x42, 0x0a, 0xa0, - 0xe8, 0xe0, 0xa8, 0x02, 0x48, 0x40, 0x08, 0xa2, - 0x3e, 0x36, 0x7e, 0x14, 0x5e, 0x56, 0x1e, 0x74, - 0x3c, 0x34, 0x7c, 0x16, 0x5c, 0x54, 0x1c, 0x76, - 0x6a, 0x62, 0x2a, 0x80, 0xca, 0xc2, 0x8a, 0x20, - 0x68, 0x60, 0x28, 0x82, 0xc8, 0xc0, 0x88, 0x22, - 0xee, 0xe6, 0xae, 0x04, 0x4e, 0x46, 0x0e, 0xa4, - 0xec, 0xe4, 0xac, 0x06, 0x4c, 0x44, 0x0c, 0xa6, - 0xe7, 0xef, 0xa7, 0x01, 0x47, 0x4f, 0x07, 0xa1, - 0xe9, 0xe1, 0xa9, 0x0f, 0x49, 0x41, 0x09, 0xaf, - 0x63, 0x6b, 0x23, 0x85, 0xc3, 0xcb, 0x83, 0x25, - 0x6d, 0x65, 0x2d, 0x8b, 0xcd, 0xc5, 0x8d, 0x2b, - 0x37, 0x3f, 0x77, 0x11, 0x57, 0x5f, 0x17, 0x71, - 0x39, 0x31, 0x79, 0x1f, 0x59, 0x51, 0x19, 0x7f, - 0xb3, 0xbb, 0xf3, 0x95, 0xd3, 0xdb, 0x93, 0xf5, - 0xbd, 0xb5, 0xfd, 0x9b, 0xdd, 0xd5, 0x9d, 0xfb, - 0xba, 0xb2, 0xfa, 0x90, 0xda, 0xd2, 0x9a, 0xf0, - 0xb8, 0xb0, 0xf8, 0x92, 0xd8, 0xd0, 0x98, 0xf2, - 0x6e, 0x66, 0x2e, 0x84, 0xce, 0xc6, 0x8e, 0x24, - 0x6c, 0x64, 0x2c, 0x86, 0xcc, 0xc4, 0x8c, 0x26, - 0x3a, 0x32, 0x7a, 0x10, 0x5a, 0x52, 0x1a, 0x70, - 0x38, 0x30, 0x78, 0x12, 0x58, 0x50, 0x18, 0x72, - 0xbe, 0xb6, 0xfe, 0x94, 0xde, 0xd6, 0x9e, 0xf4, - 0xbc, 0xb4, 0xfc, 0x96, 0xdc, 0xd4, 0x9c, 0xf6, - 0xb7, 0xbf, 0xf7, 0x91, 0xd7, 0xdf, 0x97, 0xf1, - 0xb9, 0xb1, 0xf9, 0x9f, 0xd9, 0xd1, 0x99, 0xff -}; - -static unsigned char reverse[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff -}; - -/* - * Two linear feedback shift registers are used: - * - * lfsr17: polynomial of degree 17, primitive modulo 2 (listed in Schneier) - * x^15 + x + 1 - * lfsr25: polynomial of degree 25, not know if primitive modulo 2 - * x^13 + x^5 + x^4 + x^1 + 1 - * - * Output bits are discarded, instead the feedback bits are added to produce - * the cipher stream. Depending on the mode, feedback bytes may be inverted - * bit-wise before addition. - * - * The lfsrs are seeded with bytes from the raw key: - * - * lfsr17: byte 0[0:7] at bit 9 - * byte 1[0:7] at bit 0 - * - * lfsr25: byte 2[0:4] at bit 16 - * byte 2[5:7] at bit 22 - * byte 3[0:7] at bit 8 - * byte 4[0:7] at bit 0 - * - * To prevent 0 cycles, 1's are inject at bit 8 in lfrs17 and bit 21 in - * lfsr25. - * - */ - -int -acss(ACSS_KEY *key, unsigned long len, const unsigned char *in, - unsigned char *out) -{ - unsigned long i; - unsigned long lfsr17tmp, lfsr25tmp, lfsrsumtmp; - - lfsrsumtmp = lfsr17tmp = lfsr25tmp = 0; - - /* keystream is sum of lfsrs */ - for (i = 0; i < len; i++) { - lfsr17tmp = key->lfsr17 ^ (key->lfsr17 >> 14); - key->lfsr17 = (key->lfsr17 >> 8) - ^ (lfsr17tmp << 9) - ^ (lfsr17tmp << 12) - ^ (lfsr17tmp << 15); - key->lfsr17 &= 0x1ffff; /* 17 bit LFSR */ - - lfsr25tmp = key->lfsr25 - ^ (key->lfsr25 >> 3) - ^ (key->lfsr25 >> 4) - ^ (key->lfsr25 >> 12); - key->lfsr25 = (key->lfsr25 >> 8) ^ (lfsr25tmp << 17); - key->lfsr25 &= 0x1ffffff; /* 25 bit LFSR */ - - lfsrsumtmp = key->lfsrsum; - - /* addition */ - switch (key->mode) { - case ACSS_AUTHENTICATE: - case ACSS_DATA: - key->lfsrsum = 0xff & ~(key->lfsr17 >> 9); - key->lfsrsum += key->lfsr25 >> 17; - break; - case ACSS_SESSIONKEY: - key->lfsrsum = key->lfsr17 >> 9; - key->lfsrsum += key->lfsr25 >> 17; - break; - case ACSS_TITLEKEY: - key->lfsrsum = key->lfsr17 >> 9; - key->lfsrsum += 0xff & ~(key->lfsr25 >> 17); - break; - default: - return 1; - } - key->lfsrsum += (lfsrsumtmp >> 8); - - if (key->encrypt) { - out[i] = sboxenc[(in[i] ^ key->lfsrsum) & 0xff]; - } else { - out[i] = (sboxdec[in[i]] ^ key->lfsrsum) & 0xff; - } - } - - return 0; -} - -static void -acss_seed(ACSS_KEY *key) -{ - int i; - - /* if available, mangle with subkey */ - if (key->subkey_avilable) { - for (i = 0; i < ACSS_KEYSIZE; i++) - key->seed[i] = reverse[key->data[i] ^ key->subkey[i]]; - } else { - for (i = 0; i < ACSS_KEYSIZE; i++) - key->seed[i] = reverse[key->data[i]]; - } - - /* seed lfsrs */ - key->lfsr17 = key->seed[1] - | (key->seed[0] << 9) - | (1 << 8); /* inject 1 at bit 9 */ - key->lfsr25 = key->seed[4] - | (key->seed[3] << 8) - | ((key->seed[2] & 0x1f) << 16) - | ((key->seed[2] & 0xe0) << 17) - | (1 << 21); /* inject 1 at bit 22 */ - - key->lfsrsum = 0; -} - -void -acss_setkey(ACSS_KEY *key, const unsigned char *data, int enc, int mode) -{ - memcpy(key->data, data, sizeof(key->data)); - memset(key->subkey, 0, sizeof(key->subkey)); - - if (enc != -1) - key->encrypt = enc; - key->mode = mode; - key->subkey_avilable = 0; - - acss_seed(key); -} - -void -acss_setsubkey(ACSS_KEY *key, const unsigned char *subkey) -{ - memcpy(key->subkey, subkey, sizeof(key->subkey)); - key->subkey_avilable = 1; - acss_seed(key); -} -#endif diff --git a/acss.h b/acss.h deleted file mode 100644 index 91b489542..000000000 --- a/acss.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $Id: acss.h,v 1.2 2004/02/06 04:22:43 dtucker Exp $ */ -/* - * Copyright (c) 2004 The OpenBSD project - * - * 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. - */ - -#ifndef _ACSS_H_ -#define _ACSS_H_ - -/* 40bit key */ -#define ACSS_KEYSIZE 5 - -/* modes of acss */ -#define ACSS_AUTHENTICATE 0 -#define ACSS_SESSIONKEY 1 -#define ACSS_TITLEKEY 2 -#define ACSS_DATA 3 - -typedef struct acss_key_st { - unsigned int lfsr17; /* current state of lfsrs */ - unsigned int lfsr25; - unsigned int lfsrsum; - unsigned char seed[ACSS_KEYSIZE]; - unsigned char data[ACSS_KEYSIZE]; - unsigned char subkey[ACSS_KEYSIZE]; - int encrypt; /* XXX make these bit flags? */ - int mode; - int seeded; - int subkey_avilable; -} ACSS_KEY; - -void acss_setkey(ACSS_KEY *, const unsigned char *, int, int); -void acss_setsubkey(ACSS_KEY *, const unsigned char *); -int acss(ACSS_KEY *, unsigned long, const unsigned char *, unsigned char *); - -#endif /* ifndef _ACSS_H_ */ diff --git a/cipher-acss.c b/cipher-acss.c deleted file mode 100644 index e755f92b9..000000000 --- a/cipher-acss.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2004 The OpenBSD project - * - * 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. - */ - -#include "includes.h" - -#include - -#include - -#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) - -#include "acss.h" -#include "openbsd-compat/openssl-compat.h" - -#define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data) - -typedef struct { - ACSS_KEY ks; -} EVP_ACSS_KEY; - -#define EVP_CTRL_SET_ACSS_MODE 0xff06 -#define EVP_CTRL_SET_ACSS_SUBKEY 0xff07 - -static int -acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - acss_setkey(&data(ctx)->ks,key,enc,ACSS_DATA); - return 1; -} - -static int -acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, - LIBCRYPTO_EVP_INL_TYPE inl) -{ - acss(&data(ctx)->ks,inl,in,out); - return 1; -} - -static int -acss_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) -{ - switch(type) { - case EVP_CTRL_SET_ACSS_MODE: - data(ctx)->ks.mode = arg; - return 1; - case EVP_CTRL_SET_ACSS_SUBKEY: - acss_setsubkey(&data(ctx)->ks,(unsigned char *)ptr); - return 1; - default: - return -1; - } -} - -const EVP_CIPHER * -evp_acss(void) -{ - static EVP_CIPHER acss_cipher; - - memset(&acss_cipher, 0, sizeof(EVP_CIPHER)); - - acss_cipher.nid = NID_undef; - acss_cipher.block_size = 1; - acss_cipher.key_len = 5; - acss_cipher.init = acss_init_key; - acss_cipher.do_cipher = acss_ciph; - acss_cipher.ctx_size = sizeof(EVP_ACSS_KEY); - acss_cipher.ctrl = acss_ctrl; - - return (&acss_cipher); -} -#endif - diff --git a/cipher.c b/cipher.c index 2d307e160..9ca1d0065 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.86 2013/01/12 11:22:04 djm Exp $ */ +/* $OpenBSD: cipher.c,v 1.87 2013/01/26 06:11:05 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -92,10 +92,6 @@ struct Cipher { SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm }, { "aes256-gcm@openssh.com", SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, -#endif -#ifdef USE_CIPHER_ACSS - { "acss@openssh.org", - SSH_CIPHER_SSH2, 16, 5, 0, 0, 0, 0, EVP_acss }, #endif { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } }; @@ -478,7 +474,7 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat) Cipher *c = cc->cipher; int plen = 0; - if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { + if (c->evptype == EVP_rc4) { plen = EVP_X_STATE_LEN(cc->evp); if (dat == NULL) return (plen); @@ -493,7 +489,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat) Cipher *c = cc->cipher; int plen; - if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { + if (c->evptype == EVP_rc4) { plen = EVP_X_STATE_LEN(cc->evp); memcpy(EVP_X_STATE(cc->evp), dat, plen); } diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 6c4d68def..e7439b4e7 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -1,4 +1,4 @@ -/* $Id: openssl-compat.h,v 1.23 2013/02/10 23:39:15 djm Exp $ */ +/* $Id: openssl-compat.h,v 1.24 2013/02/12 00:00:40 djm Exp $ */ /* * Copyright (c) 2005 Darren Tucker @@ -96,16 +96,6 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size #endif -#if !defined(EVP_CTRL_SET_ACSS_MODE) -# if (OPENSSL_VERSION_NUMBER >= 0x00907000L) -# define USE_CIPHER_ACSS 1 -extern const EVP_CIPHER *evp_acss(void); -# define EVP_acss evp_acss -# else -# define EVP_acss NULL -# endif -#endif - /* OpenSSL 0.9.8e returns cipher key len not context key len */ #if (OPENSSL_VERSION_NUMBER == 0x0090805fL) # define EVP_CIPHER_CTX_key_length(c) ((c)->key_len) -- cgit v1.2.3 From c31db8cd6e301c8d4024cb9250e3178d13d1be44 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Tue, 19 Feb 2013 19:01:51 -0800 Subject: - (tim) [krl.c Makefile.in regress/Makefile regress/modpipe.c] remove unneeded err.h include from krl.c. Additional portability fixes for modpipe. OK djm --- ChangeLog | 4 ++++ Makefile.in | 12 +++++++----- krl.c | 1 - regress/Makefile | 6 +----- regress/modpipe.c | 3 ++- 5 files changed, 14 insertions(+), 12 deletions(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index 41d49f6b5..cf50b4688 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 20130220 - (tim) [regress/cipher-speed.sh regress/try-ciphers.sh] shell portability fix. + - (tim) [krl.c Makefile.in regress/Makefile regress/modpipe.c] remove unneeded + err.h include from krl.c. Additional portability fixes for modpipe. OK djm 20130219 - OpenBSD CVS Sync @@ -13,6 +15,8 @@ we actually reach $offset - (djm) [regress/integrity.sh] Skip SHA2-based MACs on configurations that lack support for SHA2. + - (djm) [regress/modpipe.c] Add local err, and errx functions for platforms + that do not have them. 20130217 - OpenBSD CVS Sync diff --git a/Makefile.in b/Makefile.in index ec3e1f417..44d594441 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.331 2013/02/12 00:00:34 djm Exp $ +# $Id: Makefile.in,v 1.332 2013/02/20 03:01:51 tim Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -379,14 +379,16 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 -tests interop-tests: $(TARGETS) +regress/modpipe: $(srcdir)/regress/modpipe.c + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ + $(CC) $(CPPFLAGS) -o $@ $? \ + $(LDFLAGS) -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) + +tests interop-tests: $(TARGETS) regress/modpipe BUILDDIR=`pwd`; \ [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile ; \ - [ -f `pwd`/regress/modpipe.c ] || \ - ln -s `cd $(srcdir) && pwd`/regress/modpipe.c `pwd`/regress/modpipe.c; \ - (cd regress && make prereq); \ TEST_SHELL="@TEST_SHELL@"; \ TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ diff --git a/krl.c b/krl.c index 5ed7bd7e5..5a6bd14aa 100644 --- a/krl.c +++ b/krl.c @@ -33,7 +33,6 @@ #include "buffer.h" #include "key.h" #include "authfile.h" -#include "err.h" #include "misc.h" #include "log.h" #include "xmalloc.h" diff --git a/regress/Makefile b/regress/Makefile index c3aec43fc..779abf4fb 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,7 +1,7 @@ # $OpenBSD: Makefile,v 1.62 2013/01/18 00:45:29 djm Exp $ REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t8 t9 t-exec -tests: prereq $(REGRESS_TARGETS) +tests: $(REGRESS_TARGETS) # Interop tests are not run by default interop interop-tests: t-exec-interop @@ -146,10 +146,6 @@ t9: $(OBJ)/t9.out test "${TEST_SSH_ECC}" != yes || \ ${TEST_SSH_SSHKEYGEN} -Bf $(OBJ)/t9.out > /dev/null -prereq: modpipe - -modpipe: modpipe.c - t-exec: ${LTESTS:=.sh} @if [ "x$?" = "x" ]; then exit 0; fi; \ for TEST in ""$?; do \ diff --git a/regress/modpipe.c b/regress/modpipe.c index b05915b63..1d4229885 100755 --- a/regress/modpipe.c +++ b/regress/modpipe.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: modpipe.c,v 1.2 2013/02/19 02:15:08 djm Exp $ */ +/* $Id: modpipe.c,v 1.3 2013/02/20 03:01:52 tim Exp $ */ #include #include @@ -23,6 +23,7 @@ #include #include #include +#include "openbsd-compat/getopt.c" static void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); static void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); -- cgit v1.2.3 From 964de184a8bbb85b1992176c28963f6115c780e1 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 22 Feb 2013 10:39:59 +1100 Subject: - (dtucker) [Makefile.in configure.ac] bz#2072: don't link krb5 libs to ssh(1) since they're not needed. Patch from Pierre Ossman. --- ChangeLog | 4 ++++ Makefile.in | 8 +++++--- configure.ac | 28 ++++++++++++++-------------- 3 files changed, 23 insertions(+), 17 deletions(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index a87e7fb5a..706ec6262 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20120222 + - (dtucker) [Makefile.in configure.ac] bz#2072: don't link krb5 libs to + ssh(1) since they're not needed. Patch from Pierre Ossman. + 20130221 - (tim) [regress/forward-control.sh] shell portability fix. diff --git a/Makefile.in b/Makefile.in index 44d594441..6067063a2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.332 2013/02/20 03:01:51 tim Exp $ +# $Id: Makefile.in,v 1.333 2013/02/21 23:40:00 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -44,6 +44,8 @@ LD=@LD@ CFLAGS=@CFLAGS@ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ LIBS=@LIBS@ +K5LIBS=@K5LIBS@ +GSSLIBS=@GSSLIBS@ SSHLIBS=@SSHLIBS@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ @@ -139,10 +141,10 @@ libssh.a: $(LIBSSH_OBJS) $(RANLIB) $@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) - $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS) $(GSSLIBS) sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) - $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/configure.ac b/configure.ac index d62323d97..088bcb652 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.505 2013/02/15 01:13:01 dtucker Exp $ +# $Id: configure.ac,v 1.506 2013/02/21 23:40:00 dtucker Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org]) -AC_REVISION($Revision: 1.505 $) +AC_REVISION($Revision: 1.506 $) AC_CONFIG_SRCDIR([ssh.c]) AC_LANG([C]) @@ -3624,6 +3624,9 @@ AC_ARG_WITH([kerberos5], [$KRB5ROOT/bin/krb5-config], [$KRB5ROOT/bin:$PATH]) if test -x $KRB5CONF ; then + K5CFLAGS="`$KRB5CONF --cflags`" + K5LIBS="`$KRB5CONF --libs`" + CPPFLAGS="$CPPFLAGS $K5CFLAGS" AC_MSG_CHECKING([for gssapi support]) if $KRB5CONF | grep gssapi >/dev/null ; then @@ -3631,14 +3634,12 @@ AC_ARG_WITH([kerberos5], AC_DEFINE([GSSAPI], [1], [Define this if you want GSSAPI support in the version 2 protocol]) - k5confopts=gssapi + GSSCFLAGS="`$KRB5CONF --cflags gssapi`" + GSSLIBS="`$KRB5CONF --libs gssapi`" + CPPFLAGS="$CPPFLAGS $GSSCFLAGS" else AC_MSG_RESULT([no]) - k5confopts="" fi - K5CFLAGS="`$KRB5CONF --cflags $k5confopts`" - K5LIBS="`$KRB5CONF --libs $k5confopts`" - CPPFLAGS="$CPPFLAGS $K5CFLAGS" AC_MSG_CHECKING([whether we are using Heimdal]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include ]], [[ char *tmp = heimdal_version; ]])], @@ -3670,14 +3671,12 @@ AC_ARG_WITH([kerberos5], AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context], [ AC_DEFINE([GSSAPI]) - K5LIBS="-lgssapi_krb5 $K5LIBS" ], + GSSLIBS="-lgssapi_krb5" ], [ AC_CHECK_LIB([gssapi], [gss_init_sec_context], [ AC_DEFINE([GSSAPI]) - K5LIBS="-lgssapi $K5LIBS" ], - AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]), - $K5LIBS) - ], - $K5LIBS) + GSSLIBS="-lgssapi" ], + AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail])) + ]) AC_CHECK_HEADER([gssapi.h], , [ unset ac_cv_header_gssapi_h @@ -3705,12 +3704,13 @@ AC_ARG_WITH([kerberos5], AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h]) AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h]) - LIBS="$LIBS $K5LIBS" AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1], [Define this if you want to use libkafs' AFS support])]) fi ] ) +AC_SUBST([GSSLIBS]) +AC_SUBST([K5LIBS]) # Looking for programs, paths and files -- cgit v1.2.3 From 29c7151d2055ce8469e07e6ac40b1c5b18bfeff0 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 5 Mar 2013 21:50:09 +1100 Subject: - (dtucker) [Makefile.in] Remove trailing "\" on PATHS, which caused obscure build breakage on (at least) HP-UX 11.11. Found by Amit Kulkarni and Kevin Brott. --- ChangeLog | 3 +++ Makefile.in | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index 31e45f761..f3340b6e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ HP/UX. Spotted by Kevin Brott - (dtucker) [configure.ac] use "=" for shell test and not "==". Spotted by Amit Kulkarni and Kevin Brott. + - (dtucker) [Makefile.in] Remove trailing "\" on PATHS, which caused obscure + build breakage on (at least) HP-UX 11.11. Found by Amit Kulkarni and Kevin + Brott. 20130227 - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] diff --git a/Makefile.in b/Makefile.in index 6067063a2..45509658f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.333 2013/02/21 23:40:00 dtucker Exp $ +# $Id: Makefile.in,v 1.334 2013/03/05 10:50:09 dtucker Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -37,7 +37,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ - -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ + -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" CC=@CC@ LD=@LD@ -- cgit v1.2.3 From ff8bda8f05e85b1196ec3a135d9970c475bcdcdb Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Tue, 5 Mar 2013 14:23:58 -0800 Subject: - (tim) [Makefile.in] Add missing $(EXEEXT). Found by Roumen Petrov. --- ChangeLog | 1 + Makefile.in | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index f3340b6e5..36a52deb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ - (dtucker) [Makefile.in] Remove trailing "\" on PATHS, which caused obscure build breakage on (at least) HP-UX 11.11. Found by Amit Kulkarni and Kevin Brott. + - (tim) [Makefile.in] Add missing $(EXEEXT). Found by Roumen Petrov. 20130227 - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] diff --git a/Makefile.in b/Makefile.in index 45509658f..38ffbdc3b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.334 2013/03/05 10:50:09 dtucker Exp $ +# $Id: Makefile.in,v 1.335 2013/03/05 22:23:59 tim Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -381,7 +381,7 @@ uninstall: -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-pkcs11-helper.8 -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 -regress/modpipe: $(srcdir)/regress/modpipe.c +regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ $(CC) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -- cgit v1.2.3 From 2b6ea47106537cff31c863d05062ac97efe3f132 Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Thu, 7 Mar 2013 07:37:13 -0800 Subject: - (tim) [Makefile.in] Add another missing $(EXEEXT) I should have seen 3 days ago. --- ChangeLog | 2 ++ Makefile.in | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'Makefile.in') diff --git a/ChangeLog b/ChangeLog index 7f21ea921..728de6ad0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,8 @@ currently using. - (dtucker) [defines.h] Remove SIZEOF_CHAR bits since the test for it was removed in configure.ac rev 1.481 as it was redundant. + - (tim) [Makefile.in] Add another missing $(EXEEXT) I should have seen 3 days + ago. 20130306 - (dtucker) [regress/forward-control.sh] Wait longer for the forwarding diff --git a/Makefile.in b/Makefile.in index 38ffbdc3b..d327787b0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.335 2013/03/05 22:23:59 tim Exp $ +# $Id: Makefile.in,v 1.336 2013/03/07 15:37:13 tim Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -386,7 +386,7 @@ regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(CC) $(CPPFLAGS) -o $@ $? \ $(LDFLAGS) -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) -tests interop-tests: $(TARGETS) regress/modpipe +tests interop-tests: $(TARGETS) regress/modpipe$(EXEEXT) BUILDDIR=`pwd`; \ [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ [ -f `pwd`/regress/Makefile ] || \ -- cgit v1.2.3