Check-in [5ddead759f]
Overview
Comment:Added message status to callback command results. It is only available when OpenSSL is complied with the enable-ssl-trace option.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | errors_and_callbacks
Files: files | file ages | folders
SHA3-256: 5ddead759f4322cb531aca7d082778e6ef1602283439830661e264289945fd13
User & Date: bohagan on 2023-07-29 21:33:28
Other Links: branch diff | manifest | tags
Context
2023-07-30
00:20
Updated password callback to add rwflag size arguments to callback. Callback now works like other callbacks with the function followed by args. Refactored get result processing. Added more info to doc file. check-in: c072b00aeb user: bohagan tags: errors_and_callbacks
2023-07-29
21:33
Added message status to callback command results. It is only available when OpenSSL is complied with the enable-ssl-trace option. check-in: 5ddead759f user: bohagan tags: errors_and_callbacks
2023-07-28
19:42
Set ErrorCode for returned errors check-in: d7ece0aec4 user: bohagan tags: errors_and_callbacks
Changes
465
466
467
468
469
470
471
472


473
474
475
476
477
478
479
480
481
482
483
484
485


486
487














488
489
490
491
492
493
494
465
466
467
468
469
470
471

472
473
474


475
476
477
478
479
480
481
482
483

484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508







-
+
+

-
-









-
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+







	<br>

	<dt>
	  <strong>info</strong> <em>channel major minor message type</em>
	</dt>
	<dd>
	  This form of callback is invoked by the OpenSSL function
	  <code>SSL_CTX_set_info_callback()</code>.
	  <code>SSL_CTX_set_info_callback()</code> during connection setup
	  and use.
	  <br>
	  The <em>major</em> and <em>minor</em> arguments are used to
	  represent the state information bitmask.
	  <ul>
	  <li>Possible values for <em>major</em> are:
	  <code>handshake, alert, connect, accept</code>.</li>
	  <li>Possible values for <em>minor</em> are:
	  <code>start, done, read, write, loop, exit</code>.</li>
	  <li>The <em>message</em> argument is a descriptive string which may
	  be generated either by <code>SSL_state_string_long()</code> or by
	  <code>SSL_alert_desc_string_long()</code>, depending on context.</li>
	  <li>For alerts, the possible values for <em>type</em> are:
	  <code>warning, fatal, and unknown</code>.</li>
	  <code>warning, fatal, and unknown</code>. For others,
	  <code>info</code> is used.</li>
	  </ul>
	</dd>

	<dt>
	  <strong>message</strong> <em>channel direction version content_type data</em>
	</dt>
	<dd>
	  This form of callback is invoked by the OpenSSL function
	  <code>SSL_set_msg_callback()</code> whenever a message is sent or
	  received. It is only available when
	  OpenSSL is complied with the <em>enable-ssl-trace</em> option.
	  Where <em>direction</em> is Sent or Received, <em>version</em> is the
	  protocol version, <em>content_type</em> is the message content type,
	  and <em>data</em> is more info on the message from the <code>SSL_trace</code> API.
	</dd>
	<br>

	<dt>
	  <strong>session</strong> <em>session_id ticket lifetime</em>
	</dt>
	<dd>
	  This form of callback is invoked by the OpenSSL function
	  <code>SSL_CTX_sess_set_new_cb()</code>.
526
527
528
529
530
531
532
533
534
535



536
537
538
539
540
541
542
540
541
542
543
544
545
546



547
548
549
550
551
552
553
554
555
556







-
-
-
+
+
+







	<dl>

	<dt>
	  <strong>alpn</strong> <em>protocol</em>
	</dt>
	<dd>
	  For servers, this form of callback is invoked when the client ALPN
	  extension is received and the first <b>-alpn</b> specified protocol common
	  to the both the client and server is selected. If none, the first
	  client specified protocol is used.
	  extension is received. Where <em>protocol</em> is the first
	  <b>-alpn</b> specified protocol common to the both the client and
	  server. If none, the first client specified protocol is used.
	</dd>

	<br>

	<dt>
	  <strong>hello</strong> <em>servername</em>
	</dt>
550
551
552
553
554
555
556
557
558
559




560
561
562
563
564
565
566
567
568
569
570


571
572
573
574
575
576
577
564
565
566
567
568
569
570



571
572
573
574
575
576
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
592
593







-
-
-
+
+
+
+










-
+
+







	<br>

	<dt>
	  <strong>sni</strong> <em>servername</em>
	</dt>
	<dd>
	  For servers, this form of callback is invoked when the SNI extension
	  from the client is received. This is used when a server supports multiple
	  names, so the right certificate can be used. Called after hello
	  callback but before ALPN callback.
	  from the client is received. Where <em>servername</em> is the client
	  provided server name from the <b>-servername</b> option. This is
	  used when a server supports multiple names, so the right certificate
	  can be used. Called after hello callback but before ALPN callback.
	</dd>

	<br>

	<dt>
	  <strong>verify</strong> <em>channel depth cert status error</em>
	</dt>
	<dd>
	  This form of callback is invoked by OpenSSL when a new certificate
	  is received from the peer. It allows the client to check the
	  certificate chain verification results and choose whether to continue or not.
	  certificate verification results and choose whether to continue
	  or not. It is called for each certificate in the certificate chain.
	  <ul>
	  <li>The <em>depth</em> argument is an integer representing the
	  current depth on the certificate chain, with
	  <code>0</code> as the peer certificate and higher values going
	  up to the Certificate Authority (CA).</li>
	  <li>The <em>cert</em> argument is a list of key-value pairs similar
	  to those returned by
147
148
149
150
151
152
153
154

155
156
157
158
159
160
161
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161







-
+







}

/*
 *-------------------------------------------------------------------
 *
 * InfoCallback --
 *
 *	monitors SSL connection process
 *	Monitors SSL connection process
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Calls callback (if defined)
 *
216
217
218
219
220
221
222




















































































































223
224
225
226
227


228
229
230
231
232
233
234
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+
+







    EvalCallback(interp, statePtr, cmdPtr);
    Tcl_DecrRefCount(cmdPtr);
}

/*
 *-------------------------------------------------------------------
 *
 * MessageCallback --
 *
 *	Monitors SSL protocol messages
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Calls callback (if defined)
 *
 *-------------------------------------------------------------------
 */
#ifndef OPENSSL_NO_SSL_TRACE
static void
MessageCallback(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) {
    State *statePtr = (State*)arg;
    Tcl_Interp *interp	= statePtr->interp;
    Tcl_Obj *cmdPtr;
    char *ver, *type;
    BIO *bio;
    char buffer[15000];
    buffer[0] = 0;

    dprintf("Called");

    if (statePtr->callback == (Tcl_Obj*)NULL)
	return;

    switch(version) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(NO_SSL2) && !defined(OPENSSL_NO_SSL2)
    case SSL2_VERSION:
	ver = "SSLv2";
	break;
#endif
#if !defined(NO_SSL3) && !defined(OPENSSL_NO_SSL3)
    case SSL3_VERSION:
	ver = "SSLv3";
	break;
#endif
    case TLS1_VERSION:
	ver = "TLSv1";
	break;
    case TLS1_1_VERSION:
	ver = "TLSv1.1";
	break;
    case TLS1_2_VERSION:
	ver = "TLSv1.2";
	break;
    case TLS1_3_VERSION:
	ver = "TLSv1.3";
	break;
    case 0:
        ver = "none";
	break;
    default:
	ver = "unknown";
	break;
    }

    switch (content_type) {
    case SSL3_RT_HEADER:
	type = "Header";
        break;
    case SSL3_RT_INNER_CONTENT_TYPE:
	type = "Inner Content Type";
        break;
    case SSL3_RT_CHANGE_CIPHER_SPEC:
	type = "Change Cipher";
        break;
    case SSL3_RT_ALERT:
	type = "Alert";
        break;
    case SSL3_RT_HANDSHAKE:
	type = "Handshake";
        break;
    case SSL3_RT_APPLICATION_DATA:
	type = "App Data";
        break;
    case DTLS1_RT_HEARTBEAT:
	type = "Heartbeat";
        break;
    default:
	type = "unknown";
    }

    /* Needs compile time option "enable-ssl-trace". */
    if ((bio = BIO_new(BIO_s_mem())) != NULL) {
	int n;
	SSL_trace(write_p, version, content_type, buf, len, ssl, (void *)bio);
	n = BIO_read(bio, buffer, min(BIO_pending(bio), 14999));
	n = (n<0) ? 0 : n;
	buffer[n] = 0;
	(void)BIO_flush(bio);
 	BIO_free(bio);
   }

    /* Create command to eval */
    cmdPtr = Tcl_DuplicateObj(statePtr->callback);
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("message", -1));
    Tcl_ListObjAppendElement(interp, cmdPtr,
	    Tcl_NewStringObj(Tcl_GetChannelName(statePtr->self), -1));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(write_p ? "Sent" : "Received", -1));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(ver, -1));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(type, -1));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(buffer, -1));

    /* Eval callback command */
    Tcl_IncrRefCount(cmdPtr);
    EvalCallback(interp, statePtr, cmdPtr);
    Tcl_DecrRefCount(cmdPtr);
}
#endif

/*
 *-------------------------------------------------------------------
 *
 * VerifyCallback --
 *
 *	Monitors SSL certificate validation process. Used to control the
 *	behavior when the SSL_VERIFY_PEER flag is set. This is called
 *	whenever a certificate is inspected or decided invalid.
 *	whenever a certificate is inspected or decided invalid. Called for
 *	each certificate in the cert chain.
 *
 * Checks:
 *	certificate chain is checked starting with the deepest nesting level
 *	  (the root CA certificate) and worked upward to the peer's certificate.
 *	All signatures are valid, current time is within first and last validity time.
 *	Check that the certificate is issued by the issuer certificate issuer.
 *	Check the revocation status for each certificate.
1419
1420
1421
1422
1423
1424
1425








1426
1427
1428
1429
1430
1431
1432
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557







+
+
+
+
+
+
+
+








    /*
     * SSL Callbacks
     */
    SSL_set_app_data(statePtr->ssl, (void *)statePtr);	/* point back to us */
    SSL_set_verify(statePtr->ssl, verify, VerifyCallback);
    SSL_set_info_callback(statePtr->ssl, InfoCallback);

    /* Callback for observing protocol messages */
#ifndef OPENSSL_NO_SSL_TRACE
    /* void SSL_CTX_set_msg_callback_arg(statePtr->ctx, (void *)statePtr);
    void SSL_CTX_set_msg_callback(statePtr->ctx, MessageCallback); */
    SSL_set_msg_callback_arg(statePtr->ssl, (void *)statePtr);
    SSL_set_msg_callback(statePtr->ssl, MessageCallback);
#endif

    /* Create Tcl_Channel BIO Handler */
    statePtr->p_bio	= BIO_new_tcl(statePtr, BIO_NOCLOSE);
    statePtr->bio	= BIO_new(BIO_f_ssl());

    if (server) {
	/* Server callbacks */