1 /*        $NetBSD: tls_proxy_context_scan.c,v 1.4 2025/02/25 19:15: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_INT(TLS_ATTR_CTOS_RPK, &tls_context->ctos_rpk),
119                       RECV_ATTR_INT(TLS_ATTR_STOC_RPK, &tls_context->stoc_rpk),
120                       RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_NAME, clnt_sig_name),
121                       RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_CURVE, clnt_sig_curve),
122            RECV_ATTR_INT(TLS_ATTR_CLNT_SIG_BITS, &tls_context->clnt_sig_bits),
123                       RECV_ATTR_STR(TLS_ATTR_CLNT_SIG_DGST, clnt_sig_dgst),
124                       RECV_ATTR_STR(TLS_ATTR_SRVR_SIG_NAME, srvr_sig_name),
125                       RECV_ATTR_STR(TLS_ATTR_SRVR_SIG_CURVE, srvr_sig_curve),
126            RECV_ATTR_INT(TLS_ATTR_SRVR_SIG_BITS, &tls_context->srvr_sig_bits),
127                       RECV_ATTR_STR(TLS_ATTR_SRVR_SIG_DGST, srvr_sig_dgst),
128                       RECV_ATTR_STR(TLS_ATTR_NAMADDR, namaddr),
129                       RECV_ATTR_INT(TLS_ATTR_RPT_REPORTED,
130                                         &tls_context->rpt_reported),
131                       ATTR_TYPE_END);
132     /* Always construct a well-formed structure. */
133     tls_context->peer_CN = vstring_export(peer_CN);
134     tls_context->issuer_CN = vstring_export(issuer_CN);
135     tls_context->peer_cert_fprint = vstring_export(peer_cert_fprint);
136     tls_context->peer_pkey_fprint = vstring_export(peer_pkey_fprint);
137     tls_context->protocol = vstring_export(protocol);
138     tls_context->cipher_name = vstring_export(cipher_name);
139     tls_context->kex_name = vstring_export(kex_name);
140     tls_context->kex_curve = vstring_export(kex_curve);
141     tls_context->clnt_sig_name = vstring_export(clnt_sig_name);
142     tls_context->clnt_sig_curve = vstring_export(clnt_sig_curve);
143     tls_context->clnt_sig_dgst = vstring_export(clnt_sig_dgst);
144     tls_context->srvr_sig_name = vstring_export(srvr_sig_name);
145     tls_context->srvr_sig_curve = vstring_export(srvr_sig_curve);
146     tls_context->srvr_sig_dgst = vstring_export(srvr_sig_dgst);
147     tls_context->namaddr = vstring_export(namaddr);
148     ret = (ret == 25 ? 1 : -1);
149     if (ret != 1) {
150           tls_proxy_context_free(tls_context);
151           tls_context = 0;
152     }
153     *(TLS_SESS_STATE **) ptr = tls_context;
154     if (msg_verbose)
155           msg_info("tls_proxy_context_scan ret=%d", ret);
156     return (ret);
157 }
158 
159 /* tls_proxy_context_free - destroy object from tls_proxy_context_receive() */
160 
tls_proxy_context_free(TLS_SESS_STATE * tls_context)161 void    tls_proxy_context_free(TLS_SESS_STATE *tls_context)
162 {
163     if (tls_context->peer_CN)
164           myfree(tls_context->peer_CN);
165     if (tls_context->issuer_CN)
166           myfree(tls_context->issuer_CN);
167     if (tls_context->peer_cert_fprint)
168           myfree(tls_context->peer_cert_fprint);
169     if (tls_context->peer_pkey_fprint)
170           myfree(tls_context->peer_pkey_fprint);
171     if (tls_context->protocol)
172           myfree((void *) tls_context->protocol);
173     if (tls_context->cipher_name)
174           myfree((void *) tls_context->cipher_name);
175     if (tls_context->kex_name)
176           myfree((void *) tls_context->kex_name);
177     if (tls_context->kex_curve)
178           myfree((void *) tls_context->kex_curve);
179     if (tls_context->clnt_sig_name)
180           myfree((void *) tls_context->clnt_sig_name);
181     if (tls_context->clnt_sig_curve)
182           myfree((void *) tls_context->clnt_sig_curve);
183     if (tls_context->clnt_sig_dgst)
184           myfree((void *) tls_context->clnt_sig_dgst);
185     if (tls_context->srvr_sig_name)
186           myfree((void *) tls_context->srvr_sig_name);
187     if (tls_context->srvr_sig_curve)
188           myfree((void *) tls_context->srvr_sig_curve);
189     if (tls_context->srvr_sig_dgst)
190           myfree((void *) tls_context->srvr_sig_dgst);
191     if (tls_context->namaddr)
192           myfree((void *) tls_context->namaddr);
193     myfree((void *) tls_context);
194 }
195 
196 #endif
197