xref: /netbsd-src/external/ibm-public/postfix/dist/src/tls/tls_session.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: tls_session.c,v 1.1.1.1 2009/06/23 10:08:57 tron Exp $	*/
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 
82 void    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 
113 VSTRING *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 
150 SSL_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