Beispiel #1
0
CURLcode Curl_krb_kauth(struct connectdata *conn)
{
  des_cblock key;
  des_key_schedule schedule;
  KTEXT_ST tkt, tktcopy;
  char *name;
  char *p;
  char passwd[100];
  size_t tmp;
  ssize_t nread;
  int save;
  CURLcode result;
  unsigned char *ptr;

  save = Curl_set_command_prot(conn, prot_private);

  result = Curl_ftpsendf(conn, "SITE KAUTH %s", conn->user);

  if(result)
    return result;

  result = Curl_GetFTPResponse(&nread, conn, NULL);
  if(result)
    return result;

  if(conn->data->state.buffer[0] != '3'){
    Curl_set_command_prot(conn, save);
    return CURLE_FTP_WEIRD_SERVER_REPLY;
  }

  p = strstr(conn->data->state.buffer, "T=");
  if(!p) {
    Curl_failf(conn->data, "Bad reply from server");
    Curl_set_command_prot(conn, save);
    return CURLE_FTP_WEIRD_SERVER_REPLY;
  }

  p += 2;
  tmp = Curl_base64_decode(p, &ptr);
  if(tmp >= sizeof(tkt.dat)) {
    free(ptr);
    tmp=0;
  }
  if(!tmp || !ptr) {
    Curl_failf(conn->data, "Failed to decode base64 in reply");
    Curl_set_command_prot(conn, save);
    return CURLE_FTP_WEIRD_SERVER_REPLY;
  }
  memcpy((char *)tkt.dat, ptr, tmp);
  free(ptr);
  tkt.length = tmp;
  tktcopy.length = tkt.length;

  p = strstr(conn->data->state.buffer, "P=");
  if(!p) {
    Curl_failf(conn->data, "Bad reply from server");
    Curl_set_command_prot(conn, save);
    return CURLE_FTP_WEIRD_SERVER_REPLY;
  }
  name = p + 2;
  for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
  *p = 0;

  des_string_to_key (conn->passwd, &key);
  des_key_sched(&key, schedule);

  des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
                   tkt.length,
                   schedule, &key, DES_DECRYPT);
  if(strcmp ((char*)tktcopy.dat + 8,
              KRB_TICKET_GRANTING_TICKET) != 0) {
    afs_string_to_key(passwd,
                      krb_realmofhost(conn->host.name),
                      &key);
    des_key_sched(&key, schedule);
    des_pcbc_encrypt((void *)tkt.dat, (void *)tktcopy.dat,
                     tkt.length,
                     schedule, &key, DES_DECRYPT);
  }
  memset(key, 0, sizeof(key));
  memset(schedule, 0, sizeof(schedule));
  memset(passwd, 0, sizeof(passwd));
  if(Curl_base64_encode(conn->data, (char *)tktcopy.dat, tktcopy.length, &p)
     < 1) {
    failf(conn->data, "Out of memory base64-encoding.");
    Curl_set_command_prot(conn, save);
    return CURLE_OUT_OF_MEMORY;
  }
  memset (tktcopy.dat, 0, tktcopy.length);

  result = Curl_ftpsendf(conn, "SITE KAUTH %s %s", name, p);
  free(p);
  if(result)
    return result;

  result = Curl_GetFTPResponse(&nread, conn, NULL);
  if(result)
    return result;
  Curl_set_command_prot(conn, save);

  return CURLE_OK;
}
Beispiel #2
0
void
kerberos4_is(Authenticator *ap, unsigned char *data, int cnt)
{
    struct sockaddr_in addr;
    char realm[REALM_SZ];
    char instance[INST_SZ];
    int r;
    int addr_len;

    if (cnt-- < 1)
	return;
    switch (*data++) {
    case KRB_AUTH:
	if (krb_get_lrealm(realm, 1) != KSUCCESS) {
	    Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1);
	    auth_finished(ap, AUTH_REJECT);
	    if (auth_debug_mode)
		printf("No local realm\r\n");
	    return;
	}
	memmove(auth.dat, data, auth.length = cnt);
	if (auth_debug_mode) {
	    printf("Got %d bytes of authentication data\r\n", cnt);
	    printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
	    printd(auth.dat, auth.length);
	    printf("\r\n");
	}
	k_getsockinst(0, instance, sizeof(instance));
	addr_len = sizeof(addr);
	if(getpeername(0, (struct sockaddr *)&addr, &addr_len) < 0) {
	    if(auth_debug_mode)
		printf("getpeername failed\r\n");
	    Data(ap, KRB_REJECT, "getpeername failed", -1);
	    auth_finished(ap, AUTH_REJECT);
	    return;
	}
	r = krb_rd_req(&auth, KRB_SERVICE_NAME,
		       instance, addr.sin_addr.s_addr, &adat, "");
	if (r) {
	    if (auth_debug_mode)
		printf("Kerberos failed him as %s\r\n", name);
	    Data(ap, KRB_REJECT, (void *)krb_get_err_text(r), -1);
	    auth_finished(ap, AUTH_REJECT);
	    return;
	}
	/* save the session key */
	memmove(session_key, adat.session, sizeof(adat.session));
	krb_kntoln(&adat, name);

	if (UserNameRequested && !kuserok(&adat, UserNameRequested)){
	    char ts[MAXPATHLEN];
	    struct passwd *pw = getpwnam(UserNameRequested);

	    if(pw){
		snprintf(ts, sizeof(ts),
			 "%s%u",
			 TKT_ROOT,
			 (unsigned)pw->pw_uid);
		setenv("KRBTKFILE", ts, 1);
	    }
	    Data(ap, KRB_ACCEPT, NULL, 0);
	} else {
	    char *msg;

	    asprintf (&msg, "user `%s' is not authorized to "
		      "login as `%s'", 
		      krb_unparse_name_long(adat.pname, 
					    adat.pinst, 
					    adat.prealm), 
		      UserNameRequested ? UserNameRequested : "<nobody>");
	    if (msg == NULL)
		Data(ap, KRB_REJECT, NULL, 0);
	    else {
		Data(ap, KRB_REJECT, (void *)msg, -1);
		free(msg);
	    }
	}
	auth_finished(ap, AUTH_USER);
	break;
	
    case KRB_CHALLENGE:
#ifndef ENCRYPTION
	Data(ap, KRB_RESPONSE, NULL, 0);
#else
	if(!VALIDKEY(session_key)){
	    Data(ap, KRB_RESPONSE, NULL, 0);
	    break;
	}
	des_key_sched(&session_key, sched);
	{
	    des_cblock d_block;
	    int i;
	    Session_Key skey;

	    memmove(d_block, data, sizeof(d_block));

	    /* make a session key for encryption */
	    des_ecb_encrypt(&d_block, &session_key, sched, 1);
	    skey.type=SK_DES;
	    skey.length=8;
	    skey.data=session_key;
	    encrypt_session_key(&skey, 1);

	    /* decrypt challenge, add one and encrypt it */
	    des_ecb_encrypt(&d_block, &challenge, sched, 0);
	    for (i = 7; i >= 0; i--)
		if(++challenge[i] != 0)
		    break;
	    des_ecb_encrypt(&challenge, &challenge, sched, 1);
	    Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge));
	}
#endif
	break;

    case KRB_FORWARD:
	{
	    des_key_schedule ks;
	    unsigned char netcred[sizeof(CREDENTIALS)];
	    CREDENTIALS cred;
	    int ret;
	    if(cnt > sizeof(cred))
		abort();

	    des_set_key(&session_key, ks);
	    des_pcbc_encrypt((void*)data, (void*)netcred, cnt, 
			     ks, &session_key, DES_DECRYPT);
	    unpack_cred(netcred, cnt, &cred);
	    {
		if(strcmp(cred.service, KRB_TICKET_GRANTING_TICKET) ||
		   strncmp(cred.instance, cred.realm, sizeof(cred.instance)) ||
		   cred.lifetime < 0 || cred.lifetime > 255 ||
		   cred.kvno < 0 || cred.kvno > 255 ||
		   cred.issue_date < 0 || 
		   cred.issue_date > time(0) + CLOCK_SKEW ||
		   strncmp(cred.pname, adat.pname, sizeof(cred.pname)) ||
		   strncmp(cred.pinst, adat.pinst, sizeof(cred.pname))){
		    Data(ap, KRB_FORWARD_REJECT, "Bad credentials", -1);
		}else{
		    if((ret = tf_setup(&cred,
				       cred.pname,
				       cred.pinst)) == KSUCCESS){
		        struct passwd *pw = getpwnam(UserNameRequested);

			if (pw)
			  chown(tkt_string(), pw->pw_uid, pw->pw_gid);
			Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
		    } else{
			Data(ap, KRB_FORWARD_REJECT, 
			     krb_get_err_text(ret), -1);
		    }
		}
	    }
	    memset(data, 0, cnt);
	    memset(ks, 0, sizeof(ks));
	    memset(&cred, 0, sizeof(cred));
	}
	
	break;

    default:
	if (auth_debug_mode)
	    printf("Unknown Kerberos option %d\r\n", data[-1]);
	Data(ap, KRB_REJECT, 0, 0);
	break;
    }
}
Beispiel #3
0
static bool afs_createtoken(const char *username, const char *cell,
                            DATA_BLOB *ticket, struct ClearToken *ct)
{
    fstring clear_ticket;
    char *p = clear_ticket;
    uint32 len;
    uint32 now;

    struct afs_key key;
    des_key_schedule key_schedule;

    if (!secrets_init())
        return false;

    if (!secrets_fetch_afs_key(cell, &key)) {
        DEBUG(1, ("Could not fetch AFS service key\n"));
        return false;
    }

    ct->AuthHandle = key.kvno;

    /* Build the ticket. This is going to be encrypted, so in our
           way we fill in ct while we still have the unencrypted
           form. */

    p = clear_ticket;

    /* The byte-order */
    *p = 1;
    p += 1;

    /* "Alice", the client username */
    strncpy(p, username, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
    p += strlen(p)+1;
    strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
    p += strlen(p)+1;
    strncpy(p, cell, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
    p += strlen(p)+1;

    /* Alice's network layer address. At least Openafs-1.2.10
           ignores this, so we fill in a dummy value here. */
    SIVAL(p, 0, 0);
    p += 4;

    /* We need to create a session key */
    generate_random_buffer((uint8_t *)p, 8);

    /* Our client code needs the the key in the clear, it does not
           know the server-key ... */
    memcpy(ct->HandShakeKey, p, 8);

    p += 8;

    /* This is a kerberos 4 life time. The life time is expressed
     * in units of 5 minute intervals up to 38400 seconds, after
     * that a table is used up to lifetime 0xBF. Values between
     * 0xC0 and 0xFF is undefined. 0xFF is defined to be the
     * infinite time that never expire.
     *
     * So here we cheat and use the infinite time */
    *p = 255;
    p += 1;

    /* Ticket creation time */
    now = time(NULL);
    SIVAL(p, 0, now);
    ct->BeginTimestamp = now;

    if(lp_afs_token_lifetime() == 0)
        ct->EndTimestamp = NEVERDATE;
    else
        ct->EndTimestamp = now + lp_afs_token_lifetime();

    if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
        ct->BeginTimestamp += 1; /* Lifetime must be even */
    }
    p += 4;

    /* And here comes Bob's name and instance, in this case the
           AFS server. */
    strncpy(p, "afs", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
    p += strlen(p)+1;
    strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
    p += strlen(p)+1;

    /* And zero-pad to a multiple of 8 bytes */
    len = PTR_DIFF(p, clear_ticket);
    if (len & 7) {
        uint32 extra_space = 8-(len & 7);
        memset(p, 0, extra_space);
        p+=extra_space;
    }
    len = PTR_DIFF(p, clear_ticket);

    des_key_sched((const_des_cblock *)key.key, key_schedule);
    des_pcbc_encrypt((const unsigned char*) clear_ticket,
                     (unsigned char*) clear_ticket,
                     len, key_schedule, (C_Block *)key.key, 1);

    ZERO_STRUCT(key);

    *ticket = data_blob(clear_ticket, len);

    return true;
}
Beispiel #4
0
static BOOL afs_createtoken(const char *username, const char *cell,
			    DATA_BLOB *ticket, struct ClearToken *ct)
{
	fstring clear_ticket;
	char *p = clear_ticket;
	uint32 len;
	uint32 now;

	struct afs_key key;
	des_key_schedule key_schedule;

	if (!secrets_init()) 
		return False;

	if (!secrets_fetch_afs_key(cell, &key)) {
		DEBUG(1, ("Could not fetch AFS service key\n"));
		return False;
	}

	ct->AuthHandle = key.kvno;

	/* Build the ticket. This is going to be encrypted, so in our
           way we fill in ct while we still have the unencrypted
           form. */

	p = clear_ticket;

	/* The byte-order */
	*p = 1;
	p += 1;

	/* "Alice", the client username */
	strncpy(p, username, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;
	strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;
	strncpy(p, cell, sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;

	/* Alice's network layer address. At least Openafs-1.2.10
           ignores this, so we fill in a dummy value here. */
	SIVAL(p, 0, 0);
	p += 4;

	/* We need to create a session key */
	generate_random_buffer(p, 8, False);

	/* Our client code needs the the key in the clear, it does not
           know the server-key ... */
	memcpy(ct->HandShakeKey, p, 8);

	p += 8;

	/* Ticket lifetime. We fake everything here, so go as long as
	   possible. This is in 5-minute intervals, so 255 is 21 hours
	   and 15 minutes.*/
	*p = 255;
	p += 1;

	/* Ticket creation time */
	now = time(NULL);
	SIVAL(p, 0, now);
	ct->BeginTimestamp = now;

	ct->EndTimestamp = now + (255*60*5);
	if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
		ct->BeginTimestamp += 1; /* Lifetime must be even */
	}
	p += 4;

	/* And here comes Bob's name and instance, in this case the
           AFS server. */
	strncpy(p, "afs", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;
	strncpy(p, "", sizeof(clear_ticket)-PTR_DIFF(p,clear_ticket)-1);
	p += strlen(p)+1;

	/* And zero-pad to a multiple of 8 bytes */
	len = PTR_DIFF(p, clear_ticket);
	if (len & 7) {
		uint32 extra_space = 8-(len & 7);
		memset(p, 0, extra_space);
		p+=extra_space;
	}
	len = PTR_DIFF(p, clear_ticket);

	des_key_sched((const_des_cblock *)key.key, key_schedule);
	des_pcbc_encrypt(clear_ticket, clear_ticket,
			 len, key_schedule, (C_Block *)key.key, 1);

	ZERO_STRUCT(key);

	*ticket = data_blob(clear_ticket, len);

	return True;
}
Beispiel #5
0
void
kauth(int argc, char **argv)
{
    int ret;
    char buf[1024];
    des_cblock key;
    des_key_schedule schedule;
    KTEXT_ST tkt, tktcopy;
    char *name;
    char *p;
    int overbose;
    char passwd[100];
    int tmp;
	
    int save;

    if(argc > 2){
	printf("usage: %s [principal]\n", argv[0]);
	code = -1;
	return;
    }
    if(argc == 2)
	name = argv[1];
    else
	name = username;

    overbose = verbose;
    verbose = 0;

    save = set_command_prot(prot_private);
    ret = command("SITE KAUTH %s", name);
    if(ret != CONTINUE){
	verbose = overbose;
	set_command_prot(save);
	code = -1;
	return;
    }
    verbose = overbose;
    p = strstr(reply_string, "T=");
    if(!p){
	printf("Bad reply from server.\n");
	set_command_prot(save);
	code = -1;
	return;
    }
    p += 2;
    tmp = base64_decode(p, &tkt.dat);
    if(tmp < 0){
	printf("Failed to decode base64 in reply.\n");
	set_command_prot(save);
	code = -1;
	return;
    }
    tkt.length = tmp;
    tktcopy.length = tkt.length;
    
    p = strstr(reply_string, "P=");
    if(!p){
	printf("Bad reply from server.\n");
	verbose = overbose;
	set_command_prot(save);
	code = -1;
	return;
    }
    name = p + 2;
    for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
    *p = 0;
    
    snprintf(buf, sizeof(buf), "Password for %s:", name);
    if (des_read_pw_string (passwd, sizeof(passwd)-1, buf, 0))
        *passwd = '\0';
    des_string_to_key (passwd, &key);

    des_key_sched(&key, schedule);
    
    des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
		     tkt.length,
		     schedule, &key, DES_DECRYPT);
    if (strcmp ((char*)tktcopy.dat + 8,
		KRB_TICKET_GRANTING_TICKET) != 0) {
        afs_string_to_key (passwd, krb_realmofhost(hostname), &key);
	des_key_sched (&key, schedule);
	des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
			 tkt.length,
			 schedule, &key, DES_DECRYPT);
    }
    memset(key, 0, sizeof(key));
    memset(schedule, 0, sizeof(schedule));
    memset(passwd, 0, sizeof(passwd));
    if(base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) {
	printf("Out of memory base64-encoding.\n");
	set_command_prot(save);
	code = -1;
	return;
    }
    memset (tktcopy.dat, 0, tktcopy.length);
    ret = command("SITE KAUTH %s %s", name, p);
    free(p);
    set_command_prot(save);
    if(ret != COMPLETE){
	code = -1;
	return;
    }
    code = 0;
}
Beispiel #6
0
int des_enc_read(int fd, void *buf, int len, des_key_schedule sched,
		 des_cblock *iv)
	{
	/* data to be unencrypted */
	int net_num=0;
	static unsigned char *net=NULL;
	/* extra unencrypted data 
	 * for when a block of 100 comes in but is des_read one byte at
	 * a time. */
	static unsigned char *unnet=NULL;
	static int unnet_start=0;
	static int unnet_left=0;
	static unsigned char *tmpbuf=NULL;
	int i;
	long num=0,rnum;
	unsigned char *p;

	if (tmpbuf == NULL)
		{
		tmpbuf=OPENSSL_malloc(BSIZE);
		if (tmpbuf == NULL) return(-1);
		}
	if (net == NULL)
		{
		net=OPENSSL_malloc(BSIZE);
		if (net == NULL) return(-1);
		}
	if (unnet == NULL)
		{
		unnet=OPENSSL_malloc(BSIZE);
		if (unnet == NULL) return(-1);
		}
	/* left over data from last decrypt */
	if (unnet_left != 0)
		{
		if (unnet_left < len)
			{
			/* we still still need more data but will return
			 * with the number of bytes we have - should always
			 * check the return value */
			memcpy(buf,&(unnet[unnet_start]),
			       unnet_left);
			/* eay 26/08/92 I had the next 2 lines
			 * reversed :-( */
			i=unnet_left;
			unnet_start=unnet_left=0;
			}
		else
			{
			memcpy(buf,&(unnet[unnet_start]),len);
			unnet_start+=len;
			unnet_left-=len;
			i=len;
			}
		return(i);
		}

	/* We need to get more data. */
	if (len > MAXWRITE) len=MAXWRITE;

	/* first - get the length */
	while (net_num < HDRSIZE) 
		{
		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
#ifdef EINTR
		if ((i == -1) && (errno == EINTR)) continue;
#endif
		if (i <= 0) return(0);
		net_num+=i;
		}

	/* we now have at net_num bytes in net */
	p=net;
	/* num=0;  */
	n2l(p,num);
	/* num should be rounded up to the next group of eight
	 * we make sure that we have read a multiple of 8 bytes from the net.
	 */
	if ((num > MAXWRITE) || (num < 0)) /* error */
		return(-1);
	rnum=(num < 8)?8:((num+7)/8*8);

	net_num=0;
	while (net_num < rnum)
		{
		i=read(fd,(void *)&(net[net_num]),rnum-net_num);
#ifdef EINTR
		if ((i == -1) && (errno == EINTR)) continue;
#endif
		if (i <= 0) return(0);
		net_num+=i;
		}

	/* Check if there will be data left over. */
	if (len < num)
		{
		if (des_rw_mode & DES_PCBC_MODE)
			des_pcbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
		else
			des_cbc_encrypt(net,unnet,num,sched,iv,DES_DECRYPT);
		memcpy(buf,unnet,len);
		unnet_start=len;
		unnet_left=num-len;

		/* The following line is done because we return num
		 * as the number of bytes read. */
		num=len;
		}
	else
		{
		/* >output is a multiple of 8 byes, if len < rnum
		 * >we must be careful.  The user must be aware that this
		 * >routine will write more bytes than he asked for.
		 * >The length of the buffer must be correct.
		 * FIXED - Should be ok now 18-9-90 - eay */
		if (len < rnum)
			{

			if (des_rw_mode & DES_PCBC_MODE)
				des_pcbc_encrypt(net,tmpbuf,num,sched,iv,
						 DES_DECRYPT);
			else
				des_cbc_encrypt(net,tmpbuf,num,sched,iv,
						DES_DECRYPT);

			/* eay 26/08/92 fix a bug that returned more
			 * bytes than you asked for (returned len bytes :-( */
			memcpy(buf,tmpbuf,num);
			}
		else
			{
			if (des_rw_mode & DES_PCBC_MODE)
				des_pcbc_encrypt(net,buf,num,sched,iv,
						 DES_DECRYPT);
			else
				des_cbc_encrypt(net,buf,num,sched,iv,
						DES_DECRYPT);
			}
		}
	return num;
	}
Beispiel #7
0
int main(int argc, char *argv[])
	{
	int j,err=0;
	unsigned int i;
	des_cblock in,out,outin,iv3,iv2;
	des_key_schedule ks,ks2,ks3;
	unsigned char cbc_in[40];
	unsigned char cbc_out[40];
	DES_LONG cs;
	unsigned char cret[8];
#ifdef _CRAY
        struct {
            int a:32;
            int b:32;
        } lqret[2];
#else
        DES_LONG lqret[4];
#endif
	int num;
	char *str;

#ifndef OPENSSL_NO_DESCBCM
	TINYCLR_SSL_PRINTF("Doing cbcm\n");
	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	TINYCLR_SSL_MEMSET(cbc_out,0,40);
	TINYCLR_SSL_MEMSET(cbc_in,0,40);
	i=TINYCLR_SSL_STRLEN((char *)cbc_data)+1;
	/* i=((i+7)/8)*8; */
	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	TINYCLR_SSL_MEMSET(iv2,'\0',sizeof iv2);

	DES_ede3_cbcm_encrypt(cbc_data,cbc_out,16L,&ks,&ks2,&ks3,&iv3,&iv2,
			      DES_ENCRYPT);
	DES_ede3_cbcm_encrypt(&cbc_data[16],&cbc_out[16],i-16,&ks,&ks2,&ks3,
			      &iv3,&iv2,DES_ENCRYPT);
	/*	if (memcmp(cbc_out,cbc3_ok,
		(unsigned int)(TINYCLR_SSL_STRLEN((char *)cbc_data)+1+7)/8*8) != 0)
		{
		TINYCLR_SSL_PRINTF("des_ede3_cbc_encrypt encrypt error\n");
		err=1;
		}
	*/
	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	TINYCLR_SSL_MEMSET(iv2,'\0',sizeof iv2);
	DES_ede3_cbcm_encrypt(cbc_out,cbc_in,i,&ks,&ks2,&ks3,&iv3,&iv2,DES_DECRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0)
		{
		unsigned int n;

		TINYCLR_SSL_PRINTF("des_ede3_cbcm_encrypt decrypt error\n");
		for(n=0 ; n < i ; ++n)
		    TINYCLR_SSL_PRINTF(" %02x",cbc_data[n]);
		TINYCLR_SSL_PRINTF("\n");
		for(n=0 ; n < i ; ++n)
		    TINYCLR_SSL_PRINTF(" %02x",cbc_in[n]);
		TINYCLR_SSL_PRINTF("\n");
		err=1;
		}
#endif

	TINYCLR_SSL_PRINTF("Doing ecb\n");
	for (i=0; i<NUM_TESTS; i++)
		{
		DES_set_key_unchecked(&key_data[i],&ks);
		TINYCLR_SSL_MEMCPY(in,plain_data[i],8);
		TINYCLR_SSL_MEMSET(out,0,8);
		TINYCLR_SSL_MEMSET(outin,0,8);
		des_ecb_encrypt(&in,&out,ks,DES_ENCRYPT);
		des_ecb_encrypt(&out,&outin,ks,DES_DECRYPT);

		if (TINYCLR_SSL_MEMCMP(out,cipher_data[i],8) != 0)
			{
			TINYCLR_SSL_PRINTF("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
				pt(out));
			err=1;
			}
		if (TINYCLR_SSL_MEMCMP(in,outin,8) != 0)
			{
			TINYCLR_SSL_PRINTF("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
			err=1;
			}
		}

#ifndef LIBDES_LIT
	TINYCLR_SSL_PRINTF("Doing ede ecb\n");
	for (i=0; i<(NUM_TESTS-2); i++)
		{
		DES_set_key_unchecked(&key_data[i],&ks);
		DES_set_key_unchecked(&key_data[i+1],&ks2);
		DES_set_key_unchecked(&key_data[i+2],&ks3);
		TINYCLR_SSL_MEMCPY(in,plain_data[i],8);
		TINYCLR_SSL_MEMSET(out,0,8);
		TINYCLR_SSL_MEMSET(outin,0,8);
		des_ecb2_encrypt(&in,&out,ks,ks2,DES_ENCRYPT);
		des_ecb2_encrypt(&out,&outin,ks,ks2,DES_DECRYPT);

		if (TINYCLR_SSL_MEMCMP(out,cipher_ecb2[i],8) != 0)
			{
			TINYCLR_SSL_PRINTF("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
				pt(out));
			err=1;
			}
		if (TINYCLR_SSL_MEMCMP(in,outin,8) != 0)
			{
			TINYCLR_SSL_PRINTF("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
				i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
			err=1;
			}
		}
#endif

	TINYCLR_SSL_PRINTF("Doing cbc\n");
	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	TINYCLR_SSL_MEMSET(cbc_out,0,40);
	TINYCLR_SSL_MEMSET(cbc_in,0,40);
	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_data,cbc_out,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
			 &iv3,DES_ENCRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_out,cbc_ok,32) != 0)
		{
		TINYCLR_SSL_PRINTF("cbc_encrypt encrypt error\n");
		err=1;
		}

	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	des_ncbc_encrypt(cbc_out,cbc_in,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
			 &iv3,DES_DECRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)) != 0)
		{
		TINYCLR_SSL_PRINTF("cbc_encrypt decrypt error\n");
		err=1;
		}

#ifndef LIBDES_LIT
	TINYCLR_SSL_PRINTF("Doing desx cbc\n");
	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	TINYCLR_SSL_MEMSET(cbc_out,0,40);
	TINYCLR_SSL_MEMSET(cbc_in,0,40);
	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt(cbc_data,cbc_out,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
			 &iv3,&cbc2_key,&cbc3_key, DES_ENCRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_out,xcbc_ok,32) != 0)
		{
		TINYCLR_SSL_PRINTF("des_xcbc_encrypt encrypt error\n");
		err=1;
		}
	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	des_xcbc_encrypt(cbc_out,cbc_in,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
			 &iv3,&cbc2_key,&cbc3_key, DES_DECRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0)
		{
		TINYCLR_SSL_PRINTF("des_xcbc_encrypt decrypt error\n");
		err=1;
		}
#endif

	TINYCLR_SSL_PRINTF("Doing ede cbc\n");
	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	if ((j=DES_set_key_checked(&cbc2_key,&ks2)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	if ((j=DES_set_key_checked(&cbc3_key,&ks3)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	TINYCLR_SSL_MEMSET(cbc_out,0,40);
	TINYCLR_SSL_MEMSET(cbc_in,0,40);
	i=TINYCLR_SSL_STRLEN((char *)cbc_data)+1;
	/* i=((i+7)/8)*8; */
	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));

	des_ede3_cbc_encrypt(cbc_data,cbc_out,16L,ks,ks2,ks3,&iv3,
			     DES_ENCRYPT);
	des_ede3_cbc_encrypt(&(cbc_data[16]),&(cbc_out[16]),i-16,ks,ks2,ks3,
			     &iv3,DES_ENCRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_out,cbc3_ok,
		(unsigned int)(TINYCLR_SSL_STRLEN((char *)cbc_data)+1+7)/8*8) != 0)
		{
		unsigned int n;

		TINYCLR_SSL_PRINTF("des_ede3_cbc_encrypt encrypt error\n");
		for(n=0 ; n < i ; ++n)
		    TINYCLR_SSL_PRINTF(" %02x",cbc_out[n]);
		TINYCLR_SSL_PRINTF("\n");
		for(n=0 ; n < i ; ++n)
		    TINYCLR_SSL_PRINTF(" %02x",cbc3_ok[n]);
		TINYCLR_SSL_PRINTF("\n");
		err=1;
		}

	TINYCLR_SSL_MEMCPY(iv3,cbc_iv,sizeof(cbc_iv));
	des_ede3_cbc_encrypt(cbc_out,cbc_in,i,ks,ks2,ks3,&iv3,DES_DECRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0)
		{
		unsigned int n;

		TINYCLR_SSL_PRINTF("des_ede3_cbc_encrypt decrypt error\n");
		for(n=0 ; n < i ; ++n)
		    TINYCLR_SSL_PRINTF(" %02x",cbc_data[n]);
		TINYCLR_SSL_PRINTF("\n");
		for(n=0 ; n < i ; ++n)
		    TINYCLR_SSL_PRINTF(" %02x",cbc_in[n]);
		TINYCLR_SSL_PRINTF("\n");
		err=1;
		}

#ifndef LIBDES_LIT
	TINYCLR_SSL_PRINTF("Doing pcbc\n");
	if ((j=DES_set_key_checked(&cbc_key,&ks)) != 0)
		{
		TINYCLR_SSL_PRINTF("Key error %d\n",j);
		err=1;
		}
	TINYCLR_SSL_MEMSET(cbc_out,0,40);
	TINYCLR_SSL_MEMSET(cbc_in,0,40);
	des_pcbc_encrypt(cbc_data,cbc_out,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
			 &cbc_iv,DES_ENCRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_out,pcbc_ok,32) != 0)
		{
		TINYCLR_SSL_PRINTF("pcbc_encrypt encrypt error\n");
		err=1;
		}
	des_pcbc_encrypt(cbc_out,cbc_in,TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,&cbc_iv,
			 DES_DECRYPT);
	if (TINYCLR_SSL_MEMCMP(cbc_in,cbc_data,TINYCLR_SSL_STRLEN((char *)cbc_data)+1) != 0)
		{
		TINYCLR_SSL_PRINTF("pcbc_encrypt decrypt error\n");
		err=1;
		}

	TINYCLR_SSL_PRINTF("Doing ");
	TINYCLR_SSL_PRINTF("cfb8 ");
	err+=cfb_test(8,cfb_cipher8);
	TINYCLR_SSL_PRINTF("cfb16 ");
	err+=cfb_test(16,cfb_cipher16);
	TINYCLR_SSL_PRINTF("cfb32 ");
	err+=cfb_test(32,cfb_cipher32);
	TINYCLR_SSL_PRINTF("cfb48 ");
	err+=cfb_test(48,cfb_cipher48);
	TINYCLR_SSL_PRINTF("cfb64 ");
	err+=cfb_test(64,cfb_cipher64);

	TINYCLR_SSL_PRINTF("cfb64() ");
	err+=cfb64_test(cfb_cipher64);

	TINYCLR_SSL_MEMCPY(cfb_tmp,cfb_iv,sizeof(cfb_iv));
	for (i=0; i<sizeof(plain); i++)
		des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
			8,1,ks,&cfb_tmp,DES_ENCRYPT);
	if (TINYCLR_SSL_MEMCMP(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
		{
		TINYCLR_SSL_PRINTF("cfb_encrypt small encrypt error\n");
		err=1;
		}

	TINYCLR_SSL_MEMCPY(cfb_tmp,cfb_iv,sizeof(cfb_iv));
	for (i=0; i<sizeof(plain); i++)
		des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
			8,1,ks,&cfb_tmp,DES_DECRYPT);
	if (TINYCLR_SSL_MEMCMP(plain,cfb_buf2,sizeof(plain)) != 0)
		{
		TINYCLR_SSL_PRINTF("cfb_encrypt small decrypt error\n");
		err=1;
		}

	TINYCLR_SSL_PRINTF("ede_cfb64() ");
	err+=ede_cfb64_test(cfb_cipher64);

	TINYCLR_SSL_PRINTF("done\n");

	TINYCLR_SSL_PRINTF("Doing ofb\n");
	DES_set_key_checked(&ofb_key,&ks);
	TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	des_ofb_encrypt(plain,ofb_buf1,64,sizeof(plain)/8,ks,&ofb_tmp);
	if (TINYCLR_SSL_MEMCMP(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		TINYCLR_SSL_PRINTF("ofb_encrypt encrypt error\n");
TINYCLR_SSL_PRINTF("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
TINYCLR_SSL_PRINTF("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
		err=1;
		}
	TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	des_ofb_encrypt(ofb_buf1,ofb_buf2,64,sizeof(ofb_buf1)/8,ks,&ofb_tmp);
	if (TINYCLR_SSL_MEMCMP(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		TINYCLR_SSL_PRINTF("ofb_encrypt decrypt error\n");
TINYCLR_SSL_PRINTF("%02X %02X %02X %02X %02X %02X %02X %02X\n",
ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
TINYCLR_SSL_PRINTF("%02X %02X %02X %02X %02X %02X %02X %02X\n",
plain[8+0], plain[8+1], plain[8+2], plain[8+3],
plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
		err=1;
		}

	TINYCLR_SSL_PRINTF("Doing ofb64\n");
	DES_set_key_checked(&ofb_key,&ks);
	TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	TINYCLR_SSL_MEMSET(ofb_buf1,0,sizeof(ofb_buf1));
	TINYCLR_SSL_MEMSET(ofb_buf2,0,sizeof(ofb_buf1));
	num=0;
	for (i=0; i<sizeof(plain); i++)
		{
		des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,&ofb_tmp,
				  &num);
		}
	if (TINYCLR_SSL_MEMCMP(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		TINYCLR_SSL_PRINTF("ofb64_encrypt encrypt error\n");
		err=1;
		}
	TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	num=0;
	des_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,&ofb_tmp,
			  &num);
	if (TINYCLR_SSL_MEMCMP(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		TINYCLR_SSL_PRINTF("ofb64_encrypt decrypt error\n");
		err=1;
		}

	TINYCLR_SSL_PRINTF("Doing ede_ofb64\n");
	DES_set_key_checked(&ofb_key,&ks);
	TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	TINYCLR_SSL_MEMSET(ofb_buf1,0,sizeof(ofb_buf1));
	TINYCLR_SSL_MEMSET(ofb_buf2,0,sizeof(ofb_buf1));
	num=0;
	for (i=0; i<sizeof(plain); i++)
		{
		des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,
				       ks,&ofb_tmp,&num);
		}
	if (TINYCLR_SSL_MEMCMP(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
		{
		TINYCLR_SSL_PRINTF("ede_ofb64_encrypt encrypt error\n");
		err=1;
		}
	TINYCLR_SSL_MEMCPY(ofb_tmp,ofb_iv,sizeof(ofb_iv));
	num=0;
	des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,sizeof(ofb_buf1),ks,ks,ks,
			       &ofb_tmp,&num);
	if (TINYCLR_SSL_MEMCMP(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
		{
		TINYCLR_SSL_PRINTF("ede_ofb64_encrypt decrypt error\n");
		err=1;
		}

	TINYCLR_SSL_PRINTF("Doing cbc_cksum\n");
	DES_set_key_checked(&cbc_key,&ks);
	cs=des_cbc_cksum(cbc_data,&cret,TINYCLR_SSL_STRLEN((char *)cbc_data),ks,&cbc_iv);
	if (cs != cbc_cksum_ret)
		{
		TINYCLR_SSL_PRINTF("bad return value (%08lX), should be %08lX\n",
			(unsigned long)cs,(unsigned long)cbc_cksum_ret);
		err=1;
		}
	if (TINYCLR_SSL_MEMCMP(cret,cbc_cksum_data,8) != 0)
		{
		TINYCLR_SSL_PRINTF("bad cbc_cksum block returned\n");
		err=1;
		}

	TINYCLR_SSL_PRINTF("Doing quad_cksum\n");
	cs=des_quad_cksum(cbc_data,(des_cblock *)lqret,
		(long)TINYCLR_SSL_STRLEN((char *)cbc_data),2,(des_cblock *)cbc_iv);
	if (cs != 0x70d7a63aL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, ret %08lx should be 70d7a63a\n",
			(unsigned long)cs);
		err=1;
		}
#ifdef _CRAY
	if (lqret[0].a != 0x327eba8dL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[0] %08lx is not %08lx\n",
			(unsigned long)lqret[0].a,0x327eba8dUL);
		err=1;
		}
	if (lqret[0].b != 0x201a49ccL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[1] %08lx is not %08lx\n",
			(unsigned long)lqret[0].b,0x201a49ccUL);
		err=1;
		}
	if (lqret[1].a != 0x70d7a63aL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[2] %08lx is not %08lx\n",
			(unsigned long)lqret[1].a,0x70d7a63aUL);
		err=1;
		}
	if (lqret[1].b != 0x501c2c26L)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[3] %08lx is not %08lx\n",
			(unsigned long)lqret[1].b,0x501c2c26UL);
		err=1;
		}
#else
	if (lqret[0] != 0x327eba8dL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[0] %08lx is not %08lx\n",
			(unsigned long)lqret[0],0x327eba8dUL);
		err=1;
		}
	if (lqret[1] != 0x201a49ccL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[1] %08lx is not %08lx\n",
			(unsigned long)lqret[1],0x201a49ccUL);
		err=1;
		}
	if (lqret[2] != 0x70d7a63aL)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[2] %08lx is not %08lx\n",
			(unsigned long)lqret[2],0x70d7a63aUL);
		err=1;
		}
	if (lqret[3] != 0x501c2c26L)
		{
		TINYCLR_SSL_PRINTF("quad_cksum error, out[3] %08lx is not %08lx\n",
			(unsigned long)lqret[3],0x501c2c26UL);
		err=1;
		}
#endif
#endif

	TINYCLR_SSL_PRINTF("input word alignment test");
	for (i=0; i<4; i++)
		{
		TINYCLR_SSL_PRINTF(" %d",i);
		des_ncbc_encrypt(&(cbc_out[i]),cbc_in,
				 TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
				 &cbc_iv,DES_ENCRYPT);
		}
	TINYCLR_SSL_PRINTF("\noutput word alignment test");
	for (i=0; i<4; i++)
		{
		TINYCLR_SSL_PRINTF(" %d",i);
		des_ncbc_encrypt(cbc_out,&(cbc_in[i]),
				 TINYCLR_SSL_STRLEN((char *)cbc_data)+1,ks,
				 &cbc_iv,DES_ENCRYPT);
		}
	TINYCLR_SSL_PRINTF("\n");
	TINYCLR_SSL_PRINTF("fast crypt test ");
	str=crypt("testing","ef");
	if (TINYCLR_SSL_STRCMP("efGnQx2725bI2",str) != 0)
		{
		TINYCLR_SSL_PRINTF("fast crypt error, %s should be efGnQx2725bI2\n",str);
		err=1;
		}
	str=crypt("bca76;23","yA");
	if (TINYCLR_SSL_STRCMP("yA1Rp/1hZXIJk",str) != 0)
		{
		TINYCLR_SSL_PRINTF("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
		err=1;
		}
#ifdef OPENSSL_SYS_NETWARE
    if (err) TINYCLR_SSL_PRINTF("ERROR: %d\n", err);
#endif
	TINYCLR_SSL_PRINTF("\n");
	return(err);
	}
Beispiel #8
0
int32_t
krb_rd_priv(void *in, u_int32_t in_length, 
	    struct des_ks_struct *schedule, des_cblock *key, 
	    struct sockaddr_in *sender, struct sockaddr_in *receiver, 
	    MSG_DAT *m_data)
{
    unsigned char *p = (unsigned char*)in;
    int little_endian;
    u_int32_t clen;
    struct timeval tv;
    u_int32_t src_addr;
    int delta_t;

    unsigned char pvno, type;

    pvno = *p++;
    if(pvno != KRB_PROT_VERSION)
	return RD_AP_VERSION;
    
    type = *p++;
    little_endian = type & 1;
    type &= ~1;

    p += krb_get_int(p, &clen, 4, little_endian);
    
    if(clen + 2 > in_length)
	return RD_AP_MODIFIED;

    des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, 
		     schedule, key, DES_DECRYPT);
    
    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
    if(m_data->app_length + 17 > in_length)
	return RD_AP_MODIFIED;

    m_data->app_data = p;
    p += m_data->app_length;
    
    m_data->time_5ms = *p++;

    p += krb_get_address(p, &src_addr);

    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
	return RD_AP_BADD;

    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);

    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
    
    gettimeofday(&tv, NULL);

    /* check the time integrity of the msg */
    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
    if (delta_t > CLOCK_SKEW)
	return RD_AP_TIME;
    if (krb_debug)
	krb_warning("delta_t = %d\n", (int) delta_t);

    /*
     * caller must check timestamps for proper order and
     * replays, since server might have multiple clients
     * each with its own timestamps and we don't assume
     * tightly synchronized clocks.
     */

    return KSUCCESS;
}