/*
Diffie-Hellman key exchange.  We save the server public key and
our own D-H algorithm object so we can defer key calculations
until after we've sent the client key exchange message (which
gives client and server some useful parallelism).
173861
private void serverKeyExchange(DH_ServerKeyExchange mesg)
            throws IOException {
        if (debug != null && Debug.isOn("handshake")) {
            mesg.print(System.out);
        }
        dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
                                            sslContext.getSecureRandom());
        serverDH = mesg.getServerPublicKey();
    }
842186
function decipher(string) {

        if(string) {

            if ( typeof pw !== 'string' || pw.length < 8 ) {
                throw new Error('Please set a password with 8 or ' +
                    'more chars on process.env.CIPHER_UTIL_PW!');
            }

            if ( typeof algo !== 'string' || algo.length < 1 ) {
                throw new Error('Please choose an algorithm' +
                    ' on process.env.CIPHER_UTIL_ALGO!');
            }

            var buffer = new Buffer(string, enc),

            iv = buffer.slice(0, ivBlock),

            text = buffer.slice(ivBlock),

            toDecipher = crypto.createDecipheriv(algo, pw, iv),

            deciphered = [toDecipher.update(text)];

            deciphered.push(toDecipher.final());

            return Buffer.concat(deciphered).toString(dec);

        }

        return null;

    }
871161
public void deriveSrtcpKeys() {
        // compute the session encryption key
        byte label = 3;
        computeIv(label);

        KeyParameter encryptionKey = new KeyParameter(masterKey);
        cipher.init(true, encryptionKey);
        Arrays.fill(masterKey, (byte)0);

        cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), ivStore);

        if (authKey != null) {
            label = 4;
            computeIv(label);
            cipherCtr.getCipherStream(cipher, authKey, policy.getAuthKeyLength(), ivStore);

            switch ((policy.getAuthType())) {
	            case SRTPPolicy.HMACSHA1_AUTHENTICATION:
	                KeyParameter key =  new KeyParameter(authKey);
	                mac.init(key);
	                break;
	
	            default:
	                break;
            }
        }
        Arrays.fill(authKey, (byte)0);

        // compute the session salt
        label = 5;
        computeIv(label);
        cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), ivStore);
        Arrays.fill(masterSalt, (byte)0);

        // As last step: initialize cipher with derived encryption key.
        if (cipherF8 != null) {
            SRTPCipherF8.deriveForIV(cipherF8, encKey, saltKey);
        }
        encryptionKey = new KeyParameter(encKey);
        cipher.init(true, encryptionKey);
        Arrays.fill(encKey, (byte)0);
    }
1105519
function KEXINIT(self, cb) { // Client/Server
  randBytes(16, function(myCookie) {
    /*
      byte         SSH_MSG_KEXINIT
      byte[16]     cookie (random bytes)
      name-list    kex_algorithms
      name-list    server_host_key_algorithms
      name-list    encryption_algorithms_client_to_server
      name-list    encryption_algorithms_server_to_client
      name-list    mac_algorithms_client_to_server
      name-list    mac_algorithms_server_to_client
      name-list    compression_algorithms_client_to_server
      name-list    compression_algorithms_server_to_client
      name-list    languages_client_to_server
      name-list    languages_server_to_client
      boolean      first_kex_packet_follows
      uint32       0 (reserved for future extension)
    */
    var algos = self.config.algorithms;

    var kexBuf = algos.kexBuf;
    if (self.remoteBugs & BUGS.BAD_DHGEX) {
      var copied = false;
      var kexList = algos.kex;
      for (var j = kexList.length - 1; j >= 0; --j) {
        if (kexList[j].indexOf('group-exchange') !== -1) {
          if (!copied) {
            kexList = kexList.slice();
            copied = true;
          }
          kexList.splice(j, 1);
        }
      }
      if (copied)
        kexBuf = Buffer.from(kexList.join(','));
    }

    var hostKeyBuf = algos.serverHostKeyBuf;

    var kexInitSize = 1 + 16
                      + 4 + kexBuf.length
                      + 4 + hostKeyBuf.length
                      + (2 * (4 + algos.cipherBuf.length))
                      + (2 * (4 + algos.hmacBuf.length))
                      + (2 * (4 + algos.compressBuf.length))
                      + (2 * (4 /* languages skipped */))
                      + 1 + 4;
    var buf = Buffer.allocUnsafe(kexInitSize);
    var p = 17;

    buf[0] = MESSAGE.KEXINIT;

    if (myCookie !== false)
      myCookie.copy(buf, 1);

    writeUInt32BE(buf, kexBuf.length, p);
    p += 4;
    kexBuf.copy(buf, p);
    p += kexBuf.length;

    writeUInt32BE(buf, hostKeyBuf.length, p);
    p += 4;
    hostKeyBuf.copy(buf, p);
    p += hostKeyBuf.length;

    writeUInt32BE(buf, algos.cipherBuf.length, p);
    p += 4;
    algos.cipherBuf.copy(buf, p);
    p += algos.cipherBuf.length;

    writeUInt32BE(buf, algos.cipherBuf.length, p);
    p += 4;
    algos.cipherBuf.copy(buf, p);
    p += algos.cipherBuf.length;

    writeUInt32BE(buf, algos.hmacBuf.length, p);
    p += 4;
    algos.hmacBuf.copy(buf, p);
    p += algos.hmacBuf.length;

    writeUInt32BE(buf, algos.hmacBuf.length, p);
    p += 4;
    algos.hmacBuf.copy(buf, p);
    p += algos.hmacBuf.length;

    writeUInt32BE(buf, algos.compressBuf.length, p);
    p += 4;
    algos.compressBuf.copy(buf, p);
    p += algos.compressBuf.length;

    writeUInt32BE(buf, algos.compressBuf.length, p);
    p += 4;
    algos.compressBuf.copy(buf, p);
    p += algos.compressBuf.length;

    // Skip language lists, first_kex_packet_follows, and reserved bytes
    buf.fill(0, buf.length - 13);

    self.debug('DEBUG: Outgoing: Writing KEXINIT');

    self._state.incoming.expectedPacket = 'KEXINIT';

    var outstate = self._state.outgoing;

    outstate.kexinit = buf;

    if (outstate.status === OUT_READY) {
      // We are the one starting the rekeying process ...
      outstate.status = OUT_REKEYING;
    }

    send(self, buf, cb, true);
  });
  return true;
}
147127
function Client(publicKey, privateKey, server) {
  if (!publicKey || !privateKey) { throw new Error('cannot use null/undefined public/private CryptoPhoto keys'); }

  if (!(this instanceof Client)) { return new Client(publicKey, privateKey, server); }

  this._server = (server && server.toString().trim()) || 'http://cryptophoto.com';
  this._publicKey = publicKey;
  this._privateKey = privateKey;
}
947281
function(publicKey, privateKey) {
  var ts = new Date() / 1000 | 0;
  return {
    ts: ts,
    api_sig: crypto.createHmac('sha1', privateKey).update(ts.toString()).digest('hex'),
    api_key: publicKey
  };
}
633526
public function pbkdf2($p, $s, $c, $dkLen, $a = 'sha256') {
    $hLen = strlen(hash($a, null, true)); /* Hash length. */
    $l    = ceil($dkLen / $hLen);         /* Length in blocks of derived key. */
    $dk   = '';                           /* Derived key. */

    /* Step 1. Check dkLen. */
    if($dkLen > (2^32-1) * $hLen) {
      throw new \phpSec\Exception\GeneralSecurityException('Derived key too long');
      return false;
    }

    for ($block = 1; $block<=$l; $block ++) {
      /* Initial hash for this block. */
      $ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
      /* Do block iterations. */
      for ($i = 1; $i<$c; $i ++) {
        /* XOR iteration. */
        $ib ^= ($b = hash_hmac($a, $b, $p, true));
      }
      /* Append iterated block. */
      $dk .= $ib;
    }
    /* Returned derived key. */
    return substr($dk, 0, $dkLen);
  }
544586
function decrypt (str) {
    var decipher = crypto.createDecipher(algorithm, key)
      , dec = decipher.update(str, to, from) + decipher.final(from)
    return dec;
  }
1192336
function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
    {
        $signed = $this->privateKeyFormat != self::PRIVATE_FORMAT_XML;
        $num_primes = count($primes);
        $raw = array(
            'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
            'modulus' => $n->toBytes($signed),
            'publicExponent' => $e->toBytes($signed),
            'privateExponent' => $d->toBytes($signed),
            'prime1' => $primes[1]->toBytes($signed),
            'prime2' => $primes[2]->toBytes($signed),
            'exponent1' => $exponents[1]->toBytes($signed),
            'exponent2' => $exponents[2]->toBytes($signed),
            'coefficient' => $coefficients[2]->toBytes($signed)
        );

        // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
        // call _convertPublicKey() instead.
        switch ($this->privateKeyFormat) {
            case self::PRIVATE_FORMAT_XML:
                if ($num_primes != 2) {
                    return false;
                }
                return "<RSAKeyValue>\r\n" .
                       '  <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" .
                       '  <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" .
                       '  <P>' . base64_encode($raw['prime1']) . "</P>\r\n" .
                       '  <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" .
                       '  <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" .
                       '  <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" .
                       '  <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" .
                       '  <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" .
                       '</RSAKeyValue>';
                break;
            case self::PRIVATE_FORMAT_PUTTY:
                if ($num_primes != 2) {
                    return false;
                }
                $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
                $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
                $key.= $encryption;
                $key.= "\r\nComment: " . $this->comment . "\r\n";
                $public = pack(
                    'Na*Na*Na*',
                    strlen('ssh-rsa'),
                    'ssh-rsa',
                    strlen($raw['publicExponent']),
                    $raw['publicExponent'],
                    strlen($raw['modulus']),
                    $raw['modulus']
                );
                $source = pack(
                    'Na*Na*Na*Na*',
                    strlen('ssh-rsa'),
                    'ssh-rsa',
                    strlen($encryption),
                    $encryption,
                    strlen($this->comment),
                    $this->comment,
                    strlen($public),
                    $public
                );
                $public = base64_encode($public);
                $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
                $key.= chunk_split($public, 64);
                $private = pack(
                    'Na*Na*Na*Na*',
                    strlen($raw['privateExponent']),
                    $raw['privateExponent'],
                    strlen($raw['prime1']),
                    $raw['prime1'],
                    strlen($raw['prime2']),
                    $raw['prime2'],
                    strlen($raw['coefficient']),
                    $raw['coefficient']
                );
                if (empty($this->password) && !is_string($this->password)) {
                    $source.= pack('Na*', strlen($private), $private);
                    $hashkey = 'putty-private-key-file-mac-key';
                } else {
                    $private.= Random::string(16 - (strlen($private) & 15));
                    $source.= pack('Na*', strlen($private), $private);
                    $sequence = 0;
                    $symkey = '';
                    while (strlen($symkey) < 32) {
                        $temp = pack('Na*', $sequence++, $this->password);
                        $symkey.= pack('H*', sha1($temp));
                    }
                    $symkey = substr($symkey, 0, 32);
                    $crypto = new AES();

                    $crypto->setKey($symkey);
                    $crypto->disablePadding();
                    $private = $crypto->encrypt($private);
                    $hashkey = 'putty-private-key-file-mac-key' . $this->password;
                }

                $private = base64_encode($private);
                $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
                $key.= chunk_split($private, 64);
                $hash = new Hash('sha1');
                $hash->setKey(pack('H*', sha1($hashkey)));
                $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";

                return $key;
            default: // eg. self::PRIVATE_FORMAT_PKCS1
                $components = array();
                foreach ($raw as $name => $value) {
                    $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
                }

                $RSAPrivateKey = implode('', $components);

                if ($num_primes > 2) {
                    $OtherPrimeInfos = '';
                    for ($i = 3; $i <= $num_primes; $i++) {
                        // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
                        //
                        // OtherPrimeInfo ::= SEQUENCE {
                        //     prime             INTEGER,  -- ri
                        //     exponent          INTEGER,  -- di
                        //     coefficient       INTEGER   -- ti
                        // }
                        $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
                        $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
                        $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
                        $OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
                    }
                    $RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
                }

                $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);

                if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) {
                    $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
                    $RSAPrivateKey = pack(
                        'Ca*a*Ca*a*',
                        self::ASN1_INTEGER,
                        "\01\00",
                        $rsaOID,
                        4,
                        $this->_encodeLength(strlen($RSAPrivateKey)),
                        $RSAPrivateKey
                    );
                    $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
                    if (!empty($this->password) || is_string($this->password)) {
                        $salt = Random::string(8);
                        $iterationCount = 2048;

                        $crypto = new DES();
                        $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
                        $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);

                        $parameters = pack(
                            'Ca*a*Ca*N',
                            self::ASN1_OCTETSTRING,
                            $this->_encodeLength(strlen($salt)),
                            $salt,
                            self::ASN1_INTEGER,
                            $this->_encodeLength(4),
                            $iterationCount
                        );
                        $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";

                        $encryptionAlgorithm = pack(
                            'Ca*a*Ca*a*',
                            self::ASN1_OBJECT,
                            $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
                            $pbeWithMD5AndDES_CBC,
                            self::ASN1_SEQUENCE,
                            $this->_encodeLength(strlen($parameters)),
                            $parameters
                        );

                        $RSAPrivateKey = pack(
                            'Ca*a*Ca*a*',
                            self::ASN1_SEQUENCE,
                            $this->_encodeLength(strlen($encryptionAlgorithm)),
                            $encryptionAlgorithm,
                            self::ASN1_OCTETSTRING,
                            $this->_encodeLength(strlen($RSAPrivateKey)),
                            $RSAPrivateKey
                        );

                        $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);

                        $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
                                         '-----END ENCRYPTED PRIVATE KEY-----';
                    } else {
                        $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
                                         '-----END PRIVATE KEY-----';
                    }
                    return $RSAPrivateKey;
                }

                if (!empty($this->password) || is_string($this->password)) {
                    $iv = Random::string(8);
                    $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
                    $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
                    $des = new TripleDES();
                    $des->setKey($symkey);
                    $des->setIV($iv);
                    $iv = strtoupper(bin2hex($iv));
                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
                                     "Proc-Type: 4,ENCRYPTED\r\n" .
                                     "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
                                     "\r\n" .
                                     chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
                                     '-----END RSA PRIVATE KEY-----';
                } else {
                    $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
                                     chunk_split(base64_encode($RSAPrivateKey), 64) .
                                     '-----END RSA PRIVATE KEY-----';
                }

                return $RSAPrivateKey;
        }
    }
1257173
function(he,me){// Generate key
// Init HMAC
// Initial values
// Shortcuts
for(// Shortcut
var ge=this.cfg,_e=ue.create(ge.hasher,he),ve=fe.create(),Se=fe.create([1]),ke=ve.words,Ie=Se.words,Ae=ge.keySize,we=ge.iterations,Ee;ke.length<Ae;){Ee=_e.update(me).finalize(Se),_e.reset();// Iterations
for(var Pe=Ee.words,Be=Pe.length,Re=Ee,Te=1;Te<we;Te++){Re=_e.finalize(Re),_e.reset();// XOR intermediate with block
for(var Oe=Re.words,Ce=0;Ce<Be;Ce++)Pe[Ce]^=Oe[Ce]}ve.concat(Ee),Ie[0]++}return ve.sigBytes=4*Ae,ve}
495435
function(pk, challenge, signature) {
    var pem = "-----BEGIN RSA PUBLIC KEY-----\n" 
        + pk.replace(/(.{64})/g, "$1\n")
        + "\n-----END RSA PUBLIC KEY-----";

    var rsa = crypto.createVerify("RSA-SHA256");
    rsa.update(new Buffer(challenge, "base64"));
    if(rsa.verify(pem, signature, "base64"))
    {
        return { result : true };
    }
    else {
        return { result : false };
    }
}
839346
def public_key(self):
        

        if self._public_key is None:
            if self.algorithm == 'ec':
                key = self['private_key'].parsed
                if key['public_key']:
                    self._public_key = key['public_key'].untag()
                else:
                    self._public_key = self._compute_public_key()
            else:
                self._public_key = self._compute_public_key()

        return self._public_key
129862
function HKDF(hashAlg, salt, ikm) {
  if (!(this instanceof HKDF)) { return new HKDF(hashAlg, salt, ikm); }

  this.hashAlg = hashAlg;

  // create the hash alg to see if it exists and get its length
  var hash = crypto.createHash(this.hashAlg);
  this.hashLength = hash.digest().length;

  this.salt = salt || zeros(this.hashLength);
  this.ikm = ikm;

  // now we compute the PRK
  var hmac = crypto.createHmac(this.hashAlg, this.salt);
  hmac.update(this.ikm);
  this.prk = hmac.digest();
}
1175143
private Cipher createCipher( final byte [] pwdAsBytes, byte [] salt, final int mode )
    throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException
    {
        _digester.reset();
        
        byte[] keyAndIv = new byte[ SPICE_SIZE * 2 ];
        
        if( salt == null || salt.length == 0 )
        {
            // Unsalted!  Bad idea!
            salt = null;
        }
        
        byte[] result;
        
        int currentPos = 0;
        
        while (currentPos < keyAndIv.length)
        {
            _digester.update(pwdAsBytes);
            
            if (salt != null)
            {
                // First 8 bytes of salt ONLY!  That wasn't obvious to me
                // when using AES encrypted private keys in "Traditional
                // SSLeay Format".
                //
                // Example:
                // DEK-Info: AES-128-CBC,8DA91D5A71988E3D4431D9C2C009F249
                //
                // Only the first 8 bytes are salt, but the whole thing is
                // re-used again later as the IV.  MUCH gnashing of teeth!
                _digester.update( salt, 0, 8 );
            }
            result = _digester.digest();
            
            int stillNeed = keyAndIv.length - currentPos;
            
            // Digest gave us more than we need.  Let's truncate it.
            if (result.length > stillNeed)
            {
                byte[] b = new byte[stillNeed];
                
                System.arraycopy(result, 0, b, 0, b.length);
                
                result = b;
            }
            
            System.arraycopy(result, 0, keyAndIv, currentPos, result.length);
            
            currentPos += result.length;
            
            if (currentPos < keyAndIv.length)
            {
                // Next round starts with a hash of the hash.
                _digester.reset();
                _digester.update(result);
            }
        }

        byte[] key = new byte[ SPICE_SIZE ];
        
        byte[] iv = new byte[ SPICE_SIZE ];
        
        System.arraycopy(keyAndIv, 0, key, 0, key.length);
        
        System.arraycopy(keyAndIv, key.length, iv, 0, iv.length);

        Cipher cipher = Cipher.getInstance( CIPHER_ALG );

        cipher.init( mode, new SecretKeySpec( key, KEY_ALG ), new IvParameterSpec( iv ) );
        
        return cipher;
    }
1370168
public static byte[] encrypt(byte[] input, String key, String algorithm, byte[] ivOrSalt, int iterations) throws PageException {
	return crypt(input, key, algorithm, ivOrSalt, iterations, false);
    }
198218
public void setAlgorithm(KeyAgreementType dh) 
	{
		log("DH algorithm set: " + getDHName(dhMode) + " -> " + getDHName(dh));
		try {
			if(dhMode != null && dh.keyType == dhMode.keyType) return;
			dhMode = dh;
			switch (dhMode.keyType) {
		        case KeyAgreementType.DH_MODE_DH3K:
		    		DHParameterSpec paramSpec = new DHParameterSpec(dhP, dhG, DH_EXP_LENGTH);
		    		dhKeyGen = KeyPairGenerator.getInstance(ALGORITHM_DH);
		    		dhKeyGen.initialize(paramSpec, sr);
		    		dhKeyPair = dhKeyGen.generateKeyPair();
		    		clearEcdh();
		    		break;
		        case KeyAgreementType.DH_MODE_EC25:
		        	setupEC(256);
			        break;
		        case KeyAgreementType.DH_MODE_EC38:
		        default:
		        	setupEC(384);
			        break;
	        }
		} catch (Exception e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
	        throw new RuntimeException("Failed init Diffie-Hellman: " + e.getClass().getName() + ": " + e.getMessage() + ", bitlength p = " + dhP.bitCount());
        }
	}
385377
def _send_kex_init(self):
        
        self.clear_to_send_lock.acquire()
        try:
            self.clear_to_send.clear()
        finally:
            self.clear_to_send_lock.release()
        self.in_kex = True
        if self.server_mode:
            if (self._modulus_pack is None) and ('diffie-hellman-group-exchange-sha1' in self._preferred_kex):
                # can't do group-exchange if we don't have a pack of potential primes
                pkex = list(self.get_security_options().kex)
                pkex.remove('diffie-hellman-group-exchange-sha1')
                self.get_security_options().kex = pkex
            available_server_keys = filter(self.server_key_dict.keys().__contains__,
                                           self._preferred_keys)
        else:
            available_server_keys = self._preferred_keys

        m = Message()
        m.add_byte(chr(MSG_KEXINIT))
        m.add_bytes(rng.read(16))
        m.add_list(self._preferred_kex)
        m.add_list(available_server_keys)
        m.add_list(self._preferred_ciphers)
        m.add_list(self._preferred_ciphers)
        m.add_list(self._preferred_macs)
        m.add_list(self._preferred_macs)
        m.add_list(self._preferred_compression)
        m.add_list(self._preferred_compression)
        m.add_string('')
        m.add_string('')
        m.add_boolean(False)
        m.add_int(0)
        # save a copy for later (needed to compute a hash)
        self.local_kex_init = str(m)
        self._send_message(m)