protected void generateEphemeralClientKeyExchange(DHParameters dhParams, OutputStream os)
      throws IOException {
    AsymmetricCipherKeyPair dhAgreeClientKeyPair = generateDHKeyPair(dhParams);
    this.dhAgreeClientPrivateKey = (DHPrivateKeyParameters) dhAgreeClientKeyPair.getPrivate();

    BigInteger Yc = ((DHPublicKeyParameters) dhAgreeClientKeyPair.getPublic()).getY();
    byte[] keData = BigIntegers.asUnsignedByteArray(Yc);
    TlsUtils.writeUint24(keData.length + 2, os);
    TlsUtils.writeOpaque16(keData, os);
  }
  private void sendCertificateVerify(byte[] data) throws IOException {
    /*
     * Send signature of handshake messages so far to prove we are the owner of the
     * cert See RFC 2246 sections 4.7, 7.4.3 and 7.4.8
     */
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    TlsUtils.writeUint8(HandshakeType.certificate_verify, bos);
    TlsUtils.writeUint24(data.length + 2, bos);
    TlsUtils.writeOpaque16(data, bos);
    byte[] message = bos.toByteArray();

    rs.writeMessage(ContentType.handshake, message, 0, message.length);
  }
  public void generateClientKeyExchange(OutputStream os) throws IOException {
    /*
     * Choose a PremasterSecret and send it encrypted to the server
     */
    premasterSecret = new byte[48];
    context.getSecureRandom().nextBytes(premasterSecret);
    TlsUtils.writeVersion(premasterSecret, 0);

    PKCS1Encoding encoding = new PKCS1Encoding(new RSABlindedEngine());
    encoding.init(
        true, new ParametersWithRandom(this.rsaServerPublicKey, context.getSecureRandom()));

    try {
      byte[] keData = encoding.processBlock(premasterSecret, 0, premasterSecret.length);
      TlsUtils.writeUint24(keData.length + 2, os);
      TlsUtils.writeOpaque16(keData, os);
    } catch (InvalidCipherTextException e) {
      /*
       * This should never happen, only during decryption.
       */
      throw new TlsFatalAlert(AlertDescription.internal_error);
    }
  }
Beispiel #4
0
  /**
   * Encode this {@link OCSPStatusRequest} to an {@link OutputStream}.
   *
   * @param output the {@link OutputStream} to encode to.
   * @throws IOException
   */
  public void encode(OutputStream output) throws IOException {
    if (responderIDList == null || responderIDList.isEmpty()) {
      TlsUtils.writeUint16(0, output);
    } else {
      ByteArrayOutputStream buf = new ByteArrayOutputStream();
      for (int i = 0; i < responderIDList.size(); ++i) {
        ResponderID responderID = (ResponderID) responderIDList.elementAt(i);
        byte[] derEncoding = responderID.getEncoded(ASN1Encoding.DER);
        TlsUtils.writeOpaque16(derEncoding, buf);
      }
      TlsUtils.checkUint16(buf.size());
      TlsUtils.writeUint16(buf.size(), output);
      buf.writeTo(output);
    }

    if (requestExtensions == null) {
      TlsUtils.writeUint16(0, output);
    } else {
      byte[] derEncoding = requestExtensions.getEncoded(ASN1Encoding.DER);
      TlsUtils.checkUint16(derEncoding.length);
      TlsUtils.writeUint16(derEncoding.length, output);
      output.write(derEncoding);
    }
  }
 /**
  * Encode this {@link DigitallySigned} to an {@link OutputStream}.
  *
  * @param output the {@link OutputStream} to encode to.
  * @throws IOException
  */
 public void encode(OutputStream output) throws IOException {
   if (algorithm != null) {
     algorithm.encode(output);
   }
   TlsUtils.writeOpaque16(signature, output);
 }
  /**
   * Connects to the remote system using client authentication
   *
   * @param tlsClient
   * @throws IOException If handshake was not successful.
   */
  public void connect(TlsClient tlsClient) throws IOException {
    if (tlsClient == null) {
      throw new IllegalArgumentException("'tlsClient' cannot be null");
    }
    if (this.tlsClient != null) {
      throw new IllegalStateException("connect can only be called once");
    }

    /*
     * Send Client hello
     *
     * First, generate some random data.
     */
    this.securityParameters = new SecurityParameters();
    this.securityParameters.clientRandom = new byte[32];
    random.nextBytes(securityParameters.clientRandom);
    TlsUtils.writeGMTUnixTime(securityParameters.clientRandom, 0);

    this.tlsClientContext = new TlsClientContextImpl(random, securityParameters);

    this.rs.init(tlsClientContext);

    this.tlsClient = tlsClient;
    this.tlsClient.init(tlsClientContext);

    ByteArrayOutputStream os = new ByteArrayOutputStream();

    ProtocolVersion client_version = this.tlsClient.getClientVersion();
    this.tlsClientContext.setClientVersion(client_version);
    // TODO For SSLv3 support, server version needs to be set to ProtocolVersion.SSLv3
    this.tlsClientContext.setServerVersion(client_version);
    TlsUtils.writeVersion(client_version, os);

    os.write(securityParameters.clientRandom);

    /*
     * Length of Session id
     */
    TlsUtils.writeUint8((short) 0, os);

    /*
     * Cipher suites
     */
    this.offeredCipherSuites = this.tlsClient.getCipherSuites();

    // Integer -> byte[]
    this.clientExtensions = this.tlsClient.getClientExtensions();

    // Cipher Suites (and SCSV)
    {
      /*
       * RFC 5746 3.4. The client MUST include either an empty "renegotiation_info"
       * extension, or the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling cipher suite
       * value in the ClientHello. Including both is NOT RECOMMENDED.
       */
      boolean noRenegExt =
          clientExtensions == null || clientExtensions.get(EXT_RenegotiationInfo) == null;

      int count = offeredCipherSuites.length;
      if (noRenegExt) {
        // Note: 1 extra slot for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        ++count;
      }

      TlsUtils.writeUint16(2 * count, os);
      TlsUtils.writeUint16Array(offeredCipherSuites, os);

      if (noRenegExt) {
        TlsUtils.writeUint16(CipherSuite.TLS_EMPTY_RENEGOTIATION_INFO_SCSV, os);
      }
    }

    // Compression methods
    this.offeredCompressionMethods = this.tlsClient.getCompressionMethods();

    TlsUtils.writeUint8((short) offeredCompressionMethods.length, os);
    TlsUtils.writeUint8Array(offeredCompressionMethods, os);

    // Extensions
    if (clientExtensions != null) {
      ByteArrayOutputStream ext = new ByteArrayOutputStream();

      Enumeration keys = clientExtensions.keys();
      while (keys.hasMoreElements()) {
        Integer extType = (Integer) keys.nextElement();
        writeExtension(ext, extType, (byte[]) clientExtensions.get(extType));
      }

      TlsUtils.writeOpaque16(ext.toByteArray(), os);
    }

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    TlsUtils.writeUint8(HandshakeType.client_hello, bos);
    TlsUtils.writeUint24(os.size(), bos);
    bos.write(os.toByteArray());
    byte[] message = bos.toByteArray();

    safeWriteMessage(ContentType.handshake, message, 0, message.length);

    connection_state = CS_CLIENT_HELLO_SEND;

    /*
     * We will now read data, until we have completed the handshake.
     */
    while (connection_state != CS_DONE) {
      safeReadData();
    }

    this.tlsInputStream = new TlsInputStream(this);
    this.tlsOutputStream = new TlsOutputStream(this);
  }
 private static void writeExtension(OutputStream output, Integer extType, byte[] extValue)
     throws IOException {
   TlsUtils.writeUint16(extType.intValue(), output);
   TlsUtils.writeOpaque16(extValue, output);
 }