Examples of IKeyAgreementParty


Examples of gnu.javax.crypto.key.IKeyAgreementParty

        PublicKey serverKey = null, serverKex = null;
        KeyPair clientKeys = null, clientKex = null;
        CertificateRequest certReq;
        boolean sendKeyExchange = false;
        BigInteger srp_x = null;
        IKeyAgreementParty clientKA = null;
        IncomingMessage in; // used for key agreement protocol exchange
        OutgoingMessage out = null;

        if (suite.getKeyExchange() == "SRP")
          {
            String password = askPassword(user);
            if (DEBUG_KEY_EXCHANGE)
              {
                logger.log (Component.SSL_KEY_EXCHANGE,
                            "SRP: password read is ''{0}''", password);
              }
            byte[] userSrpPassword = password.getBytes("UTF-8");

            // instantiate and setup client-side key agreement party
            clientKA = KeyAgreementFactory.getPartyAInstance(Registry.SRP_TLS_KA);
            Map clientAttributes = new HashMap();
            clientAttributes.put(SRP6KeyAgreement.HASH_FUNCTION,
                                 Registry.SHA160_HASH);
            clientAttributes.put(SRP6KeyAgreement.USER_IDENTITY, user);
            clientAttributes.put(SRP6KeyAgreement.USER_PASSWORD, userSrpPassword);
            try
              {
                clientKA.init(clientAttributes);
                // initiate the exchange
                out = clientKA.processMessage(null);
              }
            catch (KeyAgreementException x)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
                  }
                throwHandshakeFailure();
              }
          }

        if (suite.getSignature() != "anon")
          {
            msg = Handshake.read(din, certType);
            if (DEBUG_HANDSHAKE_LAYER)
              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
            if (msg.getType() != Handshake.Type.CERTIFICATE)
              {
                throwUnexpectedMessage();
              }
            Certificate serverCertificate = (Certificate) msg.getBody();
            X509Certificate[] peerCerts = serverCertificate.getCertificates();
            try
              {
                session.trustManager.checkServerTrusted(peerCerts,
                                                        suite.getAuthType());
                if (suite.getSignature() == "RSA" &&
                    !(peerCerts[0].getPublicKey() instanceof RSAPublicKey))
                  throw new InvalidKeyException("improper public key");
                if (suite.getKeyExchange() == "DH" &&
                    !(peerCerts[0].getPublicKey() instanceof DHPublicKey))
                  throw new InvalidKeyException("improper public key");
                if (suite.getKeyExchange() == "DHE")
                  {
                    if (suite.getSignature() == "RSA" &&
                        !(peerCerts[0].getPublicKey() instanceof RSAPublicKey))
                      throw new InvalidKeyException("improper public key");
                    if (suite.getSignature() == "DSS" &&
                        !(peerCerts[0].getPublicKey() instanceof DSAPublicKey))
                      throw new InvalidKeyException("improper public key");
                  }
                session.peerCerts = peerCerts;
                session.peerVerified = true;
              }
            catch (InvalidKeyException ike)
              {
                throwHandshakeFailure();
              }
            catch (Exception x)
              {
                if (!checkCertificates(peerCerts))
                  {
                    peerUnverified(peerCerts);
                    SSLPeerUnverifiedException e =
                      new SSLPeerUnverifiedException ("could not verify peer certificate: "+
                                                      peerCerts[0].getSubjectDN());
                    e.initCause (x);
                    throw e;
                  }
                session.peerCerts = peerCerts;
                session.peerVerified = true;
              }
            serverKey = peerCerts[0].getPublicKey();
            serverKex = serverKey;
          }

        msg = Handshake.read(din, suite, serverKey);

        // Receive the server's key exchange.
        if (msg.getType() == Handshake.Type.SERVER_KEY_EXCHANGE)
          {
            if (DEBUG_HANDSHAKE_LAYER)
              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
            ServerKeyExchange skex = (ServerKeyExchange) msg.getBody();
            serverKex = skex.getPublicKey();
            if (suite.getSignature() != "anon")
              {
                ISignature sig = null;
                if (suite.getSignature() == "RSA")
                  {
                    sig = new SSLRSASignature();
                  }
                else if (suite.getSignature() == "DSS")
                  {
                    sig = SignatureFactory.getInstance(Registry.DSS_SIG);
                  }
                sig.setupVerify(Collections.singletonMap(
                  ISignature.VERIFIER_KEY, serverKey));
                byte[] buf = clientRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                buf = serverRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                if (suite.getKeyExchange() == "RSA")
                  {
                    updateSig(sig, ((RSAPublicKey) serverKex).getModulus());
                    updateSig(sig, ((RSAPublicKey) serverKex).getPublicExponent());
                  }
                else if (suite.getKeyExchange() == "DHE")
                  {
                    updateSig(sig, ((DHPublicKey) serverKex).getParams().getP());
                    updateSig(sig, ((DHPublicKey) serverKex).getParams().getG());
                    updateSig(sig, ((DHPublicKey) serverKex).getY());
                  }
                else if (suite.getKeyExchange() == "SRP")
                  {
                    updateSig(sig, ((SRPPublicKey) serverKex).getN());
                    updateSig(sig, ((SRPPublicKey) serverKex).getG());
                    byte[] srpSalt = skex.getSRPSalt();
                    sig.update((byte) srpSalt.length);
                    sig.update(srpSalt, 0, srpSalt.length);
                    updateSig(sig, ((SRPPublicKey) serverKex).getY());
                  }
                if (!sig.verify(skex.getSignature().getSigValue()))
                  {
                    throwHandshakeFailure();
                  }
              }

            if (suite.getKeyExchange() == "SRP")
              {
                // use server's key exchange data to continue
                // agreement protocol by faking a received incoming
                // message.  again the following code can be broken
                // into multiple blocks for more accurate exception
                // handling
                try
                  {
                    out = new OutgoingMessage();
                    out.writeMPI(((SRPPublicKey) serverKex).getN());
                    out.writeMPI(((SRPPublicKey) serverKex).getG());
                    out.writeMPI(new BigInteger(1, skex.getSRPSalt()));
                    out.writeMPI(((SRPPublicKey) serverKex).getY());

                    in = new IncomingMessage(out.toByteArray());

                    out = clientKA.processMessage(in);
                    if (DEBUG_KEY_EXCHANGE)
                      {
                        logger.log (Component.SSL_KEY_EXCHANGE, "clientKA isComplete? {0}",
                                    Boolean.valueOf (clientKA.isComplete()));
                      }
                  }
                catch (KeyAgreementException x)
                  {
                    if (DEBUG_KEY_EXCHANGE)
                      {
                        logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
                      }
                    throwHandshakeFailure();
                  }
              }
            msg = Handshake.read(din, suite, serverKey);
          }

        // See if the server wants us to send our certificates.
        certReq = null;
        if (msg.getType() == Handshake.Type.CERTIFICATE_REQUEST)
          {
            if (suite.getSignature() == "anon")
              {
                throwHandshakeFailure();
              }
            if (DEBUG_HANDSHAKE_LAYER)
              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
            certReq = (CertificateRequest) msg.getBody();
            msg = Handshake.read(din);
          }

        // Read ServerHelloDone.
        if (msg.getType() != Handshake.Type.SERVER_HELLO_DONE)
          {
            throwUnexpectedMessage();
          }
        if (DEBUG_HANDSHAKE_LAYER)
          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);

        // Send our certificate chain if the server asked for it.
        if (certReq != null)
          {
            String alias = session.keyManager.chooseClientAlias(
              certReq.getTypeStrings(), certReq.getAuthorities(), null);
            if (alias == null && version == ProtocolVersion.SSL_3)
              {
                Alert alert =
                  new Alert(Alert.Level.WARNING, Alert.Description.NO_CERTIFICATE);
                sendAlert(alert);
              }
            else
              {
                X509Certificate[] chain =
                  session.keyManager.getCertificateChain(alias);
                PrivateKey key = session.keyManager.getPrivateKey(alias);
                if (chain == null)
                  {
                    chain = new X509Certificate[0];
                  }
                Certificate cert = new Certificate(chain);
                msg = new Handshake(Handshake.Type.CERTIFICATE, cert);
                if (DEBUG_HANDSHAKE_LAYER)
                  logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
                msg.write(dout, version);
//                 recordOutput.setHandshakeAvail(msg.write(dout, version));;
                dout.flush();
                if (chain.length > 0)
                  {
                    session.localCerts = chain;
                    clientKeys = new KeyPair(chain[0].getPublicKey(), key);
                  }
              }
          }

        // Send our key exchange.
        byte[] preMasterSecret = null;
        ClientKeyExchange ckex = null;
        if (suite.getKeyExchange() == "RSA")
          {
            ProtocolVersion v =
              (ProtocolVersion) session.enabledProtocols.last();
            byte[] b = new byte[46];
            session.random.nextBytes (b);
            preMasterSecret = Util.concat(v.getEncoded(), b);
            EME_PKCS1_V1_5 pkcs1 = EME_PKCS1_V1_5.getInstance((RSAPublicKey) serverKex);
            BigInteger bi = new BigInteger(1,
              pkcs1.encode(preMasterSecret, session.random));
            bi = RSA.encrypt((RSAPublicKey) serverKex, bi);
            ckex = new ClientKeyExchange(Util.trim(bi));
          }
        else if (suite.getKeyExchange().startsWith("DH"))
          {
            if (clientKeys == null ||
                !(clientKeys.getPublic() instanceof DHPublicKey))
              {
                GnuDHPrivateKey tmpKey =
                  new GnuDHPrivateKey(null, ((DHPublicKey) serverKex).getParams().getP(),
                      ((DHPublicKey) serverKex).getParams().getG(), null);
                clientKA = KeyAgreementFactory.getPartyBInstance(Registry.DH_KA);
                Map attr = new HashMap();
                attr.put(DiffieHellmanKeyAgreement.KA_DIFFIE_HELLMAN_OWNER_PRIVATE_KEY,
                         tmpKey);
                attr.put(DiffieHellmanKeyAgreement.SOURCE_OF_RANDOMNESS,
                         session.random);
                try
                  {
                    clientKA.init(attr);
                    out = new OutgoingMessage();
                    out.writeMPI(((DHPublicKey) serverKex).getY());
                    in = new IncomingMessage(out.toByteArray());
                    out = clientKA.processMessage(in);
                    in = new IncomingMessage(out.toByteArray());
                    ckex = new ClientKeyExchange(in.readMPI());
                  }
                catch (KeyAgreementException kae)
                  {
                    if (DEBUG_KEY_EXCHANGE)
                      {
                        logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
                      }
                    internalError();
                    RuntimeException re = new RuntimeException (kae.getMessage());
                    re.initCause (kae);
                    throw re;
                  }
              }
            else
              {
                clientKA = KeyAgreementFactory.getPartyBInstance(Registry.ELGAMAL_KA);
                Map attr = new HashMap();
                attr.put(ElGamalKeyAgreement.KA_ELGAMAL_RECIPIENT_PRIVATE_KEY,
                         clientKeys.getPrivate());
                try
                  {
                    // The key exchange is already complete here; our public
                    // value was sent with our certificate.
                    clientKA.init(attr);
                  }
                catch (KeyAgreementException kae)
                  {
                    if (DEBUG_KEY_EXCHANGE)
                      logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
                    internalError();
                    RuntimeException re = new RuntimeException (kae.getMessage());
                    re.initCause (kae);
                    throw re;
                  }
                ckex = new ClientKeyExchange(new byte[0]);
              }
          }
        else if (suite.getKeyExchange() == "SRP")
          {
            // at this point, out --the outgoing message-- already contains
            // what we want. so...
            BigInteger A = null;
            try
              {
                in = new IncomingMessage(out.toByteArray());
                A = in.readMPI();
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "client A:{0}", A);
                  }
              }
            catch (KeyAgreementException x)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
                  }
                throwHandshakeFailure();
              }
            ckex = new ClientKeyExchange(A);
          }
        msg = new Handshake(Handshake.Type.CLIENT_KEY_EXCHANGE, ckex);
        if (DEBUG_HANDSHAKE_LAYER)
          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
        msg.write (dout, version);
//         recordOutput.setHandshakeAvail(msg.write(dout, version));;

        // Generate the master secret.
        if (suite.getKeyExchange().startsWith("DH"))
          {
            try
              {
                preMasterSecret = clientKA.getSharedSecret();
              }
            catch (KeyAgreementException kae)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
                  }
                internalError();
                RuntimeException re = new RuntimeException (kae.getMessage());
                re.initCause (kae);
                throw re;
              }
          }
        else if (suite.getKeyExchange() == "SRP")
          {
            try
              {
                preMasterSecret = clientKA.getSharedSecret();
              }
            catch (KeyAgreementException x)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
View Full Code Here

Examples of gnu.javax.crypto.key.IKeyAgreementParty

        return;
      }

    // If the selected suite turns out to be SRP, set up the key exchange
    // objects.
    IKeyAgreementParty serverKA = null;
    IncomingMessage in;
    OutgoingMessage out = null;
    if (suite.getKeyExchange() == "SRP")
      {
        // FIXME
        // Uhm, I don't think this can happen, because if remoteUser is null
        // we cannot choose an SRP ciphersuite...
        if (remoteUser == null)
          {
            Alert alert = new Alert(Alert.Level.FATAL,
              Alert.Description.MISSING_SRP_USERNAME);
            sendAlert(alert);
            throw new AlertException(alert, true);
          }

        SRPAuthInfoProvider srpDB = new SRPAuthInfoProvider();
        Map dbAttributes = new HashMap();
        dbAttributes.put(SRPRegistry.PASSWORD_DB,
          session.srpTrustManager.getPasswordFile());
        srpDB.activate(dbAttributes);

        // FIXME
        // We can also fake that the user exists, and generate a dummy (and
        // invalid) master secret, and let the handshake fail at the Finished
        // message. This is better than letting the connecting side know that
        // the username they sent isn't valid.
        //
        // But how to implement this?
        if (!srpDB.contains(remoteUser))
          {
            Alert alert = new Alert(Alert.Level.FATAL,
              Alert.Description.UNKNOWN_SRP_USERNAME);
            sendAlert(alert);
            throw new AlertException(alert, true);
          }

        serverKA = KeyAgreementFactory.getPartyBInstance(Registry.SRP_TLS_KA);
        Map serverAttributes = new HashMap();
        serverAttributes.put(SRP6KeyAgreement.HASH_FUNCTION,
                             Registry.SHA160_HASH);
        serverAttributes.put(SRP6KeyAgreement.HOST_PASSWORD_DB, srpDB);

        try
          {
            serverKA.init(serverAttributes);
            out = new OutgoingMessage();
            out.writeString(remoteUser);
            in = new IncomingMessage(out.toByteArray());
            out = serverKA.processMessage(in);
          }
        catch (KeyAgreementException x)
          {
            throwHandshakeFailure();
          }
      }

    // Check if the session specified by the client's ID corresponds
    // to a saved session, and if so, continue it.
    boolean newSession = true;
    if (DEBUG_HANDSHAKE_LAYER)
      {
        logger.log (Component.SSL_HANDSHAKE, "saved sessions: {0}", sessionContext);
      }
    if (sessionContext.containsSessionID(
        new Session.ID(clientHello.getSessionId())))
      {
        Session old = session;
        session = (Session) sessionContext.getSession(clientHello.getSessionId());
        if (!clientHello.getCipherSuites().contains(session.cipherSuite))
          {
            throwHandshakeFailure();
          }
        if (session.getPeerHost().equals(remoteHost) &&
            old.enabledProtocols.contains(session.protocol))
          {
            session = (Session) session.clone();
            suite = session.cipherSuite;
            newSession = false;
            recordInput.setSession(session);
            session.currentAlert = null;
            session.params = old.params;
            session.random = old.random;
          }
        else
          {
            if (DEBUG_HANDSHAKE_LAYER)
              {
                logger.log (Component.SSL_HANDSHAKE, "rejected section; hosts equal? {0}, same suites? {1}",
                            new Object[] { Boolean.valueOf (session.getPeerHost().equals(remoteHost)),
                                           Boolean.valueOf (old.enabledProtocols.contains(session.protocol)) });
              }
            session = old;
            session.peerHost = remoteHost;
            newSession = true;
          }
      }
    else if (DEBUG_HANDSHAKE_LAYER)
      {
        logger.log (Component.SSL_HANDSHAKE, "rejected session; have session id? {0}, saved sessions: {1}",
                    new Object[] { Boolean.valueOf (sessionContext.containsSessionID(new Session.ID(clientHello.getSessionId()))),
                                   sessionContext });
      }
    if (newSession)
      {
        byte[] buf = new byte[32];
        Session.ID sid = null;
        do
          {
            session.random.nextBytes(buf);
            sid = new Session.ID(buf);
          }
        while (sessionContext.containsSessionID(sid));
        session.sessionId = sid;
      }
    session.valid = true;
    session.peerHost = remoteHost;
    session.cipherSuite = suite;
    session.protocol = version;
    session.params.setVersion (version);

    // Send the server hello.
    Random serverRandom = new Random(Util.unixTime(),
                                     session.random.generateSeed(28));
    ServerHello serverHello = new ServerHello(version, serverRandom,
                                              session.getId(), suite,
                                              comp, extensions);
    msg = new Handshake(Handshake.Type.SERVER_HELLO, serverHello);
    if (DEBUG_HANDSHAKE_LAYER)
      logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
    msg.write(dout, version);
//     recordOutput.setHandshakeAvail(msg.write(dout, version));
    dout.flush();

    if (newSession)
      {
        X509Certificate[] certs = null;
        PrivateKey serverKey = null;
        if (suite.getSignature() != "anon")
          {
            // Send our CA-issued certificate to the client.
            String alias = session.keyManager.chooseServerAlias(suite.getAuthType(),
                                                                null, null);
            certs = session.keyManager.getCertificateChain(alias);
            serverKey = session.keyManager.getPrivateKey(alias);
            if (certs == null || serverKey == null)
              {
                throwHandshakeFailure();
              }
            session.localCerts = certs;
            Certificate serverCert = new Certificate(certs);
            msg = new Handshake(Handshake.Type.CERTIFICATE, serverCert);
            if (DEBUG_HANDSHAKE_LAYER)
              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
            msg.write(dout, version);
//             recordOutput.setHandshakeAvail(msg.write(dout, version));;
            dout.flush();
          }

        // If the certificate we sent does not contain enough information to
        // do the key exchange (in the case of ephemeral Diffie-Hellman,
        // export RSA, and SRP) we send a signed public key to be used for the
        // key exchange.
        KeyPair signPair = null;
        if (certs != null)
          {
            signPair = new KeyPair(certs[0].getPublicKey(), serverKey);
          }
        KeyPair kexPair = signPair;
        ServerKeyExchange skex = null;

        // Set up our key exchange, and/or prepare our ServerKeyExchange
        // message.
        if ((suite.getKeyExchange() == "RSA" && suite.isExportable() &&
             ((RSAPrivateKey) serverKey).getModulus().bitLength() > 512))
          {
            kexPair = KeyPool.generateRSAKeyPair();
            RSAPublicKey pubkey = (RSAPublicKey) kexPair.getPublic();
            Signature s = null;
            if (suite.getSignature() != "anon")
              {
                SSLRSASignature sig = new SSLRSASignature();
                sig.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY,
                                                       signPair.getPrivate()));
                byte[] buf = clientRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                buf = serverRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                updateSig(sig, pubkey.getModulus());
                updateSig(sig, pubkey.getPublicExponent());
                s = new Signature(sig.sign(), "RSA");
              }
            skex = new ServerKeyExchange(pubkey, s);
          }
        else if (suite.getKeyExchange() == "DH")
          {
            serverKA = KeyAgreementFactory.getPartyBInstance(Registry.ELGAMAL_KA);
            Map attr = new HashMap();
            attr.put(ElGamalKeyAgreement.KA_ELGAMAL_RECIPIENT_PRIVATE_KEY,
                     serverKey);
            try
              {
                serverKA.init(attr);
              }
            catch (KeyAgreementException kae)
              {
                if (DEBUG_KEY_EXCHANGE)
                  logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
                internalError();
                RuntimeException re = new RuntimeException (kae.getMessage());
                re.initCause (kae);
                throw re;
              }
            // We don't send a ServerKeyExchange for this suite.
          }
        else if (suite.getKeyExchange() == "DHE")
          {
            serverKA = KeyAgreementFactory.getPartyAInstance(Registry.DH_KA);
            Map attr = new HashMap();
            GnuDHPrivateKey servParams = DiffieHellman.getParams();
            attr.put(DiffieHellmanKeyAgreement.KA_DIFFIE_HELLMAN_OWNER_PRIVATE_KEY,
                     servParams);
            attr.put(DiffieHellmanKeyAgreement.SOURCE_OF_RANDOMNESS,
                     session.random);
            BigInteger serv_y = null;
            try
              {
                serverKA.init(attr);
                out = serverKA.processMessage(null);
                in = new IncomingMessage(out.toByteArray());
                serv_y = in.readMPI();
              }
            catch (KeyAgreementException kae)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "DHE exception", kae);
                  }
                internalError();
                RuntimeException re = new RuntimeException (kae.getMessage());
                re.initCause (kae);
                throw re;
              }
            GnuDHPublicKey pubkey =
              new GnuDHPublicKey(null, servParams.getParams().getP(),
                                 servParams.getParams().getG(), serv_y);
            Signature s = null;
            if (suite.getSignature() != "anon")
              {
                ISignature sig = null;
                if (suite.getSignature() == "RSA")
                  {
                    sig = new SSLRSASignature();
                  }
                else
                  {
                    sig = SignatureFactory.getInstance(Registry.DSS_SIG);
                  }
                sig.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY,
                                                       signPair.getPrivate()));
                byte[] buf = clientRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                buf = serverRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                updateSig(sig, pubkey.getParams().getP());
                updateSig(sig, pubkey.getParams().getG());
                updateSig(sig, pubkey.getY());
                s = new Signature(sig.sign(), suite.getSignature());
              }
            skex = new ServerKeyExchange(pubkey, s);
          }
        else if (suite.getKeyExchange() == "SRP")
          {
            BigInteger N = null;
            BigInteger g = null;
            BigInteger salt = null;
            BigInteger B = null;
            try
              {
                in = new IncomingMessage(out.toByteArray());
                N = in.readMPI();
                g = in.readMPI();
                salt = in.readMPI();
                B = in.readMPI();
              }
            catch (KeyAgreementException x)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "SRP exception", x);
                  }
                throwHandshakeFailure();
              }
            Signature s = null;
            final byte[] srpSalt = Util.trim(salt);
            if (suite.getSignature() != "anon")
              {
                ISignature sig = null;
                if (suite.getSignature() == "RSA")
                  {
                    sig = new SSLRSASignature();
                  }
                else
                  {
                    sig = SignatureFactory.getInstance(Registry.DSS_SIG);
                  }
                sig.setupSign(Collections.singletonMap(ISignature.SIGNER_KEY,
                                                       signPair.getPrivate()));
                byte[] buf = clientRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                buf = serverRandom.getEncoded();
                sig.update(buf, 0, buf.length);
                updateSig(sig, N);
                updateSig(sig, g);
                sig.update((byte) srpSalt.length);
                sig.update(srpSalt, 0, srpSalt.length);
                updateSig(sig, B);
                s = new Signature(sig.sign(), suite.getSignature());
              }
            final SRPPublicKey pubkey = new SRPPublicKey(N, g, B);
            skex = new ServerKeyExchange(pubkey, s, srpSalt);
          }
        if (skex != null)
          {
            msg = new Handshake(Handshake.Type.SERVER_KEY_EXCHANGE, skex);
            if (DEBUG_HANDSHAKE_LAYER)
              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
            msg.write(dout, version);
//             recordOutput.setHandshakeAvail(msg.write(dout, version));;
            dout.flush();
          }

        // If we are configured to want or need client authentication, then
        // ask for it.
        if (wantClientAuth || needClientAuth)
          {
            Principal[] auths = null;
            CertificateRequest.ClientType[] types =
              new CertificateRequest.ClientType[] {
                CertificateRequest.ClientType.RSA_SIGN,
                CertificateRequest.ClientType.DSS_SIGN,
                CertificateRequest.ClientType.RSA_FIXED_DH,
                CertificateRequest.ClientType.DSS_FIXED_DH
              };
            try
              {
                auths = (Principal[])
                  Util.transform(session.trustManager.getAcceptedIssuers(),
                    Principal.class, "getSubjectDN", null);
              }
            catch (Exception x)
              {
                internalError();
                RuntimeException re = new RuntimeException (x.getMessage());
                re.initCause (x);
                throw re;
              }
            CertificateRequest req = new CertificateRequest(types, auths);
            msg = new Handshake(Handshake.Type.CERTIFICATE_REQUEST, req);
            msg.write(dout, version);
            dout.flush();
          }

        // Send our server hello done.
        msg = new Handshake(Handshake.Type.SERVER_HELLO_DONE, null);
        if (DEBUG_HANDSHAKE_LAYER)
          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
        msg.write(dout, version);
        dout.flush();

        if (suite.getKeyExchange() == "RSA")
          {
            msg = Handshake.read(din, suite, kexPair.getPublic());
          }
        else
          {
            msg = Handshake.read(din, suite, null);
          }
        boolean clientCertOk = false;
        boolean clientCanSign = false;
        X509Certificate[] clientChain = null;
        PublicKey clientKey = null;

        // Read the client's certificate, if sent.
        if (msg.getType() == Handshake.Type.CERTIFICATE)
          {
            if (DEBUG_HANDSHAKE_LAYER)
              logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
            Certificate cliCert = (Certificate) msg.getBody();
            clientChain = cliCert.getCertificates();
            try
              {
                session.trustManager.checkClientTrusted(clientChain,
                                                        suite.getAuthType());
                session.peerCerts = clientChain;
                session.peerVerified = true;
                clientKey = clientChain[0].getPublicKey();
              }
            catch (Exception x)
              {
              }
            clientCanSign = ((clientKey instanceof DSAPublicKey) ||
                             (clientKey instanceof RSAPublicKey));
            if (suite.getKeyExchange().startsWith("DH"))
              {
                msg = Handshake.read(din, suite, clientKey);
              }
            else
              {
                msg = Handshake.read(din, suite, kexPair.getPublic());
              }
          }

        // If we require client authentication, and the client sent an
        // unverifiable certificate or no certificate at all, drop the
        // connection.
        if (!session.peerVerified && needClientAuth)
          {
            throwHandshakeFailure();
          }

        // Read the client key exchange.
        if (msg.getType() != Handshake.Type.CLIENT_KEY_EXCHANGE)
          {
            throwUnexpectedMessage();
          }
        if (DEBUG_HANDSHAKE_LAYER)
          logger.log (Component.SSL_HANDSHAKE, "{0}", msg);
        ClientKeyExchange ckex = (ClientKeyExchange) msg.getBody();
        byte[] preMasterSecret = null;
        if (suite.getKeyExchange() == "RSA")
          {
            byte[] enc = (byte[]) ckex.getExchangeObject();
            BigInteger bi = new BigInteger(1, enc);
            try
              {
                bi = RSA.decrypt(kexPair.getPrivate(), bi);
                EME_PKCS1_V1_5 pkcs1 = EME_PKCS1_V1_5.getInstance(
                  (RSAPrivateKey) kexPair.getPrivate());
                preMasterSecret = pkcs1.decode(Util.concat(new byte[1], bi.toByteArray()));
                //rsa.init(kexPair);
                //preMasterSecret = rsa.decrypt(enc);
              }
            catch (Exception x)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "RSA exception", x);
                  }
                // Generate a fake pre-master secret if the RSA decryption
                // fails.
                byte[] b = new byte[46];
                session.random.nextBytes (b);
                preMasterSecret = Util.concat(version.getEncoded(), b);
              }
          }
        else if (suite.getKeyExchange().startsWith("DH"))
          {
            try
              {
                out = new OutgoingMessage();
                if (clientKey == null)
                  out.writeMPI((BigInteger) ckex.getExchangeObject());
                else
                  out.writeMPI(((DHPublicKey) clientKey).getY());
                in = new IncomingMessage(out.toByteArray());
                serverKA.processMessage(in);
                preMasterSecret = serverKA.getSharedSecret();
              }
            catch (KeyAgreementException kae)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
                    logger.log (Component.SSL_KEY_EXCHANGE, "DH exception", kae);
                  }
                internalError();
                RuntimeException re = new RuntimeException (kae.getMessage());
                re.initCause (kae);
                throw re;
              }
          }
        else if (suite.getKeyExchange() == "SRP")
          {
            BigInteger A = (BigInteger) ckex.getExchangeObject();
            if (DEBUG_KEY_EXCHANGE)
              {
                logger.log (Component.SSL_KEY_EXCHANGE, "SRP: client A: {0}", A);
              }
            try
              {
                out = new OutgoingMessage();
                out.writeMPI(A);
                in = new IncomingMessage(out.toByteArray());
                out = serverKA.processMessage(in);
                preMasterSecret = serverKA.getSharedSecret();
              }
            catch (KeyAgreementException x)
              {
                if (DEBUG_KEY_EXCHANGE)
                  {
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.