1/*	$NetBSD$	*/
2
3/*++
4/* NAME
5/*	tls_session
6/* SUMMARY
7/*	TLS client and server session routines
8/* SYNOPSIS
9/*	#include <tls.h>
10/*
11/*	void	tls_session_stop(ctx, stream, timeout, failure, TLScontext)
12/*	TLS_APPL_STATE *ctx;
13/*	VSTREAM	*stream;
14/*	int	timeout;
15/*	int	failure;
16/*	TLS_SESS_STATE *TLScontext;
17/*
18/*	VSTRING	*tls_session_passivate(session)
19/*	SSL_SESSION *session;
20/*
21/*	SSL_SESSION *tls_session_activate(session_data, session_data_len)
22/*	char	*session_data;
23/*	int	session_data_len;
24/* DESCRIPTION
25/*	tls_session_stop() implements the tls_server_shutdown()
26/*	and the tls_client_shutdown() routines.
27/*
28/*	tls_session_passivate() converts an SSL_SESSION object to
29/*	VSTRING. The result is a null pointer in case of problems,
30/*	otherwise it should be disposed of with vstring_free().
31/*
32/*	tls_session_activate() reanimates a passivated SSL_SESSION object.
33/*	The result is a null pointer in case of problems,
34/*	otherwise it should be disposed of with SSL_SESSION_free().
35/* LICENSE
36/* .ad
37/* .fi
38/*	This software is free. You can do with it whatever you want.
39/*	The original author kindly requests that you acknowledge
40/*	the use of his software.
41/* AUTHOR(S)
42/*	Originally written by:
43/*	Lutz Jaenicke
44/*	BTU Cottbus
45/*	Allgemeine Elektrotechnik
46/*	Universitaetsplatz 3-4
47/*	D-03044 Cottbus, Germany
48/*
49/*	Updated by:
50/*	Wietse Venema
51/*	IBM T.J. Watson Research
52/*	P.O. Box 704
53/*	Yorktown Heights, NY 10598, USA
54/*
55/*	Victor Duchovni
56/*	Morgan Stanley
57/*--*/
58
59/* System library. */
60
61#include <sys_defs.h>
62
63#ifdef USE_TLS
64
65/* Utility library. */
66
67#include <vstream.h>
68#include <msg.h>
69#include <mymalloc.h>
70
71/* TLS library. */
72
73#define TLS_INTERNAL
74#include <tls.h>
75
76/* Application-specific. */
77
78#define STR	vstring_str
79
80/* tls_session_stop - shut down the TLS connection and reset state */
81
82void    tls_session_stop(TLS_APPL_STATE *unused_ctx, VSTREAM *stream, int timeout,
83			         int failure, TLS_SESS_STATE *TLScontext)
84{
85    const char *myname = "tls_session_stop";
86    int     retval;
87
88    /*
89     * Sanity check.
90     */
91    if (TLScontext == 0)
92	msg_panic("%s: stream has no active TLS context", myname);
93
94    /*
95     * Perform SSL_shutdown() twice, as the first attempt will send out the
96     * shutdown alert but it will not wait for the peer's shutdown alert.
97     * Therefore, when we are the first party to send the alert, we must call
98     * SSL_shutdown() again. On failure we don't want to resume the session,
99     * so we will not perform SSL_shutdown() and the session will be removed
100     * as being bad.
101     */
102    if (!failure) {
103	retval = tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext);
104	if (retval == 0)
105	    tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext);
106    }
107    tls_free_context(TLScontext);
108    tls_stream_stop(stream);
109}
110
111/* tls_session_passivate - passivate SSL_SESSION object */
112
113VSTRING *tls_session_passivate(SSL_SESSION *session)
114{
115    const char *myname = "tls_session_passivate";
116    int     estimate;
117    int     actual_size;
118    VSTRING *session_data;
119    unsigned char *ptr;
120
121    /*
122     * First, find out how much memory is needed for the passivated
123     * SSL_SESSION object.
124     */
125    estimate = i2d_SSL_SESSION(session, (unsigned char **) 0);
126    if (estimate <= 0) {
127	msg_warn("%s: i2d_SSL_SESSION failed: unable to cache session", myname);
128	return (0);
129    }
130
131    /*
132     * Passivate the SSL_SESSION object. The use of a VSTRING is slightly
133     * wasteful but is convenient to combine data and length.
134     */
135    session_data = vstring_alloc(estimate);
136    ptr = (unsigned char *) STR(session_data);
137    actual_size = i2d_SSL_SESSION(session, &ptr);
138    if (actual_size != estimate) {
139	msg_warn("%s: i2d_SSL_SESSION failed: unable to cache session", myname);
140	vstring_free(session_data);
141	return (0);
142    }
143    VSTRING_AT_OFFSET(session_data, actual_size);	/* XXX not public */
144
145    return (session_data);
146}
147
148/* tls_session_activate - activate passivated session */
149
150SSL_SESSION *tls_session_activate(const char *session_data, int session_data_len)
151{
152#if (OPENSSL_VERSION_NUMBER < 0x0090707fL)
153#define BOGUS_CONST
154#else
155#define BOGUS_CONST const
156#endif
157    SSL_SESSION *session;
158    BOGUS_CONST unsigned char *ptr;
159
160    /*
161     * Activate the SSL_SESSION object.
162     */
163    ptr = (BOGUS_CONST unsigned char *) session_data;
164    session = d2i_SSL_SESSION((SSL_SESSION **) 0, &ptr, session_data_len);
165    if (!session)
166	tls_print_errors();
167
168    return (session);
169}
170
171#endif
172