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

📄 cryptif.c

📁 Linux下的飞鸽传书
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2006 Takeharu KATO * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifdef HAVE_CONFIG_H#  include <config.h>#endif#include <gnome.h>#include <glib.h>#include <gconf/gconf-client.h>#include "callbacks.h"#include "interface.h"#include "support.h"#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include "common.h"static char *hexstr = "0123456789abcdef";static int get_hexstr_index(const char ch,char *index){  char *found=NULL;  char ind = 0;  int search_ch = 0;  search_ch = tolower((int)ch);  found=strchr(hexstr,(int)search_ch);  if (found == NULL) {    err_out("Character %c(%c in original message) can not be found.\n",	    search_ch, ch);    return -ESRCH;  }  ind=(char)(found - hexstr);#if 0  dbg_out("%c is %d th\n", ch, ind);#endif  *index = ind;  return 0;}intprint_hex(const char *buff,size_t len){  int i;  dbg_out("decode-in-hex:");  for (i=0;i<len;++i) {    dbg_out("%x",buff[i]>>4);    dbg_out("%x",buff[i]&0xf);  }  dbg_out("\n");}static intparse_encoded_message(const unsigned char *message,		      unsigned long *this_cap_p,		      unsigned char **hex_skey_p,		      unsigned char **enc_message_p,		      unsigned char **hex_sign_p){  int rc;  char *sp,*ep;  unsigned long this_cap;  unsigned char *hex_skey=NULL;  unsigned char *enc_message=NULL;  unsigned char *hex_sign=NULL;  char *buff=NULL;  if ( (!message) || (!this_cap_p) || (!hex_skey_p) || (!enc_message_p) )    return -EINVAL;  rc=-ENOMEM;  buff=g_strdup(message);  if (!buff)    goto error_out;  /*   *鍵情報   */  sp=buff;  ep=strchr(sp,':');  if (!ep) {    rc=-EINVAL;    err_out("Error : No cap\n");    goto free_buff_out;  }  *ep='\0';  ++ep;  errno=0;  this_cap=strtoul(sp, (char **)NULL, 16);  dbg_out("Cap:0x%x\n",this_cap);  /*   *暗号鍵   */  sp=ep;  ep=strchr(sp,':');  if (!ep) {    rc=-EINVAL;    err_out("Error : crypt key\n");    goto free_buff_out;  }  *ep='\0';  ++ep;  rc=-ENOMEM;  hex_skey=g_strdup(sp);  if (!hex_skey)    goto free_buff_out;  dbg_out("hex secret key:%s\n",hex_skey);  /*   *暗号化本文   */  sp=ep;  ep=strchr(sp,':');  if (ep) { /* これで最後の可能性もある  */    *ep='\0';    ++ep;  }  rc=-ENOMEM;  enc_message=g_strdup(sp);  if (!enc_message)    goto free_hex_skey_out;  dbg_out("hex secret body:%s\n",enc_message);  /*   *署名   */  if (ep) {    sp=ep;    rc=-ENOMEM;    hex_sign=g_strdup(sp);    if (!hex_sign)      goto free_enc_message_out;    dbg_out("hex sign:%s\n",hex_sign);  }  *this_cap_p=this_cap;  *hex_skey_p=hex_skey;  *enc_message_p=enc_message;  *hex_sign_p=hex_sign;  if (buff)    g_free(buff);  return 0; free_enc_message_out:  if (enc_message)    g_free(enc_message); free_hex_skey_out:  if (hex_skey)    g_free(hex_skey); free_buff_out:  if (buff)    g_free(buff); error_out:  return rc;}static intstring_bin2hex(const u_int8_t *bindata, int len,unsigned char **ret_p){  int rc;  int i;  size_t buf_len;  unsigned char *buff=NULL;  unsigned char *buff_p=NULL;  if ( (!bindata) || (!ret_p) )    return -EINVAL;  buf_len=len*2+1;  rc=-ENOMEM;  buff=g_malloc(buf_len);  if (!buff)    goto error_out;  memset(buff,0,buf_len);    for (i=0,buff_p=buff; i < len; ++i)    {      *buff_p++ = hexstr[bindata[i] >> 4];      *buff_p++ = hexstr[bindata[i] & 0x0f];    }  *buff_p = 0;  rc=0;  *ret_p=buff; error_out:  return rc;}static intstring_hex2bin(const char *hexdata, int *len,unsigned char **ret_p){  int rc;  int i;  size_t data_len;  size_t buf_len;  unsigned char *buff=NULL;  unsigned char *buff_p=NULL;  char low,high;  data_len=strlen(hexdata);  buf_len=data_len/2;  rc=-ENOMEM;  buff=g_malloc(buf_len);  if (!buff)    goto error_out;  memset(buff,0,buf_len);  for (i=0,buff_p=buff; (((i+1) < data_len)&&(hexdata[i]) && (hexdata[i+1])); )    {      rc=get_hexstr_index(hexdata[i++],&high);      if (rc)	goto error_out;      rc=get_hexstr_index(hexdata[i++],&low);      if (rc)	goto error_out;      *buff_p++ = ( ( (high << 4) & 0xf0)|(low & 0xf));    }    *ret_p=buff;  *len=buf_len;  return 0; error_out:  if (buff)    g_free(buff);  return rc;}intipmsg_encrypt_message(const char *peer_addr,const char *message,unsigned char **ret_str,size_t *len){  int rc;  int retry;  unsigned long peer_cap;  unsigned long skey_type,akey_type;  char *session_key=NULL;  char *enc_skey=NULL;  size_t skey_len;  char *key_e=NULL,*key_n=NULL;  char *raw_enc_body=NULL;  unsigned char *enc_body=NULL;  size_t enc_len;  unsigned char *encrypted_message=NULL;  size_t total_len;  unsigned char *sign=NULL;  unsigned long sign_type;  if ( (!peer_addr) || (!message) || (!ret_str) || (!len) )    return -EINVAL;  /*  相手の暗号化能力を取得  */  retry=PUBKEY_MAX_RETRY;  do{    rc=userdb_wait_public_key(peer_addr,&peer_cap,&key_e,&key_n);    if ( (rc<0) && (rc != -EINTR) )      return rc; /* 明示的なエラー */    if (!rc) {      /* 見付けた */      dbg_out("Found: \n\taddr=%s\ncap=%x\tpubkey-e=%s\n\tpubkey-n=%s\n",	      peer_addr,	      peer_cap,	      key_e,	      key_n);      break;     }    --retry;  }while(retry);    if ( (rc) && (!retry) )    goto free_peer_key_out;  /*   *暗号化アルゴリズムを選択   */  rc=select_symmetric_key(peer_cap,			  &skey_type,			  hostinfo_refer_ipmsg_crypt_policy_is_speed());  if (rc)    goto free_peer_key_out;    /*   * セッションキー作成と本文の暗号化   */  rc=symcrypt_encrypt_message(skey_type,message,&session_key,			      &skey_len,&raw_enc_body,&enc_len);  if (rc)    goto free_peer_key_out;  rc=string_bin2hex((const u_int8_t *)raw_enc_body, enc_len,&enc_body);  if (rc)    goto free_session_key_out;      /*   * セッションキーを暗号化   */  rc=pcrypt_encrypt_message(peer_cap,key_e,key_n,session_key,skey_len,&enc_skey,&akey_type);  if (rc)    goto free_enc_body_out;  total_len=sizeof(unsigned long)*2+strlen(enc_skey)+strlen(enc_body)+3;  rc=-ENOMEM;  encrypted_message=g_malloc(total_len);  if (!encrypted_message)    goto free_encoded_session_key;  /*    *署名を選択する   */  if (peer_cap & SIGN_CAPS) {    if (peer_cap & IPMSG_SIGN_MD5)      sign_type=IPMSG_SIGN_MD5;    if (peer_cap & IPMSG_SIGN_SHA1)      sign_type=IPMSG_SIGN_SHA1;  }else{    sign_type=0; /*  署名を使用しない  */  }  snprintf(encrypted_message,total_len,"%x:%s:%s",(skey_type|akey_type|sign_type),enc_skey,enc_body);  dbg_out("Encrypted body:%s\n",encrypted_message);  /*  FIXME 署名を選ぶ処理を分離すること  */  if (peer_cap & SIGN_CAPS) {    rc=pcrypt_sign(akey_type,sign_type,encrypted_message, &sign);    if (rc)      goto free_sign_out;    /*  本文を再作成  */    g_free(encrypted_message);    total_len += (strlen(sign)+3);    encrypted_message=g_malloc(total_len);    if (!encrypted_message)      goto free_sign_out;    snprintf(encrypted_message,total_len,"%x:%s:%s:%s",	     (skey_type|akey_type|sign_type),	     enc_skey,	     enc_body,	     sign);    dbg_out("Signed body:%s\n",encrypted_message);  }  *ret_str=encrypted_message;  *len=strlen(encrypted_message);  rc=0; free_sign_out:  if (sign)    g_free(sign); free_enc_body_out:  if (enc_body)    g_free(enc_body); free_encoded_session_key:  if (enc_skey)    g_free(enc_skey); free_session_key_out:  if (session_key)

⌨️ 快捷键说明

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