📄 change.c
字号:
/* * 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: change.c,v 1.5 2001/08/18 16:07:49 henning Exp $ */#include <config.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <ctype.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "poc.h"#include "poc_types.h"#include "poc_macros.h"#include "cardinfo.h"#include "card.h"#include "cipher.h"#include "lang.h"#include "misc.h"/* Clean sensetive data. */#define wipe_out_data() { \ overwrite_buffer(p); \ overwrite_buffer(key); \ overwrite_buffer(buffer); \ drop_mbuffer(buffer); \}/****************************************************************************** * * Function : change_card_key * * Description : This function changes the key with which the card's data is * encrypted. * * 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 change_card_key(const crypt_context * const card_crypt_ctx, const u16 port) { char key[128]; /* Encryption key. */ char *p = NULL; /* Pointer for getpass(3). */ char ret; /* Returns of CT-API calls. */ u8 *buffer = NULL; /* Buffer for storing card's data. */ u16 ctn = 0; /* Card-terminal handle. */ u16 data_size; /* Size of card's data. */ u16 card_size; /* Card's size. */ /* 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 to the caller. */ 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); card_close_terminal(ctn); return(POC_ERROR); } /* Select card's memory so we can read/write to it. */ if (card_select_file(ctn) != POC_SUCCESS) { card_close_terminal(ctn); return(POC_ERROR); } /* Allocate 2 byte to read card's size information. */ if ( (buffer = realloc(buffer, 2)) == NULL) { /* Allocation failed. */ print_err(ERR_PRFX_NM); perror(""); 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(""); perror(""); } wipe_out_data(); /* Wipe sensetive 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(); /* Wipe sensetive data. */ card_close_terminal(ctn); return(POC_ERROR); } /* Convert the 2 chars to an unsigned short. */ data_size = (buffer[0] << 8) | buffer[1]; /* If the card doesn't contain any data, we will return. */ if (data_size == 0) { print_err(STR_EMPTY_CARD); return(POC_ERROR); } /* Allocate memory to store card's data for later cryptographic actions. */ if ( (buffer = realloc(buffer, data_size)) == NULL) { print_err(ERR_PRFX_NM); perror(""); 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(""); } card_close_terminal(ctn); return(POC_ERROR); } /* * If the user specified 'plaintext' as the cipher (--cipher, option), the * card is not encrypted and we will not change anything. */ if (strcmp(card_crypt_ctx->cipher, "plaintext") == 0) { print_err(STR_CARD_NOT_ENCRYPTED); return(POC_ERROR); } /* Get the current encryption key. */ if ((p = getpass(STR_KEY_PROMPT)) == NULL) { wipe_out_data(); card_close_terminal(ctn); return(POC_ERROR); } strncpy(key, p, 128); /* Copy it to 'key' for later processing. */ /* Call the key-schedule function, which will expand the key for * later decryption. */ if ( (ret = cipher_setkey(card_crypt_ctx, key, strlen(key))) != POC_SUCCESS) { /* If the key-schedule failed, we will bail out. */ print_err(STR_CIPHER_SETKEY_ERR); wipe_out_data(); card_close_terminal(ctn); return(POC_ERROR); } /* Decrypt card's data, which is stored in 'buffer'. */ cipher_ofb(card_crypt_ctx, buffer, data_size); /* Check whether the key was correct, by testing the buffer for unprintable characters. */ /* * 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)) { /* * Something went wrong. The buffer contains non-printable characters, * so we suppose the key was wrong. We will print a warning and ask the * user whether we shall continue or stop. */ printf(STR_WARN_POSSIBLE_WRONG_KEY); if (tolower(getchar()) != 'y') { wipe_out_data(); card_close_terminal(ctn); return(POC_ERROR); } } /* Now we will ask the user to enter the new key. */ if ((p = getpass(STR_NEW_KEY_PROMPT)) == NULL) { wipe_out_data(); card_close_terminal(ctn); return(POC_ERROR); } strncpy(key, p, 128); /* Copy it to 'key' for later processing. */ /* Ask user to confirm the key. */ if (strcmp(key, getpass(STR_RETYPE_NEW_KEY_PROMPT)) != 0) { /* Mmm keys don't match. */ print_err(STR_KEYS_DONT_MATCH); wipe_out_data(); card_close_terminal(ctn); return(POC_ERROR); } /* * Call the key-schedule function, which will expand the key for later * encryption with the new key. */ if ( (ret = cipher_setkey(card_crypt_ctx, key, strlen(key))) != POC_SUCCESS) { print_err(STR_CIPHER_SETKEY_ERR); wipe_out_data(); card_close_terminal(ctn); return(POC_ERROR); } /* Encrypt the data with our new key. */ cipher_ofb(card_crypt_ctx, buffer, data_size); /* * Ok, the keys have been changed, so we will write the data back to the * card. */ if ( (ret = card_write_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); } card_close_terminal(ctn); /* Everything done. Close the terminal. */ wipe_out_data(); /* Wipe out sensetive data!! */ cipher_wipe(card_crypt_ctx); /* Wipe out cipher specific sensetive data. */ return(POC_SUCCESS); /* Everything worked... */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -