/**
   * Certificate_Verify(証明書)を受け取ったときの動作をします。
   *
   * @param line クライアントから受信した文字列
   * @return クライアントの証明書の真偽
   * @author kinbara
   */
  private boolean recieveCertificateVerify(String line) {
    boolean cert_verify = false;
    // サーバー側のダイジェストのハッシュ値
    ListIterator listIte = netDigest.listIterator();
    String digest = "";
    while (listIte.hasNext()) {
      digest += listIte.next().toString();
    }
    digest = digest.substring(0, digest.indexOf("Certificate_Verify"));
    BigInteger digest1 = new BigInteger(this.getHash(digest), 16);
    // クライアントの公開鍵で復号
    BigInteger digest2 = new BigInteger(line.substring(line.indexOf(":") + 1), 16);
    try {
      X509 x509 = new X509("src/sglserver/conf/key/ca", "CAKeyStore", this.storePasswd);
      // TODO:(注意)ユーザーの公開鍵をpeerNameでCAKeyStoreに登録している場合のみ有効
      RSAPublicKey pk = x509.getRSAPublicKey(peerName);
      digest2 = digest2.modPow(pk.getPublicExponent(), pk.getModulus()); // 復号
      // b = a.modPow(s, n); → a mod n のs乗がbに代入される
      // pk.getPublicExponent()→公開指数
      // pk.getModulus()→pkのmod値
    } catch (Exception e) {

      e.printStackTrace();
    }
    if (digest1.compareTo(digest2) == 0) {
      System.out.println(socket.getRemoteSocketAddress() + "は、信頼できます。");
      cert_verify = true;
    } else {
      System.out.println(socket.getRemoteSocketAddress() + "は、危険です。");
    }
    return (cert_verify);
  }
  /**
   * Client_Key_Exchangeを受け取ったときの動作をします。
   *
   * @param line クライアントから受信した文字列
   * @throws CertificateException
   * @throws IOException
   * @throws KeyStoreException
   * @throws NoSuchAlgorithmException
   * @throws UnrecoverableKeyException
   * @author kinbara
   */
  private void recieveClientKeyExchange(String line)
      throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException,
          UnrecoverableKeyException {

    X509 x509 = new X509("src/sglserver/conf/key/ca", "CAKeyStore", this.storePasswd);
    RSAPrivateKey sk = x509.getRSAPrivateKey("server", this.keyPasswd);
    // 暗号化されたプリマスターシークレットの抽出
    line = line.substring(line.indexOf(":") + 1);
    BigInteger preCipher = new BigInteger(line, 16);
    // プリマスターシークレットを復号
    preMastarSecret = preCipher.modPow(sk.getPrivateExponent(), sk.getModulus());
    // (事前共有鍵)=(秘密鍵). modPow((s乗:すなわちaのs乗),(元:すなわちg))
    // b = a.modPow(s, n); a mod n のs乗がbに代入される
  }
 /**
  * Server_Certificateメッセージを作成します。
  *
  * @return Server_Certificateメッセージの文字列
  * @author kinbara
  */
 private String setServerCertificate() {
   String ans = "Server_Certificate";
   ans += ":";
   // 証明書の送信
   // サーバーが自分の証明書に署名
   try {
     X509 x509 = new X509("src/sglserver/conf/key/ca", "CAKeyStore", this.storePasswd);
     byte[] sign = x509.sign("server", this.keyPasswd); // 署名
     for (int i = 0; i < sign.length; i++) {
       int val = sign[i] & 0xFF;
       if (val < 16) {
         ans += "0";
       }
       ans += Integer.toHexString(val);
     }
   } catch (Exception e) {
     e.printStackTrace();
   }
   // ダイジェストに追加
   netDigest.add(ans);
   return (ans);
 }