Reference

peks-session(3)

public key encryption tunnel negotiation

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.