Example #1
0
 /**
  * Parse the ServerCertificate message.
  *
  * @param is The stream where to parse from.
  * @return A Certificate object with the certs, the server has sended.
  * @throws IOException If something goes wrong during parsing.
  */
 protected static Certificate parse(InputStream is) throws IOException {
   X509CertificateStructure[] certs;
   int left = TlsUtils.readUint24(is);
   if (left == 0) {
     return EMPTY_CHAIN;
   }
   Vector tmp = new Vector();
   while (left > 0) {
     int size = TlsUtils.readUint24(is);
     left -= 3 + size;
     byte[] buf = new byte[size];
     TlsUtils.readFully(buf, is);
     ByteArrayInputStream bis = new ByteArrayInputStream(buf);
     ASN1InputStream ais = new ASN1InputStream(bis);
     DERObject o = ais.readObject();
     tmp.addElement(X509CertificateStructure.getInstance(o));
     if (bis.available() > 0) {
       throw new IllegalArgumentException(
           "Sorry, there is garbage data left after the certificate");
     }
   }
   certs = new X509CertificateStructure[tmp.size()];
   for (int i = 0; i < tmp.size(); i++) {
     certs[i] = (X509CertificateStructure) tmp.elementAt(i);
   }
   return new Certificate(certs);
 }
  public void processServerCertificate(Certificate serverCertificate) throws IOException {
    X509CertificateStructure x509Cert = serverCertificate.certs[0];
    SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();

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

    if (tlsSigner == null) {
      try {
        this.dhAgreeServerPublicKey =
            validateDHPublicKey((DHPublicKeyParameters) this.serverPublicKey);
      } catch (ClassCastException e) {
        throw new TlsFatalAlert(AlertDescription.certificate_unknown);
      }

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

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

    // TODO
    /*
     * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
     * signing algorithm for the certificate must be the same as the algorithm for the
     * certificate key."
     */
  }
 protected Signer ˊ(
     SignatureAndHashAlgorithm paramSignatureAndHashAlgorithm,
     boolean paramBoolean1,
     boolean paramBoolean2,
     CipherParameters paramCipherParameters) {
   int i;
   if (paramSignatureAndHashAlgorithm != null) {
     i = 1;
   } else {
     i = 0;
   }
   if (i != TlsUtils.ᐝ(this.aSQ)) {
     throw new IllegalStateException();
   }
   if ((paramSignatureAndHashAlgorithm != null)
       && ((paramSignatureAndHashAlgorithm.mK() != 2)
           || (paramSignatureAndHashAlgorithm.mL() != mS()))) {
     throw new IllegalStateException();
   }
   short s;
   if (paramSignatureAndHashAlgorithm == null) {
     s = 2;
   } else {
     s = paramSignatureAndHashAlgorithm.mK();
   }
   if (paramBoolean1) {
     paramSignatureAndHashAlgorithm = new NullDigest();
   } else {
     paramSignatureAndHashAlgorithm = TlsUtils.ͺ(s);
   }
   paramSignatureAndHashAlgorithm = new DSADigestSigner(ʻ(s), paramSignatureAndHashAlgorithm);
   paramSignatureAndHashAlgorithm.ˊ(paramBoolean2, ˋ(paramBoolean2, paramCipherParameters));
   return paramSignatureAndHashAlgorithm;
 }
  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);
  }
Example #5
0
 /**
  * Parse a {@link DigitallySigned} from an {@link InputStream}.
  *
  * @param context the {@link TlsContext} of the current connection.
  * @param input the {@link InputStream} to parse from.
  * @return a {@link DigitallySigned} object.
  * @throws IOException
  */
 public static DigitallySigned parse(TlsContext context, InputStream input) throws IOException {
   SignatureAndHashAlgorithm algorithm = null;
   if (TlsUtils.isTLSv12(context)) {
     algorithm = SignatureAndHashAlgorithm.parse(input);
   }
   byte[] signature = TlsUtils.readOpaque16(input);
   return new DigitallySigned(algorithm, signature);
 }
  protected void generateEphemeralClientKeyExchange(ECDomainParameters ecParams, OutputStream os)
      throws IOException {
    AsymmetricCipherKeyPair ecAgreeClientKeyPair = generateECKeyPair(ecParams);
    this.ecAgreeClientPrivateKey = (ECPrivateKeyParameters) ecAgreeClientKeyPair.getPrivate();

    byte[] keData = externalizeKey((ECPublicKeyParameters) ecAgreeClientKeyPair.getPublic());
    TlsUtils.writeUint24(keData.length + 1, os);
    TlsUtils.writeOpaque8(keData, os);
  }
  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);
  }
  private void processHandshake() throws IOException {
    boolean read;
    do {
      read = false;
      /*
       * We need the first 4 bytes, they contain type and length of the message.
       */
      if (handshakeQueue.size() >= 4) {
        byte[] beginning = new byte[4];
        handshakeQueue.read(beginning, 0, 4, 0);
        ByteArrayInputStream bis = new ByteArrayInputStream(beginning);
        short type = TlsUtils.readUint8(bis);
        int len = TlsUtils.readUint24(bis);

        /*
         * Check if we have enough bytes in the buffer to read the full message.
         */
        if (handshakeQueue.size() >= (len + 4)) {
          /*
           * Read the message.
           */
          byte[] buf = new byte[len];
          handshakeQueue.read(buf, 0, len, 4);
          handshakeQueue.removeData(len + 4);

          /*
           * RFC 2246 7.4.9. The value handshake_messages includes all handshake
           * messages starting at client hello up to, but not including, this
           * finished message. [..] Note: [Also,] Hello Request messages are
           * omitted from handshake hashes.
           */
          switch (type) {
            case HandshakeType.hello_request:
            case HandshakeType.finished:
              break;
            default:
              rs.updateHandshakeData(beginning, 0, 4);
              rs.updateHandshakeData(buf, 0, len);
              break;
          }

          /*
           * Now, parse the message.
           */
          processHandshakeMessage(type, buf);
          read = true;
        }
      }
    } while (read);
  }
  private void sendClientCertificate(Certificate clientCert) throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    TlsUtils.writeUint8(HandshakeType.certificate, bos);

    // Reserve space for length
    TlsUtils.writeUint24(0, bos);

    clientCert.encode(bos);
    byte[] message = bos.toByteArray();

    // Patch actual length back in
    TlsUtils.writeUint24(message.length - 4, message, 1);

    rs.writeMessage(ContentType.handshake, message, 0, message.length);
  }
 public void generateClientKeyExchange(OutputStream os) throws IOException {
   if (agreementCredentials != null) {
     TlsUtils.writeUint24(0, os);
   } else {
     generateEphemeralClientKeyExchange(ecAgreeServerPublicKey.getParameters(), os);
   }
 }
  private void sendClientKeyExchange() throws IOException {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    TlsUtils.writeUint8(HandshakeType.client_key_exchange, bos);

    // Reserve space for length
    TlsUtils.writeUint24(0, bos);

    this.keyExchange.generateClientKeyExchange(bos);
    byte[] message = bos.toByteArray();

    // Patch actual length back in
    TlsUtils.writeUint24(message.length - 4, message, 1);

    rs.writeMessage(ContentType.handshake, message, 0, message.length);
  }
Example #13
0
  public void processServerCertificate(Certificate serverCertificate) throws IOException {
    X509CertificateStructure x509Cert = serverCertificate.certs[0];
    SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();

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

    // Sanity check the PublicKeyFactory
    if (this.serverPublicKey.isPrivate()) {
      throw new TlsFatalAlert(AlertDescription.internal_error);
    }

    this.rsaServerPublicKey = validateRSAPublicKey((RSAKeyParameters) this.serverPublicKey);

    TlsUtils.validateKeyUsage(x509Cert, KeyUsage.keyEncipherment);

    // TODO
    /*
     * Perform various checks per RFC2246 7.4.2: "Unless otherwise specified, the
     * signing algorithm for the certificate must be the same as the algorithm for the
     * certificate key."
     */
  }
  protected void processCertificateVerify(
      ServerHandshakeState state, byte[] body, TlsHandshakeHash prepareFinishHash)
      throws IOException {
    ByteArrayInputStream buf = new ByteArrayInputStream(body);

    DigitallySigned clientCertificateVerify = DigitallySigned.parse(state.serverContext, buf);

    TlsProtocol.assertEmpty(buf);

    // Verify the CertificateVerify message contains a correct signature.
    try {
      // TODO For TLS 1.2, this needs to be the hash specified in the DigitallySigned
      byte[] certificateVerifyHash =
          TlsProtocol.getCurrentPRFHash(state.serverContext, prepareFinishHash, null);

      org.bouncycastle.asn1.x509.Certificate x509Cert = state.clientCertificate.getCertificateAt(0);
      SubjectPublicKeyInfo keyInfo = x509Cert.getSubjectPublicKeyInfo();
      AsymmetricKeyParameter publicKey = PublicKeyFactory.createKey(keyInfo);

      TlsSigner tlsSigner = TlsUtils.createTlsSigner(state.clientCertificateType);
      tlsSigner.init(state.serverContext);
      tlsSigner.verifyRawSignature(
          clientCertificateVerify.getAlgorithm(),
          clientCertificateVerify.getSignature(),
          publicKey,
          certificateVerifyHash);
    } catch (Exception e) {
      throw new TlsFatalAlert(AlertDescription.decrypt_error);
    }
  }
Example #15
0
 protected DigitallySigned parseSignature(InputStream input) throws IOException {
   DigitallySigned signature = DigitallySigned.parse(context, input);
   SignatureAndHashAlgorithm signatureAlgorithm = signature.getAlgorithm();
   if (signatureAlgorithm != null) {
     TlsUtils.verifySupportedSignatureAlgorithm(supportedSignatureAlgorithms, signatureAlgorithm);
   }
   return signature;
 }
Example #16
0
  /**
   * Encodes version of the ClientCertificate message
   *
   * @param os stream to write the message to
   * @throws IOException If something goes wrong
   */
  protected void encode(OutputStream os) throws IOException {
    Vector encCerts = new Vector();
    int totalSize = 0;
    for (int i = 0; i < this.certs.length; ++i) {
      byte[] encCert = certs[i].getEncoded(ASN1Encodable.DER);
      encCerts.addElement(encCert);
      totalSize += encCert.length + 3;
    }

    TlsUtils.writeUint24(totalSize + 3, os);
    TlsUtils.writeUint24(totalSize, os);

    for (int i = 0; i < encCerts.size(); ++i) {
      byte[] encCert = (byte[]) encCerts.elementAt(i);
      TlsUtils.writeOpaque24(encCert, os);
    }
  }
  /**
   * Parse a {@link CertificateRequest} from an {@link InputStream}.
   *
   * @param context the {@link TlsContext} of the current connection.
   * @param input the {@link InputStream} to parse from.
   * @return a {@link CertificateRequest} object.
   * @throws IOException
   */
  public static CertificateRequest parse(TlsContext context, InputStream input) throws IOException {
    int numTypes = TlsUtils.readUint8(input);
    short[] certificateTypes = new short[numTypes];
    for (int i = 0; i < numTypes; ++i) {
      certificateTypes[i] = TlsUtils.readUint8(input);
    }

    Vector supportedSignatureAlgorithms = null;
    if (TlsUtils.isTLSv12(context)) {
      // TODO Check whether SignatureAlgorithm.anonymous is allowed here
      supportedSignatureAlgorithms = TlsUtils.parseSupportedSignatureAlgorithms(false, input);
    }

    Vector certificateAuthorities = new Vector();
    byte[] certAuthData = TlsUtils.readOpaque16(input);
    ByteArrayInputStream bis = new ByteArrayInputStream(certAuthData);
    while (bis.available() > 0) {
      byte[] derEncoding = TlsUtils.readOpaque16(bis);
      ASN1Primitive asn1 = TlsUtils.readDERObject(derEncoding);
      certificateAuthorities.addElement(X500Name.getInstance(asn1));
    }

    return new CertificateRequest(
        certificateTypes, supportedSignatureAlgorithms, certificateAuthorities);
  }
Example #18
0
  /**
   * Parse a {@link OCSPStatusRequest} from an {@link InputStream}.
   *
   * @param input the {@link InputStream} to parse from.
   * @return a {@link OCSPStatusRequest} object.
   * @throws IOException
   */
  public static OCSPStatusRequest parse(InputStream input) throws IOException {
    Vector responderIDList = new Vector();
    {
      int length = TlsUtils.readUint16(input);
      if (length > 0) {
        byte[] data = TlsUtils.readFully(length, input);
        ByteArrayInputStream buf = new ByteArrayInputStream(data);
        do {
          byte[] derEncoding = TlsUtils.readOpaque16(buf);
          ResponderID responderID = ResponderID.getInstance(TlsUtils.readDERObject(derEncoding));
          responderIDList.addElement(responderID);
        } while (buf.available() > 0);
      }
    }

    Extensions requestExtensions = null;
    {
      int length = TlsUtils.readUint16(input);
      if (length > 0) {
        byte[] derEncoding = TlsUtils.readFully(length, input);
        requestExtensions = Extensions.getInstance(TlsUtils.readDERObject(derEncoding));
      }
    }

    return new OCSPStatusRequest(responderIDList, requestExtensions);
  }
Example #19
0
  public Hashtable getClientExtensions() throws IOException {
    Hashtable clientExtensions = new Hashtable();

    ByteArrayOutputStream srpData = new ByteArrayOutputStream();
    TlsUtils.writeOpaque8(this.identity, srpData);
    clientExtensions.put(EXT_SRP, srpData.toByteArray());

    return clientExtensions;
  }
 public byte[] generateCertificateSignature(byte[] hash) throws IOException {
   try {
     if (TlsUtils.isTLSv12(context)) {
       return signer.generateRawSignature(signatureAndHashAlgorithm, privateKey, hash);
     } else {
       return signer.generateRawSignature(privateKey, hash);
     }
   } catch (CryptoException e) {
     throw new TlsFatalAlert(AlertDescription.internal_error, e);
   }
 }
 public void generateClientKeyExchange(OutputStream os) 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) {
     TlsUtils.writeUint24(0, os);
   } else {
     generateEphemeralClientKeyExchange(dhAgreeServerPublicKey.getParameters(), os);
   }
 }
  /**
   * Encode this {@link CertificateRequest} to an {@link OutputStream}.
   *
   * @param output the {@link OutputStream} to encode to.
   * @throws IOException
   */
  public void encode(OutputStream output) throws IOException {
    if (certificateTypes == null || certificateTypes.length == 0) {
      TlsUtils.writeUint8(0, output);
    } else {
      TlsUtils.writeUint8ArrayWithUint8Length(certificateTypes, output);
    }

    if (supportedSignatureAlgorithms != null) {
      // TODO Check whether SignatureAlgorithm.anonymous is allowed here
      TlsUtils.encodeSupportedSignatureAlgorithms(supportedSignatureAlgorithms, false, output);
    }

    if (certificateAuthorities == null || certificateAuthorities.isEmpty()) {
      TlsUtils.writeUint16(0, output);
    } else {
      Vector derEncodings = new Vector(certificateAuthorities.size());

      int totalLength = 0;
      for (int i = 0; i < certificateAuthorities.size(); ++i) {
        X500Name certificateAuthority = (X500Name) certificateAuthorities.elementAt(i);
        byte[] derEncoding = certificateAuthority.getEncoded(ASN1Encoding.DER);
        derEncodings.addElement(derEncoding);
        totalLength += derEncoding.length;
      }

      TlsUtils.checkUint16(totalLength);
      TlsUtils.writeUint16(totalLength, output);

      for (int i = 0; i < derEncodings.size(); ++i) {
        byte[] encDN = (byte[]) derEncodings.elementAt(i);
        output.write(encDN);
      }
    }
  }
Example #23
0
  /**
   * Determines whether a specific array of <tt>byte</tt>s appears to contain a DTLS record.
   *
   * @param buf the array of <tt>byte</tt>s to be analyzed
   * @param off the offset within <tt>buf</tt> at which the analysis is to start
   * @param len the number of bytes within <tt>buf</tt> starting at <tt>off</tt> to be analyzed
   * @return <tt>true</tt> if the specified <tt>buf</tt> appears to contain a DTLS record
   */
  public static boolean isDtlsRecord(byte[] buf, int off, int len) {
    boolean b = false;

    if (len >= DTLS_RECORD_HEADER_LENGTH) {
      short type = TlsUtils.readUint8(buf, off);

      switch (type) {
        case ContentType.alert:
        case ContentType.application_data:
        case ContentType.change_cipher_spec:
        case ContentType.handshake:
          int major = buf[off + 1] & 0xff;
          int minor = buf[off + 2] & 0xff;
          ProtocolVersion version = null;

          if ((major == ProtocolVersion.DTLSv10.getMajorVersion())
              && (minor == ProtocolVersion.DTLSv10.getMinorVersion())) {
            version = ProtocolVersion.DTLSv10;
          }
          if ((version == null)
              && (major == ProtocolVersion.DTLSv12.getMajorVersion())
              && (minor == ProtocolVersion.DTLSv12.getMinorVersion())) {
            version = ProtocolVersion.DTLSv12;
          }
          if (version != null) {
            int length = TlsUtils.readUint16(buf, off + 11);

            if (DTLS_RECORD_HEADER_LENGTH + length <= len) b = true;
          }
          break;
        default:
          // Unless a new ContentType has been defined by the Bouncy
          // Castle Crypto APIs, the specified buf does not represent a
          // DTLS record.
          break;
      }
    }
    return b;
  }
Example #24
0
  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);
    }
  }
Example #25
0
  protected Signer makeSigner(
      SignatureAndHashAlgorithm algorithm, boolean raw, boolean forSigning, CipherParameters cp) {
    if ((algorithm != null) != TlsUtils.isTLSv12(context)) {
      throw new IllegalStateException();
    }

    if (algorithm != null && algorithm.getSignature() != SignatureAlgorithm.rsa) {
      throw new IllegalStateException();
    }

    Digest d;
    if (raw) {
      d = new NullDigest();
    } else if (algorithm == null) {
      d = new CombinedHash();
    } else {
      d = TlsUtils.createHash(algorithm.getHash());
    }

    Signer s;
    if (algorithm != null) {
      /*
       * RFC 5246 4.7. In RSA signing, the opaque vector contains the signature generated
       * using the RSASSA-PKCS1-v1_5 signature scheme defined in [PKCS1].
       */
      s = new RSADigestSigner(d, TlsUtils.getOIDForHashAlgorithm(algorithm.getHash()));
    } else {
      /*
       * RFC 5246 4.7. Note that earlier versions of TLS used a different RSA signature scheme
       * that did not include a DigestInfo encoding.
       */
      s = new GenericSigner(createRSAImpl(), d);
    }
    s.init(forSigning, cp);
    return s;
  }
Example #26
0
  public TlsBlockCipher(
      TlsClientContext context,
      BlockCipher encryptCipher,
      BlockCipher decryptCipher,
      Digest writeDigest,
      Digest readDigest,
      int cipherKeySize) {
    this.context = context;

    this.randomData = new byte[256];
    context.getSecureRandom().nextBytes(randomData);

    this.encryptCipher = encryptCipher;
    this.decryptCipher = decryptCipher;

    int key_block_size =
        (2 * cipherKeySize)
            + writeDigest.getDigestSize()
            + readDigest.getDigestSize()
            + encryptCipher.getBlockSize()
            + decryptCipher.getBlockSize();

    byte[] key_block = TlsUtils.calculateKeyBlock(context, key_block_size);

    int offset = 0;

    // Init MACs
    writeMac = new TlsMac(context, writeDigest, key_block, offset, writeDigest.getDigestSize());
    offset += writeDigest.getDigestSize();
    readMac = new TlsMac(context, readDigest, key_block, offset, readDigest.getDigestSize());
    offset += readDigest.getDigestSize();

    // Init Ciphers
    this.initCipher(
        true, encryptCipher, key_block, cipherKeySize, offset, offset + (cipherKeySize * 2));
    offset += cipherKeySize;
    this.initCipher(
        false,
        decryptCipher,
        key_block,
        cipherKeySize,
        offset,
        offset + cipherKeySize + encryptCipher.getBlockSize());
  }
  public DefaultTlsSignerCredentials(
      TlsContext context,
      Certificate certificate,
      AsymmetricKeyParameter privateKey,
      SignatureAndHashAlgorithm signatureAndHashAlgorithm) {
    if (certificate == null) {
      throw new IllegalArgumentException("'certificate' cannot be null");
    }
    if (certificate.isEmpty()) {
      throw new IllegalArgumentException("'certificate' cannot be empty");
    }
    if (privateKey == null) {
      throw new IllegalArgumentException("'privateKey' cannot be null");
    }
    if (!privateKey.isPrivate()) {
      throw new IllegalArgumentException("'privateKey' must be private");
    }
    if (TlsUtils.isTLSv12(context) && signatureAndHashAlgorithm == null) {
      throw new IllegalArgumentException(
          "'signatureAndHashAlgorithm' cannot be null for (D)TLS 1.2+");
    }

    if (privateKey instanceof RSAKeyParameters) {
      this.signer = new TlsRSASigner();
    } else if (privateKey instanceof DSAPrivateKeyParameters) {
      this.signer = new TlsDSSSigner();
    } else if (privateKey instanceof ECPrivateKeyParameters) {
      this.signer = new TlsECDSASigner();
    } else {
      throw new IllegalArgumentException(
          "'privateKey' type not supported: " + privateKey.getClass().getName());
    }

    this.signer.init(context);

    this.context = context;
    this.certificate = certificate;
    this.privateKey = privateKey;
    this.signatureAndHashAlgorithm = signatureAndHashAlgorithm;
  }
  protected void notifyClientCertificate(ServerHandshakeState state, Certificate clientCertificate)
      throws IOException {
    if (state.certificateRequest == null) {
      throw new IllegalStateException();
    }

    if (state.clientCertificate != null) {
      throw new TlsFatalAlert(AlertDescription.unexpected_message);
    }

    state.clientCertificate = clientCertificate;

    if (clientCertificate.isEmpty()) {
      state.keyExchange.skipClientCredentials();
    } else {

      /*
       * TODO RFC 5246 7.4.6. If the certificate_authorities list in the certificate request
       * message was non-empty, one of the certificates in the certificate chain SHOULD be
       * issued by one of the listed CAs.
       */

      state.clientCertificateType =
          TlsUtils.getClientCertificateType(
              clientCertificate, state.serverCredentials.getCertificate());

      state.keyExchange.processClientCertificate(clientCertificate);
    }

    /*
     * RFC 5246 7.4.6. If the client does not send any certificates, the server MAY at its
     * discretion either continue the handshake without client authentication, or respond with a
     * fatal handshake_failure alert. Also, if some aspect of the certificate chain was
     * unacceptable (e.g., it was not signed by a known, trusted CA), the server MAY at its
     * discretion either continue the handshake (considering the client unauthenticated) or send
     * a fatal alert.
     */
    state.server.notifyClientCertificate(clientCertificate);
  }
Example #29
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);
    }
  }
Example #30
0
 /**
  * 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);
 }