⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 password.c

📁 在卡片上管理密码的工具。密码被标注并集体加密存储在卡片上。因此这是一个安全存储密码的方法
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * GNU POC (passwords on card) - manage passwords on smartcards * Copyright (C) 2001 Henning Koester <henning@crackinghacking.de> * * Please report bugs to bug-poc@gnu.org * * This file is part of POC. * * This program 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. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* $Id: password.c,v 1.8 2001/08/18 16:15:43 henning Exp $ */#include <config.h>#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <errno.h>#ifdef HAVE_BYTESWAP_H #include <byteswap.h>#else#include "missing_libs.h"#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "cardinfo.h"#include "card.h"#include "lang.h"#include "poc.h"#include "poc_types.h"#include "poc_macros.h"#include "cipher.h"#include "misc.h"/****************************************************************************** * * Function    : search_free_space * * Description : This function checks whether there's still enough free memory *               on the card to store the new password+description. * * Input       : [1] needed_space (int) *                   Size of password+description+2 byte 'size of the tags'. *               [2] buffer (u8) *                   This buffer is checked for enough free space. *               [3] used_space (int) *                   Used space of 'buffer'. *               [4] buffer_size (int) *                   Buffer's size. * * Return      : -1 (not enough space left), 0 (enough free space) * *****************************************************************************/static int search_free_space(const int needed_space, const u8 * const buffer,		  const int used_space, const int buffer_size) {  if (buffer_size - used_space < needed_space) return(-1);  return(0);}/* Clean sensetive data. */#define wipe_out_data() {                     \  overwrite_buffer(password);                 \  overwrite_buffer(p);                        \  overwrite_buffer(key);                      \  overwrite_buffer(buffer);                   \  drop_mbuffer(buffer);                       \}/****************************************************************************** * * Function    : password_save * * Description : This function saves a password on the card. * * Input       : [1] card_crypt_ctx (crypt_context) *                   Information about data encryption (cipher, security-level) *               [2] port (u16) *                   Com-Port * * Return      : POC_ERROR or POC_SUCCESS * *****************************************************************************/bool password_save(const crypt_context * const card_crypt_ctx, const u16 port) {  char description[DESCR_LENGTH];  /* Description of the password. */  char password[128];              /* Password which will be saved. */  char key[128];                   /* Key for card encryption. */  u8 *buffer = NULL;               /* Buffer for card-data. */  u16 data_size;                   /* Used space on the card (in byte). */  u16 card_size;                   /* Card's size. */  char *p;                         /* Pointer for getpass(). */  char ret;                        /* used to store returns of card func. */  u16 ctn = 0;                     /* Card-terminal handle. */  int position;                    /* Offset where free-memory is found. */  /* Get the password which shall be saved. */  if ((p = getpass(STR_PASSWORD_PROMPT)) == NULL)    return(POC_ERROR);  strncpy(password, p, 128);         /* Save it in 'password'. */  /* Get password's description. */  printf(STR_DESCR_PROMPT);  fgets(description, DESCR_LENGTH, stdin);  description[strlen(description) - 1] = '\0';  /* Initialize & reset card terminal. */  if ( (card_init_terminal(ctn, port) != POC_SUCCESS) ||       (card_reset_terminal(ctn) != POC_SUCCESS) ) {    /* If initialization fails, or resetting, we will return. */    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Request ICC and check whether a memory card is inserted. */  if (card_request_icc(ctn) != MEMORY_CARD) {    /* If no memory card is present we will return. */    print_err(STR_NO_MEM_CARD);    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Select card's memory for reading and writing. */  if (card_select_file(ctn) != POC_SUCCESS) {    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Allocate 2 byte to read card's size information. */  if ( (buffer = realloc(buffer, 2)) == NULL) {    print_err(ERR_PRFX_NM);    perror("");    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Read card's size, which is stored in byte 1 and 2 of the card.   * If 'ret' is not POC_SUCCESS, we will print an error message if a memory    * error occured and return. */  if ( (ret = card_read_data(ctn, CARD_SIZE_OFFSET, 2, buffer)) !=        POC_SUCCESS) {    if (ret == POC_MEM_ERR) {      print_err(ERR_PRFX_NM);      perror("");    }    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Convert the 2 chars to an unsigned short. */  card_size = (buffer[0] << 8) | buffer[1];  /* Read data size, which is stored in byte 3-4 of the card.   * If 'ret' is not POC_SUCCESS, we will print an error message if a memory    * error occured and return. */  if ( (ret = card_read_data(ctn, DATA_SIZE_OFFSET, 2, buffer)) !=       POC_SUCCESS) {    if (ret == POC_MEM_ERR) {      print_err(ERR_PRFX_NM);      perror("");    }    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Convert the 2 chars to an unsigned short. */  data_size = (buffer[0] << 8) | buffer[1];  if (data_size != 0) {    /* If the card is not empty, we need to read the current data. */    /* Allocate more memory to store card's data. */    if ( (buffer = realloc(buffer, data_size)) == NULL) {      print_err(ERR_PRFX_NM);      perror("");      wipe_out_data();      card_close_terminal(ctn);      return(POC_ERROR);    }    /* Read all data. */    if ( (ret = 	  card_read_data(ctn, DATA_AREA_START_OFFSET, data_size, buffer)) !=	 POC_SUCCESS) {      if (ret == POC_MEM_ERR) {	print_err(ERR_PRFX_NM);	perror("");      }      wipe_out_data();      card_close_terminal(ctn);      return(POC_ERROR);    }  }  /* Check whether encryption was selected or 'plaintext' instead. */  if (strcmp(card_crypt_ctx->cipher, "plaintext") != 0) {        /* Get the encryption key. */    if ((p = getpass(STR_KEY_PROMPT)) == NULL) {      wipe_out_data();      card_close_terminal(ctn);      return(POC_ERROR);    }    strncpy(key, p, 128);        /* Save it in 'key'. */    /* Ask user to re-enter the key to avoid typos. */    if (strcmp(key, getpass(STR_RETYPE_NEW_KEY_PROMPT)) != 0) {      /* Keys don't match. Return. */      print_err(STR_KEYS_DONT_MATCH);      wipe_out_data();      card_close_terminal(ctn);      return(POC_ERROR);    }        /*      * Call the cipher's key-schedule function, which will expand the key     * for the ciphers needs.     */    if ( (ret = cipher_setkey(card_crypt_ctx, key, strlen(key))) != 	 POC_SUCCESS) {      /* Key-Schedule failed. */      print_err(STR_CIPHER_SETKEY_ERR);      wipe_out_data();      card_close_terminal(ctn);      return(POC_ERROR);    }        /* If the card is empty, no decryption is needed. */    if (data_size != 0)      cipher_ofb(card_crypt_ctx, buffer, data_size);  /* Decryption */    /*     * After decrypting the data, we will check whether the key was correct.     * This is done by checking the buffer for unprintable characters.     */    if (check_buffer(buffer, data_size)) {      /* Wrong key? Buffer contains garbage. */      printf(STR_WARN_POSSIBLE_WRONG_KEY);      if (tolower(getchar()) != 'y') {              /* Continue anyway? */	wipe_out_data();	card_close_terminal(ctn);	return(POC_ERROR);      }    }	  }  /*    * Check whether there's enough free space left, to save new password +   *  description + password_tag(1 byte) + description_tag(1byte)    */  if ( (search_free_space(strlen(password) + strlen(description) + TAG_SIZE,	buffer, data_size, card_size - 4 - 1)) == -1) {    /* The card doesn't have enough free space left... */    print_err(STR_NO_SPACE_LEFT);    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /* Set offset. For storing new entry. */  position = data_size;  /* Allocate more space for new password + description + tags. */  if ( (buffer = realloc(buffer, data_size + strlen(description) + 			 strlen(password) + TAG_SIZE)) == NULL) {    print_err(ERR_PRFX_NM);     perror("");    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  /*   * Buffer now contains the memory image of the card plus free space   * for our new entry, which consits of the password its description and   * two tags.   *   * Now we will insert the new entry at the end of the image.   */  /* DESCRIPTION */  /* First we will store the description tag. */  buffer[position] = DESCRIPTION;  /* Now the description. */  memcpy(&buffer[++position], description, strlen(description));  /* Addjust the offset for start writing the password. */  position += strlen(description);  /* PASSWORD */  /* First the password tag. */  buffer[position] = PASSWORD;  /* ... and finally the password. */  memcpy(&buffer[++position], password, strlen(password));  /* Set new data-size. */  data_size += strlen(description) + strlen(password) + TAG_SIZE;  /*   * If the user didn't select plaintext "style" for storing passwords,   * we will encrypt the buffer before writing it to the card.   */  if (strcmp(card_crypt_ctx->cipher, "plaintext") != 0)    cipher_ofb(card_crypt_ctx, buffer, data_size);       /* Encrypt */  /* First we write the data size information to the card. */  /* We need to swap 'data_size' so we can use a 'u8' (char) pointer later. */  data_size = bswap_16(data_size);  if ( (ret = card_write_data(ctn, DATA_SIZE_OFFSET, 2, (u8 *) &data_size))       != POC_SUCCESS) {    if (ret == POC_MEM_ERR) {      print_err(ERR_PRFX_NM);      perror("");    }    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }   /* Now the data area will be written to the card. */  if ( (ret = card_write_data(ctn, DATA_AREA_START_OFFSET, bswap_16(data_size),			      buffer)) != POC_SUCCESS) {    if (ret == POC_MEM_ERR) {      print_err(ERR_PRFX_NM);      perror("");    }    wipe_out_data();    card_close_terminal(ctn);    return(POC_ERROR);  }  card_close_terminal(ctn);  /* wipe clean */  wipe_out_data();  /* wipe sensetive cipher specific data. */  cipher_wipe(card_crypt_ctx);  return(POC_SUCCESS);}/****************************************************************************** * * Function    : search_and_remove * * Description : This function remove a password + description entry from the *               card's data area. * * Input       : [1] description (char) *                   The description of the password which will be removed. *               [2] buffer (u8) *                   The buffer which contains an image of the card's data *                   area. * * Return      : -1 (error), 'j' (number of removed characters) * *****************************************************************************/static int search_and_remove(const char * const description, u8 * const buffer) {  int i = 0, j = 0;    /* Counters. */  u8 *ptr;             /* Pointer for the data area. */  /*   * This loop searches for the entry with the given description    * ('description') and removes the entry (password + description).   */  while (buffer[i] != '\0') {        /* Loop until we've reached the end. */        /*     * Every entry of the data area starts with the description followed by     * the password.     */    if (buffer[i] != DESCRIPTION)   /* Did we find a new entry? */      i++;                          /* Check next byte next time. */    else {                          /* Got an entry... */      ptr = &buffer[i];      i++;      /* Compare both descriptions. */      if (!strncasecmp(description, &ptr[1], strlen(description))) {	/* Ok, found the right entry. Now we will overwrite the entry. */	do {	  j++;	  *ptr++ = '\0';	} while (*ptr != DESCRIPTION && *ptr != '\0'); /* Stop if we are at							  the end of the							  image, or at the 							  beginning of another							  entry. */	return(j);                  /* Return number of removed characters. */      }    }  }  return(-1);                       /* No description matched the given one. */}/****************************************************************************** * * Function    : defrag_card * * Description : This function defragments the card's data area. * * Input       : [1] buffer (u8) *                   Image of the card's data area. *               [2] old_size (int) *                   Size of the data area, before an entry has been removed. *               [3] freed_space (int) *                   Size of the removed entry in byte. * * Return      : nothing is returned. * *****************************************************************************/static void defrag_card(u8 * const buffer, const int old_size, const int freed_space) {  int i;  for (i = strlen(buffer); i < old_size; i++)    buffer[i] = buffer[i + freed_space];  buffer[i] = '\0';             /* End with a trailing '\0'. */}#undef wipe_out_data/* Clean sensetive data. */#define wipe_out_data() {                     \  overwrite_buffer(p);                        \  overwrite_buffer(key);                      \  overwrite_buffer(buffer);                   \  drop_mbuffer(buffer);                       \}/****************************************************************************** * * Function    : password_remove * * Description : This function removes a data area entry, which has the  *               associated description. * * Input       : [1] card_crypt_ctx (crypt_context) *                   Information about data encryption (cipher, security-level) *               [2] port (u16) *                   Com-Port *               [3] description (char) *                   The entrie's description which shall be removed. * * Return      : POC_ERROR or POC_SUCCESS *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -