/*
used by Handshaker to change the active write cipher, follows
the output of the CCS message.

Also synchronized on "this" from readRecord/delegatedTask.
176567
void changeWriteCiphers() throws SSLException {
        if (connectionState != cs_HANDSHAKE
                && connectionState != cs_RENEGOTIATE) {
            throw new SSLProtocolException(
                "State error, change cipher specs");
        }

        // ... create compressor

        CipherBox oldCipher = writeCipher;

        try {
            writeCipher = handshaker.newWriteCipher();
            writeMAC = handshaker.newWriteMAC();
        } catch (GeneralSecurityException e) {
            // "can't happen"
            throw (SSLException)new SSLException
                                ("Algorithm missing:  ").initCause(e);
        }

        // See comment above.
        oldCipher.dispose();

        // reset the flag of the first application record
        isFirstAppOutputRecord = true;
    }
543403
public void clearSign(InputStream input, OutputStream output) throws IOException, PGPException, GeneralSecurityException {

        PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), digest));
        signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privateKey);

        ArmoredOutputStream armoredOutput = new ArmoredOutputStream(output);
        armoredOutput.beginClearText(digest);

        LineIterator iterator = new LineIterator(new InputStreamReader(input));

        while (iterator.hasNext()) {
            String line = iterator.nextLine();

            // trailing spaces must be removed for signature calculation (see http://tools.ietf.org/html/rfc4880#section-7.1)
            byte[] data = trim(line).getBytes("UTF-8");

            armoredOutput.write(data);
            armoredOutput.write(EOL);

            signatureGenerator.update(data);
            if (iterator.hasNext()) {
                signatureGenerator.update(EOL);
            }
        }

        armoredOutput.endClearText();

        PGPSignature signature = signatureGenerator.generate();
        signature.encode(new BCPGOutputStream(armoredOutput));

        armoredOutput.close();
    }
860057
function _gpfStreamSecureWrite(write) {
        return function (buffer) {
            var me = this;
            //eslint-disable-line no-invalid-this
            _gpfStreamProgressStartWrite(me);
            return _gpfStreamSecureEnd(write.call(me, buffer), me, _gpfStreamProgressEndWrite);
        };
    }
1035342
private void sendHandshake(ChannelHandlerContext ctx) {
    boolean needToFlush = false;

    // Iterate until there is nothing left to write.
    while (true) {
      buffer = getOrCreateBuffer(ctx.alloc());
      try {
        handshaker.getBytesToSendToPeer(buffer);
      } catch (GeneralSecurityException e) {
        throw new RuntimeException(e);
      }
      if (!buffer.isReadable()) {
        break;
      }

      needToFlush = true;
      @SuppressWarnings("unused") // go/futurereturn-lsc
      Future<?> possiblyIgnoredError = ctx.write(buffer);
      buffer = null;
    }

    // If something was written, flush.
    if (needToFlush) {
      ctx.flush();
    }
  }
1149741
@Override
    public Script freshOutputScript(KeyPurpose purpose) {
        DeterministicKey followedKey = getKey(purpose);
        ImmutableList.Builder<ECKey> keys = ImmutableList.<ECKey>builder().add(followedKey);
        for (DeterministicKeyChain keyChain : followingKeyChains) {
            DeterministicKey followingKey = keyChain.getKey(purpose);
            checkState(followedKey.getChildNumber().equals(followingKey.getChildNumber()), "Following keychains should be in sync");
            keys.add(followingKey);
        }
        List<ECKey> marriedKeys = keys.build();
        Script redeemScript = ScriptBuilder.createRedeemScript(sigsRequiredToSpend, marriedKeys);
        return ScriptBuilder.createP2SHOutputScript(redeemScript);
    }
1066617
function readNotifyMpnDeviceTokenChange(message, tokens) {
	message.userName = protocol.decodeString(tokens[1]);
	message.sessionId = protocol.decodeString(tokens[3]);
	message.device = {};
	message.device.mpnPlatformType = protocol.decodeString(tokens[5]);
	message.device.applicationId = protocol.decodeString(tokens[7]);
	message.device.deviceToken = protocol.decodeString(tokens[9]);
	message.newDeviceToken = protocol.decodeString(tokens[11]);
}
251895
private SSLEngineResult writeAppRecord(EngineArgs ea) throws IOException {

        Status status = null;
        HandshakeStatus hsStatus = null;

        /*
         * See if the handshaker needs to report back some SSLException.
         */
        checkTaskThrown();

        /*
         * short circuit if we're closed/closing.
         */
        if (writer.isOutboundDone()) {
            return new SSLEngineResult(Status.CLOSED, getHSStatus(null), 0, 0);
        }

        /*
         * If we're still in cs_HANDSHAKE, make sure it's been
         * started.
         */
        synchronized (this) {
            if ((connectionState == cs_HANDSHAKE) ||
                    (connectionState == cs_START)) {
                kickstartHandshake();

                /*
                 * If there's no HS data available to write, we can return
                 * without trying to wrap anything.
                 */
                hsStatus = getHSStatus(null);

                if (hsStatus == HandshakeStatus.NEED_UNWRAP) {
                    return new SSLEngineResult(Status.OK, hsStatus, 0, 0);
                }
            }
        }

        /*
         * Grab a copy of this if it doesn't already exist,
         * and we can use it several places before anything major
         * happens on this side.  Races aren't critical
         * here.
         */
        if (hsStatus == null) {
            hsStatus = getHSStatus(null);
        }

        /*
         * If we have a task outstanding, this *MUST* be done before
         * doing any more wrapping, because we could be in the middle
         * of receiving a handshake message, for example, a finished
         * message which would change the ciphers.
         */
        if (hsStatus == HandshakeStatus.NEED_TASK) {
            return new SSLEngineResult(
                Status.OK, hsStatus, 0, 0);
        }

        /*
         * This will obtain any waiting outbound data, or will
         * process the outbound appData.
         */
        try {
            synchronized (writeLock) {
                hsStatus = writeRecord(outputRecord, ea);
            }
        } catch (SSLException e) {
            throw e;
        } catch (IOException e) {
            SSLException ex = new SSLException("Write problems");
            ex.initCause(e);
            throw ex;
        }

        /*
         * writeRecord might have reported some status.
         * Now check for the remaining cases.
         *
         * status above should cover:  NEED_WRAP/FINISHED
         */
        status = (isOutboundDone() ? Status.CLOSED : Status.OK);
        hsStatus = getHSStatus(hsStatus);

        return new SSLEngineResult(status, hsStatus,
            ea.deltaApp(), ea.deltaNet());
    }
490087
def _update_sig(self, m, key):
        
        if self.sig_alg is None:
            if self.tls_session.tls_version >= 0x0300:
                self.sig_val = key.sign(m, t='pkcs', h='md5-sha1')
            else:
                self.sig_val = key.sign(m, t='pkcs', h='md5')
        else:
            h, sig = _tls_hash_sig[self.sig_alg].split('+')
            if sig.endswith('pss'):
                t = "pss"
            else:
                t = "pkcs"
            self.sig_val = key.sign(m, t=t, h=h)
1094003
def write_lock
      index = lock_modify_index.nil? ? 0 : lock_modify_index
      value = generate_lockfile
      return true if value == true
      Diplomat::Kv.put(@lock, value, cas: index)
    end
1168002
private void dispatchServerChannelChangeOverwrittenPermissionsEvent(
            ServerChannel channel, Permissions newPermissions, Permissions oldPermissions, DiscordEntity entity) {
        if (newPermissions.equals(oldPermissions)) {
            // This can be caused by adding a user/role in a channels overwritten permissions without modifying
            // any of its values. We don't need to dispatch an event for this.
            return;
        }
        ServerChannelChangeOverwrittenPermissionsEvent event =
                new ServerChannelChangeOverwrittenPermissionsEventImpl(
                        channel, newPermissions, oldPermissions, entity);

        api.getEventDispatcher().dispatchServerChannelChangeOverwrittenPermissionsEvent(
                (DispatchQueueSelector) channel.getServer(),
                (entity instanceof Role) ? (Role) entity : null,
                channel.getServer(),
                channel,
                (entity instanceof User) ? (User) entity : null,
                event);
    }
1115779
@Override
    public void setWriteStatetoCloseAllowedNoSync() {
        currentState = (currentState | WRITE_WAITING) & WRITE_WAITING_CLEAR_OUT;
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
            Tr.debug(tc, "setWriteStatetoCloseAllowedNoSync");
        }
    }
343707
function LockStateCharateristic(opts) {
	LockStateCharateristic.super_.call(this, objectAssign({
		uuid: 'ee0c2081-8786-40ba-ab96-99b91ac981d8',
		properties: ['read'],
		sizeof: 1
	}, opts));
}
232314
private long writeLockVictimIfSet() {
		long victimLockstamp = victimLock.readLock();
		if (hasVictim) {
			// try to upgrade our read lock to write exclusive if victim
			long writeLockStamp = victimLock.tryConvertToWriteLock(victimLockstamp);
			// could not get write lock
			if (writeLockStamp == 0L) {
				// so unlock the victim
				victimLock.unlock(victimLockstamp);
				// now just block until we have exclusive lock
				victimLockstamp = victimLock.writeLock();
				// make sure victim is still set with our new write lock
				if (!hasVictim) {
					// victim has been cleared by another thread... so just give
					// up our lock
					victimLock.tryUnlockWrite();
					return 0L;
				} else
					return victimLockstamp;
			} else {
				return writeLockStamp;
			}
		} else {
			victimLock.unlock(victimLockstamp);
			return 0L;
		}
	}
261434
public VirtualConnection encryptAndWriteAsync(long numBytes, boolean forceQueue, int timeout) {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.entry(tc, "encryptAndWriteAsync: " + numBytes);
        }

        this.asyncBytesToWrite = 0L;
        this.asyncTimeout = timeout;
        VirtualConnection vc = null;

        try {
            long numBytesLeft = numBytes;
            // make sure we have an output buffer of the target size ready
            final int packetSize = getConnLink().getPacketBufferSize();
            if (numBytesLeft > packetSize) {
                getEncryptedAppBuffer(packetSize * 2);
            } else {
                getEncryptedAppBuffer(1);
            }
            final int cap = this.encryptedAppBuffer.capacity();
            final TCPWriteRequestContext tcp = getConnLink().getDeviceWriteInterface();
            SSLEngineResult result;
            int produced;

            do {
                this.encryptedAppBuffer.clear();

                result = encryptMessage();
                numBytesLeft -= result.bytesConsumed();
                produced = result.bytesProduced();
                if (0 < produced) {
                    while (0 < numBytesLeft && (cap - produced) >= packetSize) {
                        // space in the current output buffer to encrypt a little more
                        // Note: JSSE requires a full packet size of open space regardless of the input
                        // amount, so even 100 bytes to encrypt requires 16K of output space
                        result = encryptMessage();
                        numBytesLeft -= result.bytesConsumed();
                        produced += result.bytesProduced();
                    }

                    // in case this goes async, save bytes-left to pick up later
                    this.asyncBytesToWrite = numBytesLeft;
                    this.encryptedAppBuffer.flip();
                    tcp.setBuffer(this.encryptedAppBuffer);
                    vc = tcp.write(TCPWriteRequestContext.WRITE_ALL_DATA, this, forceQueue, timeout);
                }
            } while (null != vc && 0 < numBytesLeft && 0 < produced);

        } catch (IOException exception) {
            // No FFDC needed. Callback will handle.
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                Tr.debug(tc, "Caught exception during encryption, " + exception);
            }
            this.callback.error(getConnLink().getVirtualConnection(), this, exception);
        } catch (Exception original) {
            synchronized (closeSync) {
                // if close has been called then assume this exception was due to a race condition
                // with the close logic. so no FFDC here.
                if (closeCalled) {
                    return null;
                } else {
                    throw original;
                }
            }
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.exit(tc, "encryptAndWriteAsync: " + vc);
        }
        return vc;
    }
1224994
private void serverKeyExchange(RSA_ServerKeyExchange mesg)
            throws IOException, GeneralSecurityException {
        if (debug != null && Debug.isOn("handshake")) {
            mesg.print(System.out);
        }
        if (!mesg.verify(serverKey, clnt_random, svr_random)) {
            fatalSE(Alerts.alert_handshake_failure,
                "server key exchange invalid");
            // NOTREACHED
        }
        ephemeralServerKey = mesg.getPublicKey();
    }
182893
public Sha256Hash hashForSignature(int inputIndex, byte[] connectedScript, byte sigHashType) {
        // The SIGHASH flags are used in the design of contracts, please see this page for a further understanding of
        // the purposes of the code in this method:
        //
        //   https://en.bitcoin.it/wiki/Contracts

        try {
            // Create a copy of this transaction to operate upon because we need make changes to the inputs and outputs.
            // It would not be thread-safe to change the attributes of the transaction object itself.
            Transaction tx = this.params.getDefaultSerializer().makeTransaction(this.bitcoinSerialize());

            // Clear input scripts in preparation for signing. If we're signing a fresh
            // transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
            // EC math so we'll do it anyway.
            for (int i = 0; i < tx.inputs.size(); i++) {
                TransactionInput input = tx.inputs.get(i);
                input.clearScriptBytes();
                input.setWitness(null);
            }

            // This step has no purpose beyond being synchronized with Bitcoin Core's bugs. OP_CODESEPARATOR
            // is a legacy holdover from a previous, broken design of executing scripts that shipped in Bitcoin 0.1.
            // It was seriously flawed and would have let anyone take anyone elses money. Later versions switched to
            // the design we use today where scripts are executed independently but share a stack. This left the
            // OP_CODESEPARATOR instruction having no purpose as it was only meant to be used internally, not actually
            // ever put into scripts. Deleting OP_CODESEPARATOR is a step that should never be required but if we don't
            // do it, we could split off the best chain.
            connectedScript = Script.removeAllInstancesOfOp(connectedScript, ScriptOpCodes.OP_CODESEPARATOR);

            // Set the input to the script of its output. Bitcoin Core does this but the step has no obvious purpose as
            // the signature covers the hash of the prevout transaction which obviously includes the output script
            // already. Perhaps it felt safer to him in some way, or is another leftover from how the code was written.
            TransactionInput input = tx.inputs.get(inputIndex);
            input.setScriptBytes(connectedScript);

            if ((sigHashType & 0x1f) == SigHash.NONE.value) {
                // SIGHASH_NONE means no outputs are signed at all - the signature is effectively for a "blank cheque".
                tx.outputs = new ArrayList<>(0);
                // The signature isn't broken by new versions of the transaction issued by other parties.
                for (int i = 0; i < tx.inputs.size(); i++)
                    if (i != inputIndex)
                        tx.inputs.get(i).setSequenceNumber(0);
            } else if ((sigHashType & 0x1f) == SigHash.SINGLE.value) {
                // SIGHASH_SINGLE means only sign the output at the same index as the input (ie, my output).
                if (inputIndex >= tx.outputs.size()) {
                    // The input index is beyond the number of outputs, it's a buggy signature made by a broken
                    // Bitcoin implementation. Bitcoin Core also contains a bug in handling this case:
                    // any transaction output that is signed in this case will result in both the signed output
                    // and any future outputs to this public key being steal-able by anyone who has
                    // the resulting signature and the public key (both of which are part of the signed tx input).

                    // Bitcoin Core's bug is that SignatureHash was supposed to return a hash and on this codepath it
                    // actually returns the constant "1" to indicate an error, which is never checked for. Oops.
                    return Sha256Hash.wrap("0100000000000000000000000000000000000000000000000000000000000000");
                }
                // In SIGHASH_SINGLE the outputs after the matching input index are deleted, and the outputs before
                // that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1.
                tx.outputs = new ArrayList<>(tx.outputs.subList(0, inputIndex + 1));
                for (int i = 0; i < inputIndex; i++)
                    tx.outputs.set(i, new TransactionOutput(tx.params, tx, Coin.NEGATIVE_SATOSHI, new byte[] {}));
                // The signature isn't broken by new versions of the transaction issued by other parties.
                for (int i = 0; i < tx.inputs.size(); i++)
                    if (i != inputIndex)
                        tx.inputs.get(i).setSequenceNumber(0);
            }

            if ((sigHashType & SigHash.ANYONECANPAY.value) == SigHash.ANYONECANPAY.value) {
                // SIGHASH_ANYONECANPAY means the signature in the input is not broken by changes/additions/removals
                // of other inputs. For example, this is useful for building assurance contracts.
                tx.inputs = new ArrayList<>();
                tx.inputs.add(input);
            }

            ByteArrayOutputStream bos = new ByteArrayOutputStream(tx.length);
            tx.bitcoinSerializeToStream(bos, false);
            // We also have to write a hash type (sigHashType is actually an unsigned char)
            uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
            // Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out
            // however then we would expect that it is IS reversed.
            Sha256Hash hash = Sha256Hash.twiceOf(bos.toByteArray());
            bos.close();

            return hash;
        } catch (IOException e) {
            throw new RuntimeException(e);  // Cannot happen.
        }
    }
628059
HandshakeMessage getKickstartMessage() throws SSLException {
        // session ID of the ClientHello message
        SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();

        // a list of cipher suites sent by the client
        CipherSuiteList cipherSuites = getActiveCipherSuites();

        // set the max protocol version this client is supporting.
        maxProtocolVersion = protocolVersion;

        //
        // Try to resume an existing session.  This might be mandatory,
        // given certain API options.
        //
        session = ((SSLSessionContextImpl)sslContext
                        .engineGetClientSessionContext())
                        .get(getHostSE(), getPortSE());
        if (debug != null && Debug.isOn("session")) {
            if (session != null) {
                System.out.println("%% Client cached "
                    + session
                    + (session.isRejoinable() ? "" : " (not rejoinable)"));
            } else {
                System.out.println("%% No cached client session");
            }
        }
        if (session != null) {
            // If unsafe server certificate change is not allowed, reserve
            // current server certificates if the preious handshake is a
            // session-resumption abbreviated initial handshake.
            if (!allowUnsafeServerCertChange && session.isSessionResumption()) {
                try {
                    // If existing, peer certificate chain cannot be null.
                    reservedServerCerts =
                        (X509Certificate[])session.getPeerCertificates();
                } catch (SSLPeerUnverifiedException puve) {
                    // Maybe not certificate-based, ignore the exception.
                }
            }
            if (!session.isRejoinable()) {
                session = null;
            }
        }

        if (session != null) {
            CipherSuite sessionSuite = session.getSuite();
            ProtocolVersion sessionVersion = session.getProtocolVersion();
            if (isNegotiable(sessionSuite) == false) {
                if (debug != null && Debug.isOn("session")) {
                    System.out.println("%% can't resume, unavailable cipher");
                }
                session = null;
            }

            if ((session != null) && !isNegotiable(sessionVersion)) {
                if (debug != null && Debug.isOn("session")) {
                    System.out.println("%% can't resume, protocol disabled");
                }
                session = null;
            }

            if (session != null) {
                if (debug != null) {
                    if (Debug.isOn("handshake") || Debug.isOn("session")) {
                        System.out.println("%% Try resuming " + session
                            + " from port " + getLocalPortSE());
                    }
                }

                sessionId = session.getSessionId();
                maxProtocolVersion = sessionVersion;

                // Update SSL version number in underlying SSL socket and
                // handshake output stream, so that the output records (at the
                // record layer) have the correct version
                setVersion(sessionVersion);
            }

            /*
             * Force use of the previous session ciphersuite, and
             * add the SCSV if enabled.
             */
            if (!enableNewSession) {
                if (session == null) {
                    throw new SSLHandshakeException(
                        "Can't reuse existing SSL client session");
                }

                Collection<CipherSuite> cipherList = new ArrayList<>(2);
                cipherList.add(sessionSuite);
                if (!secureRenegotiation &&
                        cipherSuites.contains(CipherSuite.C_SCSV)) {
                    cipherList.add(CipherSuite.C_SCSV);
                }   // otherwise, renegotiation_info extension will be used

                cipherSuites = new CipherSuiteList(cipherList);
            }
        }

        if (session == null && !enableNewSession) {
            throw new SSLHandshakeException("No existing session to resume");
        }

        // exclude SCSV for secure renegotiation
        if (secureRenegotiation && cipherSuites.contains(CipherSuite.C_SCSV)) {
            Collection<CipherSuite> cipherList =
                        new ArrayList<>(cipherSuites.size() - 1);
            for (CipherSuite suite : cipherSuites.collection()) {
                if (suite != CipherSuite.C_SCSV) {
                    cipherList.add(suite);
                }
            }

            cipherSuites = new CipherSuiteList(cipherList);
        }

        // make sure there is a negotiable cipher suite.
        boolean negotiable = false;
        for (CipherSuite suite : cipherSuites.collection()) {
            if (isNegotiable(suite)) {
                negotiable = true;
                break;
            }
        }

        if (!negotiable) {
            throw new SSLHandshakeException("No negotiable cipher suite");
        }

        // Not a TLS1.2+ handshake
        // For SSLv2Hello, HandshakeHash.reset() will be called, so we
        // cannot call HandshakeHash.protocolDetermined() here. As it does
        // not follow the spec that HandshakeHash.reset() can be only be
        // called before protocolDetermined.
        // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
        //     handshakeHash.protocolDetermined(maxProtocolVersion);
        // }

        // create the ClientHello message
        ClientHello clientHelloMessage = new ClientHello(
                sslContext.getSecureRandom(), maxProtocolVersion,
                sessionId, cipherSuites);

        // add signature_algorithm extension
        if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
            // we will always send the signature_algorithm extension
            Collection<SignatureAndHashAlgorithm> localSignAlgs =
                                                getLocalSupportedSignAlgs();
            if (localSignAlgs.isEmpty()) {
                throw new SSLHandshakeException(
                            "No supported signature algorithm");
            }

            clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
        }

        // add server_name extension
        if (enableSNIExtension) {
            // We cannot use the hostname resolved from name services.  For
            // virtual hosting, multiple hostnames may be bound to the same IP
            // address, so the hostname resolved from name services is not
            // reliable.
            String hostname = getRawHostnameSE();

            // we only allow FQDN
            if (hostname != null && hostname.indexOf('.') > 0 &&
                    !IPAddressUtil.isIPv4LiteralAddress(hostname) &&
                    !IPAddressUtil.isIPv6LiteralAddress(hostname)) {
                clientHelloMessage.addServerNameIndicationExtension(hostname);
            }
        }

        // reset the client random cookie
        clnt_random = clientHelloMessage.clnt_random;

        /*
         * need to set the renegotiation_info extension for:
         * 1: secure renegotiation
         * 2: initial handshake and no SCSV in the ClientHello
         * 3: insecure renegotiation and no SCSV in the ClientHello
         */
        if (secureRenegotiation ||
                !cipherSuites.contains(CipherSuite.C_SCSV)) {
            clientHelloMessage.addRenegotiationInfoExtension(clientVerifyData);
        }

        // NPN_CHANGES_BEGIN
        if (isInitialHandshake)
        {
            NextProtoNego.ClientProvider provider = conn != null ?
                    (NextProtoNego.ClientProvider)NextProtoNego.get(conn) :
                    (NextProtoNego.ClientProvider)NextProtoNego.get(engine);
            if (provider != null)
            {
                if (provider.supports())
                {
                    if (NextProtoNego.debug)
                        System.err.println(new StringBuilder("[C] NPN supported for ").append(conn != null ? conn : engine));
                    clientHelloMessage.extensions.add(new NextProtoNegoExtension());
                }
                else
                {
                    if (NextProtoNego.debug)
                        System.err.println(new StringBuilder("[C] NPN not supported for ").append(conn != null ? conn : engine));
                }
            }
            else
            {
                if (NextProtoNego.debug)
                    System.err.println(new StringBuilder("[C] NPN client provider not present for ").append(conn != null ? conn : engine));
            }
        }
        // NPN_CHANGES_END

        return clientHelloMessage;
    }