1 /* $NetBSD: tls_proxy_client_print.c,v 1.2 2020/03/18 19:05:21 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* tls_proxy_client_print 3 6 /* SUMMARY 7 /* write TLS_CLIENT_XXX structures to stream 8 /* SYNOPSIS 9 /* #include <tls_proxy.h> 10 /* 11 /* int tls_proxy_client_param_print(print_fn, stream, flags, ptr) 12 /* ATTR_PRINT_MASTER_FN print_fn; 13 /* VSTREAM *stream; 14 /* int flags; 15 /* void *ptr; 16 /* 17 /* int tls_proxy_client_init_print(print_fn, stream, flags, ptr) 18 /* ATTR_PRINT_MASTER_FN print_fn; 19 /* VSTREAM *stream; 20 /* int flags; 21 /* void *ptr; 22 /* 23 /* int tls_proxy_client_start_print(print_fn, stream, flags, ptr) 24 /* ATTR_PRINT_MASTER_FN print_fn; 25 /* VSTREAM *stream; 26 /* int flags; 27 /* void *ptr; 28 /* DESCRIPTION 29 /* tls_proxy_client_param_print() writes a TLS_CLIENT_PARAMS structure to 30 /* the named stream using the specified attribute print routine. 31 /* tls_proxy_client_param_print() is meant to be passed as a call-back to 32 /* attr_print(), thusly: 33 /* 34 /* SEND_ATTR_FUNC(tls_proxy_client_param_print, (void *) param), ... 35 /* 36 /* tls_proxy_client_init_print() writes a full TLS_CLIENT_INIT_PROPS 37 /* structure to the named stream using the specified attribute 38 /* print routine. tls_proxy_client_init_print() is meant to 39 /* be passed as a call-back to attr_print(), thusly: 40 /* 41 /* SEND_ATTR_FUNC(tls_proxy_client_init_print, (void *) init_props), ... 42 /* 43 /* tls_proxy_client_start_print() writes a TLS_CLIENT_START_PROPS 44 /* structure, without stream or file descriptor members, to 45 /* the named stream using the specified attribute print routine. 46 /* tls_proxy_client_start_print() is meant to be passed as a 47 /* call-back to attr_print(), thusly: 48 /* 49 /* SEND_ATTR_FUNC(tls_proxy_client_start_print, (void *) start_props), ... 50 /* DIAGNOSTICS 51 /* Fatal: out of memory. 52 /* LICENSE 53 /* .ad 54 /* .fi 55 /* The Secure Mailer license must be distributed with this software. 56 /* AUTHOR(S) 57 /* Wietse Venema 58 /* Google, Inc. 59 /* 111 8th Avenue 60 /* New York, NY 10011, USA 61 /*--*/ 62 63 #ifdef USE_TLS 64 65 /* System library. */ 66 67 #include <sys_defs.h> 68 69 /* Utility library */ 70 71 #include <argv_attr.h> 72 #include <attr.h> 73 #include <msg.h> 74 75 /* Global library. */ 76 77 #include <mail_params.h> 78 79 /* TLS library. */ 80 81 #include <tls.h> 82 #include <tls_proxy.h> 83 84 85 #define STR(x) vstring_str(x) 86 #define LEN(x) VSTRING_LEN(x) 87 88 /* tls_proxy_client_param_print - send TLS_CLIENT_PARAMS over stream */ 89 90 int tls_proxy_client_param_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp, 91 int flags, void *ptr) 92 { 93 TLS_CLIENT_PARAMS *params = (TLS_CLIENT_PARAMS *) ptr; 94 int ret; 95 96 if (msg_verbose) 97 msg_info("begin tls_proxy_client_param_print"); 98 99 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 100 SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist), 101 SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST, 102 params->tls_medium_clist), 103 SEND_ATTR_STR(VAR_TLS_LOW_CLIST, params->tls_low_clist), 104 SEND_ATTR_STR(VAR_TLS_EXPORT_CLIST, 105 params->tls_export_clist), 106 SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist), 107 SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto), 108 SEND_ATTR_STR(VAR_TLS_EECDH_STRONG, 109 params->tls_eecdh_strong), 110 SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA, 111 params->tls_eecdh_ultra), 112 SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks), 113 SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS, 114 params->tls_ssl_options), 115 SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS, 116 params->tls_dane_digests), 117 SEND_ATTR_STR(VAR_TLS_MGR_SERVICE, 118 params->tls_mgr_service), 119 SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher), 120 SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES, 121 params->tls_daemon_rand_bytes), 122 SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA, 123 params->tls_append_def_CA), 124 SEND_ATTR_INT(VAR_TLS_BC_PKEY_FPRINT, 125 params->tls_bc_pkey_fprint), 126 SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST, 127 params->tls_preempt_clist), 128 SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD, 129 params->tls_multi_wildcard), 130 ATTR_TYPE_END); 131 /* Do not flush the stream. */ 132 if (msg_verbose) 133 msg_info("tls_proxy_client_param_print ret=%d", ret); 134 return (ret); 135 } 136 137 /* tls_proxy_client_init_print - send TLS_CLIENT_INIT_PROPS over stream */ 138 139 int tls_proxy_client_init_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp, 140 int flags, void *ptr) 141 { 142 TLS_CLIENT_INIT_PROPS *props = (TLS_CLIENT_INIT_PROPS *) ptr; 143 int ret; 144 145 if (msg_verbose) 146 msg_info("begin tls_proxy_client_init_print"); 147 148 #define STRING_OR_EMPTY(s) ((s) ? (s) : "") 149 150 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 151 SEND_ATTR_STR(TLS_ATTR_LOG_PARAM, 152 STRING_OR_EMPTY(props->log_param)), 153 SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL, 154 STRING_OR_EMPTY(props->log_level)), 155 SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth), 156 SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE, 157 STRING_OR_EMPTY(props->cache_type)), 158 SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES, 159 STRING_OR_EMPTY(props->chain_files)), 160 SEND_ATTR_STR(TLS_ATTR_CERT_FILE, 161 STRING_OR_EMPTY(props->cert_file)), 162 SEND_ATTR_STR(TLS_ATTR_KEY_FILE, 163 STRING_OR_EMPTY(props->key_file)), 164 SEND_ATTR_STR(TLS_ATTR_DCERT_FILE, 165 STRING_OR_EMPTY(props->dcert_file)), 166 SEND_ATTR_STR(TLS_ATTR_DKEY_FILE, 167 STRING_OR_EMPTY(props->dkey_file)), 168 SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE, 169 STRING_OR_EMPTY(props->eccert_file)), 170 SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE, 171 STRING_OR_EMPTY(props->eckey_file)), 172 SEND_ATTR_STR(TLS_ATTR_CAFILE, 173 STRING_OR_EMPTY(props->CAfile)), 174 SEND_ATTR_STR(TLS_ATTR_CAPATH, 175 STRING_OR_EMPTY(props->CApath)), 176 SEND_ATTR_STR(TLS_ATTR_MDALG, 177 STRING_OR_EMPTY(props->mdalg)), 178 ATTR_TYPE_END); 179 /* Do not flush the stream. */ 180 if (msg_verbose) 181 msg_info("tls_proxy_client_init_print ret=%d", ret); 182 return (ret); 183 } 184 185 /* tls_proxy_client_certs_print - send x509 certificates over stream */ 186 187 static int tls_proxy_client_certs_print(ATTR_PRINT_MASTER_FN print_fn, 188 VSTREAM *fp, int flags, void *ptr) 189 { 190 TLS_CERTS *tls_certs = (TLS_CERTS *) ptr; 191 TLS_CERTS *tp; 192 int count; 193 int ret; 194 195 for (tp = tls_certs, count = 0; tp != 0; tp = tp->next, count++) 196 /* void */ ; 197 if (msg_verbose) 198 msg_info("tls_proxy_client_certs_print count=%d", count); 199 200 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 201 SEND_ATTR_INT(TLS_ATTR_COUNT, count), 202 ATTR_TYPE_END); 203 204 if (ret == 0 && count > 0) { 205 VSTRING *buf = vstring_alloc(100); 206 int n; 207 208 for (tp = tls_certs, n = 0; ret == 0 && n < count; tp = tp->next, n++) { 209 size_t len = i2d_X509(tp->cert, (unsigned char **) 0); 210 unsigned char *bp; 211 212 VSTRING_RESET(buf); 213 VSTRING_SPACE(buf, len); 214 bp = (unsigned char *) STR(buf); 215 i2d_X509(tp->cert, &bp); 216 if ((char *) bp - STR(buf) != len) 217 msg_panic("i2d_X509 failed to encode certificate"); 218 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 219 SEND_ATTR_DATA(TLS_ATTR_CERT, LEN(buf), STR(buf)), 220 ATTR_TYPE_END); 221 } 222 vstring_free(buf); 223 } 224 /* Do not flush the stream. */ 225 if (msg_verbose) 226 msg_info("tls_proxy_client_certs_print ret=%d", count); 227 return (ret); 228 } 229 230 /* tls_proxy_client_pkeys_print - send public keys over stream */ 231 232 static int tls_proxy_client_pkeys_print(ATTR_PRINT_MASTER_FN print_fn, 233 VSTREAM *fp, int flags, void *ptr) 234 { 235 TLS_PKEYS *tls_pkeys = (TLS_PKEYS *) ptr; 236 TLS_PKEYS *tp; 237 int count; 238 int ret; 239 240 for (tp = tls_pkeys, count = 0; tp != 0; tp = tp->next, count++) 241 /* void */ ; 242 if (msg_verbose) 243 msg_info("tls_proxy_client_pkeys_print count=%d", count); 244 245 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 246 SEND_ATTR_INT(TLS_ATTR_COUNT, count), 247 ATTR_TYPE_END); 248 249 if (ret == 0 && count > 0) { 250 VSTRING *buf = vstring_alloc(100); 251 int n; 252 253 for (tp = tls_pkeys, n = 0; ret == 0 && n < count; tp = tp->next, n++) { 254 size_t len = i2d_PUBKEY(tp->pkey, (unsigned char **) 0); 255 unsigned char *bp; 256 257 VSTRING_RESET(buf); 258 VSTRING_SPACE(buf, len); 259 bp = (unsigned char *) STR(buf); 260 i2d_PUBKEY(tp->pkey, &bp); 261 if ((char *) bp - STR(buf) != len) 262 msg_panic("i2d_PUBKEY failed to encode public key"); 263 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 264 SEND_ATTR_DATA(TLS_ATTR_PKEY, LEN(buf), STR(buf)), 265 ATTR_TYPE_END); 266 } 267 vstring_free(buf); 268 } 269 /* Do not flush the stream. */ 270 if (msg_verbose) 271 msg_info("tls_proxy_client_pkeys_print ret=%d", count); 272 return (ret); 273 } 274 275 /* tls_proxy_client_tlsa_print - send TLS_TLSA over stream */ 276 277 static int tls_proxy_client_tlsa_print(ATTR_PRINT_MASTER_FN print_fn, 278 VSTREAM *fp, int flags, void *ptr) 279 { 280 TLS_TLSA *tls_tlsa = (TLS_TLSA *) ptr; 281 TLS_TLSA *tp; 282 int count; 283 int ret; 284 285 for (tp = tls_tlsa, count = 0; tp != 0; tp = tp->next, count++) 286 /* void */ ; 287 if (msg_verbose) 288 msg_info("tls_proxy_client_tlsa_print count=%d", count); 289 290 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 291 SEND_ATTR_INT(TLS_ATTR_COUNT, count), 292 ATTR_TYPE_END); 293 294 if (ret == 0 && count > 0) { 295 int n; 296 297 for (tp = tls_tlsa, n = 0; ret == 0 && n < count; tp = tp->next, n++) { 298 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 299 SEND_ATTR_STR(TLS_ATTR_MDALG, tp->mdalg), 300 SEND_ATTR_FUNC(argv_attr_print, 301 (void *) tp->certs), 302 SEND_ATTR_FUNC(argv_attr_print, 303 (void *) tp->pkeys), 304 ATTR_TYPE_END); 305 } 306 } 307 /* Do not flush the stream. */ 308 if (msg_verbose) 309 msg_info("tls_proxy_client_tlsa_print ret=%d", count); 310 return (ret); 311 } 312 313 /* tls_proxy_client_dane_print - send TLS_DANE over stream */ 314 315 static int tls_proxy_client_dane_print(ATTR_PRINT_MASTER_FN print_fn, 316 VSTREAM *fp, int flags, void *ptr) 317 { 318 TLS_DANE *dane = (TLS_DANE *) ptr; 319 int ret; 320 321 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 322 SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0), 323 ATTR_TYPE_END); 324 if (msg_verbose) 325 msg_info("tls_proxy_client_dane_print dane=%d", dane != 0); 326 327 if (ret == 0 && dane != 0) { 328 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 329 SEND_ATTR_FUNC(tls_proxy_client_tlsa_print, 330 (void *) dane->ta), 331 SEND_ATTR_FUNC(tls_proxy_client_tlsa_print, 332 (void *) dane->ee), 333 SEND_ATTR_FUNC(tls_proxy_client_certs_print, 334 (void *) dane->certs), 335 SEND_ATTR_FUNC(tls_proxy_client_pkeys_print, 336 (void *) dane->pkeys), 337 SEND_ATTR_STR(TLS_ATTR_DOMAIN, 338 STRING_OR_EMPTY(dane->base_domain)), 339 SEND_ATTR_INT(TLS_ATTR_FLAGS, dane->flags), 340 SEND_ATTR_LONG(TLS_ATTR_EXP, dane->expires), 341 ATTR_TYPE_END); 342 } 343 /* Do not flush the stream. */ 344 if (msg_verbose) 345 msg_info("tls_proxy_client_dane_print ret=%d", ret); 346 return (ret); 347 } 348 349 /* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */ 350 351 int tls_proxy_client_start_print(ATTR_PRINT_MASTER_FN print_fn, 352 VSTREAM *fp, int flags, void *ptr) 353 { 354 TLS_CLIENT_START_PROPS *props = (TLS_CLIENT_START_PROPS *) ptr; 355 int ret; 356 357 if (msg_verbose) 358 msg_info("begin tls_proxy_client_start_print"); 359 360 #define STRING_OR_EMPTY(s) ((s) ? (s) : "") 361 362 ret = print_fn(fp, flags | ATTR_FLAG_MORE, 363 SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout), 364 SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level), 365 SEND_ATTR_STR(TLS_ATTR_NEXTHOP, 366 STRING_OR_EMPTY(props->nexthop)), 367 SEND_ATTR_STR(TLS_ATTR_HOST, 368 STRING_OR_EMPTY(props->host)), 369 SEND_ATTR_STR(TLS_ATTR_NAMADDR, 370 STRING_OR_EMPTY(props->namaddr)), 371 SEND_ATTR_STR(TLS_ATTR_SNI, 372 STRING_OR_EMPTY(props->sni)), 373 SEND_ATTR_STR(TLS_ATTR_SERVERID, 374 STRING_OR_EMPTY(props->serverid)), 375 SEND_ATTR_STR(TLS_ATTR_HELO, 376 STRING_OR_EMPTY(props->helo)), 377 SEND_ATTR_STR(TLS_ATTR_PROTOCOLS, 378 STRING_OR_EMPTY(props->protocols)), 379 SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE, 380 STRING_OR_EMPTY(props->cipher_grade)), 381 SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS, 382 STRING_OR_EMPTY(props->cipher_exclusions)), 383 SEND_ATTR_FUNC(argv_attr_print, 384 (void *) props->matchargv), 385 SEND_ATTR_STR(TLS_ATTR_MDALG, 386 STRING_OR_EMPTY(props->mdalg)), 387 SEND_ATTR_FUNC(tls_proxy_client_dane_print, 388 (void *) props->dane), 389 ATTR_TYPE_END); 390 /* Do not flush the stream. */ 391 if (msg_verbose) 392 msg_info("tls_proxy_client_start_print ret=%d", ret); 393 return (ret); 394 } 395 396 #endif 397