NAME
server_negotiate_session_key,
client_negotiate_session_key - public key encryption tunnel negotiation
SYNOPSIS
#include <peks.h>
int server_negotiate_session_key
(peks_key *private_key, int socket,
const char *client_name, peks_key *dh_group);
int client_negotiate_session_key
(const char *cipher_type, int socket,
const char *server_name, const char *key_file);
extern int peks_recv_timeout;
DESCRIPTION
Server_negotiate_session_key () starts an encrypted client session on the server. After a successful initalization all io data passed through the iostream transparent socket layer (see iostream(3) for details) will be encrypted.
The first argument private_key must be non-NULL. It is used to authenticate the server while setting up the session.
The second argument socket is an open TCP socket. The other arguments are used to find a private key to derive the public key from, needed to negotiate the session keys.
If the last argument dh_group is non-NULL, its prime module and generator is used for the Diffie Hellman key negotiation. Otherwise the module and generator are taken from the private_key.
By setting the global variable peks_recv_timeout to some positive value n, a timeout is imposed on waiting for an answer while the handshake is active. This is done by temporarily changing the receive timeout value using io_recv_tmo().
Note:
A client that connects to the server for the first time will store the public key from the server and tell the server to terminate key negotiation. So -1 is returned on the server and the global variable errno will be set the as the error code for the symbol SRV_CLIENT_KNOCKING (see also peks-errnum(3)).
Example:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <peks.h>
#include <messages.h>
/* ERROR () and EXIT () are macros with
the obvious functionality */
for (;;) {
int n = server_negotiate_session_key
(key, /* default key */
socket, /* open socket */
inet_ntoa (address->sin_addr), /* client addr */
"/etc/peks/private.keys") ; /* key file */
if (n >= 0) /* success */
break;
if (errno != errnum (SRV_CLIENT_KNOCKING)) {
ERROR ("Cannot negotiate keys: %s - aborting",
peks_strerr (errno)) ;
EXIT (1);
}
} /* end for (;;) */
Clinet_negotiate_session_key () starts an encrypted session on the client. The function starts waiting for a peks server to negotiate session keys. For communication, the open socket passed as second argument socket is used.
The argument cipher_type is a string "<block-cipher>/<hash-type>" composed of two text fields separated by a slash. For the values that can be used here consult the file cipher.h from the sorce code. Currently, the following block ciphers are available
blowfish - 16 byte key length, 8 byte block length
blowfish160 - 16 byte key length, 16 byte block length
twofish - 16 byte key length, 16 byte block length
3des - 16 byte key length (hashed to 24 bytes),
8 byte block length
and the hash types
ripem160 - 20 byte result sha1 - 20 byte result md5 - 20 byte result
Thanks to the gnupg people where I got the sources, from.
The other two the arguments server_name and key_file are used to check the public key from the server against the list of servers, already known.
If both, the argument key_file is non-NULL and the argument server_name is non-NULL, the server key just received is checked as follows:
If there is no file with name key_file, it is just created.
An existing key file file must be privately owned and must neither be world nor group read/writable.
If the file with name key_file exists, it is searched for a line tag matching the argument server_name. Host names in the key file can be used as well as ip addesses. If the argument server_name matches line tag, the corresponding key fields are checked against the public key just received from the server.
If the public key received does not match the ones found in the file key_file, an error value -1 is returned and no session is opened.
If there is no public key from this server in the file key_file, a line with the public server keys is appended to the file and an error value -1 is returned. No session will be opened. The global error varaiable errno will be set to the error symbol STORED_SERVER_KEY (see peks_stderr(3) for details).
Otherwise, an encrypted session with the server will have been opened and pushed (see io_push(3) for details) upon the transparent socket layer.
Example:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <peks.h>
#include <messages.h>
/* ERROR () and EXIT () are macros with
the obvious functionality */
for (;;) {
int n = client_negotiate_session_key
("blowfish160/sha1", /* encr type */
socket, /* open socket */
inet_ntoa (address->sin_addr), /* server addr */
"~/.server.keys") ; /* key file */
if (n >= 0) /* success */
break;
if (errno != errnum (STORED_SERVER_KEY)) {
ERROR ("Cannot negotiate keys: %s - aborting",
peks_strerr (errno)) ;
EXIT (1);
}
} /* end for (;;) */
RETURN VALUE
Server_negotiate_session_key () returns 0, on success while an encrypted session with the client will have been opened and pushed (see io_push(3) for details) upon the transparent socket layer. On error, -1 is returned while the global variable errno will be set.
Clinet_negotiate_session_key () returns 0, on success while an encrypted session with the server will have been opened and pushed (see io_push(3) for details) upon the transparent socket layer. On error, -1 is returned while the global variable errno will be set.
ERROR CODES
Some error codes besides the errno(3) interface are used, here. They are referred to as error symbols (see peks-errnum(3) for details):
SRV_MAGIC_FAILED Server could not read magic string SRV_WRONG_MAGIC Client sent incompatible magic string SRV_CLIENT_KNOCKING Client was knocking at the door, only SRV_CLIENT_RESPERR Initial client response was garbage CANT_EXPAND_FNAME Cannot expand file name ($HOME missing?) SERVER_SPOOF_ALERT Spoof alert: Server key has changed STORED_SERVER_KEY Host key for that server has been saved
ENVIRONMENT VARIABLES
- HOME
-
Used for the key file name expansion when there is a leading tilde-slash as in "~/<key_file>".
SEE ALSO
socket(3), iostream(3), io_push(3), io_ctrl(3), io_recv_tmo(3), gethostbyname(3), peks-keyfile(5), errno(3), peks-errnum(3),
AUTHOR
The peks package where these functions belong to was written by Jordan Hrycaj <[email protected]>, originally to support the nessus security scanner.