pub(crate) fn from_reader(reader: &mut Reader<'_>, passphrase: Option<String>) -> Result<PrivateKey> {
        let preamble = reader.read_cstring()?;

        if preamble != "openssh-key-v1" {
            return Err(Error::InvalidFormat);
        }

        // These values are for encrypted keys which are not supported
        let cipher_name = reader.read_string()?;
        let kdf = reader.read_string()?;

        #[allow(unused_variables)]
        let encryption_data = reader.read_bytes()?;

        // This seems to be hardcoded into the standard
        let number_of_keys = reader.read_u32()?;
        if number_of_keys != 1 {
            return Err(Error::InvalidFormat);
        }

        // A full pubkey with the same format as seen in certificates
        let pubkey = reader
        .read_bytes()
        .and_then(|v| PublicKey::from_bytes(&v))?;

        let remaining_length = match reader.read_u32()?.try_into() {
            Ok(rl) => rl,
            Err(_) => return Err(Error::InvalidFormat),
        };

        #[allow(unused_mut)]
        let mut remaining_bytes = reader.read_raw_bytes(remaining_length)?;

        match (cipher_name.as_str(), kdf.as_str(), passphrase) {
            ("none", "none", _) => (),
            #[cfg(feature = "encrypted-keys")]
            ("aes256-ctr", "bcrypt", Some(passphrase)) => {
                let mut enc_reader = Reader::new(&encryption_data);
                let salt = enc_reader.read_bytes()?;
                let rounds = enc_reader.read_u32()?;
                let mut output = [0; 48];
                if let Err(_) = bcrypt_pbkdf(passphrase.as_str(), &salt, rounds, &mut output) {
                    return Err(Error::InvalidFormat);
                }

                let mut cipher = Aes256Ctr::new(
                    &GenericArray::from_slice(&output[..32]),
                    &GenericArray::from_slice(&output[32..]),
                );

                match cipher.try_apply_keystream(&mut remaining_bytes) {
                    Ok(_) => (),
                    Err(_) => return Err(Error::InvalidFormat),
                }
            },
            ("aes256-ctr", "bcrypt", None) => return Err(Error::EncryptedPrivateKey),
            _ => return Err(Error::EncryptedPrivateKeyNotSupported),
        };

        let mut reader = Reader::new(&remaining_bytes);

        // These four bytes are repeated and are used to checks that a key has
        // been decrypted successfully
        if reader.read_u32()? != reader.read_u32()? {
            return Err(Error::InvalidFormat);
        }
        
        let private_key = read_private_key(&mut reader)?;

        if private_key.pubkey != pubkey {
            return Err(Error::InvalidFormat);
        }

        Ok(private_key)
    }
/// This function is used for extracting a private key from an existing reader.
This function is used for extracting a private key from an existing reader.
This function is used for extracting a private key from an existing reader .
pub(crate) fn from_reader(reader: &mut Reader<'_>, passphrase: Option<String>) -> Result<PrivateKey> {
        let preamble = reader.read_cstring()?;
        if preamble != "openssh-key-v1" {
            return Err(Error::InvalidFormat);
        }
        // These values are for encrypted keys which are not supported
        let cipher_name = reader.read_string()?;
        let kdf = reader.read_string()?;
        #[allow(unused_variables)]
        let encryption_data = reader.read_bytes()?;
        // This seems to be hardcoded into the standard
        let number_of_keys = reader.read_u32()?;
        if number_of_keys != 1 {
            return Err(Error::InvalidFormat);
        }
        // A full pubkey with the same format as seen in certificates
        let pubkey = reader
        .read_bytes()
        .and_then(|v| PublicKey::from_bytes(&v))?;
        let remaining_length = match reader.read_u32()?.try_into() {
            Ok(rl) => rl,
            Err(_) => return Err(Error::InvalidFormat),
        };
        #[allow(unused_mut)]
        let mut remaining_bytes = reader.read_raw_bytes(remaining_length)?;
        match (cipher_name.as_str(), kdf.as_str(), passphrase) {
            ("none", "none", _) => (),
            #[cfg(feature = "encrypted-keys")]
            ("aes256-ctr", "bcrypt", Some(passphrase)) => {
                let mut enc_reader = Reader::new(&encryption_data);
                let salt = enc_reader.read_bytes()?;
                let rounds = enc_reader.read_u32()?;
                let mut output = [0; 48];
                if let Err(_) = bcrypt_pbkdf(passphrase.as_str(), &salt, rounds, &mut output) {
                    return Err(Error::InvalidFormat);
                }
                let mut cipher = Aes256Ctr::new(
                    &GenericArray::from_slice(&output[..32]),
                    &GenericArray::from_slice(&output[32..]),
                );
                match cipher.try_apply_keystream(&mut remaining_bytes) {
                    Ok(_) => (),
                    Err(_) => return Err(Error::InvalidFormat),
                }
            },
            ("aes256-ctr", "bcrypt", None) => return Err(Error::EncryptedPrivateKey),
            _ => return Err(Error::EncryptedPrivateKeyNotSupported),
        };
        let mut reader = Reader::new(&remaining_bytes);
        // These four bytes are repeated and are used to checks that a key has
        // been decrypted successfully
        if reader.read_u32()? != reader.read_u32()? {
            return Err(Error::InvalidFormat);
        }
        let private_key = read_private_key(&mut reader)?;
        if private_key.pubkey != pubkey {
            return Err(Error::InvalidFormat);
        }
        Ok(private_key)
    }
pub ( crate ) fn from_reader ( reader : & mut Reader < ' _ > , passphrase : Option < String > ) -> Result < PrivateKey > { let preamble = reader . read_cstring ( ) ? ; if preamble != " " { return Err ( Error :: InvalidFormat ) ; } // These values are for encrypted keys which are not supported let cipher_name = reader . read_string ( ) ? ; let kdf = reader . read_string ( ) ? ; # [ allow ( unused_variables ) ] let encryption_data = reader . read_bytes ( ) ? ; // This seems to be hardcoded into the standard let number_of_keys = reader . read_u32 ( ) ? ; if number_of_keys != 1 { return Err ( Error :: InvalidFormat ) ; } // A full pubkey with the same format as seen in certificates let pubkey = reader . read_bytes ( ) . and_then ( | v | PublicKey :: from_bytes ( & v ) ) ? ; let remaining_length = match reader . read_u32 ( ) ? . try_into ( ) { Ok ( rl ) => rl , Err ( _ ) => return Err ( Error :: InvalidFormat ) , } ; # [ allow ( unused_mut ) ] let mut remaining_bytes = reader . read_raw_bytes ( remaining_length ) ? ; match ( cipher_name . as_str ( ) , kdf . as_str ( ) , passphrase ) { ( " " , " " , _ ) => ( ) , # [ cfg ( feature " " ) ] ( " " , " " , Some ( passphrase ) ) => { let mut enc_reader = Reader :: new ( & encryption_data ) ; let salt = enc_reader . read_bytes ( ) ? ; let rounds = enc_reader . read_u32 ( ) ? ; let mut output = [ 0 ; 48 ] ; if let Err ( _ ) = bcrypt_pbkdf ( passphrase . as_str ( ) , & salt , rounds , & mut output ) { return Err ( Error :: InvalidFormat ) ; } let mut cipher = Aes256Ctr :: new ( & GenericArray :: from_slice ( & output [ .. 32 ] ) , & GenericArray :: from_slice ( & output [ 32 .. ] ) , ) ; match cipher . try_apply_keystream ( & mut remaining_bytes ) { Ok ( _ ) => ( ) , Err ( _ ) => return Err ( Error :: InvalidFormat ) , } } , ( " " , " " , None ) => return Err ( Error :: EncryptedPrivateKey ) , _ => return Err ( Error :: EncryptedPrivateKeyNotSupported ) , } ; let mut reader = Reader :: new ( & remaining_bytes ) ; // These four bytes are repeated and are used to checks that a key has // been decrypted successfully if reader . read_u32 ( ) ? != reader . read_u32 ( ) ? { return Err ( Error :: InvalidFormat ) ; } let private_key = read_private_key ( & mut reader ) ? ; if private_key . pubkey != pubkey { return Err ( Error :: InvalidFormat ) ; } Ok ( private_key ) }
This function is used for extracting a private key from an existing reader.
This function is used for extracting a private key from an existing reader .
reader
&mut Reader<'_>
passphrase
Option<String>