Go to the source code of this file.
Functions | |
int | send_command_recv_ans (int sock, char *command, int tm, Buffer *key, EVP_CIPHER *cipher) |
Buffer | recv_mesg_until_end (int sock, int tm, Buffer *key, EVP_CIPHER *cipher) |
Buffer | send_algor_recv_spki (int sock, char *algor, int tm, Buffer *key, EVP_CIPHER *cipher) |
int | send_spki_recv_ans (int sock, Buffer mkey, int tm, Buffer *key, EVP_CIPHER *cipher) |
int | check_auth (Buffer ahost, int aport, Buffer userid, Buffer passwd, int chmode, int keyex, int cryptm, char *cfn, int cont) |
int | start_CRYPT_transfer (int sock, int keyex, int cryptm, Buffer ipaddr, char *cfn, int tm, Buffer *shdkey, EVP_CIPHER **cipher) |
int | stop_CRYPT_transfer (int sock, int tm, Buffer *shdkey, EVP_CIPHER *cipher) |
int check_auth | ( | Buffer | ahost, | |
int | aport, | |||
Buffer | userid, | |||
Buffer | passwd, | |||
int | chmode, | |||
int | keyex, | |||
int | cryptm, | |||
char * | cfn, | |||
int | cont | |||
) |
int check_auth(Buffer ahost, int aport, Buffer userid, Buffer passwd, int keyex, int cryptm, char* cfn, int cont)
認証サーバに接続し,認証を行なう.
keyex, cryptm が両方指定してある場合には暗号化通信が行なわれる. 暗号化通信を行ない,かつ cfn がNULLで無い場合は,サーバの確認を行う.
ahost | 認証ホストの名前. | |
aport | 認証ホストのポート番号. | |
userid | ユーザID | |
passwd | パスワード | |
chmode | チャレンジキー交換モード.OFF:チャレンジキーを交換しない.ON:チャレンジキーを交換する. 暗号化通信が行われない場合は,強制的にチャレンジキーを交換する(ONになる). | |
keyex | 鍵交換アルゴリズム | |
cryptm | 共有鍵暗号アルゴリズム | |
cfn | 認証ホストの公開鍵が保存されたファイル.認証ホスト検証用.NULLの場合は検証しない. | |
cont | 暗号合意,またはサーバ確認に失敗した場合に処理を継続するかどうか. TRUE:処理を続ける.FALSE:エラーを返す. |
0 | 正常終了. | |
JBXL_ISNET_PASSWD_ERROR | ユーザ認証失敗(ユーザは存在するが,パスワードが一致しない) | |
JBXL_ISNET_USER_ERROR | ユーザ認証失敗(ユーザが存在しない) | |
JBXL_ISNET_CONNECT_ERROR | 認証サーバとの接続エラー | |
JBXL_ISNET_START_ERROR | 認証サーバとの通信開始エラー (相手は認証サーバでない?) | |
JBXL_ISNET_AGREE_ERROR | 暗号合意エラー(サーバ認証を含む) | |
JBXL_ISNET_CHALLENGE_ERROR | チャレンジキー合意エラー |
Definition at line 213 of file isnet_client.c.
References Buffer::buf, cat_Buffer(), cat_s2Buffer, clear_Buffer(), copy_s2Buffer, DEBUG_MODE, FALSE, free_Buffer(), free_EVP_CIPHER(), freeNull, get_ipaddr_byname(), init_Buffer(), JBXL_ARGS_ERROR, JBXL_ISNET_CHALLENGE_ERROR, JBXL_ISNET_CONNECT_ERROR, JBXL_ISNET_PASSWD_ERROR, JBXL_ISNET_START_ERROR, JBXL_ISNET_USER_ERROR, LBUF, make_Buffer(), make_Buffer_bystr, ON, PRINT_MESG, recv_mesg_until_end(), send_command_recv_ans(), socket_close(), start_CRYPT_transfer(), stop_CRYPT_transfer(), tcp_client_socket, TRUE, and x2crypt().
00214 { 00215 int cryptf, sock, cc, tm = 10; 00216 Buffer ipaddr, buf, salt; 00217 Buffer shdkey; 00218 char* pass; 00219 char* chip; 00220 00221 if (ahost.buf==NULL) return JBXL_ARGS_ERROR; 00222 00223 // 認証サーバへ接続 00224 sock = tcp_client_socket((char*)ahost.buf, aport); 00225 if (sock<0) { 00226 DEBUG_MODE PRINT_MESG("CHECK_AUTH: auth server open error.\n"); 00227 return JBXL_ISNET_CONNECT_ERROR; 00228 } 00229 DEBUG_MODE PRINT_MESG("CHECK_AUTH: auth server opened.\n"); 00230 00231 // 通信開始 00232 cc = send_command_recv_ans(sock, (char*)"HELLO", tm, NULL, NULL); 00233 if (cc!=0) { 00234 socket_close(sock); 00235 return JBXL_ISNET_START_ERROR; 00236 } 00237 00238 shdkey = init_Buffer(); 00239 // supported only DH now 00240 //if (keyex!=SSL_DH) return JBXL_ISNET_PUBKEYALG_ERROR; 00241 00242 // 暗号合意 00243 cryptf = FALSE; 00244 EVP_CIPHER* cipher = NULL; 00245 if (keyex!=0 && cryptm!=0) { 00246 cryptf = TRUE; 00247 chip = get_ipaddr_byname((char*)ahost.buf, AF_INET); 00248 ipaddr = make_Buffer_bystr(chip); 00249 freeNull(chip); 00250 cc = start_CRYPT_transfer(sock, keyex, cryptm, ipaddr, cfn, tm, &shdkey, &cipher); 00251 free_Buffer(&ipaddr); 00252 if (cc!=0 && !cont) { 00253 free_EVP_CIPHER(&cipher); 00254 socket_close(sock); 00255 return cc; 00256 } 00257 // 以後暗号化通信 00258 } 00259 00260 // チャレンジキー合意 00261 if (cryptf==FALSE) chmode = ON; 00262 00263 if (chmode==ON) { 00264 cc = send_command_recv_ans(sock, (char*)"KEYEX CHLNG", tm, &shdkey, cipher); 00265 if (cc!=0) { 00266 socket_close(sock); 00267 return JBXL_ISNET_CHALLENGE_ERROR; 00268 } 00269 } 00270 else { 00271 cc = send_command_recv_ans(sock, (char*)"KEYEX NOCHLNG", tm, &shdkey, cipher); 00272 if (cc!=0) { 00273 if (cc==169) { // Unkown KEYEX operand. Support for old version. 00274 chmode = ON; 00275 } 00276 else { 00277 socket_close(sock); 00278 return JBXL_ISNET_CHALLENGE_ERROR; 00279 } 00280 } 00281 } 00282 00284 // ユーザIDを送る. 00285 buf = make_Buffer(LBUF); 00286 copy_s2Buffer("USERID ", &buf); 00287 cat_Buffer(&userid, &buf); 00288 cc = send_command_recv_ans(sock, (char*)buf.buf, tm, &shdkey, cipher); 00289 if (cc!=0) { 00290 free_Buffer(&buf); 00291 free_EVP_CIPHER(&cipher); 00292 socket_close(sock); 00293 return JBXL_ISNET_USER_ERROR; 00294 } 00295 00296 // SALTを得る. 00297 if (chmode==ON) { 00298 salt = recv_mesg_until_end(sock, tm, &shdkey, cipher); 00299 //DEBUG_MODE PRINT_ESC("SALT = [%s]\n", (char*)salt.buf); 00300 } 00301 clear_Buffer(&buf); 00302 00303 // パスワードを計算して送る. 00304 copy_s2Buffer("PASSWD ", &buf); 00305 if (chmode==ON) { 00306 pass = x2crypt((char*)passwd.buf, (char*)salt.buf); 00307 cat_s2Buffer(pass, &buf); 00308 freeNull(pass); 00309 } 00310 else { 00311 cat_s2Buffer((char*)passwd.buf, &buf); 00312 } 00313 cc = send_command_recv_ans(sock, (char*)buf.buf, tm, &shdkey, cipher); 00314 free_Buffer(&buf); 00315 00316 if (cc) { 00317 free_EVP_CIPHER(&cipher); 00318 socket_close(sock); 00319 return JBXL_ISNET_PASSWD_ERROR; 00320 } 00321 00322 // 暗号化通信終了 00323 if (cryptf) cc = stop_CRYPT_transfer(sock, tm, &shdkey, cipher); 00324 00325 cc = send_command_recv_ans(sock, (char*)"BYE", tm, &shdkey, cipher); 00326 00327 socket_close(sock); 00328 DEBUG_MODE PRINT_MESG("CHECK_AUTH: auth server normally closed.\n"); 00329 00330 free_EVP_CIPHER(&cipher); 00331 if (cryptf) free_Buffer(&shdkey); 00332 00333 return 0; 00334 }
Buffer recv_mesg_until_end(int sock, int tm, Buffer* key, EVP_CIPHER* cipher)
非暗号化データの場合は "END" が送られて来るまで,メッセージを受信し, バッファに追加する(簡易バッファリング機能あり).
暗号化データの場合は,改行コード(\r\n)が来るまで受信する.
sock | サーバのソケット. | |
tm | タイムアウト時間.秒単位. | |
key | 暗号鍵 | |
cipher | 暗号方式 |
Definition at line 79 of file isnet_client.c.
References Buffer::buf, cat_Buffer(), clear_Buffer(), free_Buffer(), get_plain_sBuffer(), LBUF, make_Buffer(), RECVBUFSZ, strnrvscmp(), and tcp_recv_Buffer_wait().
Referenced by check_auth(), and send_algor_recv_spki().
00080 { 00081 int cc; 00082 Buffer ret, buf, dec; 00083 00084 ret = make_Buffer(LBUF); 00085 buf = make_Buffer(RECVBUFSZ); 00086 00087 do { 00088 cc = tcp_recv_Buffer_wait(sock, &buf, tm); 00089 if (cc>0) { 00090 cat_Buffer(&buf, &ret); 00091 clear_Buffer(&buf); 00092 if (key!=NULL && cipher!=NULL) { 00093 if (!strnrvscmp("\r\n", (const char*)ret.buf, 2)) break; 00094 } 00095 else { 00096 if (!strnrvscmp("\r\nEND\r\n", (const char*)ret.buf, 7) || 00097 !strnrvscmp("\nEND\n", (const char*)ret.buf, 5)) break; 00098 } 00099 } 00100 } while(cc>0); 00101 00102 dec = get_plain_sBuffer(ret, key, cipher); 00103 free_Buffer(&buf); 00104 free_Buffer(&ret); 00105 return dec; 00106 }
Buffer send_algor_recv_spki(int sock, char* algor, int tm, Buffer* key, EVP_CIPHER* cipher)
サーバへ公開鍵暗号アルゴリズム algorを使用することを通知し,サーバから SPKIをもらう.
sock | サーバへのソケット | |
algor | 使用アルゴリズム.現在サポートしているのは "DH" のみ. | |
tm | タイムアウト(sec) | |
key | 暗号鍵 | |
cipher | 暗号方式 |
Definition at line 123 of file isnet_client.c.
References Buffer::buf, cat_s2Buffer, decode_base64_Buffer(), free_Buffer(), get_line_Buffer(), init_Buffer(), make_Buffer_bystr, recv_mesg_until_end(), send_command_recv_ans(), and Buffer::state.
Referenced by start_CRYPT_transfer().
00124 { 00125 int cc; 00126 Buffer com, ret, buf; 00127 00128 ret = init_Buffer(); // 初期化 00129 if (algor==NULL) return ret; 00130 00131 com = make_Buffer_bystr((char*)"KEYEX "); 00132 cat_s2Buffer(algor, &com); 00133 cc = send_command_recv_ans(sock, (char*)com.buf, tm, key, cipher); 00134 free_Buffer(&com); 00135 if (cc!=0) { ret.state = cc; return ret; } 00136 00137 ret = recv_mesg_until_end(sock, tm, key, cipher); // サーバの返答 00138 buf = get_line_Buffer(ret, 1); // SPKI(BASE64) 00139 free_Buffer(&ret); 00140 00141 ret = decode_base64_Buffer(buf); // 鍵をデコードする. 00142 free_Buffer(&buf); 00143 00144 return ret; 00145 }
int send_command_recv_ans | ( | int | sock, | |
char * | command, | |||
int | tm, | |||
Buffer * | key, | |||
EVP_CIPHER * | cipher | |||
) |
int send_command_recv_ans(int sock, char* command, int tm, Buffer* key, EVP_CIPHER* cipher)
サーバにコマンド(\r\nを自動的に添付)を送り,"OK" か "ERR" の返答を待つ.
sock | サーバのソケット. | |
command | サーバへ送るコマンド. | |
tm | タイムアウト時間.秒単位. | |
key | 暗号鍵 | |
cipher | 暗号方式 |
0 | 正常終了 (サーバから "OK" を受信した) | |
1以上 | エラー番号(サーバから "ERR"を受信した). | |
JBXL_NET_RECV_ERROR | 通信エラー | |
JBXL_ARGS_ERROR | コマンドが NULL. | |
JBXL_ISNET_CMD_ERROR | サーバから "OK", "ERR" 以外のものを受信した. |
Definition at line 23 of file isnet_client.c.
References Buffer::buf, cat_s2Buffer, chomp_Buffer(), copy_s2Buffer, DEBUG_MODE, free_Buffer(), get_command(), get_operand(), get_plain_sBuffer(), JBXL_ARGS_ERROR, JBXL_ISNET_CMD_ERROR, LNAME, make_Buffer(), PRINT_MESG, tcp_recv_Buffer_wait(), and tcp_send_crypt_sBuffer().
Referenced by check_auth(), send_algor_recv_spki(), send_spki_recv_ans(), start_CRYPT_transfer(), and stop_CRYPT_transfer().
00024 { 00025 int cc, nn; 00026 Buffer ret, ans, buf, eno; 00027 00028 if (command==NULL) return JBXL_ARGS_ERROR; 00029 00030 buf = make_Buffer(LNAME); 00031 copy_s2Buffer(command, &buf); 00032 cat_s2Buffer("\r\n", &buf); 00033 cc = tcp_send_crypt_sBuffer(sock, &buf, key, cipher); 00034 free_Buffer(&buf); 00035 00036 ret = make_Buffer(LNAME); 00037 cc = tcp_recv_Buffer_wait(sock, &ret, tm); 00038 if (cc<=0) { 00039 free_Buffer(&ret); 00040 return cc; 00041 } 00042 buf = get_plain_sBuffer(ret, key, cipher); 00043 chomp_Buffer(&buf); 00044 ans = get_command(buf); 00045 00046 if (!strcmp("OK", (const char*)ans.buf)) nn = 0; 00047 else if (!strcmp("ERR", (const char*)ans.buf)) { 00048 eno = get_operand(buf); 00049 nn = atoi((const char*)eno.buf); 00050 free_Buffer(&eno); 00051 DEBUG_MODE PRINT_MESG("SEND_COMMAND_RECV_ANS: error = %d\n", nn); 00052 } 00053 else nn = JBXL_ISNET_CMD_ERROR; 00054 00055 free_Buffer(&ret); 00056 free_Buffer(&buf); 00057 free_Buffer(&ans); 00058 00059 return nn; 00060 }
int send_spki_recv_ans(int sock, Buffer mkey, int tm, Buffer* key, EVP_CIPHER* cipher)
サーバへ自分の SPKI(DER)を送信して,返答を待つ.
sock | サーバへのソケット | |
mkey | 自分の SPKI (DER) | |
tm | タイムアウト(sec) | |
key | 暗号鍵 | |
cipher | 暗号方式 |
0 | 正常終了 | |
0以外 | サーバからのエラー番号 |
Definition at line 163 of file isnet_client.c.
References Buffer::buf, encode_base64_Buffer(), free_Buffer(), and send_command_recv_ans().
Referenced by start_CRYPT_transfer().
00164 { 00165 int cc; 00166 Buffer enc; 00167 00168 cc = send_command_recv_ans(sock, (char*)"KEYEX SPKI", tm, key, cipher); 00169 if (cc!=0) return cc; 00170 00171 enc = encode_base64_Buffer(mkey); // 自分の公開鍵情報をエンコード 00172 cc = send_command_recv_ans(sock, (char*)enc.buf, tm, key, cipher); 00173 free_Buffer(&enc); 00174 00175 return cc; 00176 }
int start_CRYPT_transfer | ( | int | sock, | |
int | keyex, | |||
int | cryptm, | |||
Buffer | ipaddr, | |||
char * | cfn, | |||
int | tm, | |||
Buffer * | shdkey, | |||
EVP_CIPHER ** | cipher | |||
) |
サーバ側と暗号化通信を行うためのネゴシエーションを行う.
ネゴシエーションが成功した場合,この関数終了後から暗号化通信が始まる.
sock | 認証ホストへのソケット. | |
keyex | 鍵交換アルゴリズムを指定(現在の所,SSL_DH のみ). | |
cryptm | 共通鍵暗号のアルゴリズム | |
ipaddr | 認証ホストのIPアドレス.認証ホスト検証用. | |
cfn | 認証ホストの公開鍵が保存されたファイル.認証ホスト検証用.NULLの場合は検証しない. | |
tm | タイムアウト(sec) | |
[out] | shdkey | 共通鍵が返る. |
[out] | cipher | 暗号タイプが返る. |
0 | 成功.これ以後,暗号化による通信を行う. | |
JBXL_ISNET_SERVER_ERROR | 認証ホストの検証エラー | |
JBXL_ISNET_PUBKEYALG_ERROR | 知らない公開鍵暗号アルゴリズム | |
JBXL_ISNET_CMNKEYALG_ERROR | 知らない共通鍵暗号アルゴリズム | |
JBXL_ISNET_NULLANS_ERROR | サーバからの返答が NULL |
Definition at line 365 of file isnet_client.c.
References Buffer::buf, check_server_spki(), free_Buffer(), gen_CRYPT_SharedKey(), gen_DHspki_fs(), init_EVPAPI_Buffer(), JBXL_ISNET_DHKEY_ERROR, JBXL_ISNET_NULLANS_ERROR, JBXL_ISNET_PUBKEYALG_ERROR, JBXL_ISNET_SERVER_ERROR, PRINT_MESG, send_algor_recv_spki(), send_command_recv_ans(), send_spki_recv_ans(), SSL_3DES3CBC, SSL_AES128CBC, and SSL_DH.
Referenced by check_auth().
00366 { 00367 Buffer spki, mpki; 00368 00369 if (cfn!=NULL && ipaddr.buf!=NULL) { 00370 if (!check_server_spki(ipaddr, spki, cfn)) return JBXL_ISNET_SERVER_ERROR; 00371 } 00372 00373 if (keyex==SSL_DH) { 00374 spki = send_algor_recv_spki(sock, (char*)"DH", tm, NULL, NULL); 00375 // 00376 if (spki.buf!=NULL) { 00377 DH* dhkey = NULL; 00378 mpki = gen_DHspki_fs(spki, &dhkey); 00379 if (dhkey!=NULL) { 00380 gen_CRYPT_SharedKey(keyex, spki, shdkey, (void*)dhkey); 00381 DH_free(dhkey); 00382 } 00383 else { 00384 PRINT_MESG("ERROR: start_CRYPT_transfer: DH Key is NULL\n"); 00385 return JBXL_ISNET_DHKEY_ERROR; 00386 } 00387 } 00388 else { 00389 PRINT_MESG("ERROR: start_CRYPT_transfer: spki is NULL\n"); 00390 return JBXL_ISNET_NULLANS_ERROR; 00391 } 00392 } 00393 //else if (keyex==SSL_RSA) spki = send_algor_recv_spki(sock, (char*)"RSA", tm); 00394 else return JBXL_ISNET_PUBKEYALG_ERROR; 00395 00396 /* 00397 DEBUG_MODE { 00398 Buffer enc; 00399 enc = encode_base64_Buffer(spki); 00400 PRINT_MESG("SERVER SPKI = [%s]\n", enc.buf); 00401 free_Buffer(&enc); 00402 }*/ 00403 00404 int cc = send_spki_recv_ans(sock, mpki, tm, NULL, NULL); 00405 if (cc==0) { 00406 if (cryptm==SSL_AES128CBC) { 00407 cc = send_command_recv_ans(sock, (char*)"CRYPT AES128CBC", tm, NULL, NULL); 00408 *cipher = init_EVPAPI_Buffer(SSL_AES128CBC); 00409 } 00410 else if (cryptm==SSL_3DES3CBC) { 00411 cc = send_command_recv_ans(sock, (char*)"CRYPT 3DES3CBC", tm, NULL, NULL); 00412 *cipher = init_EVPAPI_Buffer(SSL_3DES3CBC); 00413 } 00414 } 00415 00416 free_Buffer(&spki); 00417 free_Buffer(&mpki); 00418 if (cc!=0) { 00419 free_Buffer(shdkey); 00420 *cipher = NULL; 00421 return cc; 00422 } 00423 00424 return 0; 00425 }
int stop_CRYPT_transfer | ( | int | sock, | |
int | tm, | |||
Buffer * | shdkey, | |||
EVP_CIPHER * | cipher | |||
) |
int stop_CRYPT_transfer(int sock, int tm, Buffer* shdkey, EVP_CIPHER* cipher)
クライアント側での暗号化通信終了処理.
サーバに暗号使用終了を伝え,自分も使用を終了する.
sock | サーバへのソケット | |
tm | タイムアウト時間(sec) | |
shdkey | 共通鍵 | |
cipher | 暗号タイプが返る. |
0 | 正常終了 (サーバから"OK"を受信した) | |
1以上 | エラー番号(サーバから"ERR"を受信した). | |
負数 | エラー |
Definition at line 445 of file isnet_client.c.
References send_command_recv_ans().
Referenced by check_auth().
00446 { 00447 int cc; 00448 00449 cc = send_command_recv_ans(sock, (char*)"CRYPT RESET", tm, shdkey, cipher); 00450 return cc; 00451 }