#include <rx/rx_opaque.h>
#include <opr/queue.h>
+#include <rx/rxgk_types.h>
+
#define MAXCELLCHARS 64
#define MAXHOSTCHARS 64
#define MAXHOSTSPERCELL 8
extern afs_int32 afsconf_GetLatestKey(struct afsconf_dir *adir,
afs_int32 * avno,
struct ktc_encryptionKey *akey);
+extern afs_int32 afsconf_GetLatestRXGKKey(struct afsconf_dir *adir,
+ afs_int32 *avno, afs_int32 *enctype,
+ rxgk_key *key);
extern int afsconf_GetKey(void *rock, int avno,
struct ktc_encryptionKey *akey);
+extern int afsconf_GetRXGKKey(void *rock, afs_int32 *avno, afs_int32 *enctype,
+ rxgk_key *key);
extern int afsconf_AddKey(struct afsconf_dir *adir, afs_int32 akvno,
char akey[8], afs_int32 overwrite);
extern int afsconf_DeleteKey(struct afsconf_dir *adir, afs_int32 akvno);
/* Need rx/rx.h to get working assert(), used by LOCK_GLOBAL_MUTEX */
#include <rx/rx.h>
#include <rx/rx_atomic.h>
+#ifdef AFS_RXGK_ENV
+#include <rx/rxgk.h>
+#endif
+#include <afs/opr.h>
#include <afs/stds.h>
#include <afs/pthread_glock.h>
#include <afs/afsutil.h>
return 0;
}
+static int
+_afsconf_GetLatestRXGKKey(afsconf_keyType type, struct afsconf_dir *rock,
+ afs_int32 *avno, afs_int32 *enctype, rxgk_key *key)
+{
+#ifdef AFS_RXGK_ENV
+ struct afsconf_typedKeyList *list = NULL;
+ struct afsconf_typedKey *typedKey = NULL;
+ afs_int32 code;
+ int key_i;
+
+ code = afsconf_GetLatestKeysByType(rock, type, &list);
+ if (code != 0)
+ goto done;
+
+ for (key_i = 0; key_i < list->nkeys; key_i++) {
+ if (typedKey == NULL)
+ typedKey = list->keys[key_i];
+ else if (rxgk_enctype_better(typedKey->subType, list->keys[key_i]->subType))
+ typedKey = list->keys[key_i];
+ }
+
+ opr_Assert(typedKey != NULL);
+
+ /* We picked a key; copy to the output parameters */
+ code = rxgk_make_key(key, typedKey->key.val, typedKey->key.len,
+ typedKey->subType);
+ if (code != 0)
+ goto done;
+ if (avno != NULL)
+ *avno = typedKey->kvno;
+ if (enctype != NULL)
+ *enctype = typedKey->subType;
+
+ done:
+ afsconf_PutTypedKeyList(&list);
+ return code;
+#else /* AFS_RXGK_ENV */
+ return AFSCONF_NOTFOUND;
+#endif
+}
+
+/**
+ * Obtain the "best" rxgk key from KeyFileExt
+ *
+ * Return the key and its enctype and kvno, for encrypting outgoing tokens.
+ *
+ * @param[in] rock The configuration directory to be used.
+ * @param[out] avno The key version number of key.
+ * @param[out] enctype The RFC 3961 enctype of key.
+ * @param[out] key The returned rxgk key.
+ */
+int
+afsconf_GetLatestRXGKKey(struct afsconf_dir *rock, afs_int32 *avno,
+ afs_int32 *enctype, rxgk_key *key)
+{
+ return _afsconf_GetLatestRXGKKey(afsconf_rxgk, rock, avno, enctype, key);
+}
+
+static int
+_afsconf_GetRXGKKey(afsconf_keyType type, void *rock, afs_int32 *avno,
+ afs_int32 *enctype, rxgk_key *key)
+{
+#ifdef AFS_RXGK_ENV
+ struct afsconf_dir *dir = rock;
+ struct afsconf_typedKey *typedKey;
+ afs_int32 code;
+
+ /* No information at all means "pick the best/newest one". */
+ if (*avno == 0 && *enctype == 0)
+ return _afsconf_GetLatestRXGKKey(type, dir, avno, enctype, key);
+
+ code = afsconf_GetKeyByTypes(dir, type, *avno, *enctype, &typedKey);
+ if (code != 0)
+ return code;
+
+ code = rxgk_make_key(key, typedKey->key.val, typedKey->key.len,
+ typedKey->subType);
+ afsconf_typedKey_put(&typedKey);
+
+ return code;
+#else /* AFS_RXGK_ENV */
+ return AFSCONF_NOTFOUND;
+#endif
+}
+
+/**
+ * Obtain a particular RXGK key from KeyFileExt
+ *
+ * Use the specified kvno and enctype to fetch an rxgk key from KeyFileExt
+ * and return it as an rxgk_key. Specifying the kvno/enctype pair as both
+ * zeros causes the "best" rxgk key to be returned, and the kvno/enctype
+ * of that key returned to the caller.
+ *
+ * @param[in] rock An afsconf_dir* for the configuration directory. This
+ * is a void* just so this can be easily used as a
+ * callback function that uses a void* rock.
+ * @param[inout] avno The requested kvno (if non-zero), or zero to request
+ * the latest key and have its kvno returned in this
+ * parameter.
+ * @param[inout] enctype The requested enctype (if non-zero), or zero
+ * to request the latest key and have its
+ * enctype returned in this parameter.
+ * @param[out] key The returned rxgk key.
+ */
+int
+afsconf_GetRXGKKey(void *rock, afs_int32 *avno,
+ afs_int32 *enctype, rxgk_key *key)
+{
+ return _afsconf_GetRXGKKey(afsconf_rxgk, rock, avno, enctype, key);
+}
+
int
afsconf_AddKey(struct afsconf_dir *dir, afs_int32 kvno, char key[8],
afs_int32 overwrite)
afsconf_GetExtendedCellInfo
afsconf_GetKey
afsconf_GetLatestKey
+afsconf_GetLatestRXGKKey
afsconf_GetLocalCell
afsconf_GetNoAuthFlag
+afsconf_GetRXGKKey
afsconf_IsLocalRealmMatch
afsconf_Open
afsconf_ParseNetFiles
include @TOP_OBJDIR@/src/config/Makefile.pthread
include @TOP_OBJDIR@/src/config/Makefile.libtool
-INCLS= ${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/rxgk.h ${TOP_INCDIR}/rx/rxgk_errs.h \
- ${TOP_INCDIR}/rx/rxgk_int.h
+INCLS= ${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/rxgk.h ${TOP_INCDIR}/rx/rxgk_types.h \
+ ${TOP_INCDIR}/rx/rxgk_errs.h ${TOP_INCDIR}/rx/rxgk_int.h
LT_objs = rxgk_client.lo rxgk_server.lo rxgk_errs.lo rxgk_int.cs.lo \
rxgk_int.xdr.lo rxgk_int.ss.lo rxgk_procs.lo rxgk_token.lo \
depinstall: \
${TOP_INCDIR}/rx/rxgk.h \
+ ${TOP_INCDIR}/rx/rxgk_types.h \
${TOP_INCDIR}/rx/rxgk_errs.h \
${TOP_INCDIR}/rx/rxgk_int.h
${TOP_INCDIR}/rx/rxgk.h: ${srcdir}/rxgk.h ${TOP_INCDIR}/rx/rxgk_errs.h \
- ${TOP_INCDIR}/rx/rxgk_int.h
+ ${TOP_INCDIR}/rx/rxgk_int.h ${TOP_INCDIR}/rx/rxgk_types.h
${INSTALL_DATA} ${srcdir}/rxgk.h $@
+${TOP_INCDIR}/rx/rxgk_types.h: ${srcdir}/rxgk_types.h
+ ${INSTALL_DATA} ${srcdir}/rxgk_types.h $@
+
${TOP_INCDIR}/rx/rxgk_errs.h: rxgk_errs.h
${INSTALL_DATA} $? $@
#
test: all
-install: liboafs_rxgk.la rxgk.h rxgk_errs.h rxgk_int.h
+install: liboafs_rxgk.la rxgk.h rxgk_types.h rxgk_errs.h rxgk_int.h
if [ "@ENABLE_RXGK@" = yes ]; then \
${INSTALL} -d ${DESTDIR}${includedir}/rx; \
${INSTALL_DATA} ${srcdir}/rxgk.h ${DESTDIR}${includedir}/rx/rxgk.h ; \
+ ${INSTALL_DATA} ${srcdir}/rxgk_types.h ${DESTDIR}${includedir}/rx/rxgk_types.h ; \
${INSTALL_DATA} rxgk_errs.h ${DESTDIR}${includedir}/rx/rxgk_errs.h ; \
${INSTALL_DATA} rxgk_int.h ${DESTDIR}${includedir}/rx/rxgk_int.h ; \
fi
-dest: liboafs_rxgk.la rxgk.h rxgk_errs.h rxgk_int.h
+dest: liboafs_rxgk.la rxgk.h rxgk_types.h rxgk_errs.h rxgk_int.h
if [ "@ENABLE_RXGK@" = yes ]; then \
${INSTALL} -d ${DEST}${includedir}/rx; \
${INSTALL_DATA} ${srcdir}/rxgk.h ${DEST}/include/rx/rxgk.h ; \
+ ${INSTALL_DATA} ${srcdir}/rxgk_types.h ${DEST}/include/rx/rxgk_types.h ; \
${INSTALL_DATA} rxgk_errs.h ${DEST}/include/rx/rxgk_errs.h ; \
${INSTALL_DATA} rxgk_int.h ${DEST}/include/rx/rxgk_int.h ; \
fi
rxgk_decrypt_in_key
rxgk_derive_tk
rxgk_encrypt_in_key
+rxgk_enctype_better
rxgk_make_key
rxgk_make_token
rxgk_mic_in_key
/* Pull in the protocol description */
#include <rx/rxgk_int.h>
+/* Pull in our basic type definitions */
+#include <rx/rxgk_types.h>
+
/* RX-internal headers we depend on. */
#include <rx/rx_opaque.h>
#include <rx/rx_identity.h>
return secondsToRxgkTime(tv.tv_sec) + (rxgkTime)tv.tv_usec * 10;
}
-/* rxgk_key is an opaque type to wrap our RFC3961 implementation's concept
- * of a key. It has (at least) the keyblock and length, and enctype. */
-typedef struct rxgk_key_s * rxgk_key;
-
typedef afs_int32 (*rxgk_getkey_func)(void *rock, afs_int32 *kvno,
afs_int32 *enctype, rxgk_key *key);
afs_uint32 key_number) AFS_NONNULL();
afs_int32 rxgk_cipher_expansion(rxgk_key k0, afs_uint32 *len_out) AFS_NONNULL();
afs_int32 rxgk_nonce(RXGK_Data *nonce, afs_uint32 len) AFS_NONNULL();
+int rxgk_enctype_better(afs_int32 old_enctype, afs_int32 new_enctype);
/* rxgk_token.c */
afs_int32 rxgk_make_token(struct rx_opaque *out, RXGK_TokenInfo *info,
krb5_generate_random_block(nonce->val, len);
return 0;
}
+
+/* Returns the "score" of an enctype, giving a rough ordering of enctypes by
+ * strength. Higher scores are better. */
+static_inline int
+etype_score(afs_int32 etype)
+{
+ switch (etype) {
+ case ETYPE_ARCFOUR_HMAC_MD5_56: return 0;
+ case ETYPE_DES_CBC_MD4: return 1;
+ case ETYPE_DES_CBC_CRC: return 2;
+ case ETYPE_DES_CBC_MD5: return 3;
+ case ETYPE_ARCFOUR_HMAC_MD5: return 4;
+ case ETYPE_DES3_CBC_SHA1: return 5;
+
+ case 25 /* camellia128 */: return 6;
+ case ETYPE_AES128_CTS_HMAC_SHA1_96: return 7;
+
+ /* aes128-cts-hmac-sha256-128 */
+ case 19: return 8;
+
+ case 26 /* camellia256 */: return 9;
+ case ETYPE_AES256_CTS_HMAC_SHA1_96: return 10;
+
+ /* aes256-cts-hmac-sha384-192 */
+ case 20: return 11;
+ }
+ return -1;
+}
+
+/**
+ * Determines which of the two given enctypes is "stronger".
+ *
+ * @param[in] old_enctype An enctype to compare.
+ * @param[in] new_enctype Another enctype to compare.
+ *
+ * @return 1 if new_enctype is better/stronger than old_enctype. 0 otherwise.
+ */
+int
+rxgk_enctype_better(afs_int32 old_enctype, afs_int32 new_enctype)
+{
+ int old_score, new_score;
+
+ /* Negative enctypes are reserved for local use. */
+ if (new_enctype < 0) return 1;
+ if (old_enctype < 0) return 0;
+
+ old_score = etype_score(old_enctype);
+ new_score = etype_score(new_enctype);
+
+ if (old_score < new_score) {
+ /* 'new' enctype is better */
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 2013, 2014 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Basic public type definitions for RXGK.
+ */
+
+#ifndef OPENAFS_RXGK_TYPES_H
+#define OPENAFS_RXGK_TYPES_H
+
+/* rxgk_key is an opaque type to wrap our RFC3961 implementation's concept
+ * of a key. It has (at least) the keyblock and length, and enctype. */
+typedef struct rxgk_key_s * rxgk_key;
+
+#endif /* OPENAFS_RXGK_TYPES_H */