1 What is libassh ?
libassh is a free software library written in C that implements the Secure Shell protocol version 2. The client and server sides are implemented with the same set of features.
Its design supports portability, reliability and small footprint. This makes libassh a good choice to implement embedded ssh clients and servers. It strives to let the application access every feature of the protocol so that it can be used to implement full featured ssh client and server applications as well.
It comes with a test suite, some example applications and the fine manual you are reading. An other manual is available with details of the internal API.
1.1 Event based ssh [link]
The API has been designed to support both, asynchronous and synchronous types of programming interfaces of the application and operating system.
The core library does not provides blocking functions nor does it rely on a callback based API. Instead, the library reports events which do not require immediate processing by the application. This design is agnostic with regard to the programming model . It allows easy integration in applications, including those based on event loops provided by existing libraries and toolkits.
Moreover, this design fully supports the asynchronous nature of the ssh2 protocol. This does not only mean that the library calls are non-blocking, it is also able to handle out of order operations allowed by the protocol. This includes handling and replying to multiple channel open messages out of order.
The lack of an ssh2 library written in C with this design has been the main reason of starting the project.
1.2 Modular ssh [link]
The ssh2 protocol is specified in a modular way so that implementers can freely add new crypto algorithms, new services and new user authentication methods without breaking compatibility with other implementations.
The libassh implementation of ssh2 is modular, as allowed by the specification. It supports working with ssh2 software components that are not provided with the library. This includes dynamically registering additional ssh2 algorithms as well as running custom ssh2 services. Moreover it allows using an external memory allocator and working with an external random number generator.
1.3 Clean design [link]
The modular design makes the code more readable by not including crypto algorithms specific code in the core protocol implementation. This approach enforces uses of well defined and documented APIs between the software components, which eases the code review process.
Although it's well known that basing protocol implementations on finite state machines helps excluding unforeseen protocol states and improves identification of all possible edge conditions, the ssh2 specification does not provide a state based description of the protocol [29]. As a consequence, many implementations of ssh2 do not rely on finite state machines. Protocol state fuzzing techniques are needed in order to extract state diagrams and perform a partial analysis of their corner case behavior [26] [27] [28].
The libassh implementation is based on multiple state machines. Using separate state machines for the various parts of the protocol helps avoiding unexpected interactions between the layers [27]. The state machines implemented in libassh are documented in the provided state diagrams.
No global variables are used and multiple library contexts and sessions can be created. This makes the library safe to use in multi-threaded applications.
1.4 Portable ssh [link]
libassh has been designed to run on a variety of platforms ranging from UNIX servers to embedded devices with bare metal implementations.
The library core only contains algorithmic stuff, mostly protocol state machines. It has no dependencies other than the standard C library and perform no operating system calls. The library returns specific events in order to let the application transfer the ssh2 network stream over any reliable data pipe, usually a TCP connection.
This makes this ssh2 implementation portable on any platform provided that a support for standard C is available. This architecture requires the library user to develop some glue code for the target platform. This code is provided in the form of helper functions for convenient use on POSIX platforms. Optional support for file formats used by OpenSSH is provided as well.
Because the library comes with a set of standard ssh2 algorithm implementations, it can be used standalone. Alternate modules relying on external libraries like Libgcrypt, OpenSSL, libsodium and Zlib are available in order to further extend the set of supported algorithms and methods.
The clear source organization and file naming helps identify the core components and modules when porting the library to a new platform.
1.5 Security [link]
The library implements several security related features.
It comes with implementations of many ssh2 algorithms, support for common user authentication methods and key formats. Passphrase encrypted SSH keys can be loaded and saved. The library is also able to generate new user keys and host keys.
Because using fast and secure ssh2 algorithms among those supported by the remote implementation is the most desirable thing for the user, the library is able to compute a simple score that can be used to advertise the overall level of security of a session. This is based on algorithms negotiated during the key-exchange process as well as involved host keys. It is also possible to select and sort algorithms based on their speed and safety before running a session. This helps the user keep control without requiring him to know strengths and weakness of the various crypto algorithms.
Multi-factor user authentication and password change requests are both supported. In order to enable use of hardware authentication tokens, the user authentication code is able to work with both, internally and externally generated signatures.
Providing those feature is not sufficient to make the implementation reliably secure, that's why special care has been taken to avoid leaking secret material. In order to mitigate side channel attacks , all builtin implementations of public key cryptography rely on a big number engine with strict constant time operations. Moreover, the library can be configured to store sensitive data and temporary buffers in secure memory.
1.6 Performances [link]
The library uses a zero copy approach to pass data between the network stream, the channels and the application. This is achieved by giving the application a direct access to buffers stored in the library packet objects. Moreover, the application is allowed to take full control of the channel flow control mechanism specified in rfc4254.
An optional packet pool allocator is provided in order to recycle packets and reduce pressure on the memory allocator.
A large set of compile time configuration macros is available which allows optimization of the library footprint on embedded targets. The modular design allows retaining only a small set of ssh2 algorithms and makes it easy to add support for hardware cryptographic accelerators.
The library only needs to allocate a few kilobytes in order to run a client or server session.
1.7 Testing [link]
A set of test programs helps ensure that the ssh2 implementation follows the standard and behaves well on corner cases.
The libassh design supports testability. The modular approach enables writing unit tests for the variaous components as well as plugging custom test components. Thanks to the portable design, a client instance and a server instance living in the same test program are able to communicate in a deterministic and efficient manner because no operating system calls are involved. Several stress tests are available for the different protocol layers. They are able to perform many key-exchange, user authentication and channel operations per second.
Fuzzing is used to reach more corner cases. Randomly corrupted packets and random memory allocation failures are injected while the library is tested for compliance and memory leaks. In addition to the fuzzing features integrated in the various stress test programs, a libfuzzer based test application is included.
In order to maintain the compatibility of libaash with other implementations of ssh2, a session replaying tool is also provided. It allows including regression tests against other implementations as part of the test suite. Because it records and replays sessions at the packet level, other implementations do not need to be available when running the tests.