/*
   PKCIPE - public key based configuration tool for CIPE

   Copyright 2000 Olaf Titz <olaf@bigred.inka.de>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version
   2 of the License, or (at your option) any later version.
*/
/* $Id: pkcipe.h,v 1.10 2000/12/05 19:21:11 olaf Exp $ */

#ifndef _PKCIPE_H_
#define _PKCIPE_H_

#include <signal.h>
#include <stdio.h>
#include <netinet/in.h>
#include <openssl/evp.h>
#include "config.h"
#include "cipelib.h"

/* packet.c */

extern int timeout;
#define PKTMAXLEN 1024  /* must be greater than DH_PRIME_BYTES
                           and the length of the used RSA keys */
extern void signInit(void);
extern void vrfyInit(void);
extern void setSendKey(const unsigned char *key);
extern void setRecvKey(const unsigned char *key);
extern int packetSend(int fd, unsigned char *d, int len);
extern int packetSendBN(int fd, int typ, const BIGNUM *a);
extern int packetRecv(int fd, unsigned char *d, int len);
extern BIGNUM *packetExtrBN(const unsigned char *d, int len);
extern int signFinal(unsigned char *dst, int *len, const EVP_PKEY *key);
extern int vrfyFinal(const unsigned char *dst, int len, const EVP_PKEY *key);

/* debugging */

#ifdef DEBUG
#define DEB_PROTO	  1
#define DEB_KEY		  2
#define DEB_BNUM	  4
#define DEB_PKT		  8
#define DEB_PKTERR	 16
#define DEB_LOCK	 32
#define DEB_SIGN	 64
#define DEB_PDUMP	128
#define DEB_PSHA1       256
#endif

/* proto.c */

#define PKTF_SIGNED	0x40	/* Sign sent packet */
#define PKTF_REVSIGN	0x80	/* Sign received packet */

#define PKT_DEBUG	(0x00)
#define PKT_ERROR       (0x01)
#define PKT_DONE        (0x02)
#define PKT_NONCE	(0x11|PKTF_REVSIGN)
#define PKT_DHKEY	(0x12|PKTF_SIGNED)
#define PKT_IDENT	(0x13|PKTF_SIGNED)
#define PKT_SIGN	(0x14)
#define PKT_READY	(0x15)
#define PKT_OPT_REQ	(0x16)
#define PKT_OPT_ACK	(0x17)
#define PKT_OPT_NAK	(0x18)
#define PKT_OPT_REJ	(0x19)

typedef enum {
    Snonce=PKT_NONCE,
    Sdhkey=PKT_DHKEY,
    Sident=PKT_IDENT,
    Ssign=PKT_SIGN,
    Sopt=PKT_OPT_REQ,
    Sready=PKT_READY,
    Serr=PKT_ERROR,
    Sdone=PKT_DONE
} pState;

/* max length of identity name */
#define MAXIDLEN	120

#define MAX_SUPPORTED_PROTOCOL 2

extern int protoVersion;
extern char *myIdentity;
extern char *peerIdentity;
extern EVP_PKEY *myKey;
extern int initDH(void);
extern int doProtocol(int fd, struct in_addr addr);

/* negotiate.c */

#define OF_DEFAULT	' '
#define OF_REQUIRE	'+'
#define OF_REQVAL	'='
#define OF_REJECT	'-'
#define OF_MIN		'>'
#define OF_MAX		'<'
#define OF_IGNORE	'~'

extern int cipeSocket;
extern void setOption(const char *n, const char *v, char oflag);
extern void readOptions(FILE *f);
extern pState negotiate(int fd, unsigned char *pkt, int len);
extern pState ready(int fd);

/* lock.c */

extern int lockMaster(void);
extern int unlockMaster(void);
extern int lockPeer(void);

/* p_sha1.c */

typedef struct {
    int  seed_len;
    int  secret_len;
    char A[20];
    /* Pseudo-elements:
       char seed[seed_len];
       char secret[secret_len];
       The algorithm requires that seed immediately follows A */
} P_SHA1_CTX;

#define psha1_seed(ctx)   ((ctx)->A+20)
#define psha1_secret(ctx) ((ctx)->A+20+(ctx)->seed_len)

extern P_SHA1_CTX *P_SHA1_init(const char *secret, int secret_len,
                               const char *seed, int seed_len);
extern void P_SHA1_block(P_SHA1_CTX *ctx, char *dst);
extern void P_SHA1_free(P_SHA1_CTX *ctx);

/* main.c */

extern void SSLprinterror(int level);

#endif
