Esempio n. 1
1
/**
 * @ingroup SnmpParser
 * @brief SNMPv3 암호화된 PDU 를 복호화한다.
 * @param pszPacket			암호화된 PDU
 * @param iPacketLen		암호화된 PDU 길이
 * @param pszPassWord		private 비밀번호
 * @param pszEngineId		SNMPv3 engine ID
 * @param iEngineIdLen	SNMPv3 engine ID 길이
 * @param pszPrivParam	msgPrivacyParameter
 * @param iPrivParamLen msgPrivacyParameter 길이
 * @param strPlain			평문 PDU 저장 변수
 * @returns 성공하면 true 를 리턴하고 실패하면 false 를 리턴한다.
 */
bool SnmpDecrypt( const char * pszPacket, int iPacketLen, const char * pszPassWord, const char * pszEngineId, int iEngineIdLen
	, const char * pszPrivParam, int iPrivParamLen, std::string & strPlain )
{
	uint8_t szKey[16], szAuthKey[16], szIv[8];

	strPlain.clear();

	if( SnmpMakeKey( pszPassWord, szKey ) == false ) return false;
	if( SnmpMakeAuthKey( szKey, (const uint8_t *)pszEngineId, iEngineIdLen, szAuthKey ) == false ) return false;

	char * pszPlain = (char *)malloc( iPacketLen );
	if( pszPlain == NULL ) return false;

	for( int i = 0; i < 8; ++i )
	{
		szIv[i] = pszPrivParam[i] ^ szAuthKey[8+i];
	}

  DES_key_schedule	sttKeySchedule;
  DES_cblock				sttBlock;

	memcpy( sttBlock, szAuthKey, sizeof(sttBlock) );
	DES_key_sched( &sttBlock, &sttKeySchedule );

	DES_cbc_encrypt( (uint8_t *)pszPacket, (uint8_t *)pszPlain, iPacketLen, &sttKeySchedule, (DES_cblock *)szIv, DES_DECRYPT );	
	strPlain.append( pszPlain, iPacketLen );

	free( pszPlain );

	return true;
}
Esempio n. 2
0
/*
 * Long passwords, i.e 9 characters or more.
 */
static void
afs_transarc_StringToKey (char *str, char *cell, DES_cblock *key)
{
    DES_key_schedule schedule;
    DES_cblock temp_key;
    DES_cblock ivec;
    char password[512];
    int  passlen;

    strncpy (password, str, sizeof(password));
    password[sizeof(password)-1] = '\0';
    if ((passlen = strlen (password)) < sizeof(password)-1)
        strncat (password, cell, sizeof(password)-passlen);
    if ((passlen = strlen(password)) > sizeof(password)) passlen = sizeof(password);

    memcpy(&ivec, "kerberos", 8);
    memcpy(&temp_key, "kerberos", 8);
    des_fixup_key_parity (&temp_key);
    DES_key_sched (&temp_key, &schedule);
    DES_cbc_cksum ((unsigned char *)password, &ivec, passlen, &schedule, &ivec);

    memcpy(&temp_key, &ivec, 8);
    des_fixup_key_parity (&temp_key);
    DES_key_sched (&temp_key, &schedule);
    DES_cbc_cksum ((unsigned char *)password, key, passlen, &schedule, &ivec);

    des_fixup_key_parity (key);
}
Esempio n. 3
0
static void
StringToKey(char *str, char *cell,	/* cell for password */
	    struct ktc_encryptionKey *key)
{
    DES_key_schedule schedule;
    DES_cblock temp_key;
    DES_cblock ivec;
    char password[BUFSIZ];
    int passlen;

    strncpy(password, str, sizeof(password));
    if ((passlen = strlen(password)) < sizeof(password) - 1)
	strncat(password, cell, sizeof(password) - passlen);
    if ((passlen = strlen(password)) > sizeof(password))
	passlen = sizeof(password);

    memcpy(&ivec, "kerberos", 8);
    memcpy(&temp_key, "kerberos", 8);
    DES_set_odd_parity(&temp_key);
    DES_key_sched(&temp_key, &schedule);
    DES_cbc_cksum((DES_cblock *) password, &ivec, passlen, &schedule, &ivec);

    memcpy(&temp_key, &ivec, 8);
    DES_set_odd_parity(&temp_key);
    DES_key_sched(&temp_key, &schedule);
    DES_cbc_cksum((DES_cblock *)password, ktc_to_cblock(key), passlen,
		   &schedule, &ivec);

    DES_set_odd_parity(ktc_to_cblock(key));
}
Esempio n. 4
0
static afs_int32
check_auth(struct packet *pkt, char *auth, int authLen,
	   struct ktc_encryptionKey *key, char *name, char *inst,
	   char *cell)
{
    char *packet;
    DES_key_schedule schedule;
    afs_int32 cksum;
    afs_int32 time_sec;
    int byteOrder = pkt->byteOrder;

    DES_key_sched(ktc_to_cblock(key), &schedule);
    DES_pcbc_encrypt(auth, auth, authLen, &schedule, ktc_to_cblockptr(key), DECRYPT);
    packet = auth;
    if (strcmp(packet, name) != 0)
	return KABADTICKET;
    packet += strlen(packet) + 1;
    if (strcmp(packet, inst) != 0)
	return KABADTICKET;
    packet += strlen(packet) + 1;
    if (strcmp(packet, cell) != 0)
	return KABADTICKET;
    packet += strlen(packet) + 1;
    getint(cksum);
    /* Comments in the original IBM source suggest this byte was/is "time_msec" */
    packet++;
    getint(time_sec);
    if ((packet - auth) > authLen)
	return KABADTICKET;
    return 0;
}
Esempio n. 5
0
static afs_int32
create_cipher(char *cipher, int *cipherLen,
	      struct ktc_encryptionKey *sessionKey, char *sname,
	      char *sinst, Date start, Date end, afs_int32 kvno,
	      char *ticket, int ticketLen, struct ktc_encryptionKey *key)
{
    char *answer;
    int slen;
    unsigned char life = time_to_life(start, end);
    int len;
    DES_key_schedule schedule;
    afs_int32 code;

    answer = cipher;
    len =
	sizeof(*sessionKey) + strlen(sname) + strlen(sinst) + strlen(lrealm) +
	3 /*nulls */  + 3 + ticketLen + sizeof(Date);
    if (len > *cipherLen)
	return KAANSWERTOOLONG;
    if (ticketLen > 255)
	return KAANSWERTOOLONG;
    if (kvno > 255)
	return KAANSWERTOOLONG;

    memcpy(answer, sessionKey, sizeof(*sessionKey));
    answer += sizeof(*sessionKey);
    putstr(sname);
    putstr(sinst);
    putstr(lrealm);
    *answer++ = life;
    *answer++ = (unsigned char)kvno;
    *answer++ = (unsigned char)ticketLen;
    memcpy(answer, ticket, ticketLen);
    answer += ticketLen;
    putint(start);

    if (krb_udp_debug) {
	printf("Printing ticket (%d) and date: ", ticketLen);
	ka_PrintBytes(ticket, ticketLen);
	ka_PrintBytes(answer - 4, 4);
	printf("\n");
    }

    if ((code = DES_key_sched(ktc_to_cblock(key), &schedule)))
	printf("In KAAuthenticate: key_sched returned %d\n", code);
    DES_pcbc_encrypt(cipher, cipher, len, &schedule, ktc_to_cblockptr(key), ENCRYPT);
    *cipherLen = round_up_to_ebs(len);

    if (krb_udp_debug) {
	printf("Printing cipher (%d): ", *cipherLen);
	ka_PrintBytes(cipher, *cipherLen);
	printf("\n");
    }
    return 0;
}
Esempio n. 6
0
void
tokenchallenge(char *user, char *challenge, int size, char *card_type)
{
	TOKENDB_Rec tr;
	TOKEN_CBlock cb;
	DES_key_schedule ks;
	int r, c;

	r = 1;	/* no reduced input mode by default! */

	if ((tt->modes & TOKEN_RIM) &&
	    tokendb_getrec(user, &tr) == 0 &&
	    (tr.mode & TOKEN_RIM)) {
		c = 0;
		while ((r = tokendb_lockrec(user, &tr, TOKEN_LOCKED)) == 1) {
			if (c++ >= 60)
				break;
			sleep(1);
		}
		tr.flags &= ~TOKEN_LOCKED;
		if (r == 0 && tr.rim[0]) {
			h2cb(tr.secret, &cb);
			DES_fixup_key_parity(&cb.cb);
			DES_key_sched(&cb.cb, &ks);
			DES_ecb_encrypt(&tr.rim, &cb.cb, &ks, DES_ENCRYPT);
			memcpy(tr.rim, cb.cb, 8);
			for (r = 0; r < 8; ++r) {
				if ((tr.rim[r] &= 0xf) > 9)
					tr.rim[r] -= 10;
				tr.rim[r] |= 0x30;
			}
			r = 0;		/* reset it back */
			memcpy(tokennumber.ct, tr.rim, 8);
			tokennumber.ct[8] = 0;
			tokendb_putrec(user, &tr);
		}
	}
	if (r != 0 || tr.rim[0] == '\0') {
		memset(tokennumber.ct, 0, sizeof(tokennumber.ct));
		snprintf(tokennumber.ct, sizeof(tokennumber.ct), "%8.8u",
		    arc4random());
		if (r == 0) {
			memcpy(tr.rim, tokennumber.ct, 8);
			tokendb_putrec(user, &tr);
		}
	}

	snprintf(challenge, size, "%s Challenge \"%s\"\r\n%s Response: ",
	    card_type, tokennumber.ct, card_type);
}
Esempio n. 7
0
int enc(char *sopath,char *filename)
{
	//printf("you are in the enc program\n");
        SHA_CTX md;
	int eight=8;
	DES_key_schedule schedule1;
	DES_key_schedule schedule2;
	DES_key_schedule schedule3;
        FILE *fp;
        unsigned char buffer[10],DES_output[8];
	char DES_input[8],ch;
        unsigned char digest[20],file_digest[20];
        int count,i,len_of_pass,verify=1,no_of_bytes;
	unsigned char random_bits1[20],random_bits2[20],DES_key1[8],DES_key2[8],DES_key3[8],IV[8];
	char *buf,*buff;
	

	if(RAND_bytes(random_bits1,20)==0)
	{
		fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n");
		exit(1);
	}
	if(RAND_bytes(random_bits2,20)==0)
	{
		fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n");
		exit(1);
	}
/**************************************
COMPUTE SHA1 OF FILE
**************************************/

        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"(input file %s does not exist)\n",filename);
                exit(1);
        }
        SHA1_Init(&md);
        while((count=fread(&buffer,1,10,fp)))
        {
                SHA1_Update(&md,buffer,count);
        }
        SHA1_Final(file_digest,&md);

/*        for(i=0;i<20;i++)
        {
                printf("%02x",file_digest[i]);
        }*/

/**************************************
ASK FOR PASSWORD FOR DES
**************************************/
buf=(char *)malloc(4096*sizeof(char));
buff=(char *)malloc(4096*sizeof(char));
des_read_pw(buf,buff,4096,"Enter passphrase for DES encryption: ",verify);

//printf("buff=%s",buf);
//printf("buff2=%s\n",buff);
len_of_pass=strlen(buf);
//printf("len_of_pass=%d\n",len_of_pass);

/**************************************
GENERATE SHA1 OF THE PASSWORD
**************************************/

	SHA1_Init(&md);

	//free(&md);
	//SHA1_Update(&md,"yesnomaybe",10);
	SHA1_Update(&md,buf,strlen(buf));
	SHA1_Final(digest,&md);

	//printf("The SHA1 of password is\n");
        for(i=0;i<20;i++)
        {
                //printf("%02x",digest[i]);
        }

        //printf("\n");
	

/*******************************************
COMPUTE SHA1 OF X AND RANDOM BITS(RB1) 1
*******************************************/
/*	SHA1_Init(&md);
	SHA1_Update(&md,digest,20);
	SHA1_Update(&md,HW4_random_bits_1,20);
	SHA1_Final(X_RB1,&md);
	for(i=0;i<20;i++)
	{
		//printf("%02x",X_RB1[i]);
	}
	//printf("\n");*/

/******************************************
COMPUTE SHA1 OF RB1(Y) AND RANDOM BITS 2(RB2)
******************************************/
/*	SHA1_Init(&md);
        SHA1_Update(&md,X_RB1,20);
        SHA1_Update(&md,HW4_random_bits_2,20);
        SHA1_Final(X_RB2,&md);
        for(i=0;i<20;i++)
        {
                //printf("%02x",X_RB2[i]);
        }
        //printf("\n");*/

/***************************************
COMPUTER IV AND 3 DES KEYS
***************************************/
//	SC_3des_key_gen(NULL,digest,IV,DES_key1,DES_key2,DES_key3);


	SmartcardState pss=(SmartcardState)NULL;
void *handle=NULL;
//void *vp =NULL;
SC_Init_Func *pfn_init=NULL;
SC_Cleanup_Func *pfn_cleanup=NULL;
SC_GetSignatureSize_Func *pfn_getsigsize=NULL;
SC_3DesKeyGen_Func *pfn_sc_enc=NULL;

handle = dlopen(sopath, RTLD_NOW|RTLD_GLOBAL);
if (handle==NULL)
{
//fprintf(stderr, "%s\n",sopath);
fprintf(stderr, "%s\n",
dlerror());
fprintf(stderr,"dlopen() failed\n");
exit(1);
}
pfn_init = (SC_Init_Func*)dlsym(handle,"SC_init");


pfn_cleanup = (SC_Cleanup_Func*)dlsym(handle,"SC_cleanup");


pfn_getsigsize = (SC_GetSignatureSize_Func*)dlsym(handle,"SC_get_signature_size");

pfn_sc_enc = (SC_3DesKeyGen_Func *)dlsym(handle,"SC_3des_key_gen");

if(pfn_init==NULL || pfn_cleanup==NULL || pfn_getsigsize==NULL || pfn_sc_enc==NULL)
{
fprintf(stderr,"(cannot find smartcard functions in this library)\n");
exit(1);
}


pss = (pfn_init)();
//printf("sig size is %d\n", (pfn_getsigsize)(pss));

(pfn_sc_enc) (pss,digest,IV,DES_key1,DES_key2,DES_key3);

(pfn_cleanup)(pss);
dlclose(handle);

/*	for(i=0;i<8;i++)
	IV[i]=X_RB1[i];
	for(i=8,j=0;i<16;i++,j++)
	DES_key1[j]=X_RB1[i];
	for(i=0;i<8;i++)
	DES_key2[i]=X_RB2[i];
	for(i=8,j=0;i<16;i++,j++)
	DES_key3[j]=X_RB2[i];
	printf("IV=");
	for(i=0;i<8;i++)
	printf("%02x",IV[i]);
	printf("\nDES KEY 1=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key1[i]);
	printf("\nDES key 2=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key2[i]);
	printf("\nDES key 3=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key3[i]);
	printf("\n");*/


	
	
	DES_set_odd_parity((DES_cblock *)DES_key1);
	DES_set_odd_parity((DES_cblock *)DES_key2);
	DES_set_odd_parity((DES_cblock *)DES_key3);
	
	DES_key_sched((DES_cblock *)DES_key1,&schedule1);
	DES_set_key((DES_cblock *)DES_key1,&schedule1); 

        DES_key_sched((DES_cblock *)DES_key2,&schedule2);
        DES_set_key((DES_cblock *)DES_key2,&schedule2);

        DES_key_sched((DES_cblock *)DES_key3,&schedule3);
        DES_set_key((DES_cblock *)DES_key3,&schedule3);

/******************************************
READ FILE 8 BYTES AT A TIME AND ENCRYPT IT
******************************************/

	if((fp=fopen(filename,"rb"))==NULL)
	{
		fprintf(stderr,"{input file %s does not exist}\n",filename);
		exit(1);
	}
	i=0;
	while((count=fread(&ch,1,1,fp)))
	{
	i++;
	}
//	printf("no. of bytes=%d\n",i);
	no_of_bytes=i%8;
	fclose(fp);	
	printf("HW4");
	if(no_of_bytes>0)
	printf("%c",no_of_bytes);
	else
	printf("%c",eight);
        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"{input file %s does not exist}\n",filename);
                exit(1);
        }
	while((count=fread(&DES_input,1,8,fp)))
	{
		if(count!=8)
		{
		for(i=count;i<8;i++)
		DES_input[i]='\0';
		DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,1);
		for(i=0;i<8;i++)
		printf("%c",DES_output[i]);
	//	printf("%s",DES_output);
		}
		else
		{
	//	printf("%d\n",count);	
		DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,1);
		for(i=0;i<8;i++)
		printf("%c",DES_output[i]);
//    		printf("%s",DES_output);
		}
	}
	for(i=0;i<20;i++)
	printf("%c",file_digest[i]);
		

	return 1;


}
_SCAPI_NOT_CONFIGURED
#endif                          /* NETSNMP_USE_INTERNAL_MD5 */
/*******************************************************************-o-******
 * sc_encrypt
 *
 * Parameters:
 *	 privtype	Type of privacy cryptographic transform.
 *	*key		Key bits for crypting.
 *	 keylen		Length of key (buffer) in bytes.
 *	*iv		IV bits for crypting.
 *	 ivlen		Length of iv (buffer) in bytes.
 *	*plaintext	Plaintext to crypt.
 *	 ptlen		Length of plaintext.
 *	*ciphertext	Ciphertext to crypt.
 *	*ctlen		Length of ciphertext.
 *      
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_SC_NOT_CONFIGURED	Encryption is not supported.
 *	SNMPERR_SC_GENERAL_FAILURE	Any other error
 *
 *
 * Encrypt plaintext into ciphertext using key and iv.
 *
 * ctlen contains actual number of crypted bytes in ciphertext upon
 * successful return.
 */
int
sc_encrypt(const oid * privtype, size_t privtypelen,
           u_char * key, u_int keylen,
           u_char * iv, u_int ivlen,
           u_char * plaintext, u_int ptlen,
           u_char * ciphertext, size_t * ctlen)
#if defined(NETSNMP_USE_OPENSSL)
{
    int             rval = SNMPERR_SUCCESS;
    u_int           properlength = 0, properlength_iv = 0;
    u_char          pad_block[128];      /* bigger than anything I need */
    u_char          my_iv[128];  /* ditto */
    int             pad, plast, pad_size = 0;
    int             have_trans;
#ifndef NETSNMP_DISABLE_DES
#ifdef OLD_DES
    DES_key_schedule key_sch;
#else
    DES_key_schedule key_sched_store;
    DES_key_schedule *key_sch = &key_sched_store;
#endif
    DES_cblock       key_struct;
#endif
#ifdef HAVE_AES
    AES_KEY aes_key;
    int new_ivlen = 0;
#endif

    DEBUGTRACE;

    /*
     * Sanity check.
     */
#if	!defined(NETSNMP_ENABLE_SCAPI_AUTHPRIV)
    snmp_log(LOG_ERR, "Encryption support not enabled.\n");
    return SNMPERR_SC_NOT_CONFIGURED;
#endif

    if (!privtype || !key || !iv || !plaintext || !ciphertext || !ctlen
        || (keylen <= 0) || (ivlen <= 0) || (ptlen <= 0) || (*ctlen <= 0)
        || (privtypelen != USM_LENGTH_OID_TRANSFORM)) {
        QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
    } else if (ptlen > *ctlen) {
        QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
    }
#ifdef NETSNMP_ENABLE_TESTING_CODE
    {
        size_t          buf_len = 128, out_len = 0;
        u_char         *buf = (u_char *) malloc(buf_len);

        if (buf != NULL) {
            if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
                                         iv, ivlen)) {
                DEBUGMSGTL(("scapi", "encrypt: IV: %s/", buf));
            } else {
                DEBUGMSGTL(("scapi", "encrypt: IV: %s [TRUNCATED]/", buf));
            }
            out_len = 0;
            if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
                                         key, keylen)) {
                DEBUGMSG(("scapi", "%s\n", buf));
            } else {
                DEBUGMSG(("scapi", "%s [TRUNCATED]\n", buf));
            }
            out_len = 0;
            if (sprint_realloc_hexstring(&buf, &buf_len, &out_len, 1,
                                         plaintext, 16)) {
                DEBUGMSGTL(("scapi", "encrypt: string: %s\n", buf));
            } else {
                DEBUGMSGTL(("scapi", "encrypt: string: %s [TRUNCATED]\n",
                            buf));
            }
            free(buf);
        } else {
            DEBUGMSGTL(("scapi",
                        "encrypt: malloc fail for debug output\n"));
        }
    }
#endif                          /* NETSNMP_ENABLE_TESTING_CODE */


    /*
     * Determine privacy transform.
     */
    have_trans = 0;
#ifndef NETSNMP_DISABLE_DES
    if (ISTRANSFORM(privtype, DESPriv)) {
        properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
        properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES_IV);
        pad_size = properlength;
        have_trans = 1;
    }
#endif
#ifdef HAVE_AES
    if (ISTRANSFORM(privtype, AESPriv)) {
        properlength = BYTESIZE(SNMP_TRANS_PRIVLEN_AES);
        properlength_iv = BYTESIZE(SNMP_TRANS_PRIVLEN_AES_IV);
        have_trans = 1;
    }
#endif
    if (!have_trans) {
        QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
    }

    if ((keylen < properlength) || (ivlen < properlength_iv)) {
        QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);
    }

    memset(my_iv, 0, sizeof(my_iv));

#ifndef NETSNMP_DISABLE_DES
    if (ISTRANSFORM(privtype, DESPriv)) {

        /*
         * now calculate the padding needed 
         */
        pad = pad_size - (ptlen % pad_size);
        plast = (int) ptlen - (pad_size - pad);
        if (pad == pad_size)
            pad = 0;
        if (ptlen + pad > *ctlen) {
            QUITFUN(SNMPERR_GENERR, sc_encrypt_quit);    /* not enough space */
        }
        if (pad > 0) {              /* copy data into pad block if needed */
            memcpy(pad_block, plaintext + plast, pad_size - pad);
            memset(&pad_block[pad_size - pad], pad, pad);   /* filling in padblock */
        }

        memcpy(key_struct, key, sizeof(key_struct));
        (void) DES_key_sched(&key_struct, key_sch);

        memcpy(my_iv, iv, ivlen);
        /*
         * encrypt the data 
         */
        DES_ncbc_encrypt(plaintext, ciphertext, plast, key_sch,
                         (DES_cblock *) my_iv, DES_ENCRYPT);
        if (pad > 0) {
            /*
             * then encrypt the pad block 
             */
            DES_ncbc_encrypt(pad_block, ciphertext + plast, pad_size,
                             key_sch, (DES_cblock *) my_iv, DES_ENCRYPT);
            *ctlen = plast + pad_size;
        } else {
            *ctlen = plast;
        }
    }
#endif
#ifdef HAVE_AES
    if (ISTRANSFORM(privtype, AESPriv)) {
        (void) AES_set_encrypt_key(key, properlength*8, &aes_key);

        memcpy(my_iv, iv, ivlen);
        /*
         * encrypt the data 
         */
        AES_cfb128_encrypt(plaintext, ciphertext, ptlen,
                           &aes_key, my_iv, &new_ivlen, AES_ENCRYPT);
        *ctlen = ptlen;
    }
#endif
  sc_encrypt_quit:
    /*
     * clear memory just in case 
     */
    memset(my_iv, 0, sizeof(my_iv));
    memset(pad_block, 0, sizeof(pad_block));
#ifndef NETSNMP_DISABLE_DES
    memset(key_struct, 0, sizeof(key_struct));
#ifdef OLD_DES
    memset(&key_sch, 0, sizeof(key_sch));
#else
    memset(&key_sched_store, 0, sizeof(key_sched_store));
#endif
#endif
#ifdef HAVE_AES
    memset(&aes_key,0,sizeof(aes_key));
#endif
    return rval;

}                               /* end sc_encrypt() */
Esempio n. 9
0
int
tokenuserinit(int flags, char *username, unsigned char *usecret, unsigned mode)
{
	TOKENDB_Rec tokenrec;
	TOKEN_CBlock secret;
	TOKEN_CBlock nulls;
	TOKEN_CBlock checksum;
	TOKEN_CBlock checktxt;
	DES_key_schedule key_schedule;

	memset(&secret, 0, sizeof(secret));

	/*
	 * If no user secret passed in, create one
	 */

	if ( (flags & TOKEN_GENSECRET) )
		tokenseed(&secret);
	else
		memcpy(&secret, usecret, sizeof(DES_cblock));

	DES_fixup_key_parity(&secret.cb);

	/*
	 * Check if the db record already exists.  If there's no
	 * force-init flag and it exists, go away. Else,
	 * create the user's db record and put to the db.
	 */


	if (!(flags & TOKEN_FORCEINIT) &&
	    tokendb_getrec(username, &tokenrec) == 0)
		return (1);

	memset(&tokenrec, 0, sizeof(tokenrec));
	strlcpy(tokenrec.uname, username, sizeof(tokenrec.uname));
	cb2h(secret, tokenrec.secret);
	tokenrec.mode = 0;
	tokenrec.flags = TOKEN_ENABLED | TOKEN_USEMODES;
	tokenrec.mode = mode;
	memset(tokenrec.reserved_char1, 0, sizeof(tokenrec.reserved_char1));
	memset(tokenrec.reserved_char2, 0, sizeof(tokenrec.reserved_char2));

	if (tokendb_putrec(username, &tokenrec))
		return (-1);

	/*
	 * Check if the shared secret was generated here. If so, we
	 * need to inform the user about it in order that it can be
	 * programmed into the token. See tokenverify() (above) for
	 * discussion of cipher generation.
	 */

	if (!(flags & TOKEN_GENSECRET)) {
		memset(&secret, 0, sizeof(secret));
		return (0);
	}

	printf("Shared secret for %s\'s token: "
	    "%03o %03o %03o %03o %03o %03o %03o %03o\n",
	    username, secret.cb[0], secret.cb[1], secret.cb[2], secret.cb[3],
	    secret.cb[4], secret.cb[5], secret.cb[6], secret.cb[7]);

	DES_key_sched(&secret.cb, &key_schedule);
	memset(&secret, 0, sizeof(secret));
	memset(&nulls, 0, sizeof(nulls));
	DES_ecb_encrypt(&nulls.cb, &checksum.cb, &key_schedule, DES_ENCRYPT);
	memset(&key_schedule, 0, sizeof(key_schedule));
	HTONL(checksum.ul[0]);
	snprintf(checktxt.ct, sizeof(checktxt.ct), "%8.8x", checksum.ul[0]);
	printf("Hex Checksum: \"%s\"", checktxt.ct);

	h2d(checktxt.ct);
	printf("\tDecimal Checksum: \"%s\"\n", checktxt.ct);

	return (0);
}
Esempio n. 10
0
int
tokenverify(char *username, char *challenge, char *response)
{
	char	*state;
	TOKENDB_Rec tokenrec;
	TOKEN_CBlock tmp;
	TOKEN_CBlock cmp_text;
	TOKEN_CBlock user_seed;
	TOKEN_CBlock cipher_text;
	DES_key_schedule key_schedule;


	memset(cmp_text.ct, 0, sizeof(cmp_text.ct));
	memset(user_seed.ct, 0, sizeof(user_seed.ct));
	memset(cipher_text.ct, 0, sizeof(cipher_text.ct));
	memset(tokennumber.ct, 0, sizeof(tokennumber.ct));

	(void)strtok(challenge, "\"");
	state = strtok(NULL, "\"");
	tmp.ul[0] = strtoul(state, NULL, 10);
	snprintf(tokennumber.ct, sizeof(tokennumber.ct), "%8.8u",tmp.ul[0]);

	/*
	 * Retrieve the db record for the user. Nuke it as soon as
	 * we have translated out the user's shared secret just in
	 * case we (somehow) get core dumped...
	 */

	if (tokendb_getrec(username, &tokenrec))
		return (-1);

	h2cb(tokenrec.secret, &user_seed);
	memset(&tokenrec.secret, 0, sizeof(tokenrec.secret));

	if (!(tokenrec.flags & TOKEN_ENABLED))
		return (-1);

	/*
	 * Compute the anticipated response in hex. Nuke the user's
	 * shared secret asap.
	 */

	DES_fixup_key_parity(&user_seed.cb);
	DES_key_sched(&user_seed.cb, &key_schedule);
	memset(user_seed.ct, 0, sizeof(user_seed.ct));
	DES_ecb_encrypt(&tokennumber.cb, &cipher_text.cb, &key_schedule,
	    DES_ENCRYPT);
	memset(&key_schedule, 0, sizeof(key_schedule));

	/*
	 * The token thinks it's descended from VAXen.  Deal with i386
	 * endian-ness of binary cipher prior to generating ascii from first
	 * 32 bits.
	 */

	HTONL(cipher_text.ul[0]);
	snprintf(cmp_text.ct, sizeof(cmp_text.ct), "%8.8x", cipher_text.ul[0]);

	if (tokenrec.mode & TOKEN_PHONEMODE) {
		/*
		 * If we are a CRYPTOCard, we need to see if we are in
		 * "telephone number mode".  If so, transmogrify the fourth
		 * digit of the cipher.  Lower case response just in case
		 * it's * hex.  Compare hex cipher with anticipated response
		 * from token.
		 */

		lcase(response);

		if (response[3] == '-')
			cmp_text.ct[3] = '-';
	}

	if ((tokenrec.mode & TOKEN_HEXMODE) && !strcmp(response, cmp_text.ct))
		return (0);

	/*
	 * No match against the computed hex cipher.  The token could be
	 * in decimal mode.  Pervert the string to magic decimal equivalent.
	 */

	h2d(cmp_text.ct);

	if ((tokenrec.mode & TOKEN_DECMODE) && !strcmp(response, cmp_text.ct))
		return (0);

	return (-1);
}
Esempio n. 11
0
int openssl_test()
{
    EVP_MD_CTX md_ctx;
    testVector a, b, c;
    byte       hash[SHA_DIGEST_SIZE];

    a.input  = "1234567890123456789012345678901234567890123456789012345678"
               "9012345678901234567890";
    a.output = "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6"
               "\x7a";
    a.inLen  = strlen(a.input);
    a.outLen = strlen(a.output);

    EVP_MD_CTX_init(&md_ctx);
    EVP_DigestInit(&md_ctx, EVP_md5());

    EVP_DigestUpdate(&md_ctx, a.input, a.inLen);
    EVP_DigestFinal(&md_ctx, hash, 0);

    if (memcmp(hash, a.output, MD5_DIGEST_SIZE) != 0)
        return -71;

    b.input  = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
               "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
               "aaaaaaaaaa";
    b.output = "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7"
               "\x53\x99\x5E\x26\xA0";
    b.inLen  = strlen(b.input);
    b.outLen = strlen(b.output);

    EVP_MD_CTX_init(&md_ctx);
    EVP_DigestInit(&md_ctx, EVP_sha1());

    EVP_DigestUpdate(&md_ctx, b.input, b.inLen);
    EVP_DigestFinal(&md_ctx, hash, 0);

    if (memcmp(hash, b.output, SHA_DIGEST_SIZE) != 0)
        return -72;

    if (RAND_bytes(hash, sizeof(hash)) != 1)
        return -73;
            
    c.input  = "what do ya want for nothing?";
    c.output = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7"
               "\x38";
    c.inLen  = strlen(c.input);
    c.outLen = strlen(c.output);

    HMAC(EVP_md5(), "Jefe", 4, (byte*)c.input, (int)c.inLen, hash, 0);

    if (memcmp(hash, c.output, MD5_DIGEST_SIZE) != 0)
        return -74;

    { /* des test */
    const byte vector[] = { /* "now is the time for all " w/o trailing 0 */
        0x6e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74,
        0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20,
        0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20
    };

    byte plain[24];
    byte cipher[24];

    const_DES_cblock key = 
    {
        0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef
    };

    DES_cblock iv = 
    {
        0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef
    };

    DES_key_schedule sched;

    const byte verify[] = 
    {
        0x8b,0x7c,0x52,0xb0,0x01,0x2b,0x6c,0xb8,
        0x4f,0x0f,0xeb,0xf3,0xfb,0x5f,0x86,0x73,
        0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b
    };

    DES_key_sched(&key, &sched);

    DES_cbc_encrypt(vector, cipher, sizeof(vector), &sched, &iv, DES_ENCRYPT);
    DES_cbc_encrypt(cipher, plain, sizeof(vector), &sched, &iv, DES_DECRYPT);

    if (memcmp(plain, vector, sizeof(vector)) != 0)
        return -75;

    if (memcmp(cipher, verify, sizeof(verify)) != 0)
        return -76;

        /* test changing iv */
    DES_ncbc_encrypt(vector, cipher, 8, &sched, &iv, DES_ENCRYPT);
    DES_ncbc_encrypt(vector + 8, cipher + 8, 16, &sched, &iv, DES_ENCRYPT);

    if (memcmp(cipher, verify, sizeof(verify)) != 0)
        return -77;

    }  /* end des test */

    return 0;
}
Esempio n. 12
0
int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,des_key_schedule schedule)
  {
  return DES_key_sched(key, (DES_key_schedule *)schedule);
  }
Esempio n. 13
0
int dec(char *sopath,char *filename)
{
	//printf("you are in the enc program\n");
        SHA_CTX md;
	DES_key_schedule schedule1;
	DES_key_schedule schedule2;
	DES_key_schedule schedule3;
        FILE *fp;
	char DES_output[9],DES_input[9];
        unsigned char buffer[10];
	char ch;
        unsigned char digest[20],file_digest[20];
        int count,i,len_of_pass,verify=0,n,last_byte_size,to_read_upto,count_buf_size,temp_count;
	unsigned char random_bits1[20],random_bits2[20],DES_key1[8],DES_key2[8],DES_key3[8],IV[8];
	char *buf,*buff;
	

	if(RAND_bytes(random_bits1,20)==0)
	{
		fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n");
		exit(1);
	}
	if(RAND_bytes(random_bits2,20)==0)
	{
		fprintf(stderr,"Error obtaining 20 bytes of random bits from OPENSSL\n");
		exit(1);
	}
/**************************************
COMPUTE SHA1 OF FILE
**************************************/

        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"(%s file does not exist)\n",filename);
                exit(1);
        }
	count=0;
	while(fread(&ch,1,1,fp))
{
	if(count==0)
	{
	if(ch!='H')
	{
	fprintf(stderr,"(%s is not generated  by the enc command)\n",filename);
	exit(1);	
	}
	}
	if(count==1)
	{
	if(ch!='W')
	{
	fprintf(stderr,"(%s is not generated by the enc command)\n",filename);
	}
	}
	if(count==2)
	{
	if(ch!='4')
	{
	fprintf(stderr,"(%s is not generated by the enc command)\n",filename);
	}
	}
        count++;
}
	fclose(fp);
        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"(%s is not generated  by enc command)\n",filename);
                exit(1);
        }
	

        SHA1_Init(&md);
        while((count=fread(&buffer,1,10,fp)))
        {
                SHA1_Update(&md,buffer,count);
        }
        SHA1_Final(file_digest,&md);

/*        for(i=0;i<20;i++)
        {
                printf("%02x",file_digest[i]);
        }*/

/**************************************
ASK FOR PASSWORD FOR DES
**************************************/
buf=(char *)malloc(4096*sizeof(char));
buff=(char *)malloc(4096*sizeof(char));
des_read_pw(buf,buff,4096,"Enter passphrase for DES decryption: ",verify);

//printf("buff=%s",buf);
//printf("buff2=%s\n",buff);
len_of_pass=strlen(buf);
//printf("len_of_pass=%d\n",len_of_pass);

/**************************************
GENERATE SHA1 OF THE PASSWORD
**************************************/

	SHA1_Init(&md);

	//free(&md);
	//SHA1_Update(&md,"yesnomaybe",10);
	SHA1_Update(&md,buf,strlen(buf));
	SHA1_Final(digest,&md);

	//printf("The SHA1 of password is\n");
        for(i=0;i<20;i++)
        {
                //printf("%02x",digest[i]);
        }

        //printf("\n");
	

/*******************************************
COMPUTE SHA1 OF X AND RANDOM BITS(RB1) 1
*******************************************/
/*	SHA1_Init(&md);
	SHA1_Update(&md,digest,20);
	SHA1_Update(&md,HW4_random_bits_1,20);
	SHA1_Final(X_RB1,&md);
	for(i=0;i<20;i++)
	{
		//printf("%02x",X_RB1[i]);
	}
	//printf("\n");*/

/******************************************
COMPUTE SHA1 OF RB1(Y) AND RANDOM BITS 2(RB2)
******************************************/
/*	SHA1_Init(&md);
        SHA1_Update(&md,X_RB1,20);
        SHA1_Update(&md,HW4_random_bits_2,20);
        SHA1_Final(X_RB2,&md);
        for(i=0;i<20;i++)
        {
                //printf("%02x",X_RB2[i]);
        }
        //printf("\n");*/

/***************************************
COMPUTER IV AND 3 DES KEYS
***************************************/
//	SC_3des_key_gen(NULL,digest,IV,DES_key1,DES_key2,DES_key3);

	SmartcardState pss=(SmartcardState)NULL;
void *handle=NULL;
//void *vp =NULL;
SC_Init_Func *pfn_init=NULL;
SC_Cleanup_Func *pfn_cleanup=NULL;
SC_GetSignatureSize_Func *pfn_getsigsize=NULL;
SC_3DesKeyGen_Func *pfn_sc_dec=NULL;

handle = dlopen(sopath, RTLD_NOW|RTLD_GLOBAL);
if (handle==NULL)
{
//fprintf(stderr, "%s\n",sopath);
fprintf(stderr, "%s\n",
dlerror());
fprintf(stderr,"dlopen() failed\n");
exit(1);
}
pfn_init = (SC_Init_Func*)dlsym(handle,"SC_init");


pfn_cleanup = (SC_Cleanup_Func*)dlsym(handle,"SC_cleanup");


pfn_getsigsize = (SC_GetSignatureSize_Func*)dlsym(handle,"SC_get_signature_size");

pfn_sc_dec = (SC_3DesKeyGen_Func *)dlsym(handle,"SC_3des_key_gen");

if(pfn_init==NULL || pfn_cleanup==NULL || pfn_getsigsize==NULL || pfn_sc_dec==NULL)
{
fprintf(stderr,"(cannot find smartcard functions in this library)\n");
exit(1);
}


pss = (pfn_init)();
//printf("sig size is %d\n", (pfn_getsigsize)(pss));
//int sz=(pfn_getsigsize)(pss);

(pfn_sc_dec) (pss,digest,IV,DES_key1,DES_key2,DES_key3);

(pfn_cleanup)(pss);
dlclose(handle);


/*	for(i=0;i<8;i++)
	IV[i]=X_RB1[i];
	for(i=8,j=0;i<16;i++,j++)
	DES_key1[j]=X_RB1[i];
	for(i=0;i<8;i++)
	DES_key2[i]=X_RB2[i];
	for(i=8,j=0;i<16;i++,j++)
	DES_key3[j]=X_RB2[i];
	printf("IV=");
	for(i=0;i<8;i++)
	printf("%02x",IV[i]);
	printf("\nDES KEY 1=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key1[i]);
	printf("\nDES key 2=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key2[i]);
	printf("\nDES key 3=");
	for(i=0;i<8;i++)
	printf("%02x",DES_key3[i]);
	printf("\n");*/


	
	
	DES_set_odd_parity((DES_cblock *)DES_key1);
	DES_set_odd_parity((DES_cblock *)DES_key2);
	DES_set_odd_parity((DES_cblock *)DES_key3);
	
	DES_key_sched((DES_cblock *)DES_key1,&schedule1);
	DES_set_key((DES_cblock *)DES_key1,&schedule1); 

        DES_key_sched((DES_cblock *)DES_key2,&schedule2);
        DES_set_key((DES_cblock *)DES_key2,&schedule2);

        DES_key_sched((DES_cblock *)DES_key3,&schedule3);
        DES_set_key((DES_cblock *)DES_key3,&schedule3);

/******************************************
READ FILE 8 BYTES AT A TIME AND ENCRYPT IT
******************************************/

	if((fp=fopen(filename,"rb"))==NULL)
	{
		fprintf(stderr,"{input file %s does not exist}\n",filename);
		exit(1);
	}
	i=0;
	while((count=fread(&ch,1,1,fp)))
	{
	i++;
	if(i==4)
	{
	last_byte_size=(int)ch;
	}
	}//while ends
	fclose(fp);
//	printf("last_bytes_size=%d",last_byte_size);
//	printf("\ntotal count=%d\n",i);
	to_read_upto=i-20;
//	printf("to read upto=%d\n",to_read_upto);
        if((fp=fopen(filename,"rb"))==NULL)
        {
                fprintf(stderr,"{input file %s does not exist}\n",filename);
                exit(1);
        }
	n=0;count_buf_size=0;i=0;temp_count=0;
	for(i=0;i<4;i++)
	fread(&ch,1,1,fp);
	n=4;

	while(!feof(fp))
	{
	if(n==(to_read_upto-8))
	{
	  //	printf("\nlast byte reading\n");
		for(i=0;i<8;i++)
		DES_input[i]=fgetc(fp);
		DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,DES_DECRYPT);
		
		for(i=0;i<last_byte_size;i++)
		printf("%c",DES_output[i]);	
		exit(1);
	}	
	for(i=0;i<8;i++)
	{
		if(n==(to_read_upto+1))
		exit(1);
	n++;
	DES_input[i]=fgetc(fp);
	}
	DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,DES_DECRYPT);
	for(i=0;i<8;i++)
	printf("%c",DES_output[i]);
	}//while feof ends
		
	
/*	while((count=fread(&ch,1,1,fp)))
	{
//		printf("%c",ch);
		n++;
		if(n>4)//skip first four bytes of encrypted file
		{
		if(n==to_read_upto+1)
		break;
			
		DES_input[count_buf_size]=ch;	
		printf("%c",DES_input[count_buf_size]);
		
	
		count_buf_size++;
		if(count_buf_size==7)
		{	
			//for(i=0;i<8;i++)
			//printf("%c",DES_input[i]);
			temp_count++;
			DES_ede3_cbc_encrypt(DES_input,DES_output,8,&schedule1,&schedule2,&schedule3,(DES_cblock*)IV,DES_DECRYPT);
			if(n==to_read_upto-7)
			{
//			printf("in other loop\n");
//			for(i=0;i<last_byte_size;i++)
//			printf("%c",DES_output[i]);
			}
			else
			{
//			for(i=0;i<8;i++)
//			printf("%c",DES_output[i]);
			count_buf_size=0;
			}
		}
		}//if count >4 ends
	}	
//	printf("count=%d\n",temp_count);
//	printf("loop count=%d\n",n);
	for(i=0;i<20;i++)
	printf("%c",file_digest[i]);
	//printf("%s\n",file_digest);*/
		

	return 1;


}
Esempio n. 14
0
void cIrdeto2::ScheduleKey(const unsigned char *key)
{
  DES_key_sched((DES_cblock *)key,&ks1);
  DES_key_sched((DES_cblock *)(key+8),&ks2);
}
Esempio n. 15
0
static int afppasswd(const struct passwd *pwd, 
		     const char *path, const int pathlen, 
		     unsigned char *passwd, int len, 
		     const int set)
{
  uint8_t key[DES_KEY_SZ*2];
  char buf[MAXPATHLEN + 1], *p;
  DES_key_schedule schedule;
  FILE *fp;
  unsigned int i, j;
  int keyfd = -1, err = 0;
  off_t pos;
  
  if ((fp = fopen(path, (set) ? "r+" : "r")) == NULL) {
    LOG(log_error, logtype_uams, "Failed to open %s", path);
    return AFPERR_ACCESS;
  }
  
  /* open the key file if it exists */
  strcpy(buf, path);
  if (pathlen < (int) sizeof(buf) - 5) {
    strcat(buf, ".key");
    keyfd = open(buf, O_RDONLY);
  } 
  
  pos = ftell(fp);
  memset(buf, 0, sizeof(buf));
  while (fgets(buf, sizeof(buf), fp)) {
    if ((p = strchr(buf, ':'))) {
      if ( strlen(pwd->pw_name) == (p - buf) &&
           strncmp(buf, pwd->pw_name, p - buf) == 0) {
	p++;
	if (*p == PASSWD_ILLEGAL) {
	  LOG(log_info, logtype_uams, "invalid password entry for %s", pwd->pw_name);
	  err = AFPERR_ACCESS;
	  goto afppasswd_done;
	}
	goto afppasswd_found;
      }
    }
    pos = ftell(fp);
    memset(buf, 0, sizeof(buf));
  }
  err = AFPERR_PARAM;
  goto afppasswd_done;

afppasswd_found:
  if (!set) {
    /* convert to binary. */
    for (i = j = 0; i < sizeof(key); i += 2, j++)
      p[j] = (unhex(p[i]) << 4) | unhex(p[i + 1]);
    if (j <= DES_KEY_SZ)
      memset(p + j, 0, sizeof(key) - j);
  }

  if (keyfd > -1) {
      /* read in the hex representation of an 8-byte key */
      read(keyfd, key, sizeof(key));

      /* convert to binary key */
      for (i = j = 0; i < strlen((char *) key); i += 2, j++)
	key[j] = (unhex(key[i]) << 4) | unhex(key[i + 1]);
      if (j <= DES_KEY_SZ)
	memset(key + j, 0, sizeof(key) - j);
      DES_key_sched((DES_cblock *) key, &schedule);
      memset(key, 0, sizeof(key));

      if (set) {
	/* NOTE: this takes advantage of the fact that passwd doesn't
	 *       get used after this call if it's being set. */
	DES_ecb_encrypt((DES_cblock *) passwd, (DES_cblock *) passwd, &schedule,
		    DES_ENCRYPT);
      } else {
	/* decrypt the password */
	DES_ecb_encrypt((DES_cblock *) p, (DES_cblock *) p, &schedule, DES_DECRYPT);
      }
      memset(&schedule, 0, sizeof(schedule));
  }

  if (set) {
    const unsigned char hextable[] = "0123456789ABCDEF";
    struct flock lock;
    int fd = fileno(fp);

    /* convert to hex password */
    for (i = j = 0; i < DES_KEY_SZ; i++, j += 2) {
      key[j] = hextable[(passwd[i] & 0xF0) >> 4];
      key[j + 1] = hextable[passwd[i] & 0x0F];
    }
    memcpy(p, key, sizeof(key));

    /* get exclusive access to the user's password entry. we don't
     * worry so much on reads. in the worse possible case there, the 
     * user will just need to re-enter their password. */
    lock.l_type = F_WRLCK;
    lock.l_start = pos;
    lock.l_len = 1;
    lock.l_whence = SEEK_SET;

    fseek(fp, pos, SEEK_SET);
    fcntl(fd, F_SETLKW, &lock);
    fwrite(buf, p - buf + sizeof(key), 1, fp);
    lock.l_type = F_UNLCK;
    fcntl(fd, F_SETLK, &lock);
  } else