⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslhandshakeprotocol.java

📁 这是linux下ssl vpn的实现程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
      }
      else {
        throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE);
      }
    }
    catch (CertificateException ex) {
      throw new SSLException(SSLException.UNSUPPORTED_CERTIFICATE,
                             ex.getMessage());
    }
    catch (IOException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage() == null ? ex.getClass().getName() :
                             ex.getMessage());
    }

    if (secret[0] == 0) {
      byte[] tmp = new byte[secret.length - 1];
      System.arraycopy(secret, 1, tmp, 0, secret.length - 1);
      secret = tmp;
    }

    sendMessage(CLIENT_KEY_EXCHANGE_MSG, secret);

    // Calculate the master secret
    calculateMasterSecret();

/* DEBUG */ log.debug("Generating key data");

    // Generate the keys etc and put the cipher into use
    byte[] keydata;
    int length = 0;

    length += pendingCipherSuite.getKeyLength() * 2;
    length += pendingCipherSuite.getMACLength() * 2;
    length += pendingCipherSuite.getIVLength() * 2;

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    MD5Digest md5 = new MD5Digest();
    SHA1Digest sha1 = new SHA1Digest();

    int turn = 0;
    while (out.size() < length) {
      md5.reset();
      sha1.reset();

      for (int i = 0; i <= turn; i++) {
        sha1.update( (byte) ('A' + turn));
      }

      sha1.update(masterSecret, 0, masterSecret.length);
      sha1.update(serverRandom, 0, serverRandom.length);
      sha1.update(clientRandom, 0, clientRandom.length);

      md5.update(masterSecret, 0, masterSecret.length);
      byte[] tmp = new byte[sha1.getDigestSize()];
      sha1.doFinal(tmp, 0);
      md5.update(tmp, 0, tmp.length);
      tmp = new byte[md5.getDigestSize()];
      md5.doFinal(tmp, 0);

      // Write out a block of key data
      out.write(tmp, 0, tmp.length);

      turn++;
    }

    keydata = out.toByteArray();

    ByteArrayInputStream in = new ByteArrayInputStream(keydata);

    byte[] encryptKey = new byte[pendingCipherSuite.getKeyLength()];
    byte[] encryptIV = new byte[pendingCipherSuite.getIVLength()];
    byte[] encryptMAC = new byte[pendingCipherSuite.getMACLength()];
    byte[] decryptKey = new byte[pendingCipherSuite.getKeyLength()];
    byte[] decryptIV = new byte[pendingCipherSuite.getIVLength()];
    byte[] decryptMAC = new byte[pendingCipherSuite.getMACLength()];

    try {
      in.read(encryptMAC);
      in.read(decryptMAC);
      in.read(encryptKey);
      in.read(decryptKey);
      in.read(encryptIV);
      in.read(decryptIV);
    }
    catch (IOException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage() == null ? ex.getClass().getName() :
                             ex.getMessage());

    }

    pendingCipherSuite.init(encryptKey, encryptIV, encryptMAC,
                            decryptKey, decryptIV, decryptMAC);

    currentHandshakeStep = SERVER_HELLO_DONE_MSG;

    // Send the change cipher spec
    socket.sendCipherChangeSpec(pendingCipherSuite);

    // Send the finished msg
    sendHandshakeFinished();

  }

  SSLCipherSuite getPendingCipherSuite() {
    return pendingCipherSuite;
  }

  void updateHandshakeHashes(byte[] data) {

/* DEBUG */ log.debug("Updating handshake hashes");

    handshakeMD5.update(data, 0, data.length);
    handshakeSHA1.update(data, 0, data.length);
  }

  private void completeHandshakeHashes() {

/* DEBUG */ log.debug("Completing handshake hashes");

    // Complete the handshale hashes
    handshakeMD5.update( (byte) 0x43);
    handshakeMD5.update( (byte) 0x4c);
    handshakeMD5.update( (byte) 0x4e);
    handshakeMD5.update( (byte) 0x54);

    handshakeMD5.update(masterSecret, 0, masterSecret.length);

    for (int i = 0; i < 48; i++) {
      handshakeMD5.update( (byte) 0x36);
    }

    byte[] tmp = new byte[handshakeMD5.getDigestSize()];
    handshakeMD5.doFinal(tmp, 0);

    handshakeMD5.reset();

    /* DEBUG */log.debug("Master secret is " + masterSecret.length + " bytes long and first byte is " + masterSecret[0]);

    handshakeMD5.update(masterSecret, 0, masterSecret.length);
    for (int i = 0; i < 48; i++) {
      handshakeMD5.update( (byte) 0x5c);
    }

    handshakeMD5.update(tmp, 0, tmp.length);

    handshakeSHA1.update( (byte) 0x43);
    handshakeSHA1.update( (byte) 0x4c);
    handshakeSHA1.update( (byte) 0x4e);
    handshakeSHA1.update( (byte) 0x54);

    handshakeSHA1.update(masterSecret, 0, masterSecret.length);
    for (int i = 0; i < 40; i++) {
      handshakeSHA1.update( (byte) 0x36);
    }

    tmp = new byte[handshakeSHA1.getDigestSize()];
    handshakeSHA1.doFinal(tmp, 0);

    handshakeSHA1.reset();
    handshakeSHA1.update(masterSecret, 0, masterSecret.length);
    for (int i = 0; i < 40; i++) {
      handshakeSHA1.update( (byte) 0x5c);
    }

    handshakeSHA1.update(tmp, 0, tmp.length);

  }

  private void sendHandshakeFinished() throws SSLException {

    completeHandshakeHashes();

/* DEBUG */ log.debug("Sending client FINISHED");

    byte[] msg = new byte[handshakeMD5.getDigestSize()
        + handshakeSHA1.getDigestSize()];

    handshakeMD5.doFinal(msg, 0);
    handshakeSHA1.doFinal(msg, handshakeMD5.getDigestSize());

    sendMessage(FINISHED_MSG, msg);

    currentHandshakeStep = FINISHED_MSG;

  }

  private void onCertificateMsg(byte[] msg) throws SSLException {

    ByteArrayInputStream in = new ByteArrayInputStream(msg);

    // Get the length of the certificate chain
    int length2 = (in.read() & 0xFF) << 16
        | (in.read() & 0xFF) << 8
        | (in.read() & 0xFF);

    try {

      boolean trusted = false;

      X509Certificate chainCert;
      while(in.available() > 0 && !trusted) {
        // The length of the next certificate (we dont need this as rthe DERInputStream does the work
        int certlen = (in.read() & 0xFF) << 16
            | (in.read() & 0xFF) << 8
            | (in.read() & 0xFF);

        // Now read the certificate
        DERInputStream der = new
            DERInputStream(in);

        ASN1Sequence certificate =
            (ASN1Sequence) der.readObject();

        // Get the x509 certificate structure
        chainCert = new X509Certificate(X509CertificateStructure.getInstance(
            certificate));

        if(x509==null)
          x509 = chainCert;

        // Verify if this part of the chain is trusted
        try {
          trusted = context.getTrustedCACerts().isTrustedCertificate(
              chainCert,
              context.isInvalidCertificateAllowed(),
              context.isUntrustedCertificateAllowed());
        }
        catch (SSLException ex1) {
          /* DEBUG */log.warn("Failed to verify certificate against trust store (This may not be an error)", ex1);
        }
      }

      if(!trusted)
        throw new SSLException(SSLException.BAD_CERTIFICATE,
            "The server certificate was either invalid or untrusted");

    }
    catch (IOException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage());
    }

/* DEBUG */ log.debug("Server X509 Certificate...");
/* DEBUG */ log.debug("Subject DN: " + x509.getSubjectDN());
/* DEBUG */ log.debug("Issuer DN: " + x509.getIssuerDN());

    currentHandshakeStep = CERTIFICATE_MSG;

  }

  private void onServerHelloMsg(byte[] msg) throws SSLException {

    try {
      ByteArrayInputStream in = new ByteArrayInputStream(msg);

      majorVersion = in.read();
      minorVersion = in.read();

      serverRandom = new byte[32];
      in.read(serverRandom);

      sessionID = new byte[ (in.read() & 0xFF)];
      in.read(sessionID);

      cipherSuiteID = new SSLCipherSuiteID(in.read(), in.read());

      pendingCipherSuite = (SSLCipherSuite)
          context.getCipherSuiteClass(cipherSuiteID).newInstance();

      compressionID = in.read();

      currentHandshakeStep = SERVER_HELLO_MSG;
    }
    catch (IllegalAccessException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage() == null ? ex.getClass().getName() :
                             ex.getMessage());

    }
    catch (InstantiationException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage() == null ? ex.getClass().getName() :
                             ex.getMessage());
    }
    catch (IOException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage() == null ? ex.getClass().getName() :
                             ex.getMessage());
    }

  }

  private void sendClientHello() throws SSLException {

/* DEBUG */ log.debug("Sending client HELLO");

    ByteArrayOutputStream msg = new ByteArrayOutputStream();

    try {
      clientRandom = new byte[32];
      context.getRND().nextBytes(clientRandom);
      long time = System.currentTimeMillis();
      clientRandom[0] = (byte) ( (time >> 24) & 0xFF);
      clientRandom[1] = (byte) ( (time >> 16) & 0xFF);
      clientRandom[2] = (byte) ( (time >> 8) & 0xFF);
      clientRandom[3] = (byte) (time & 0xFF);

      // Write the version
      msg.write(SSLTransport.VERSION_MAJOR);
      msg.write(SSLTransport.VERSION_MINOR);

      // Write the random bytes
      msg.write(clientRandom);

      // Write the session identifier - currently were not caching so zero length
      msg.write(0);

      // Write the cipher ids - TODO: we need to set the preferred as first
      SSLCipherSuiteID[] ids = context.getCipherSuiteIDs();
      msg.write(0);
      msg.write(ids.length * 2);

      for (int i = 0; i < ids.length; i++) {
        msg.write(ids[i].id1);
        msg.write(ids[i].id2);
      }

      // Compression - no compression is currently supported
      msg.write(1);
      msg.write(0);
    }
    catch (IOException ex) {
      throw new SSLException(SSLException.INTERNAL_ERROR,
                             ex.getMessage() == null ? ex.getClass().getName() :
                             ex.getMessage());
    }

    sendMessage(CLIENT_HELLO_MSG, msg.toByteArray());

    currentHandshakeStep = CLIENT_HELLO_MSG;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -