diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in
index 42c6b142a96bca471087541b8b5c8df589540971..4d2dbb1ee93c97a12e8dbcb65c44e1431660bc71 100644
--- a/slurm/slurm.h.in
+++ b/slurm/slurm.h.in
@@ -138,13 +138,10 @@ enum node_states {
  *	PROTOCOL DATA STRUCTURE DEFINITIONS
 \*****************************************************************************/
 
-typedef struct {
-	uint32_t job_id;	/* job's id */
-	uid_t user_id;		/* user who job is running as */
-	char *node_list;	/* list of allocated nodes */
-	time_t expiration_time;	/* expiration of credential */
-	char signature[SLURM_SSL_SIGNATURE_LENGTH];	
-} slurm_job_credential_t;
+#ifndef __slurm_cred_t_defined
+#  define __slurm_cred_t_defined
+   typedef struct slurm_job_credential * slurm_cred_t;
+#endif
 
 typedef struct job_descriptor {	/* For submit, allocate, and update requests */
 	uint16_t contiguous;	/* 1 if job requires contiguous nodes,
@@ -254,7 +251,7 @@ typedef struct job_step_specs {
 typedef struct job_step_create_response_msg {
 	uint32_t job_step_id;	/* assigned job step id */
 	char *node_list;	/* list of allocated nodes */
-	slurm_job_credential_t *credentials;
+	slurm_cred_t cred;      /* slurm job credential */
 #ifdef	HAVE_LIBELAN3
 	qsw_jobinfo_t qsw_job;	/* Elan3 switch context, opaque data structure */
 #endif
@@ -340,7 +337,7 @@ typedef struct resource_allocation_and_run_response_msg {
 	slurm_addr *node_addr;	/* network addresses */
 
 	uint32_t job_step_id;	/* assigned step id */
-	slurm_job_credential_t *credentials;
+	slurm_cred_t cred;      /* slurm job credential */
 #ifdef HAVE_LIBELAN3
 	qsw_jobinfo_t qsw_job;	/* Elan3 switch context, opaque data structure */
 #endif
diff --git a/slurm/slurm_errno.h b/slurm/slurm_errno.h
index 7166a97751fb54ea8a109fa25de57f8155e2ecd8..37ed30b2d4d67a1b3d8a03fcecd5c57ad7548f52 100644
--- a/slurm/slurm_errno.h
+++ b/slurm/slurm_errno.h
@@ -141,6 +141,7 @@ enum {
 	ESLURMD_INVALID_JOB_CREDENTIAL,
 	ESLURMD_CREDENTIAL_EXPIRED,
 	ESLURMD_CREDENTIAL_REVOKED,
+	ESLURMD_CREDENTIAL_REPLAYED,
 	ESLURMD_CREATE_BATCH_DIR_ERROR,
 	ESLURMD_MODIFY_BATCH_DIR_ERROR,
 	ESLURMD_CREATE_BATCH_SCRIPT_ERROR,
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 753db92a930ae8e96b7789ab7dd50a29e85db740..f115f05d41e49734e7fbe5b7434eac75052a4b25 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -60,10 +60,8 @@ libdaemonize_la_SOURCES =  \
 	fd.c fd.h
 
 libcred_la_SOURCES =       \
-	credential_utils.c \
-	credential_utils.h \
-	signature_utils.c  \
-	signature_utils.h
+	slurm_cred.h       \
+	slurm_cred.c       
 
 libhostlist_la_SOURCES   = \
 	hostlist.c hostlist.h
diff --git a/src/common/credential_utils.c b/src/common/credential_utils.c
deleted file mode 100644
index ba554e11808fa6715cb31f04d9019f8536679643..0000000000000000000000000000000000000000
--- a/src/common/credential_utils.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*****************************************************************************\
- *  credential_utils.c - slurm authentication credential management functions
- *  $Id$
- *****************************************************************************
- *  Written by Kevin Tew <tewk@llnl.gov>
- *  
- *  This file is part of SLURM, a resource management program.
- *  For details, see <http://www.llnl.gov/linux/slurm/>.
- *  
- *  SLURM is free software; you can redistribute it and/or modify it under
- *  the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either version 2 of the License, or (at your option)
- *  any later version.
- *  
- *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
- *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- *  details.
- *  
- *  You should have received a copy of the GNU General Public License along
- *  with SLURM; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
-\*****************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-
-#include <slurm/slurm_errno.h>
-
-#include "src/common/credential_utils.h"
-#include "src/common/hostlist.h"
-#include "src/common/list.h"
-#include "src/common/log.h"
-#include "src/common/pack.h"
-#include "src/common/signature_utils.h"
-#include "src/common/slurm_protocol_api.h"
-#include "src/common/slurm_protocol_pack.h"
-#include "src/common/xmalloc.h"
-
-#define MAX_NAME_LEN 1024
-
-/* global variables */
-
-/* prototypes */
-
-static int  _clear_expired_revoked_credentials(List list);
-static int  _is_credential_still_valid(slurm_job_credential_t *, List);
-static void _free_credential_state(void *credential_state);
-static int  _insert_credential_state(slurm_job_credential_t *l, List);
-static int  _insert_revoked_credential_state(revoke_credential_msg_t *, List);
-static void _pack_one_cred(credential_state_t *, Buf);
-static int  _unpack_one_cred(credential_state_t *, Buf);
-
-static int  _init_credential_state( credential_state_t *, 
-		                    slurm_job_credential_t *);
-
-int
-sign_credential(slurm_ssl_key_ctx_t * ctx, slurm_job_credential_t * cred)
-{
-	Buf buffer;
-	int length, rc;
-	int sigsize = SLURM_SSL_SIGNATURE_LENGTH;
-
-	buffer = init_buf(4096);
-	pack_job_credential(cred, buffer);
-	length = get_buf_offset(buffer) - SLURM_SSL_SIGNATURE_LENGTH;
-
-	rc = slurm_ssl_sign(ctx, get_buf_data(buffer), length,
-			    cred->signature, &sigsize);
-	free_buf(buffer);
-
-	if (rc != 0)
-	       return SLURM_ERROR;
-
-	if (sigsize != SLURM_SSL_SIGNATURE_LENGTH)
-		error("signature size not correct in ssl_sign!");
-
-	return SLURM_SUCCESS;
-}
-
-
-int
-verify_credential(slurm_ssl_key_ctx_t * ctx, slurm_job_credential_t * cred,
-		  List cred_state_list)
-{
-	int rc;
-	time_t now = time(NULL);
-	int length;
-	Buf buffer;
-
-	buffer = init_buf(4096);
-	pack_job_credential(cred, buffer);
-	length = get_buf_offset(buffer) - SLURM_SSL_SIGNATURE_LENGTH;
-
-	rc = slurm_ssl_verify(ctx, get_buf_data(buffer), length,
-			      cred->signature, SLURM_SSL_SIGNATURE_LENGTH);
-	free_buf(buffer);
-
-	if (rc) {
-		error("Invalid credential submitted");
-		slurm_seterrno_ret(ESLURMD_INVALID_JOB_CREDENTIAL);
-	}
-
-	if (cred->expiration_time < now) {
-		error("credential has expired expiration=%lx now=%lx",
-		      (long)cred->expiration_time , (long)now);
-		slurm_seterrno_ret(ESLURMD_CREDENTIAL_EXPIRED);
-	}
-
-#if WE_WANT_TO_CONFIRM_NODELIST_IN_CREDENTIAL
-	/* FIXME:XXX: if so desired */
-	char this_node_name[MAX_NAME_LEN];
-	if ((rc = getnodename(this_node_name, MAX_NAME_LEN)))
-		fatal("slurmd: getnodename: %m");
-
-	if ( verify_node_name_list ( this_node_name , 
-	                             credential->node_list ) )
-		slurm_seterrno_ret(
-			ESLURMD_NODE_NAME_NOT_PRESENT_IN_CREDENTIAL);
-#endif
-
-	/* XXX:
-	 * need code to check to make sure that only the specified 
-	 * number of procs per node are used to launch tasks and not more
-	 */
-
-	if ((rc = _is_credential_still_valid(cred, cred_state_list))) {
-		slurm_seterrno_ret(rc);
-	}
-
-	return SLURM_SUCCESS;
-}
-
-void 
-print_credential(slurm_job_credential_t * cred)
-{
-	int i, j = 0;
-	long long_tmp;
-	char sig_str[SLURM_SSL_SIGNATURE_LENGTH*4];
-
-	for (i=0; i<SLURM_SSL_SIGNATURE_LENGTH; i+=sizeof(long)) {
-		memcpy(&long_tmp, &cred->signature[i], sizeof(long));
-		sprintf(&sig_str[(j++)*9], "%8lx ", long_tmp);
-	}
-
-       info("cred uid:%u job_id:%u time:%lx",
-            cred->user_id, cred->job_id, (long)cred->expiration_time);
-       info("cred signature:%s", sig_str);
-}
-
-int 
-revoke_credential(revoke_credential_msg_t * msg, List list)
-{
-	time_t              now   = time(NULL);
-	uint32_t            jobid = msg->job_id;
-	ListIterator        i     = NULL;
-	credential_state_t *state = NULL;
-
-	i = list_iterator_create(list);
-
-	while ( (state = list_next(i)) && (state->job_id != jobid) ) {;}
-
-	list_iterator_destroy(i);
-
-	if (state) {
-		state->revoked     = true;
-		state->revoke_time = now;
-	} else
-		_insert_revoked_credential_state(msg, list);
-
-	return SLURM_SUCCESS;
-}
-
-
-
-static int
-_is_credential_still_valid(slurm_job_credential_t * credential, List list)
-{
-	uint32_t            jobid = credential->job_id;
-	ListIterator        i     = NULL;
-	credential_state_t *state = NULL;
-
-	_clear_expired_revoked_credentials(list);
-
-	i = list_iterator_create(list);
-
-	while ( (state = list_next(i)) && (state->job_id != jobid)) {;}
-
-	list_iterator_destroy(i);
-
-	if (!state)
-		_insert_credential_state(credential, list);
-	else if (state->revoked)
-		return ESLURMD_CREDENTIAL_REVOKED;
-
-	return SLURM_SUCCESS;
-}
-
-void
-clear_expired_credentials(List l)
-{
-	_clear_expired_revoked_credentials(l);
-}
-
-/*
- * This function is not thread-safe. However, it should only
- * be used from _clear_expired_revoked_credentials(), below,
- * which is only called from a single thread.
- */
-static char *
-_cred_string(uint32_t jobid)
-{
-	static char buf[256];
-	snprintf(buf, sizeof(buf), "job%d", jobid);
-	return buf;
-}
-
-static void
-_print_expired_list(hostlist_t hl)
-{
-	char buf[1024];
-
-	xassert(hl != NULL);
-
-	if (!hostlist_count(hl))
-		return;
-
-	hostlist_ranged_string(hl, sizeof(buf), buf);
-	debug2("expired credentials for: %s", buf);
-}
-
-static int 
-_clear_expired_revoked_credentials(List list)
-{
-	time_t now = time(NULL);
-	ListIterator iterator;
-	credential_state_t *s;
-	hostlist_t hl = hostlist_create(NULL);
-
-	debug2("clearing expired credentials");
-
-	iterator = list_iterator_create(list);
-	while ((s = list_next(iterator))) {
-		if (now > (s->expiration + EXPIRATION_WINDOW) ) {
-			hostlist_push(hl, _cred_string(s->job_id));
-			list_delete(iterator);
-		}
-	}
-	list_iterator_destroy(iterator);
-
-	_print_expired_list(hl);
-	hostlist_destroy(hl);
-
-	return SLURM_SUCCESS;
-}
-
-bool 
-credential_is_cached(List list, uint32_t jobid)
-{
-	ListIterator i;
-	credential_state_t *state;
-
-	debug2("checking for cached credential for job %u", jobid);
-
-	i = list_iterator_create(list);
-	while ( (state = list_next(i)) && (state->job_id != jobid) ) {;}
-	list_iterator_destroy(i);
-
-	return (state != NULL);
-}
-
-int 
-initialize_credential_state_list(List * list)
-{
-	*list = list_create((ListDelF) _free_credential_state);
-	return SLURM_SUCCESS;
-}
-
-int 
-destroy_credential_state_list(List list)
-{
-	list_destroy(list);
-	return SLURM_SUCCESS;
-}
-
-static int
-_init_credential_state(credential_state_t * credential_state,
-		      slurm_job_credential_t * credential)
-{
-	credential_state->job_id	= credential->job_id;
-	credential_state->expiration	= credential->expiration_time;
-	credential_state->revoked	= false;
-	return SLURM_SUCCESS;
-}
-
-static void 
-_free_credential_state(void *state)
-{
-	if (state) {
-		xfree(state);
-	}
-}
-
-static int 
-_insert_credential_state(slurm_job_credential_t * credential, List list)
-{
-	credential_state_t *s = xmalloc(sizeof(*s));
-
-	_init_credential_state(s, credential);
-	list_append(list, s);
-
-	return SLURM_SUCCESS;
-}
-
-int
-_insert_revoked_credential_state(revoke_credential_msg_t *msg, List list)
-{
-	time_t now = time(NULL);
-	credential_state_t *s = xmalloc(sizeof(*s));
-
-	s->job_id      = msg->job_id;
-	s->expiration  = msg->expiration_time;
-	s->revoked     = true;
-	s->revoke_time = now;
-
-	list_append(list, s);
-	return SLURM_SUCCESS;
-}
-
-/* pack_credential_list
- * pack a list of credentials into a machine independent format buffer
- * IN list		- list to credentials to pack
- * IN/OUT buffer	- existing buffer into which the credential
- *			  information should be stored
- */ 
-void 
-pack_credential_list(List list, Buf buffer)
-{
-	ListIterator        i = NULL;
-	credential_state_t *s = NULL;
-
-	i = list_iterator_create(list);
-	while ((s = list_next(i)))
-		_pack_one_cred(s, buffer);
-	list_iterator_destroy(i);
-}
-
-/* unpack_credential_list
- * unpack a list of credentials from a machine independent format buffer
- * IN/OUT list		- existing list onto which the records in 
- *			  the buffer are added
- * IN buffer		- existing buffer from which the credential
- *			  information should be read
- * RET int		- zero or error code
- */ 
-int 
-unpack_credential_list(List list, Buf buffer)
-{
-	credential_state_t *s = NULL;
-
-	do {
-		s = xmalloc(sizeof(slurm_job_credential_t));
-		if (_unpack_one_cred(s, buffer)) {
-			xfree(s);
-			return SLURM_ERROR;
-		} else	
-			list_append(list, s);
-	} while (remaining_buf(buffer));
-
-	return SLURM_SUCCESS;
-}
-
-static void 
-_pack_one_cred(credential_state_t *state, Buf buffer)
-{
-	pack32(state->job_id,		buffer);
-	pack16(state->revoked,		buffer);
-	pack16(state->procs_allocated,	buffer);
-	pack16(state->total_procs,	buffer);
-	pack_time(state->revoke_time,	buffer);
-	pack_time(state->expiration,	buffer);
-}
-
-static int 
-_unpack_one_cred(credential_state_t *state, Buf buffer)
-{
-	safe_unpack32(&state->job_id,		buffer);
-	safe_unpack16(&state->revoked,		buffer);
-	safe_unpack16(&state->procs_allocated,	buffer);
-	safe_unpack16(&state->total_procs,	buffer);
-	unpack_time(&state->revoke_time,	buffer);
-	unpack_time(&state->expiration,		buffer);
-	return SLURM_SUCCESS;
-
-      unpack_error:
-	return SLURM_ERROR;
-}
diff --git a/src/common/credential_utils.h b/src/common/credential_utils.h
deleted file mode 100644
index 9aa76d34b14e9117e0964e3dafbf5e82fd9dc0c7..0000000000000000000000000000000000000000
--- a/src/common/credential_utils.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*****************************************************************************\
- *  credential_utils.h - slurm authentication credential management functions
- *****************************************************************************
- *  Written by Kevin Tew <tewk@llnl.gov>, et. al.
- *  
- *  This file is part of SLURM, a resource management program.
- *  For details, see <http://www.llnl.gov/linux/slurm/>.
- *  
- *  SLURM is free software; you can redistribute it and/or modify it under
- *  the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either version 2 of the License, or (at your option)
- *  any later version.
- *  
- *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
- *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- *  details.
- *  
- *  You should have received a copy of the GNU General Public License along
- *  with SLURM; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
-\*****************************************************************************/
-
-#ifndef _CREDENTIAL_UTILS_H
-#define _CREDENTIAL_UTILS_H
-
-#include <stdint.h>
-#include <stdio.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-
-#include "src/common/list.h"
-#include "src/common/pack.h"
-#include "src/common/signature_utils.h"
-#include "src/common/slurm_protocol_api.h"
-
-typedef struct credential_state {
-	uint32_t job_id;	/* job_id this credential corresponds to */
-	uint16_t revoked;	/* boolean true/false */
-	uint16_t procs_allocated;  /* number of credential procs running */
-	uint16_t total_procs;	/* number of procs in credential */
-	time_t revoke_time;	/* time of revoke - this is informational only 
-				 * not used */
-	time_t expiration;	/* expiration date set at credential creation 
-				 * time */
-} credential_state_t;
-
-/* time to wait after expiration_time before removing credential_state 
- * from credential_state_list, time in seconds */
-#define EXPIRATION_WINDOW 600
-
-/* function prototypes */
-/* initialize_credential_state_list
- * called from slurmd_init initializes the List structure pointed to by list
- * IN list	- type List 
- * RET int	- zero or error code
- */
-int initialize_credential_state_list(List * list);
-
-/* destroy_credential_state_list
- * destroys a initialized list
- * IN list	- type List 
- * RET int	- zero or error code
- */
-int destroy_credential_state_list(List list);
-
-/* print_credential
- * log a credential using info() function
- */
-void print_credential(slurm_job_credential_t * cred);
-
-/* verify_credential
- * given a credential message and a verify_ctx containing the public key
- * this method verifies the credential and creates the necessary state  
- * objectin the credential_state_list
- * IN ctx		- slurm ssl public key ctx
- * IN cred		- credential to verify
- * IN l			- list to add credential state object to 
- * RET int		- zero or error code
- */
-int verify_credential(slurm_ssl_key_ctx_t *ctx, slurm_job_credential_t *cred,
-		      List l);
-
-/* sign_credential
- * signs a credential before transmit
- * used by slurmctld
- * IN sign_ctx		- slurm ssl private key ctx
- * IN credential	- credential to sign 
- * RET int		- zero or error code
- */
-extern int sign_credential(slurm_ssl_key_ctx_t * sign_ctx,
-			   slurm_job_credential_t * credential);
-
-/* revoke_credential
- * expires a credential in the credential_state_list
- * IN msg	- revoke rpc message
- * IN list	- list to revoke credential state object in
- * RET int	- zero or error code
- */
-extern int revoke_credential(revoke_credential_msg_t * msg, List list);
-
-/* pack_credential_list
- * pack a list of credentials into a machine independent format buffer
- * IN list		- list to credentials to pack
- * IN/OUT buffer	- existing buffer into which the credential
- *			  information should be stored
- */ 
-extern void pack_credential_list(List list, Buf buffer);
-
-/* unpack_credential_list
- * unpack a list of credentials from a machine independent format buffer
- * IN/OUT list		- existing list into which the credential records 
- *			  from the buffer are added
- * IN buffer		- existing buffer from which the credential
- *			  information should be read
- * RET int		- zero or error code
- */ 
-extern int unpack_credential_list(List list, Buf buffer);
-
-/*
- * Returns true if credential for job id jobid is already cached in the
- * credential state list
- */
-bool credential_is_cached(List state_list, uint32_t jobid);
-
-/*
- * Force expiration of expired credentials from the 
- * state list (l).
- */
-void  clear_expired_credentials(List l);
-
-#endif /* !_CREDENTIAL_UTILS_H */
-
diff --git a/src/common/pack.h b/src/common/pack.h
index 13c1a081135eecd3fcfb3b753ee4d7820bac3c0f..44c6a179feff4f5577a5a091c0272202a363ec3a 100644
--- a/src/common/pack.h
+++ b/src/common/pack.h
@@ -43,6 +43,7 @@
 
 #include <assert.h>
 #include <time.h>
+#include <string.h>
 
 #define BUF_MAGIC 0x42554545
 
diff --git a/src/common/signature_utils.c b/src/common/signature_utils.c
deleted file mode 100644
index 881b4353fd244159464a3dae5a2cd6abb2fab8be..0000000000000000000000000000000000000000
--- a/src/common/signature_utils.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*****************************************************************************\
- * signature_utils.c - functions related to job cred signatures
- * $Id$
- *****************************************************************************
- *  Copyright (C) 2002 The Regents of the University of California.
- *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
- *  Written by Kevin Tew <tewk@llnl.gov>.
- *  UCRL-CODE-2002-040.
- *  
- *  This file is part of SLURM, a resource management program.
- *  For details, see <http://www.llnl.gov/linux/slurm/>.
- *  
- *  SLURM is free software; you can redistribute it and/or modify it under
- *  the terms of the GNU General Public License as published by the Free
- *  Software Foundation; either version 2 of the License, or (at your option)
- *  any later version.
- *  
- *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
- *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
- *  details.
- *  
- *  You should have received a copy of the GNU General Public License along
- *  with SLURM; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
-\*****************************************************************************/
-#if HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <stdio.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-
-#include <slurm/slurm_errno.h>
-
-#include "src/common/credential_utils.h"
-#include "src/common/log.h"
-#include "src/common/signature_utils.h"
-#include "src/common/slurm_protocol_api.h"
-#include "src/common/xmalloc.h"
-
-
-int slurm_ssl_init()
-{
-	ERR_load_crypto_strings();
-	OpenSSL_add_all_algorithms();
-	return SLURM_SUCCESS;
-}
-
-int slurm_ssl_destroy()
-{
-	EVP_cleanup();
-	ERR_free_strings();
-	return SLURM_SUCCESS;
-}
-
-int slurm_init_signer(slurm_ssl_key_ctx_t * ctx, char *path)
-{
-	FILE     *fp = NULL;
-	EVP_PKEY *pk = NULL;
-	int       rc = SLURM_SUCCESS;
-
-	if (!(fp = fopen(path, "r"))) {
-		error ("can't open key file '%s' : %m", path);
-		return SLURM_ERROR;
-	};
-
-	if (PEM_read_PrivateKey(fp, &pk, NULL, NULL)) 
-		ctx->key.private = pk;
-	else {
-		error ("PEM_read_PrivateKey [%s]: %m", path);
-		rc = SLURM_ERROR;
-	}
-	fclose(fp);
-
-	if (pk && (EVP_PKEY_size(pk) > SLURM_SSL_SIGNATURE_LENGTH)) {
-		error ("slurm_ssl_sign: key size too large");
-		rc = SLURM_ERROR;
-	}
-
-	return rc;
-}
-
-int slurm_init_verifier(slurm_ssl_key_ctx_t * ctx, char *path)
-{
-	FILE *fp = NULL;
-	int   rc = SLURM_SUCCESS;
-
-	if ((fp = fopen(path, "r")) == NULL) {
-		error ("can't open certificate file '%s' : %m ", path);
-		return SLURM_ERROR;
-	}
-
-	ctx->key.public = NULL;
-	if (!PEM_read_PUBKEY(fp, &ctx->key.public, NULL, NULL)) {
-		error("PEM_read_PUBKEY[%s]: %m",path);
-		rc = SLURM_ERROR;
-	}
-	fclose(fp);
-
-	return rc;
-}
-
-int slurm_destroy_ssl_key_ctx(slurm_ssl_key_ctx_t * ctx)
-{
-	if (ctx) EVP_PKEY_free(ctx->key.private);
-	return SLURM_SUCCESS;
-}
-
-
-int
-slurm_ssl_sign(slurm_ssl_key_ctx_t *ctx, 
-               char *data, int datalen, char *sig,  int *siglen )
-{
-	EVP_MD_CTX ectx;
-
-
-	EVP_SignInit(&ectx, EVP_sha1());
-
-	EVP_SignUpdate(&ectx, data, datalen);
-
-	if (!EVP_SignFinal(&ectx, sig, siglen, ctx->key.private)) {
-		ERR_print_errors_fp(log_fp()); 
-		return SLURM_ERROR;
-	}
-
-	return SLURM_SUCCESS;
-}
-
-int
-slurm_ssl_verify(slurm_ssl_key_ctx_t * ctx, 
-                 char *data, int datalen, char *sig, int siglen)
-{
-	EVP_MD_CTX ectx;
-
-	EVP_VerifyInit(&ectx, EVP_sha1());
-
-	EVP_VerifyUpdate(&ectx, data, datalen);
-
-	if (!EVP_VerifyFinal(&ectx, sig, siglen, ctx->key.public)) {
-		error("EVP_VerifyFinal: %s", 
-		      ERR_error_string(ERR_get_error(), NULL));
-		return SLURM_ERROR;
-	}
-	return SLURM_SUCCESS;
-}
diff --git a/src/common/signature_utils.h b/src/common/signature_utils.h
deleted file mode 100644
index b2acbcbdd95fb13cdc8656287bc361b7498c018a..0000000000000000000000000000000000000000
--- a/src/common/signature_utils.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef _SIGNATURE_UTILS_H
-#define _SIGNATURE_UTILS_H
-#include <stdio.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-
-#include "src/common/slurm_protocol_api.h"
-
-enum key_type { SIGNER_PRIVATE_KEY, VERIFIER_PUBLIC_KEY };
-enum { SLURM_OPENSSL_SIGNED = 1 };
-enum { SLURM_OPENSSL_VERIFIED = 1 };
-
-typedef struct slurm_ssl_key_ctx {
-	enum key_type key_type;
-	unsigned int key_length;
-	union key {
-		EVP_PKEY *private;
-		EVP_PKEY *public;
-	} key;
-} slurm_ssl_key_ctx_t;
-
-/* slurm_ssl_init
- * calls the approriate ssl init functions for crypto functions 
- * should be called once before using other slurm_ssl functions
- * RET 			- return code
- */
-int slurm_ssl_init();
-
-/* slurm_ssl_destroy
- * calls the approriate ssl destroy fucntions for crypto functions
- * should be called right before exit
- * RET 			- return code
- */
-int slurm_ssl_destroy();
-
-/* slurm_init_signer
- * loads a private key to later be used to sign messages
- * OUT ctx		- context to initialize
- * IN path		- path to private key
- * RET			- return code
- */
-int slurm_init_signer(slurm_ssl_key_ctx_t * ctx, char *path);
-
-/* slurm_init_verifier
- * loads a public key out of a X509 cert to verify signed messages
- * OUT ctx		- context to initialize
- * IN path		- path to certificate 
- * RET			- return code
- */
-int slurm_init_verifier(slurm_ssl_key_ctx_t * ctx, char *path);
-
-
-/* slurm_destroy_ssl_key_ctx
- * destroys an initialezed ssl_key_ctx
- * IN ctx		- context to destroy 
- * RET			- return code
- */
-int slurm_destroy_ssl_key_ctx(slurm_ssl_key_ctx_t * ctx);
-
-/* slurm_ssl_sign
- * using a private key ctx and a buffer creates a signature in buffer
- *
- * IN ctx		- private key ctx
- * IN data_buffer	- buffer to sign
- * IN data_length	- length of data buffer
- * OUT signature_buffer	- signature
- * OUT signature_length	- signature length
- * RET 			- return code
- */
-int slurm_ssl_sign(slurm_ssl_key_ctx_t * ctx, char *data_buffer,
-		   int data_length, char *signature_buffer,
-		   int *signature_length);
-
-/* slurm_ssl_verify
- * using a public key ctx and a buffer verifies a signature in buffer
- * IN ctx		- private key ctx
- * IN data_buffer	- buffer to verify 
- * IN data_length	- length of data buffer
- * OUT signature_buffer	- signature
- * OUT signature_length	- signature length
- * RET 			- return code
- */
-int slurm_ssl_verify(slurm_ssl_key_ctx_t * ctx, char *data_buffer,
-		     int data_length, char *signature_buffer,
-		     int signature_length);
-
-#endif
diff --git a/src/common/slurm_cred.c b/src/common/slurm_cred.c
new file mode 100644
index 0000000000000000000000000000000000000000..49a7e21cf72d8666623020a2c568538a64cdc33f
--- /dev/null
+++ b/src/common/slurm_cred.c
@@ -0,0 +1,1037 @@
+/*****************************************************************************\
+ * src/common/slurm_cred.c - SLURM job credential functions
+ * $Id$
+ *****************************************************************************
+ *  Copyright (C) 2002 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by Mark A. Grondona <mgrondona@llnl.gov>.
+ *  UCRL-CODE-2002-040.
+ *  
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://www.llnl.gov/linux/slurm/>.
+ *  
+ *  SLURM is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *  
+ *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
+ *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ *  details.
+ *  
+ *  You should have received a copy of the GNU General Public License along
+ *  with SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <slurm/slurm_errno.h>
+
+#include <stdarg.h>
+
+/*
+ * OpenSSL includes
+ */
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+#include "src/common/macros.h"
+#include "src/common/list.h"
+#include "src/common/log.h"
+#include "src/common/xmalloc.h"
+#include "src/common/xassert.h"
+#include "src/common/xstring.h"
+
+#include "src/common/slurm_cred.h"
+
+/* 
+ * Default credential information expiration window:
+ */
+#define DEFAULT_EXPIRATION_WINDOW 600
+
+/* 
+ * slurm job credential state 
+ * 
+ */
+typedef struct {
+	uint32_t jobid;		/* SLURM job id for this credential         */
+	uint32_t stepid;	/* SLURM step id for this credential        */
+	time_t   expiration;    /* Time at which cred is no longer good     */
+} cred_state_t;
+
+/*
+ * slurm job state information
+ * tracks jobids for which all future credentials have been revoked
+ *
+ */
+typedef struct {
+	uint32_t jobid;         
+	bool     revoked;       /* True if all creds for jobid are revoked  */
+	time_t   ctime;         /* Time that this entry was created         */
+	time_t   expiration;    /* Time at which credentials were revoked   */
+} job_state_t;
+
+
+/*
+ * Completion of slurm credential context
+ */
+enum ctx_type {
+	SLURM_CRED_CREATOR,
+	SLURM_CRED_VERIFIER
+};
+
+struct slurm_cred_context {
+#ifndef NDEBUG
+#  define CRED_CTX_MAGIC 0x0c0c0c
+	int magic;
+#endif
+	enum ctx_type  type;       /* type of context (creator or verifier) */
+	EVP_PKEY      *key;        /* private or public key                 */
+	List           job_list;   /* List of used jobids (for verifier)    */
+	List           state_list; /* List of cred states (for verifier)    */
+
+	int   expiry_window;       /* expiration window for cached creds    */
+
+	EVP_PKEY      *exkey;      /* Old public key if key is updated      */
+	time_t         exkey_exp;  /* Old key expiration time               */
+};
+
+/*
+ * Completion of slurm job credential type:
+ *
+ */
+struct slurm_job_credential {
+	uint32_t jobid;        /* Job ID associated with this credential    */
+	uint32_t stepid;       /* Job step ID for this credential           */
+	uid_t    uid;          /* user for which this cred is valid         */
+	time_t   ctime;        /* time of credential creation               */
+	char    *nodes;        /* list of hostnames for which the cred is ok*/
+
+	unsigned char *signature; /* credential signature                   */
+	int      siglen;          /* signature length in bytes              */
+};
+
+
+
+/*
+ * Static prototypes:
+ */
+
+static slurm_cred_ctx_t _slurm_cred_ctx_alloc(void);
+static slurm_cred_t     _slurm_cred_alloc(void);
+
+static int  _ctx_update_private_key(slurm_cred_ctx_t ctx, const char *path);
+static int  _ctx_update_public_key(slurm_cred_ctx_t ctx, const char *path);
+static bool _exkey_is_valid(slurm_cred_ctx_t ctx);
+
+static cred_state_t * _cred_state_create(slurm_cred_ctx_t ctx, slurm_cred_t c);
+static job_state_t  * _job_state_create(slurm_cred_t c);
+static void           _cred_state_destroy(cred_state_t *cs);
+static void           _job_state_destroy(job_state_t   *js);
+
+static job_state_t  * _find_job_state(slurm_cred_ctx_t ctx, uint32_t jobid);
+
+static void _insert_cred_state(slurm_cred_ctx_t ctx, slurm_cred_t cred);
+static void _insert_job_state(slurm_cred_ctx_t ctx,  slurm_cred_t cred);
+static void _clear_expired_job_states(slurm_cred_ctx_t ctx);
+static void _clear_expired_credential_states(slurm_cred_ctx_t ctx);
+static void _verifier_ctx_init(slurm_cred_ctx_t ctx);
+
+static bool _credential_replayed(slurm_cred_ctx_t ctx, slurm_cred_t cred);
+static bool _credential_revoked(slurm_cred_ctx_t ctx, slurm_cred_t cred);
+
+static EVP_PKEY * _read_private_key(const char *path);
+static EVP_PKEY * _read_public_key(const char  *path);
+
+static int _slurm_cred_sign(slurm_cred_ctx_t ctx, slurm_cred_t cred);
+static int _slurm_cred_verify_signature(slurm_cred_ctx_t ctx, slurm_cred_t c);
+
+static job_state_t  * _job_state_unpack_one(Buf buffer);
+static cred_state_t * _cred_state_unpack_one(Buf buffer);
+
+static void _pack_cred(slurm_cred_t cred, Buf buffer);
+static void _job_state_unpack(slurm_cred_ctx_t ctx, Buf buffer);
+static void _job_state_pack(slurm_cred_ctx_t ctx, Buf buffer);
+static void _cred_state_unpack(slurm_cred_ctx_t ctx, Buf buffer);
+static void _cred_state_pack(slurm_cred_ctx_t ctx, Buf buffer);
+static void _job_state_pack_one(job_state_t *j, Buf buffer);
+static void _cred_state_pack_one(cred_state_t *s, Buf buffer);
+
+
+
+slurm_cred_ctx_t 
+slurm_cred_creator_ctx_create(const char *path)
+{
+	slurm_cred_ctx_t ctx = NULL;
+	
+	xassert(path != NULL);
+
+	ctx = _slurm_cred_ctx_alloc();
+
+	ctx->type = SLURM_CRED_CREATOR;
+
+	if (!(ctx->key = _read_private_key(path))) 
+		goto fail;
+
+	return ctx;
+
+    fail:
+	xfree(ctx);
+	return NULL;
+}
+
+
+slurm_cred_ctx_t 
+slurm_cred_verifier_ctx_create(const char *path)
+{
+	slurm_cred_ctx_t ctx = NULL;
+
+	xassert(path != NULL);
+
+	ctx = _slurm_cred_ctx_alloc();
+	ctx->type = SLURM_CRED_VERIFIER;
+
+	if (!(ctx->key = _read_public_key(path)))
+		goto fail;
+
+	_verifier_ctx_init(ctx);
+	return ctx;
+
+    fail:
+	xfree(ctx);
+	return NULL;
+}
+
+
+void
+slurm_cred_ctx_destroy(slurm_cred_ctx_t ctx)
+{
+	if (ctx == NULL)
+		return;
+
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+
+	if (ctx->key)
+		EVP_PKEY_free(ctx->key);
+	if (ctx->job_list)
+		list_destroy(ctx->job_list);
+	if (ctx->state_list)
+		list_destroy(ctx->state_list);
+
+	xassert(ctx->magic = ~CRED_CTX_MAGIC);
+
+	xfree(ctx);
+
+	return;
+}
+
+int 
+slurm_cred_ctx_set(slurm_cred_ctx_t ctx, slurm_cred_opt_t opt, ...)
+{
+	int     rc  = SLURM_SUCCESS;
+	va_list ap;
+
+	va_start(ap, opt);
+
+	switch (opt) {
+	case SLURM_CRED_OPT_EXPIRY_WINDOW: 
+		ctx->expiry_window = va_arg(ap, int);
+		break;
+	default:
+		slurm_seterrno(EINVAL);
+		rc = SLURM_ERROR;
+		break;
+	}
+
+	va_end(ap);
+
+	return rc;
+}
+
+int
+slurm_cred_ctx_get(slurm_cred_ctx_t ctx, slurm_cred_opt_t opt, ...)
+{
+	int rc = SLURM_SUCCESS;
+	va_list ap;
+	int *intp;
+
+	va_start(ap, opt);
+
+	switch (opt) {
+	case SLURM_CRED_OPT_EXPIRY_WINDOW: 
+		intp  = va_arg(ap, int *);
+		*intp = ctx->expiry_window;
+		break;
+	default:
+		slurm_seterrno(EINVAL);
+		rc = SLURM_ERROR;
+		break;
+	}
+
+	va_end(ap);
+
+	return rc;
+}
+
+int 
+slurm_cred_ctx_key_update(slurm_cred_ctx_t ctx, const char *path)
+{
+	if (ctx->type == SLURM_CRED_CREATOR)
+		return _ctx_update_private_key(ctx, path);
+	else
+		return _ctx_update_public_key(ctx, path);
+
+}
+
+
+slurm_cred_t
+slurm_cred_create(slurm_cred_ctx_t ctx, slurm_cred_arg_t *arg)
+{
+	slurm_cred_t cred = NULL;
+
+	xassert(ctx != NULL);
+	xassert(arg != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type == SLURM_CRED_CREATOR);
+
+	cred = _slurm_cred_alloc();
+
+	cred->jobid  = arg->jobid;
+	cred->stepid = arg->stepid;
+	cred->uid    = arg->uid;
+	cred->nodes  = xstrdup(arg->hostlist);
+	cred->ctime  = time(NULL);
+
+	if (_slurm_cred_sign(ctx, cred) < 0) 
+		goto fail;
+
+	return cred;
+
+    fail:
+	slurm_cred_destroy(cred);
+	return NULL;
+}
+
+
+int
+slurm_cred_verify(slurm_cred_ctx_t ctx, slurm_cred_t cred, 
+		  slurm_cred_arg_t *arg)
+{
+	time_t now = time(NULL);
+
+	xassert(ctx  != NULL);
+	xassert(cred != NULL);
+	xassert(arg  != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type  == SLURM_CRED_VERIFIER);
+
+	if (_slurm_cred_verify_signature(ctx, cred) < 0)
+		slurm_seterrno_ret(ESLURMD_INVALID_JOB_CREDENTIAL);
+
+	if (now > (cred->ctime + ctx->expiry_window)) 
+		slurm_seterrno_ret(ESLURMD_CREDENTIAL_EXPIRED);
+
+	if (_credential_revoked(ctx, cred))
+		slurm_seterrno_ret(ESLURMD_CREDENTIAL_REVOKED);
+
+	if (_credential_replayed(ctx, cred))
+		slurm_seterrno_ret(ESLURMD_CREDENTIAL_REPLAYED);
+
+	/*
+	 * set arguments to cred contents
+	 */
+	arg->jobid    = cred->jobid;
+	arg->stepid   = cred->stepid;
+	arg->uid      = cred->uid;
+	arg->hostlist = xstrdup(cred->nodes);
+
+	return SLURM_SUCCESS;
+}
+
+
+void
+slurm_cred_destroy(slurm_cred_t cred)
+{
+	if (cred == NULL)
+		return;
+
+	if (cred->nodes)
+		xfree(cred->nodes);
+	if (cred->signature)
+		xfree(cred->signature);
+	xfree(cred);
+}
+
+
+bool
+slurm_cred_jobid_cached(slurm_cred_ctx_t ctx, uint32_t jobid)
+{
+	xassert(ctx != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type  == SLURM_CRED_VERIFIER);
+
+	_clear_expired_job_states(ctx);
+
+	/*
+	 * Return true if we find a cached job state for job id `jobid'
+	 */
+	return (_find_job_state(ctx, jobid) != NULL);
+}
+
+
+int
+slurm_cred_revoke(slurm_cred_ctx_t ctx, uint32_t jobid)
+{
+	job_state_t  *j = NULL;
+
+	xassert(ctx != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type  == SLURM_CRED_VERIFIER);
+
+	_clear_expired_job_states(ctx);
+
+	if (!(j = _find_job_state(ctx, jobid))) 
+		slurm_seterrno_ret(ESRCH);
+
+	j->revoked     = true;
+	j->expiration  = time(NULL) + ctx->expiry_window;
+
+	return SLURM_SUCCESS;
+}
+
+int
+slurm_cred_get_signature(slurm_cred_t cred, char *data, int *datalen)
+{
+	data     = cred->signature;
+	*datalen = cred->siglen;
+	return SLURM_SUCCESS;
+}
+
+void
+slurm_cred_pack(slurm_cred_t cred, Buf buffer)
+{
+	_pack_cred(cred, buffer);
+	packmem(cred->signature, (uint16_t) cred->siglen, buffer);
+	return;
+}
+
+slurm_cred_t
+slurm_cred_unpack(Buf buffer)
+{
+	uint16_t     len;
+	slurm_cred_t cred = NULL;
+	char       **sigp;
+
+	xassert(buffer != NULL);
+
+	cred = _slurm_cred_alloc();
+
+	sigp = (char **) &cred->signature;
+
+	safe_unpack32(          &cred->jobid,        buffer);
+	safe_unpack32(          &cred->stepid,       buffer);
+	safe_unpack32(          &cred->uid,          buffer);
+	safe_unpackstr_xmalloc( &cred->nodes, &len,  buffer);
+	safe_unpack_time(       &cred->ctime,        buffer);
+	safe_unpackmem_xmalloc( sigp,         &len,  buffer);
+
+	cred->siglen = len;
+
+	return cred;
+
+    unpack_error:
+	slurm_cred_destroy(cred);
+	return NULL;
+}
+
+int
+slurm_cred_ctx_pack(slurm_cred_ctx_t ctx, Buf buffer)
+{
+	_job_state_pack(ctx, buffer);
+	_cred_state_pack(ctx, buffer);
+
+	return SLURM_SUCCESS;
+}
+
+int
+slurm_cred_ctx_unpack(slurm_cred_ctx_t ctx, Buf buffer)
+{
+	xassert(ctx != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type  == SLURM_CRED_VERIFIER);
+
+	/* 
+	 * Unpack job state list and cred state list from buffer
+	 * appening them onto ctx->state_list and ctx->job_list.
+	 */
+	_job_state_unpack(ctx, buffer);
+	_cred_state_unpack(ctx, buffer);
+
+	return SLURM_SUCCESS;
+}
+
+void
+slurm_cred_print(slurm_cred_t cred)
+{
+	if (cred == NULL)
+		return;
+
+	info("Cred: Jobid   %u",  cred->jobid         );
+	info("Cred: Stepid  %u",  cred->jobid         );
+	info("Cred: UID     %lu", cred->uid           );
+	info("Cred: Nodes   %s",  cred->nodes         );
+	info("Cred: ctime   %s",  ctime(&cred->ctime) );
+	info("Cred: siglen  %d",  cred->siglen        );
+
+}
+
+
+static EVP_PKEY *
+_read_private_key(const char *path)
+{
+	FILE     *fp = NULL;
+	EVP_PKEY *pk = NULL;
+
+	xassert(path != NULL);
+
+	if (!(fp = fopen(path, "r"))) {
+		error ("can't open key file '%s' : %m", path);
+		return NULL;
+	}
+
+	if (!PEM_read_PrivateKey(fp, &pk, NULL, NULL))
+		error ("PEM_read_PrivateKey [%s]: %m", path);
+
+	fclose(fp);
+
+	return pk;
+}
+
+
+static EVP_PKEY *
+_read_public_key(const char *path)
+{
+	FILE     *fp = NULL;
+	EVP_PKEY *pk = NULL;
+
+	xassert(path != NULL);
+
+	if ((fp = fopen(path, "r")) == NULL) {
+		error ("can't open public key '%s' : %m ", path);
+		return NULL;
+	}
+
+	if (!PEM_read_PUBKEY(fp, &pk, NULL, NULL)) 
+		error("PEM_read_PUBKEY[%s]: %m", path);
+
+	fclose(fp);
+
+	return pk;
+}
+
+
+static void 
+_verifier_ctx_init(slurm_cred_ctx_t ctx)
+{
+	xassert(ctx != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type == SLURM_CRED_VERIFIER);
+
+	ctx->job_list   = list_create((ListDelF) _job_state_destroy);
+	ctx->state_list = list_create((ListDelF) _cred_state_destroy);
+
+	return;
+}
+
+
+static int
+_ctx_update_private_key(slurm_cred_ctx_t ctx, const char *path)
+{
+	EVP_PKEY *pk   = NULL;
+	EVP_PKEY *tmpk = NULL;
+
+	xassert(ctx != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type  == SLURM_CRED_CREATOR);
+
+	if (!(pk = _read_private_key(path)))
+		return SLURM_ERROR;
+
+	tmpk = ctx->key;
+	ctx->key = pk;
+
+	EVP_PKEY_free(tmpk);
+
+	return SLURM_SUCCESS;
+}
+
+
+static int
+_ctx_update_public_key(slurm_cred_ctx_t ctx, const char *path)
+{
+	EVP_PKEY *pk   = NULL;
+
+	xassert(ctx != NULL);
+	xassert(ctx->magic == CRED_CTX_MAGIC);
+	xassert(ctx->type  == SLURM_CRED_VERIFIER);
+
+	if (!(pk = _read_public_key(path)))
+		return SLURM_ERROR;
+
+	if (ctx->exkey) 
+		EVP_PKEY_free(ctx->exkey);
+
+	ctx->exkey = ctx->key;
+	ctx->key   = pk;
+
+	/*
+	 * exkey expires in expiry_window seconds.
+	 * This should be long enough to capture any keys in-flight.
+	 */
+	ctx->exkey_exp = time(NULL) + ctx->expiry_window;
+
+	return SLURM_SUCCESS;
+}
+
+
+static bool
+_exkey_is_valid(slurm_cred_ctx_t ctx)
+{
+	time_t now = time(NULL);
+
+	if (!ctx->exkey) return false;
+	
+	if (now > ctx->exkey_exp) {
+		EVP_PKEY_free(ctx->exkey);
+		ctx->exkey = NULL;
+		return false;
+	}
+
+	return true;
+}
+
+
+static slurm_cred_ctx_t
+_slurm_cred_ctx_alloc(void)
+{
+	slurm_cred_ctx_t ctx = xmalloc(sizeof(*ctx));
+
+	ctx->key           = NULL;
+	ctx->job_list      = NULL;
+	ctx->state_list    = NULL;
+	ctx->expiry_window = DEFAULT_EXPIRATION_WINDOW;
+
+	ctx->exkey         = NULL;
+	ctx->exkey_exp     = (time_t) -1;
+
+	xassert(ctx->magic = CRED_CTX_MAGIC);
+
+	return ctx;
+}
+
+static slurm_cred_t 
+_slurm_cred_alloc(void)
+{
+	slurm_cred_t cred = xmalloc(sizeof(*cred));
+
+	cred->jobid     = 0;
+	cred->stepid    = 0;
+	cred->uid       = (uid_t) -1;
+	cred->nodes     = NULL;
+	cred->signature = NULL;
+	cred->siglen    = 0;
+
+	return cred;
+}
+
+static const char *
+_ssl_error(void)
+{
+	return ERR_reason_error_string(ERR_get_error()); 
+}
+
+static void
+_print_data(char *data, int datalen)
+{
+	char buf[1024];
+	size_t len = 0;
+	int i;
+
+	for (i = 0; i < datalen; i += sizeof(char))
+		len += sprintf(buf+len, "%02x", data[i]);
+}
+
+static int
+_slurm_cred_sign(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	EVP_MD_CTX ectx;
+	Buf        buffer;
+	int        rc    = SLURM_SUCCESS;
+	int       *lenp  = &cred->siglen;
+	int        ksize = EVP_PKEY_size(ctx->key);
+
+	/*
+	 * Allocate memory for signature: at most EVP_PKEY_size() bytes
+	 */
+	cred->signature = xmalloc(ksize * sizeof(unsigned char));
+
+	buffer = init_buf(4096);
+	_pack_cred(cred, buffer);
+
+	EVP_SignInit(&ectx, EVP_sha1());
+	EVP_SignUpdate(&ectx, get_buf_data(buffer), get_buf_offset(buffer));
+
+	if (!(EVP_SignFinal(&ectx, cred->signature, lenp, ctx->key))) {
+		ERR_print_errors_fp(log_fp());
+		rc = SLURM_ERROR;
+	}
+
+	free_buf(buffer);
+
+	return rc;
+}
+
+static int
+_slurm_cred_verify_signature(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	EVP_MD_CTX     ectx;
+	Buf            buffer;
+	int            rc;
+	unsigned char *sig    = cred->signature;
+	int            siglen = cred->siglen; 
+
+	buffer = init_buf(4096);
+	_pack_cred(cred, buffer);
+
+	EVP_VerifyInit(&ectx, EVP_sha1());
+	EVP_VerifyUpdate(&ectx, get_buf_data(buffer), get_buf_offset(buffer));
+
+	if (!(rc = EVP_VerifyFinal(&ectx, sig, siglen, ctx->key))) {
+		/*
+		 * Check against old key if one exists and is valid
+		 */
+		if (_exkey_is_valid(ctx))
+			rc = EVP_VerifyFinal(&ectx, sig, siglen, ctx->exkey);
+	}
+
+	if (!rc) {
+		ERR_load_crypto_strings();
+		error("EVP_VerifyFinal: %s", _ssl_error());
+		ERR_free_strings();
+		rc = SLURM_ERROR;
+	} else
+		rc = SLURM_SUCCESS;
+
+	free_buf(buffer);
+
+	return rc;
+}
+
+
+static void
+_pack_cred(slurm_cred_t cred, Buf buffer)
+{
+	pack32(    cred->jobid,  buffer);
+	pack32(    cred->stepid, buffer);
+	pack32(    cred->uid,    buffer);
+	packstr(   cred->nodes,  buffer);
+	pack_time( cred->ctime,  buffer);
+}
+
+
+static bool
+_credential_replayed(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	ListIterator  i = NULL;
+	cred_state_t *s = NULL;
+
+	_clear_expired_credential_states(ctx);
+	
+	i = list_iterator_create(ctx->state_list);
+
+	while ((s = list_next(i))) {
+		if ((s->jobid == cred->jobid) && (s->stepid == cred->stepid))
+			break;
+	}
+
+	list_iterator_destroy(i);
+
+	/*
+	 * If we found a match, this credential is being replayed.
+	 */
+	if (s) return true; 
+
+	/*
+	 * Otherwise, save the credential state
+	 */
+	_insert_cred_state(ctx, cred);
+	return false;
+}
+
+
+static bool
+_credential_revoked(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	job_state_t  *j = NULL;
+
+	_clear_expired_job_states(ctx);
+
+	if (!(j = _find_job_state(ctx, cred->jobid))) 
+		_insert_job_state(ctx, cred);
+	else if (j->revoked)
+		return true;
+
+	return false;
+}
+
+
+static job_state_t *
+_find_job_state(slurm_cred_ctx_t ctx, uint32_t jobid)
+{
+	ListIterator  i = NULL;
+	job_state_t  *j = NULL;
+
+	i = list_iterator_create(ctx->job_list);
+	while ((j = list_next(i)) && (j->jobid != jobid)) {;}
+	list_iterator_destroy(i);
+	return j;
+}
+
+
+static void
+_insert_job_state(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	job_state_t *j = _job_state_create(cred);
+	list_append(ctx->job_list, j);
+}
+
+
+static job_state_t *
+_job_state_create(slurm_cred_t cred)
+{
+	job_state_t *j = xmalloc(sizeof(*j));
+
+	j->jobid      = cred->jobid;
+	j->revoked    = false;
+	j->ctime      = time(NULL);
+	j->expiration = (time_t) -1;
+
+	return j;
+}
+
+static void
+_job_state_destroy(job_state_t *j)
+{
+	xfree(j);
+}
+
+
+static void
+_clear_expired_job_states(slurm_cred_ctx_t ctx)
+{
+	time_t        now = time(NULL);
+	ListIterator  i   = NULL;
+	job_state_t  *j   = NULL;
+
+	i = list_iterator_create(ctx->job_list);
+
+	while ((j = list_next(i))) {
+		if (j->revoked && (now > j->expiration))
+			list_delete(i);
+	}
+
+	list_iterator_destroy(i);
+}
+
+
+static void
+_clear_expired_credential_states(slurm_cred_ctx_t ctx)
+{
+	time_t        now = time(NULL);
+	ListIterator  i   = NULL;
+	cred_state_t *s   = NULL;
+
+	i = list_iterator_create(ctx->state_list);
+
+	while ((s = list_next(i))) {
+		if (now > s->expiration)
+			list_delete(i);
+	}
+
+	list_iterator_destroy(i);
+}
+
+
+static void 
+_insert_cred_state(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	cred_state_t *s = _cred_state_create(ctx, cred);
+	list_append(ctx->state_list, s);
+}
+
+
+static cred_state_t *
+_cred_state_create(slurm_cred_ctx_t ctx, slurm_cred_t cred)
+{
+	cred_state_t *s = xmalloc(sizeof(*s));
+
+	s->jobid      = cred->jobid;
+	s->stepid     = cred->stepid;
+	s->expiration = cred->ctime + ctx->expiry_window;
+
+	return s;
+}
+
+static void
+_cred_state_destroy(cred_state_t *s)
+{
+	xfree(s);
+}
+
+
+static void
+_cred_state_pack_one(cred_state_t *s, Buf buffer)
+{
+	pack32(s->jobid, buffer);
+	pack32(s->stepid, buffer);
+	pack_time(s->expiration, buffer);
+}
+
+
+static cred_state_t *
+_cred_state_unpack_one(Buf buffer)
+{
+	cred_state_t *s = xmalloc(sizeof(*s));
+
+	safe_unpack32(&s->jobid, buffer);
+	safe_unpack32(&s->stepid, buffer);
+	safe_unpack_time(&s->expiration, buffer);
+	return s;
+
+   unpack_error:
+	_cred_state_destroy(s);
+	return NULL;
+}
+
+
+static void 
+_job_state_pack_one(job_state_t *j, Buf buffer)
+{
+	pack32(j->jobid, buffer);
+	pack16((uint16_t) j->revoked, buffer);
+	pack_time(j->ctime, buffer);
+	pack_time(j->expiration, buffer);
+
+	_print_data(buffer->head, buffer->processed);
+}
+
+
+static job_state_t *
+_job_state_unpack_one(Buf buffer)
+{
+	uint16_t     revoked = 0;
+	job_state_t *j = xmalloc(sizeof(*j));
+
+	safe_unpack32(    &j->jobid,      buffer);
+	safe_unpack16(    &revoked,       buffer);
+	safe_unpack_time( &j->ctime,      buffer);
+	safe_unpack_time( &j->expiration, buffer);
+
+	if (revoked) j->revoked = true;
+
+	return j;
+
+    unpack_error:
+	_job_state_destroy(j);
+	return NULL;
+}
+
+
+static void
+_cred_state_pack(slurm_cred_ctx_t ctx, Buf buffer)
+{
+	ListIterator  i = NULL;
+	cred_state_t *s = NULL;
+
+	pack32(list_count(ctx->state_list), buffer);
+
+	i = list_iterator_create(ctx->state_list);
+	while ((s = list_next(i)))
+		_cred_state_pack_one(s, buffer);
+	list_iterator_destroy(i);
+}
+
+
+static void
+_cred_state_unpack(slurm_cred_ctx_t ctx, Buf buffer)
+{
+	time_t        now = time(NULL);
+	int           n   = 0;
+	int           i   = 0;
+	cred_state_t *s   = NULL;
+
+	safe_unpack32(&n, buffer);
+
+	for (i = 0; i < n; i++) {
+		if (!(s = _cred_state_unpack_one(buffer)))
+			goto unpack_error;
+
+		if (now < s->expiration)
+			list_append(ctx->state_list, s);
+	}
+
+	return;
+
+    unpack_error:
+	error("Unable to unpack job credential state information");
+	return;
+}
+
+
+static void
+_job_state_pack(slurm_cred_ctx_t ctx, Buf buffer)
+{
+	ListIterator  i = NULL;
+	job_state_t  *j = NULL;
+
+	pack32((uint32_t) list_count(ctx->job_list), buffer);
+
+
+	i = list_iterator_create(ctx->job_list);
+	while ((j = list_next(i)))
+		_job_state_pack_one(j, buffer);
+	list_iterator_destroy(i);
+}
+
+
+static void
+_job_state_unpack(slurm_cred_ctx_t ctx, Buf buffer)
+{
+	time_t       now = time(NULL);
+	uint32_t     n   = 0;
+	int          i   = 0;
+	job_state_t *j   = NULL;
+
+	safe_unpack32(&n, buffer);
+
+	for (i = 0; i < n; i++) {
+		if (!(j = _job_state_unpack_one(buffer)))
+			goto unpack_error;
+
+		if (j->revoked && (now < j->expiration))
+			list_append(ctx->job_list, j);
+	}
+
+	return;
+
+    unpack_error:
+	error("Unable to unpack job state information");
+	return;
+}
+
+
diff --git a/src/common/slurm_cred.h b/src/common/slurm_cred.h
new file mode 100644
index 0000000000000000000000000000000000000000..78e585699c71cbf3c3abafce11cf1489e447ac31
--- /dev/null
+++ b/src/common/slurm_cred.h
@@ -0,0 +1,183 @@
+/*****************************************************************************\
+ * src/common/slurm_cred.h  - SLURM job credential operations
+ * $Id$
+ *****************************************************************************
+ *  Copyright (C) 2002 The Regents of the University of California.
+ *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+ *  Written by AUTHOR <AUTHOR@llnl.gov>.
+ *  UCRL-CODE-2002-040.
+ *  
+ *  This file is part of SLURM, a resource management program.
+ *  For details, see <http://www.llnl.gov/linux/slurm/>.
+ *  
+ *  SLURM is free software; you can redistribute it and/or modify it under
+ *  the terms of the GNU General Public License as published by the Free
+ *  Software Foundation; either version 2 of the License, or (at your option)
+ *  any later version.
+ *  
+ *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
+ *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ *  details.
+ *  
+ *  You should have received a copy of the GNU General Public License along
+ *  with SLURM; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+\*****************************************************************************/
+
+#ifndef _HAVE_SLURM_CRED_H
+#define _HAVE_SLURM_CRED_H
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#if HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+
+#if HAVE_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+#include "src/common/pack.h"
+
+/*
+ * The incomplete slurm_cred_t type is also defined in slurm.h for
+ * users of the api, so check to ensure that this header has not been
+ * included after slurm.h:
+ */
+#ifndef __slurm_cred_t_defined
+#  define __slurm_cred_t_defined
+   typedef struct slurm_job_credential * slurm_cred_t;
+#endif
+
+/* 
+ * The slurm_cred_ctx_t incomplete type
+ */
+typedef struct slurm_cred_context   * slurm_cred_ctx_t;
+
+
+/*
+ * Initialize current process for slurm credential creation.
+ *
+ * `privkey' contains the absolute path to the slurmctld private
+ * key, which needs to be readable by the current process. 
+ *
+ * Returns 0 for success, -1 on failure and sets errno to reason.
+ *
+ *
+ */
+slurm_cred_ctx_t slurm_cred_creator_ctx_create(const char *privkey);
+
+/*
+ * Initialize current process for slurm credential verification.
+ * `pubkey' contains the absolute path to the slurmctld public key.
+ *
+ * Returns 0 for success, -1 on failure.
+ */
+slurm_cred_ctx_t slurm_cred_verifier_ctx_create(const char *pubkey);
+
+/*
+ * Set and get credential context options
+ *
+ */
+typedef enum {
+	SLURM_CRED_OPT_EXPIRY_WINDOW /* expiration time of creds (int );  */
+} slurm_cred_opt_t;
+
+int slurm_cred_ctx_set(slurm_cred_ctx_t ctx, slurm_cred_opt_t opt, ...);
+int slurm_cred_ctx_get(slurm_cred_ctx_t ctx, slurm_cred_opt_t opt, ...);
+
+/*
+ * Update the context's current key.
+ */
+int slurm_cred_ctx_key_update(slurm_cred_ctx_t ctx, const char *keypath);
+
+
+/* 
+ * Destroy a credential context, freeing associated memory.
+ */
+void slurm_cred_ctx_destroy(slurm_cred_ctx_t ctx);
+
+/*
+ * Pack and unpack slurm credential context. 
+ *
+ * On pack() ctx is packed in machine-independent format into the
+ * buffer, on unpack() the contents of the buffer are used to 
+ * intialize the state of the context ctx.
+ */
+int  slurm_cred_ctx_pack(slurm_cred_ctx_t ctx, Buf buffer);
+int  slurm_cred_ctx_unpack(slurm_cred_ctx_t ctx, Buf buffer);
+
+
+/*
+ * Container for SLURM credential create and verify arguments:
+ */
+typedef struct {
+	uint32_t jobid;
+	uint32_t stepid;
+	uid_t    uid;
+	char    *hostlist;
+} slurm_cred_arg_t;
+
+/*
+ * Create a slurm credential using the values in `arg.'
+ * The credential is signed using the creators public key.
+ *
+ * `arg' must be non-NULL and have valid values. The arguments
+ * will be copied as is into the slurm job credential.
+ *
+ * Returns NULL on failure.
+ */
+slurm_cred_t slurm_cred_create(slurm_cred_ctx_t ctx, slurm_cred_arg_t *arg);
+
+/*
+ * Verify the signed credential `cred,' and return cred contents in
+ * the cred_arg structure. The credential is cached and cannot be reused.
+ * 
+ */
+int slurm_cred_verify(slurm_cred_ctx_t ctx, slurm_cred_t cred, 
+		      slurm_cred_arg_t *arg);
+
+/*
+ * Revoke all credentials for job id jobid
+ */
+int slurm_cred_revoke(slurm_cred_ctx_t ctx, uint32_t jobid);
+
+
+/*
+ * Returns true if the credential context has a cached state for
+ * job id jobid.
+ */
+bool slurm_cred_jobid_cached(slurm_cred_ctx_t ctx, uint32_t jobid);
+
+
+/* Free memory associated with slurm credential `cred.'
+ */
+void slurm_cred_destroy(slurm_cred_t cred);
+
+/*
+ * Pack a slurm credential for network transmission
+ */
+void slurm_cred_pack(slurm_cred_t cred, Buf buffer);
+
+/*
+ * Unpack a slurm job credential
+ */
+slurm_cred_t slurm_cred_unpack(Buf buffer);
+
+/*
+ * Get a pointer to the slurm credential signature
+ * (used by slurm IO connections to verify connecting agent)
+ */
+int slurm_cred_get_signature(slurm_cred_t cred, char *data, int *len);
+
+
+/*
+ * Print a slurm job credential using the info() call
+ */
+void slurm_cred_print(slurm_cred_t cred);
+
+
+#endif  /* _HAVE_SLURM_CREDS_H */
diff --git a/src/common/slurm_errno.c b/src/common/slurm_errno.c
index 978eeeb80694282af344dac8890c0f9eb5a1b0bf..0f9d9326c84c21fa9ea2ab9d0d27533174d68f94 100644
--- a/src/common/slurm_errno.c
+++ b/src/common/slurm_errno.c
@@ -181,7 +181,11 @@ static slurm_errtab_t slurm_errtab[] = {
 	{ ESLURMD_INVALID_JOB_CREDENTIAL, 
 	  "Invalid job credential"				},
 	{ ESLURMD_CREDENTIAL_REVOKED, 
-	  "Job credential revoked" },
+	  "Job credential revoked"                              },
+	{ ESLURMD_CREDENTIAL_EXPIRED, 
+	  "Job credential expired"                              },
+	{ ESLURMD_CREDENTIAL_REPLAYED, 
+	  "Job credential replayed"                             },
 	{ ESLURMD_CREATE_BATCH_DIR_ERROR,
 	  "Slurmd could not create a batch directory"		},
 	{ ESLURMD_MODIFY_BATCH_DIR_ERROR,
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index 80e71f486f98c1ed4e37ed7e1d42d1bd50df3fe8..975f15c863597a9db3bfa6a1579cd2f681a74534 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -37,6 +37,7 @@
 #include <stdio.h>
 
 #include "src/common/log.h"
+#include "src/common/slurm_cred.h"
 #include "src/common/slurm_protocol_defs.h"
 #include "src/common/xmalloc.h"
 
@@ -233,32 +234,35 @@ void slurm_free_task_exit_msg(task_exit_msg_t * msg)
 void slurm_free_launch_tasks_request_msg(launch_tasks_request_msg_t * msg)
 {
 	int i;
-	if (msg) {
-		xfree(msg->credential);
-		if (msg->env) {
-			for (i = 0; i < msg->envc; i++) {
-				xfree(msg->env[i]);
-			}
-			xfree(msg->env);
+	if (msg == NULL)
+		return;
+
+
+	slurm_cred_destroy(msg->cred);
+
+	if (msg->env) {
+		for (i = 0; i < msg->envc; i++) {
+			xfree(msg->env[i]);
 		}
-		xfree(msg->cwd);
-		if (msg->argv) {
-			for (i = 0; i < msg->argc; i++) {
-				xfree(msg->argv[i]);
-			}
-			xfree(msg->argv);
+		xfree(msg->env);
+	}
+	xfree(msg->cwd);
+	if (msg->argv) {
+		for (i = 0; i < msg->argc; i++) {
+			xfree(msg->argv[i]);
 		}
-		xfree(msg->global_task_ids);
-		xfree(msg->ofname);
-		xfree(msg->ofname);
-		xfree(msg->ofname);
+		xfree(msg->argv);
+	}
+	xfree(msg->global_task_ids);
+	xfree(msg->ofname);
+	xfree(msg->ofname);
+	xfree(msg->ofname);
 
-#		ifdef HAVE_LIBELAN3
-		qsw_free_jobinfo(msg->qsw_job);
-#		endif
+#	ifdef HAVE_LIBELAN3
+	qsw_free_jobinfo(msg->qsw_job);
+#	endif
 
-		xfree(msg);
-	}
+	xfree(msg);
 }
 
 void slurm_free_reattach_tasks_request_msg(reattach_tasks_request_msg_t *msg)
diff --git a/src/common/slurm_protocol_defs.h b/src/common/slurm_protocol_defs.h
index f9d6a3940492d5555cda68f1ffba76cf93b56cc2..cafb33c440ac436c3c952fd3f13c27d57533277c 100644
--- a/src/common/slurm_protocol_defs.h
+++ b/src/common/slurm_protocol_defs.h
@@ -256,7 +256,7 @@ typedef struct launch_tasks_request_msg {
 
 	int32_t   slurmd_debug; /* remote slurmd debug level */
 
-	slurm_job_credential_t *credential;	/* job credential            */
+	slurm_cred_t cred;	/* job credential            */
 
 #ifdef HAVE_LIBELAN3
 	qsw_jobinfo_t qsw_job;	/* Elan3 switch context */
@@ -287,7 +287,6 @@ typedef struct revoke_credential_msg {
 	uint32_t job_id;
 	uint32_t job_uid;
 	time_t expiration_time;
-	char signature[SLURM_SSL_SIGNATURE_LENGTH];
 } revoke_credential_msg_t;
 
 typedef struct job_time_msg {
diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c
index a28087b6e408611ac999d83ae31b68bfd8ee82d8..a9208e026634f6254891d696629f585eb88e44d3 100644
--- a/src/common/slurm_protocol_pack.c
+++ b/src/common/slurm_protocol_pack.c
@@ -37,6 +37,7 @@
 #include "src/common/log.h"
 #include "src/common/pack.h"
 #include "src/common/slurm_auth.h"
+#include "src/common/slurm_cred.h"
 #include "src/common/slurm_protocol_api.h"
 #include "src/common/slurm_protocol_defs.h"
 #include "src/common/slurm_protocol_pack.h"
@@ -889,7 +890,7 @@ static void
 	pack16(msg->node_cnt, buffer);
 	_pack_slurm_addr_array(msg->node_addr, msg->node_cnt, buffer);
 
-	pack_job_credential(msg->credentials, buffer);
+	slurm_cred_pack(msg->cred, buffer);
 #ifdef HAVE_LIBELAN3
 	qsw_pack_jobinfo(msg->qsw_job, buffer);
 #endif
@@ -938,7 +939,7 @@ static int
 	} else
 		tmp_ptr->node_addr = NULL;
 
-	if (unpack_job_credential(&tmp_ptr->credentials, buffer))
+	if (!(tmp_ptr->cred = slurm_cred_unpack(buffer)))
 		goto unpack_error;
 #ifdef HAVE_LIBELAN3
 	qsw_alloc_jobinfo(&tmp_ptr->qsw_job);
@@ -1157,8 +1158,6 @@ _pack_revoke_credential_msg(revoke_credential_msg_t * msg, Buf buffer)
 	pack32(msg->job_id,  buffer);
 	pack32(msg->job_uid, buffer);
 	pack_time(msg->expiration_time, buffer);
-	packmem_array(msg->signature,
-		      (uint32_t) SLURM_SSL_SIGNATURE_LENGTH, buffer);
 }
 
 static int
@@ -1168,14 +1167,12 @@ _unpack_revoke_credential_msg(revoke_credential_msg_t ** msg, Buf buffer)
 
 	/* alloc memory for structure */
 	assert(msg);
-	tmp_ptr = xmalloc(sizeof(slurm_job_credential_t));
+	tmp_ptr = xmalloc(sizeof(*tmp_ptr));
 	*msg = tmp_ptr;
 
 	safe_unpack32(&(tmp_ptr->job_id),  buffer);
 	safe_unpack32(&(tmp_ptr->job_uid), buffer);
 	safe_unpack_time(& (tmp_ptr->expiration_time), buffer);
-	safe_unpackmem_array(tmp_ptr->signature,
-			     (uint32_t) SLURM_SSL_SIGNATURE_LENGTH, buffer);
 
 	return SLURM_SUCCESS;
 
@@ -1214,58 +1211,6 @@ _unpack_update_job_time_msg(job_time_msg_t ** msg, Buf buffer)
 	return SLURM_ERROR;
 }
 
-/* pack_job_credential
- * packs a slurm job credential
- * IN cred - pointer to the credential
- * IN/OUT buffer - destination of the pack, contains pointers that are 
- *			automatically updated
- */
-void
-pack_job_credential(slurm_job_credential_t * cred, Buf buffer)
-{
-	assert(cred != NULL);
-
-	pack32(cred->job_id, buffer);
-	pack16((uint16_t) cred->user_id, buffer);
-	packstr(cred->node_list, buffer);
-	pack_time(cred->expiration_time, buffer);
-	packmem_array(cred->signature,
-		      (uint32_t) SLURM_SSL_SIGNATURE_LENGTH, buffer);
-}
-
-/* unpack_job_credential
- * unpacks a slurm job credential
- * OUT cred - pointer to the credential pointer
- * IN/OUT buffer - source of the unpack, contains pointers that are 
- *			automatically updated
- * RET 0 or error code
- */
-int
-unpack_job_credential(slurm_job_credential_t ** cred, Buf buffer)
-{
-	uint16_t uint16_tmp;
-	slurm_job_credential_t *tmp_ptr;
-
-	/* alloc memory for structure */
-	tmp_ptr = xmalloc(sizeof(slurm_job_credential_t));
-	*cred = tmp_ptr;
-
-	safe_unpack32(&(tmp_ptr->job_id), buffer);
-	safe_unpack16((uint16_t *) & (tmp_ptr->user_id), buffer);
-	safe_unpackstr_xmalloc(&(tmp_ptr->node_list), &uint16_tmp, buffer);
-	safe_unpack_time(&(tmp_ptr->expiration_time), buffer);
-	safe_unpackmem_array(tmp_ptr->signature,
-			     (uint32_t) SLURM_SSL_SIGNATURE_LENGTH, buffer);
-
-	return SLURM_SUCCESS;
-
-      unpack_error:
-	xfree(tmp_ptr->node_list);
-	xfree(tmp_ptr);
-	*cred = NULL;
-	return SLURM_ERROR;
-}
-
 static void
 _pack_job_step_create_response_msg(job_step_create_response_msg_t * msg,
 				   Buf buffer)
@@ -1274,7 +1219,7 @@ _pack_job_step_create_response_msg(job_step_create_response_msg_t * msg,
 
 	pack32(msg->job_step_id, buffer);
 	packstr(msg->node_list, buffer);
-	pack_job_credential(msg->credentials, buffer);
+	slurm_cred_pack(msg->cred, buffer);
 #ifdef HAVE_LIBELAN3
 	qsw_pack_jobinfo(msg->qsw_job, buffer);
 #endif
@@ -1295,7 +1240,7 @@ _unpack_job_step_create_response_msg(job_step_create_response_msg_t ** msg,
 
 	safe_unpack32(&tmp_ptr->job_step_id, buffer);
 	safe_unpackstr_xmalloc(&tmp_ptr->node_list, &uint16_tmp, buffer);
-	if (unpack_job_credential(&tmp_ptr->credentials, buffer))
+	if (!(tmp_ptr->cred = slurm_cred_unpack(buffer)))
 		goto unpack_error;
 
 #ifdef HAVE_LIBELAN3
@@ -2061,7 +2006,7 @@ _pack_launch_tasks_request_msg(launch_tasks_request_msg_t * msg, Buf buffer)
 	pack32(msg->nprocs, buffer);
 	pack32(msg->uid, buffer);
 	pack32(msg->srun_node_id, buffer);
-	pack_job_credential(msg->credential, buffer);
+	slurm_cred_pack(msg->cred, buffer);
 	pack32(msg->tasks_to_launch, buffer);
 	packstr_array(msg->env, msg->envc, buffer);
 	packstr(msg->cwd, buffer);
@@ -2097,7 +2042,7 @@ _unpack_launch_tasks_request_msg(launch_tasks_request_msg_t **
 	safe_unpack32(&msg->nprocs, buffer);
 	safe_unpack32(&msg->uid, buffer);
 	safe_unpack32(&msg->srun_node_id, buffer);
-	if (unpack_job_credential(&msg->credential, buffer))
+	if (!(msg->cred = slurm_cred_unpack(buffer)))
 		goto unpack_error;
 	safe_unpack32(&msg->tasks_to_launch, buffer);
 	safe_unpackstr_array(&msg->env, &msg->envc, buffer);
diff --git a/src/common/slurm_protocol_pack.h b/src/common/slurm_protocol_pack.h
index 1a76d1bc4d35b104d2c590efa10f36986deffc6a..d8d7f9ccd77359e0aa60fb5271b45e5941da6634 100644
--- a/src/common/slurm_protocol_pack.h
+++ b/src/common/slurm_protocol_pack.h
@@ -125,7 +125,7 @@ extern int unpack_msg ( slurm_msg_t * msgi , Buf buffer );
  * IN/OUT buffer - destination of the pack, contains pointers that are 
  *			automatically updated
  */
-void pack_job_credential ( slurm_job_credential_t* cred , Buf buffer ) ;
+/* void pack_job_credential ( slurm_job_credential_t* cred , Buf buffer ) ;*/
 
 /* unpack_job_credential
  * unpacks a slurm job credential
@@ -134,7 +134,7 @@ void pack_job_credential ( slurm_job_credential_t* cred , Buf buffer ) ;
  *			automatically updated
  * RET 0 or error code
  */
-int unpack_job_credential( slurm_job_credential_t** cred , Buf buffer ) ;
+/* int unpack_job_credential( slurm_job_credential_t** cred , Buf buffer ) ;*/
 
 /* pack_job_step_info
  * packs a slurm job steps info
diff --git a/src/common/slurm_protocol_util.c b/src/common/slurm_protocol_util.c
index c7f78673905f3e8e87861ab5dda23e8a19bcc948..c6a4040c2a8a9d58aa30616df6fe6dd5bca311dc 100644
--- a/src/common/slurm_protocol_util.c
+++ b/src/common/slurm_protocol_util.c
@@ -239,16 +239,6 @@ int write_io_stream_header2(slurm_io_stream_header_t * header, slurm_fd fd)
 	return SLURM_SUCCESS;
 }
 
-/* log the supplied slurm credential as debug3() level */
-void slurm_print_job_credential(slurm_job_credential_t * credential)
-{
-	debug3("credential.job_id: %i", credential->job_id);
-	debug3("credential.user_id: %i", credential->user_id);
-	debug3("credential.node_list: %s", credential->node_list);
-	debug3("credential.expiration_time: %lu",
-	       credential->expiration_time);
-	debug3("credential.signature: %#x", credential->signature);
-}
 
 /* log the supplied slurm task launch message as debug3() level */
 void slurm_print_launch_task_msg(launch_tasks_request_msg_t * msg)
@@ -258,7 +248,6 @@ void slurm_print_launch_task_msg(launch_tasks_request_msg_t * msg)
 	debug3("job_id: %i", msg->job_id);
 	debug3("job_step_id: %i", msg->job_step_id);
 	debug3("uid: %i", msg->uid);
-	slurm_print_job_credential(msg->credential);
 	debug3("tasks_to_launch: %i", msg->tasks_to_launch);
 	debug3("envc: %i", msg->envc);
 	for (i = 0; i < msg->envc; i++) {
diff --git a/src/common/slurm_protocol_util.h b/src/common/slurm_protocol_util.h
index 8150009e23d071c9be40aceb39c58bf81136a660..2b22c10520c20778173079538303d7f305525169 100644
--- a/src/common/slurm_protocol_util.h
+++ b/src/common/slurm_protocol_util.h
@@ -122,7 +122,7 @@ extern int read_io_stream_header2(slurm_io_stream_header_t * header, slurm_fd fd
 extern int write_io_stream_header(slurm_io_stream_header_t * header, slurm_fd fd);
 
 /* log the supplied slurm credential as debug3() level */
-extern void slurm_print_job_credential(slurm_job_credential_t * credential);
+/* extern void slurm_print_job_credential(slurm_job_credential_t * credential);*/
 
 /*
  * write an i/o stream header to the supplied slurm stream