?? cryptif.c
字號:
/* * 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)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -