xLib/isnet_client.c File Reference

This graph shows which files directly or indirectly include this file:

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)

Function Documentation

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で無い場合は,サーバの確認を行う.

Parameters:
ahost 認証ホストの名前.
aport 認証ホストのポート番号.
userid ユーザID
passwd パスワード
chmode チャレンジキー交換モード.OFF:チャレンジキーを交換しない.ON:チャレンジキーを交換する. 暗号化通信が行われない場合は,強制的にチャレンジキーを交換する(ONになる).
keyex 鍵交換アルゴリズム
cryptm 共有鍵暗号アルゴリズム
cfn 認証ホストの公開鍵が保存されたファイル.認証ホスト検証用.NULLの場合は検証しない.
cont 暗号合意,またはサーバ確認に失敗した場合に処理を継続するかどうか. TRUE:処理を続ける.FALSE:エラーを返す.
Return values:
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 }

Here is the call graph for this function:

Buffer recv_mesg_until_end ( int  sock,
int  tm,
Buffer key,
EVP_CIPHER *  cipher 
)

Buffer recv_mesg_until_end(int sock, int tm, Buffer* key, EVP_CIPHER* cipher)

非暗号化データの場合は "END" が送られて来るまで,メッセージを受信し, バッファに追加する(簡易バッファリング機能あり).
暗号化データの場合は,改行コード(\r\n)が来るまで受信する.

Parameters:
sock サーバのソケット.
tm タイムアウト時間.秒単位.
key 暗号鍵
cipher 暗号方式
Returns:
受信データ."END"を含む.暗号の場合は復号化される.

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

Buffer send_algor_recv_spki ( int  sock,
char *  algor,
int  tm,
Buffer key,
EVP_CIPHER *  cipher 
)

Buffer send_algor_recv_spki(int sock, char* algor, int tm, Buffer* key, EVP_CIPHER* cipher)

サーバへ公開鍵暗号アルゴリズム algorを使用することを通知し,サーバから SPKIをもらう.

Parameters:
sock サーバへのソケット
algor 使用アルゴリズム.現在サポートしているのは "DH" のみ.
tm タイムアウト(sec)
key 暗号鍵
cipher 暗号方式
Returns:
サーバの X.509 SPKI (DER)

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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" の返答を待つ.

Parameters:
sock サーバのソケット.
command サーバへ送るコマンド.
tm タイムアウト時間.秒単位.
key 暗号鍵
cipher 暗号方式
Return values:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

int send_spki_recv_ans ( int  sock,
Buffer  mkey,
int  tm,
Buffer key,
EVP_CIPHER *  cipher 
)

int send_spki_recv_ans(int sock, Buffer mkey, int tm, Buffer* key, EVP_CIPHER* cipher)

サーバへ自分の SPKI(DER)を送信して,返答を待つ.

Parameters:
sock サーバへのソケット
mkey 自分の SPKI (DER)
tm タイムアウト(sec)
key 暗号鍵
cipher 暗号方式
Return values:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

int start_CRYPT_transfer ( int  sock,
int  keyex,
int  cryptm,
Buffer  ipaddr,
char *  cfn,
int  tm,
Buffer shdkey,
EVP_CIPHER **  cipher 
)

int start_CRYPT_transfer(int sock, int keyex, int cryptm, Buffer ipaddr, char* cfn, int tm, Buffer* shdkey, EVP_CIPHER** cipher)

サーバ側と暗号化通信を行うためのネゴシエーションを行う.

ネゴシエーションが成功した場合,この関数終了後から暗号化通信が始まる.

Parameters:
sock 認証ホストへのソケット.
keyex 鍵交換アルゴリズムを指定(現在の所,SSL_DH のみ).
cryptm 共通鍵暗号のアルゴリズム
ipaddr 認証ホストのIPアドレス.認証ホスト検証用.
cfn 認証ホストの公開鍵が保存されたファイル.認証ホスト検証用.NULLの場合は検証しない.
tm タイムアウト(sec)
[out] shdkey 共通鍵が返る.
[out] cipher 暗号タイプが返る.
Return values:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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)

クライアント側での暗号化通信終了処理.

サーバに暗号使用終了を伝え,自分も使用を終了する.

Parameters:
sock サーバへのソケット
tm タイムアウト時間(sec)
shdkey 共通鍵
cipher 暗号タイプが返る.
Return values:
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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on 15 Nov 2023 for JunkBox_Lib by  doxygen 1.6.1