Logo Search packages:      
Sourcecode: g2ipmsg version File versions  Download package

int ipmsg_encrypt_message ( const char *  peer_addr,
const char *  message,
unsigned char **  ret_str,
size_t *  len 
)

メッセージを暗号化する

Parameters:
[in] peer_addr 送信先IPアドレス
[in] message 暗号化するメッセージ
[out] ret_str 暗号化したメッセージを指すポインタ変数のアドレス
[out] len 暗号化メッセージ長返却領域
Return values:
0 正常終了
-EINVAL 引数異常

Definition at line 354 of file cryptif.c.

References pcrypt_encrypt_message(), pcrypt_sign(), PUBKEY_MAX_RETRY, select_signature(), select_symmetric_key(), string_bin2hex(), and symcrypt_encrypt_message().

Referenced by ipmsg_send_sendmsg_packets().

                                          {
      int                           rc = 0;
      int                        retry = 0;
      unsigned long           peer_cap = 0;
      unsigned long          skey_type = 0, akey_type = 0;
      char                *session_key = NULL;
      char                   *enc_skey = NULL;
      size_t                  skey_len = 0;
      char                      *key_e = NULL, *key_n = NULL;
      char               *raw_enc_body = NULL;
      unsigned char          *enc_body = NULL;
      size_t                   enc_len = 0;
      unsigned char *encrypted_message = NULL;
      size_t                 total_len = 0;
      unsigned char              *sign = NULL;
      unsigned long         sign_type = 0;
      int                           i = 0;

      if ( (peer_addr == NULL) || (message == NULL) || 
           (ret_str == NULL) || (len == NULL) ) {
            rc = -EINVAL;
            goto error_out;
      }

      /*  相手の暗号化能力を取得  */
      retry = PUBKEY_MAX_RETRY;
      do{
            rc = userdb_wait_public_key(peer_addr, &peer_cap, &key_e, &key_n);
            if ( (rc < 0) && (rc != -EINTR) ) {
                  goto error_out; /* 明示的なエラー */
            }
            if (rc == 0) { /* 見付けた */
                  dbg_out("Found: \n\taddr = %s\n"
                      "\tcap = %x\n"
                      "\tpubkey-e = %s\n"
                      "\tpubkey-n = %s\n",
                      peer_addr,
                      peer_cap,
                      key_e,
                      key_n);

                  break; 
            }
            --retry;
      } while(retry > 0);
  
      if ( (rc != 0) && (retry == 0) )
            goto free_peer_key_out; /* 取得失敗 */

      /*
       *暗号化アルゴリズムを選択
       */
      rc = select_symmetric_key(peer_cap, &skey_type, 
          hostinfo_refer_ipmsg_crypt_policy_is_speed());
      if (rc != 0)
            goto free_peer_key_out;
      
      /*
       * セッションキー作成と本文の暗号化
       */
      rc = symcrypt_encrypt_message(skey_type, message, &session_key,
          &skey_len, &raw_enc_body, &enc_len);
      if (rc != 0)
            goto free_peer_key_out;

      rc = string_bin2hex((const u_int8_t *)raw_enc_body, enc_len, &enc_body);
      if (rc != 0)
            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 != 0)
            goto free_enc_body_out;
      /*
       * 暗号化文字列長取得
       * longの長さは, 64ビット環境の場合は, 8バイトになるので, 
       * 1バイトあたりの表示領域長(2)をlongのバイト長文だけ掛け合わせることで,
       * 領域長に対するアーキ依存性を排除する.
       * +3はデリミタ(':')2つとヌルターミネートの分 
       */
      total_len = sizeof(unsigned long) * 2 + strlen(enc_skey) + strlen(enc_body) + 3;

      encrypted_message = g_malloc(total_len);
      if (encrypted_message == NULL) {
            rc = -ENOMEM;
            goto free_encoded_session_key;
      }

      /* 
       *署名を選択する
       */
      rc = select_signature(peer_cap, &sign_type, 
          hostinfo_refer_ipmsg_crypt_policy_is_speed());
      if (rc != 0) {
            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);

      if (sign_type != 0) {
            /*
             * 小文字に変換
             */
            for(i = 0; i < total_len; ++i) {
                  encrypted_message[i] = tolower((int)encrypted_message[i]);
            }
            rc = pcrypt_sign(akey_type, sign_type, encrypted_message, &sign);

            if (rc != 0)
                  goto free_sign_out;

            g_free(encrypted_message);    
            /*  
             * 署名を付して本文を再作成  
             */
            total_len += (strlen(sign) + 1); /* +1は, デリミタ分 */
            encrypted_message = g_malloc(total_len);
            if (encrypted_message == NULL)
                  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);
      }

      /*
       * 小文字に変換
       */
      total_len = strlen(encrypted_message);
      for(i = 0; i < total_len; ++i) {
            encrypted_message[i] = tolower((int)encrypted_message[i]);
      }
      
      /*
       * 解析結果返却
       */

      *ret_str = encrypted_message;
      *len     = total_len;

      rc = 0;

free_sign_out:
      if (sign != NULL)
            g_free(sign);

free_enc_body_out:
      if (enc_body != NULL)
            g_free(enc_body);

free_encoded_session_key:
      if (enc_skey != NULL)
            g_free(enc_skey);

free_session_key_out:
      if (session_key != NULL)
            g_free(session_key);

      if (raw_enc_body != NULL)
            g_free(raw_enc_body);

free_peer_key_out:
      if (key_e != NULL)
            g_free(key_e);

      if (key_n != NULL)
            g_free(key_n);

error_out:
      return rc;
}


Generated by  Doxygen 1.6.0   Back to index