1 /*	$NetBSD: tls_proxy_context_scan.c,v 1.3 2022/10/08 16:12:50 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	tls_proxy_context_scan
6 /* SUMMARY
7 /*	read TLS session state from stream
8 /* SYNOPSIS
9 /*	#include <tls_proxy.h>
10 /*
11 /*	int     tls_proxy_context_scan(scan_fn, stream, flags, ptr)
12 /*	ATTR_SCAN_COMMON_FN scan_fn;
13 /*	VSTREAM *stream;
14 /*	int     flags;
15 /*	void    *ptr;
16 /*
17 /*	void	tls_proxy_context_free(tls_context)
18 /*	TLS_SESS_STATE *tls_context;
19 /* DESCRIPTION
20 /*	tls_proxy_context_scan() reads the public members of a
21 /*	TLS_ATTR_STATE structure from the named stream using the
22 /*	specified attribute scan routine.  tls_proxy_context_scan()
23 /*	is meant to be passed as a call-back to attr_scan() as shown
24 /*	below.
25 /*
26 /*	tls_proxy_context_free() destroys a TLS context object that
27 /*	was received with tls_proxy_context_scan().
28 /*
29 /*	TLS_ATTR_STATE *tls_context = 0;
30 /*	...
31 /*	... RECV_ATTR_FUNC(tls_proxy_context_scan, (void *) &tls_context), ...
32 /*	...
33 /*	if (tls_context)
34 /*	    tls_proxy_context_free(tls_context);
35 /* DIAGNOSTICS
36 /*	Fatal: out of memory.
37 /* LICENSE
38 /* .ad
39 /* .fi
40 /*	The Secure Mailer license must be distributed with this software.
41 /* AUTHOR(S)
42 /*	Wietse Venema
43 /*	IBM T.J. Watson Research
44 /*	P.O. Box 704
45 /*	Yorktown Heights, NY 10598, USA
46 /*
47 /*	Wietse Venema
48 /*	Google, Inc.
49 /*	111 8th Avenue
50 /*	New York, NY 10011, USA
51 /*--*/
52 
53 #ifdef USE_TLS
54 
55 /* System library. */
56 
57 #include <sys_defs.h>
58 
59 /* Utility library */
60 
61 #include <attr.h>
62 #include <msg.h>
63 
64 /* TLS library. */
65 
66 #include <tls.h>
67 #include <tls_proxy.h>
68 
69 /* tls_proxy_context_scan - receive TLS session state from stream */
70 
tls_proxy_context_scan(ATTR_SCAN_COMMON_FN scan_fn,VSTREAM * fp,int flags,void * ptr)71 int     tls_proxy_context_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp,
72 			               int flags, void *ptr)
73 {
74     TLS_SESS_STATE *tls_context
75     = (TLS_SESS_STATE *) mymalloc(sizeof(*tls_context));;
76     int     ret;
77     VSTRING *peer_CN = vstring_alloc(25);
78     VSTRING *issuer_CN = vstring_alloc(25);
79     VSTRING *peer_cert_fprint = vstring_alloc(60);	/* 60 for SHA-1 */
80     VSTRING *peer_pkey_fprint = vstring_alloc(60);	/* 60 for SHA-1 */
81     VSTRING *protocol = vstring_alloc(25);
82     VSTRING *cipher_name = vstring_alloc(25);
83     VSTRING *kex_name = vstring_alloc(25);
84     VSTRING *kex_curve = vstring_alloc(25);
85     VSTRING *clnt_sig_name = vstring_alloc(25);
86     VSTRING *clnt_sig_curve = vstring_alloc(25);
87     VSTRING *clnt_sig_dgst = vstring_alloc(25);
88     VSTRING *srvr_sig_name = vstring_alloc(25);
89     VSTRING *srvr_sig_curve = vstring_alloc(25);
90     VSTRING *srvr_sig_dgst = vstring_alloc(25);
91     VSTRING *namaddr = vstring_alloc(100);
92 
93     if (msg_verbose)
94 	msg_info("begin tls_proxy_context_scan");
95 
96     /*
97      * Note: memset() is not a portable way to initialize non-integer types.
98      */
99     memset(tls_context, 0, sizeof(*tls_context));
100     ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
101 		  RECV_ATTR_STR(TLS_ATTR_PEER_CN, peer_CN),
102 		  RECV_ATTR_STR(TLS_ATTR_ISSUER_CN, issuer_CN),
103 		  RECV_ATTR_STR(TLS_ATTR_PEER_CERT_FPT, peer_cert_fprint),
104 		  RECV_ATTR_STR(TLS_ATTR_PEER_PKEY_FPT, peer_pkey_fprint),
105 		  RECV_ATTR_INT(TLS_ATTR_SEC_LEVEL,
106 				&tls_context->level),
107 		  RECV_ATTR_INT(TLS_ATTR_PEER_STATUS,
108 				&tls_context->peer_status),
109 		  RECV_ATTR_STR(TLS_ATTR_CIPHER_PROTOCOL, protocol),
110 		  RECV_ATTR_STR(TLS_ATTR_CIPHER_NAME, cipher_name),
111 		  RECV_ATTR_INT(TLS_ATTR_CIPHER_USEBITS,
112 				&tls_context->cipher_usebits),
113 		  RECV_ATTR_INT(TLS_ATTR_CIPHER_ALGBITS,
114 				&tls_context->cipher_algbits),
115 		  RECV_ATTR_STR(TLS_ATTR_KEX_NAME, kex_name),
116 		  RECV_ATTR_STR(TLS_ATTR_KEX_CURVE, kex_curve),
117 		  RECV_ATTR_INT(TLS_ATTR_KEX_BITS, &tls_context->kex_bits),
118 		  RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_NAME, clnt_sig_name),
119 		  RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_CURVE, clnt_sig_curve),
120 	 RECV_ATTR_INT(TLS_ATTR_CLNT_SIG_BITS, &tls_context->clnt_sig_bits),
121 		  RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_DGST, clnt_sig_dgst),
122 		  RECV_ATTR_STR(TLS_ATTR_SRVR_SIG_NAME, srvr_sig_name),
123 		  RECV_ATTR_STR(TLS_ATTR_SRVR_SIG_CURVE, srvr_sig_curve),
124 	 RECV_ATTR_INT(TLS_ATTR_SRVR_SIG_BITS, &tls_context->srvr_sig_bits),
125 		  RECV_ATTR_STR(TLS_ATTR_SRVR_SIG_DGST, srvr_sig_dgst),
126 		  RECV_ATTR_STR(TLS_ATTR_NAMADDR, namaddr),
127 		  ATTR_TYPE_END);
128     /* Always construct a well-formed structure. */
129     tls_context->peer_CN = vstring_export(peer_CN);
130     tls_context->issuer_CN = vstring_export(issuer_CN);
131     tls_context->peer_cert_fprint = vstring_export(peer_cert_fprint);
132     tls_context->peer_pkey_fprint = vstring_export(peer_pkey_fprint);
133     tls_context->protocol = vstring_export(protocol);
134     tls_context->cipher_name = vstring_export(cipher_name);
135     tls_context->kex_name = vstring_export(kex_name);
136     tls_context->kex_curve = vstring_export(kex_curve);
137     tls_context->clnt_sig_name = vstring_export(clnt_sig_name);
138     tls_context->clnt_sig_curve = vstring_export(clnt_sig_curve);
139     tls_context->clnt_sig_dgst = vstring_export(clnt_sig_dgst);
140     tls_context->srvr_sig_name = vstring_export(srvr_sig_name);
141     tls_context->srvr_sig_curve = vstring_export(srvr_sig_curve);
142     tls_context->srvr_sig_dgst = vstring_export(srvr_sig_dgst);
143     tls_context->namaddr = vstring_export(namaddr);
144     ret = (ret == 22 ? 1 : -1);
145     if (ret != 1) {
146 	tls_proxy_context_free(tls_context);
147 	tls_context = 0;
148     }
149     *(TLS_SESS_STATE **) ptr = tls_context;
150     if (msg_verbose)
151 	msg_info("tls_proxy_context_scan ret=%d", ret);
152     return (ret);
153 }
154 
155 /* tls_proxy_context_free - destroy object from tls_proxy_context_receive() */
156 
tls_proxy_context_free(TLS_SESS_STATE * tls_context)157 void    tls_proxy_context_free(TLS_SESS_STATE *tls_context)
158 {
159     if (tls_context->peer_CN)
160 	myfree(tls_context->peer_CN);
161     if (tls_context->issuer_CN)
162 	myfree(tls_context->issuer_CN);
163     if (tls_context->peer_cert_fprint)
164 	myfree(tls_context->peer_cert_fprint);
165     if (tls_context->peer_pkey_fprint)
166 	myfree(tls_context->peer_pkey_fprint);
167     if (tls_context->protocol)
168 	myfree((void *) tls_context->protocol);
169     if (tls_context->cipher_name)
170 	myfree((void *) tls_context->cipher_name);
171     if (tls_context->kex_name)
172 	myfree((void *) tls_context->kex_name);
173     if (tls_context->kex_curve)
174 	myfree((void *) tls_context->kex_curve);
175     if (tls_context->clnt_sig_name)
176 	myfree((void *) tls_context->clnt_sig_name);
177     if (tls_context->clnt_sig_curve)
178 	myfree((void *) tls_context->clnt_sig_curve);
179     if (tls_context->clnt_sig_dgst)
180 	myfree((void *) tls_context->clnt_sig_dgst);
181     if (tls_context->srvr_sig_name)
182 	myfree((void *) tls_context->srvr_sig_name);
183     if (tls_context->srvr_sig_curve)
184 	myfree((void *) tls_context->srvr_sig_curve);
185     if (tls_context->srvr_sig_dgst)
186 	myfree((void *) tls_context->srvr_sig_dgst);
187     if (tls_context->namaddr)
188 	myfree((void *) tls_context->namaddr);
189     myfree((void *) tls_context);
190 }
191 
192 #endif
193