public void processClientKeyExchange(InputStream input) throws IOException {
    if (dhAgreePublicKey != null) {
      // For dss_fixed_dh and rsa_fixed_dh, the key arrived in the client certificate
      return;
    }

    BigInteger Yc = TlsDHUtils.readDHParameter(input);

    this.dhAgreePublicKey =
        TlsDHUtils.validateDHPublicKey(new DHPublicKeyParameters(Yc, dhParameters));
  }
  public void processServerCertificate(Certificate serverCertificate) throws IOException {
    if (serverCertificate.isEmpty()) {
      throw new TlsFatalAlert(AlertDescription.bad_certificate);
    }

    org.ripple.bouncycastle.asn1.x509.Certificate x509Cert = serverCertificate.getCertificateAt(0);

    SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
    try {
      this.serverPublicKey = PublicKeyFactory.createKey(keyInfo);
    } catch (RuntimeException e) {
      throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
    }

    if (tlsSigner == null) {
      try {
        this.dhAgreePublicKey =
            TlsDHUtils.validateDHPublicKey((DHPublicKeyParameters) this.serverPublicKey);
        this.dhParameters = validateDHParameters(dhAgreePublicKey.getParameters());
      } catch (ClassCastException e) {
        throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
      }

      TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyAgreement);
    } else {
      if (!tlsSigner.isValidPublicKey(this.serverPublicKey)) {
        throw new TlsFatalAlert(AlertDescription.certificate_unknown);
      }

      TlsUtils.validateKeyUsage(x509Cert, KeyUsage.digitalSignature);
    }

    super.processServerCertificate(serverCertificate);
  }
  protected DHParameters validateDHParameters(DHParameters params) throws IOException {
    if (params.getP().bitLength() < getMinimumPrimeBits()) {
      throw new TlsFatalAlert(AlertDescription.insufficient_security);
    }

    return TlsDHUtils.validateDHParameters(params);
  }
  public byte[] generatePremasterSecret() throws IOException {
    if (agreementCredentials != null) {
      return agreementCredentials.generateAgreement(dhAgreePublicKey);
    }

    if (dhAgreePrivateKey != null) {
      return TlsDHUtils.calculateDHBasicAgreement(dhAgreePublicKey, dhAgreePrivateKey);
    }

    throw new TlsFatalAlert(AlertDescription.internal_error);
  }
 public void generateClientKeyExchange(OutputStream output) throws IOException {
   /*
    * RFC 2246 7.4.7.2 If the client certificate already contains a suitable Diffie-Hellman
    * key, then Yc is implicit and does not need to be sent again. In this case, the Client Key
    * Exchange message will be sent, but will be empty.
    */
   if (agreementCredentials == null) {
     this.dhAgreePrivateKey =
         TlsDHUtils.generateEphemeralClientKeyExchange(
             context.getSecureRandom(), dhParameters, output);
   }
 }