コード例 #1
0
ファイル: PuTTY.php プロジェクト: msulistijo/PhpseclibBundle
 /**
  * Convert a private key to the appropriate format.
  *
  * @access public
  * @param \phpseclib\Math\BigInteger $n
  * @param \phpseclib\Math\BigInteger $e
  * @param \phpseclib\Math\BigInteger $d
  * @param array $primes
  * @param array $exponents
  * @param array $coefficients
  * @param string $password optional
  * @return string
  */
 static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
 {
     if (count($primes) != 2) {
         return false;
     }
     $raw = array('modulus' => $n->toBytes(true), 'publicExponent' => $e->toBytes(true), 'privateExponent' => $d->toBytes(true), 'prime1' => $primes[1]->toBytes(true), 'prime2' => $primes[2]->toBytes(true), 'exponent1' => $exponents[1]->toBytes(true), 'exponent2' => $exponents[2]->toBytes(true), 'coefficient' => $coefficients[2]->toBytes(true));
     $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
     $encryption = !empty($password) || is_string($password) ? 'aes256-cbc' : 'none';
     $key .= $encryption;
     $key .= "\r\nComment: " . self::$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(self::$comment), self::$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($password) && !is_string($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);
         $crypto = new AES();
         $crypto->setKey(static::generateSymmetricKey($password, 32));
         $crypto->disablePadding();
         $private = $crypto->encrypt($private);
         $hashkey = 'putty-private-key-file-mac-key' . $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;
 }
コード例 #2
0
ファイル: PKCS1.php プロジェクト: msulistijo/PhpseclibBundle
 /**
  * Convert a public key to the appropriate format
  *
  * @access public
  * @param \phpseclib\Math\BigInteger $n
  * @param \phpseclib\Math\BigInteger $e
  * @return string
  */
 static function savePublicKey(BigInteger $n, BigInteger $e)
 {
     $modulus = $n->toBytes(true);
     $publicExponent = $e->toBytes(true);
     // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
     // RSAPublicKey ::= SEQUENCE {
     //     modulus           INTEGER,  -- n
     //     publicExponent    INTEGER   -- e
     // }
     $components = array('modulus' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($modulus)), $modulus), 'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($publicExponent)), $publicExponent));
     $RSAPublicKey = pack('Ca*a*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])), $components['modulus'], $components['publicExponent']);
     $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" . chunk_split(base64_encode($RSAPublicKey), 64) . '-----END RSA PUBLIC KEY-----';
     return $RSAPublicKey;
 }
コード例 #3
0
 /**
  * Convert a public key to the appropriate format
  *
  * @access public
  * @param \phpseclib\Math\BigInteger $n
  * @param \phpseclib\Math\BigInteger $e
  * @return string
  */
 function savePublicKey(BigInteger $n, BigInteger $e)
 {
     $publicExponent = $e->toBytes(true);
     $modulus = $n->toBytes(true);
     // from <http://tools.ietf.org/html/rfc4253#page-15>:
     // string    "ssh-rsa"
     // mpint     e
     // mpint     n
     $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
     $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . self::$comment;
     return $RSAPublicKey;
 }
コード例 #4
0
ファイル: MSBLOB.php プロジェクト: msulistijo/PhpseclibBundle
 /**
  * Convert a private key to the appropriate format.
  *
  * @access public
  * @param \phpseclib\Math\BigInteger $n
  * @param \phpseclib\Math\BigInteger $e
  * @param \phpseclib\Math\BigInteger $d
  * @param array $primes
  * @param array $exponents
  * @param array $coefficients
  * @param string $password optional
  * @return string
  */
 static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
 {
     $n = strrev($n->toBytes());
     $e = str_pad(strrev($e->toBytes()), 4, "");
     $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX);
     $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e);
     $key .= $n;
     $key .= strrev($primes[1]->toBytes());
     $key .= strrev($primes[2]->toBytes());
     $key .= strrev($exponents[1]->toBytes());
     $key .= strrev($exponents[2]->toBytes());
     $key .= strrev($coefficients[1]->toBytes());
     $key .= strrev($d->toBytes());
     return base64_encode($key);
 }
コード例 #5
0
ファイル: SSH1.php プロジェクト: msulistijo/PhpseclibBundle
 /**
  * Connect to an SSHv1 server
  *
  * @return bool
  * @throws \UnexpectedValueException on receipt of unexpected packets
  * @throws \RuntimeException on other errors
  * @access private
  */
 function _connect()
 {
     $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout);
     if (!$this->fsock) {
         throw new \RuntimeException(rtrim("Cannot connect to {$host}. Error {$errno}. {$errstr}"));
     }
     $this->server_identification = $init_line = fgets($this->fsock, 255);
     if (defined('NET_SSH1_LOGGING')) {
         $this->_append_log('<-', $this->server_identification);
         $this->_append_log('->', $this->identifier . "\r\n");
     }
     if (!preg_match('#SSH-([0-9\\.]+)-(.+)#', $init_line, $parts)) {
         throw new \RuntimeException('Can only connect to SSH servers');
     }
     if ($parts[1][0] != 1) {
         throw new \RuntimeException("Cannot connect to {$parts['1']} servers");
     }
     fputs($this->fsock, $this->identifier . "\r\n");
     $response = $this->_get_binary_packet();
     if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
         throw new \UnexpectedValueException('Expected SSH_SMSG_PUBLIC_KEY');
     }
     $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
     $this->_string_shift($response[self::RESPONSE_DATA], 4);
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->server_key_public_exponent = $server_key_public_exponent;
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->server_key_public_modulus = $server_key_public_modulus;
     $this->_string_shift($response[self::RESPONSE_DATA], 4);
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->host_key_public_exponent = $host_key_public_exponent;
     $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
     $host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
     $this->host_key_public_modulus = $host_key_public_modulus;
     $this->_string_shift($response[self::RESPONSE_DATA], 4);
     // get a list of the supported ciphers
     extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
     foreach ($this->supported_ciphers as $mask => $name) {
         if (($supported_ciphers_mask & 1 << $mask) == 0) {
             unset($this->supported_ciphers[$mask]);
         }
     }
     // get a list of the supported authentications
     extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
     foreach ($this->supported_authentications as $mask => $name) {
         if (($supported_authentications_mask & 1 << $mask) == 0) {
             unset($this->supported_authentications[$mask]);
         }
     }
     $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
     $session_key = Random::string(32);
     $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
     if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($server_key_public_exponent, $server_key_public_modulus));
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($host_key_public_exponent, $host_key_public_modulus));
     } else {
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($host_key_public_exponent, $host_key_public_modulus));
         $double_encrypted_session_key = $this->_rsa_crypt($double_encrypted_session_key, array($server_key_public_exponent, $server_key_public_modulus));
     }
     $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES;
     $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
     if (!$this->_send_binary_packet($data)) {
         throw new \RuntimeException('Error sending SSH_CMSG_SESSION_KEY');
     }
     switch ($cipher) {
         //case self::CIPHER_NONE:
         //    $this->crypto = new \phpseclib\Crypt\Null();
         //    break;
         case self::CIPHER_DES:
             $this->crypto = new DES();
             $this->crypto->disablePadding();
             $this->crypto->enableContinuousBuffer();
             $this->crypto->setKey(substr($session_key, 0, 8));
             break;
         case self::CIPHER_3DES:
             $this->crypto = new TripleDES(TripleDES::MODE_3CBC);
             $this->crypto->disablePadding();
             $this->crypto->enableContinuousBuffer();
             $this->crypto->setKey(substr($session_key, 0, 24));
             break;
             //case self::CIPHER_RC4:
             //    $this->crypto = new RC4();
             //    $this->crypto->enableContinuousBuffer();
             //    $this->crypto->setKey(substr($session_key, 0,  16));
             //    break;
     }
     $response = $this->_get_binary_packet();
     if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
         throw new \UnexpectedValueException('Expected SSH_SMSG_SUCCESS');
     }
     $this->bitmap = self::MASK_CONNECTED;
     return true;
 }
コード例 #6
0
ファイル: SSH2.php プロジェクト: msulistijo/PhpseclibBundle
 /**
  * Returns the server public host key.
  *
  * Caching this the first time you connect to a server and checking the result on subsequent connections
  * is recommended.  Returns false if the server signature is not signed correctly with the public host key.
  *
  * @return mixed
  * @throws \RuntimeException on badly formatted keys
  * @throws \phpseclib\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format
  * @access public
  */
 function getServerPublicHostKey()
 {
     if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
         if (!$this->_connect()) {
             return false;
         }
     }
     $signature = $this->signature;
     $server_public_host_key = $this->server_public_host_key;
     extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4)));
     $this->_string_shift($server_public_host_key, $length);
     if ($this->signature_validated) {
         return $this->bitmap ? $this->signature_format . ' ' . base64_encode($this->server_public_host_key) : false;
     }
     $this->signature_validated = true;
     switch ($this->signature_format) {
         case 'ssh-dss':
             $zero = new BigInteger();
             $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
             $p = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
             $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
             $q = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
             $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
             $g = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
             $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
             $y = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
             /* The value for 'dss_signature_blob' is encoded as a string containing
                r, followed by s (which are 160-bit integers, without lengths or
                padding, unsigned, and in network byte order). */
             $temp = unpack('Nlength', $this->_string_shift($signature, 4));
             if ($temp['length'] != 40) {
                 $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
                 throw new \RuntimeException('Invalid signature');
             }
             $r = new BigInteger($this->_string_shift($signature, 20), 256);
             $s = new BigInteger($this->_string_shift($signature, 20), 256);
             switch (true) {
                 case $r->equals($zero):
                 case $r->compare($q) >= 0:
                 case $s->equals($zero):
                 case $s->compare($q) >= 0:
                     $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
                     throw new \RuntimeException('Invalid signature');
             }
             $w = $s->modInverse($q);
             $u1 = $w->multiply(new BigInteger(sha1($this->exchange_hash), 16));
             list(, $u1) = $u1->divide($q);
             $u2 = $w->multiply($r);
             list(, $u2) = $u2->divide($q);
             $g = $g->modPow($u1, $p);
             $y = $y->modPow($u2, $p);
             $v = $g->multiply($y);
             list(, $v) = $v->divide($p);
             list(, $v) = $v->divide($q);
             if (!$v->equals($r)) {
                 //user_error('Bad server signature');
                 return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
             }
             break;
         case 'ssh-rsa':
             $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
             $e = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
             $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
             $rawN = $this->_string_shift($server_public_host_key, $temp['length']);
             $n = new BigInteger($rawN, -256);
             $nLength = strlen(ltrim($rawN, ""));
             /*
             $temp = unpack('Nlength', $this->_string_shift($signature, 4));
             $signature = $this->_string_shift($signature, $temp['length']);
             
             $rsa = new RSA();
             $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
             $rsa->load(array('e' => $e, 'n' => $n), 'raw');
             if (!$rsa->verify($this->exchange_hash, $signature)) {
                 //user_error('Bad server signature');
                 return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
             }
             */
             $temp = unpack('Nlength', $this->_string_shift($signature, 4));
             $s = new BigInteger($this->_string_shift($signature, $temp['length']), 256);
             // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the
             // following URL:
             // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
             // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
             if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
                 $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
                 throw new \RuntimeException('Invalid signature');
             }
             $s = $s->modPow($e, $n);
             $s = $s->toBytes();
             $h = pack('N4H*', 0x302130, 0x906052b, 0xe03021a, 0x5000414, sha1($this->exchange_hash));
             $h = chr(0x1) . str_repeat(chr(0xff), $nLength - 2 - strlen($h)) . $h;
             if ($s != $h) {
                 //user_error('Bad server signature');
                 return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
             }
             break;
         default:
             $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
             throw new NoSupportedAlgorithmsException('Unsupported signature format');
     }
     return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
 }
コード例 #7
0
ファイル: XML.php プロジェクト: msulistijo/PhpseclibBundle
 /**
  * Convert a public key to the appropriate format
  *
  * @access public
  * @param \phpseclib\Math\BigInteger $n
  * @param \phpseclib\Math\BigInteger $e
  * @return string
  */
 static function savePublicKey(BigInteger $n, BigInteger $e)
 {
     return "<RSAKeyValue>\r\n" . '  <Modulus>' . base64_encode($n->toBytes()) . "</Modulus>\r\n" . '  <Exponent>' . base64_encode($e->toBytes()) . "</Exponent>\r\n" . '</RSAKeyValue>';
 }