Check-in [e02e24c84a]
Overview
Comment:Added signature hash and type to connection status Changed validation result to verification.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | status_x509
Files: files | file ages | folders
SHA3-256: e02e24c84af6ff3bc296d8e89afe7c6974a30672595ded7d396f56133a978788
User & Date: bohagan on 2023-06-17 23:09:12
Other Links: branch diff | manifest | tags
Context
2023-06-18
21:47
Added post handshake cert request option check-in: fec0e414e9 user: bohagan tags: status_x509
2023-06-17
23:09
Added signature hash and type to connection status Changed validation result to verification. check-in: e02e24c84a user: bohagan tags: status_x509
2023-06-16
18:04
Change to use NULL for empty pointers check-in: ee0728f6d6 user: bohagan tags: status_x509
Changes
269
270
271
272
273
274
275
276
277


278
279
280
281
282
283






284
285
286
287
288
289
290
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







-
-
+
+






+
+
+
+
+
+







        <dt><strong>peername</strong> <em>name</em></dt>
        <dd>The peername from the certificate.</dd>
        <dt><strong>sbits</strong> <em>n</em></dt>
        <dd>The number of bits used for the session key.</dd>
        <dt><strong>cipher</strong> <em>cipher</em></dt>
        <dd>The current cipher in use between the client and
            server channels.</dd>
        <dt><strong>validation</strong> <em>result</em></dt>
        <dd>Certificate validation result.</dd>
        <dt><strong>verification<em>result</em></dt>
        <dd>Certificate verification result.</dd>
        <dt><strong>alpn</strong> <em>protocol</em></dt>
        <dd>The protocol selected after Application-Layer Protocol
	    Negotiation (ALPN).</dd>
        <dt><strong>protocol</strong> <em>value</em></dt>
        <dd>The protocol version used for the connection:
	  SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3, or unknown</dd>
        <dt><strong>signature_hash</strong> <em>string</em></dt>
        <dd>The signature hash value.</dd>
        <dt><strong>signature_type</strong> <em>type</em></dt>
        <dd>The signature type value.</dd>
        <dt><strong>ca_names</strong> <em>list</em></dt>
        <dd>List of the Certificate Authorities used to create the certificate.</dd>
    </dl>
</blockquote>

    <dt><a name="tls::connection"><strong>tls::connection</strong>
    <em>channel</em></a></dt>
    <dd>Returns the current connection status of an SSL channel. The
        result is a list of key-value pairs describing the
358
359
360
361
362
363
364
365


366
367
368
369
370
371
372
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378
379







-
+
+







	additional information on the cipher. If <em>supported</em>
	is specified as true, then only the ciphers supported for protocol
	will be listed.</dd>

    <dt><a name="tls::protocols"><strong>tls::protocols</strong></a></dt>
    <dd>Returns a list of supported protocols. Valid values are:
	<b>ssl2</b>, <b>ssl3</b>, <b>tls1</b>, <b>tls1.1</b>, <b>tls1.2</b>,
	and <b>tls1.3</b>.</dd>
	and <b>tls1.3</b>. Exact list depends on OpenSSL version and
	compile time flags.</dd>

    <dt><a name="tls::version"><strong>tls::version</strong></a></dt>
    <dd>Returns the OpenSSL version string.</dd>
</dl>

<h3><a name="CALLBACK OPTIONS">CALLBACK OPTIONS</a></h3>

394
395
396
397
398
399
400
401
402
403




404
405
406
407
408
409
410
401
402
403
404
405
406
407



408
409
410
411
412
413
414
415
416
417
418







-
-
-
+
+
+
+








	<dl>

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

	<br>

<!--	This form of callback is disabled.

	<dt>
419
420
421
422
423
424
425
426


427
428
429
430
431
432
433
427
428
429
430
431
432
433

434
435
436
437
438
439
440
441
442







-
+
+







	<br>
-->

	<dt>
	  <strong>hello</strong> <em>servername</em>
	</dt>
	<dd>
	  This form of callback is invoked during client hello message processing.
	  For servers, this form of callback is invoked during client hello
	  message processing.
	</dd>

	<br>

	<dt>
	  <strong>info</strong> <em>channel major minor message</em>
	</dt>
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
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







-
-
-
-
+
+
+
+









-
-
+
+
+








	<br>

	<dt>
	  <strong>sni</strong> <em>servername</em>
	</dt>
	<dd>
	  This form of callback is invoked when the server receives the SNI
	  header from the client where <i>servername</i> is the client
	  specified servername. Used to allow multiple names for
	  same server so the right certificate can be used.
	  For servers, this form of callback is invoked when the SNI header
	  from the client is received. Where <i>servername</i> is the client
	  specified servername. This is used when a server supports multiple
	  names, so the right certificate can be used.
	</dd>

	<br>
	<br>

	<dt>
	  <strong>verify</strong> <em>channel depth cert status error</em>
	</dt>
	<dd>
	  This form of callback is invoked by the OpenSSL function
	  <code>SSL_set_verify()</code>.
	  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 verification result and choose whether to continue or not.
	  <br>
	  The <em>depth</em> argument is an integer representing the
	  current depth on the certificate chain, with
	  <code>0</code> as the subject certificate and higher values
	  denoting progressively more indirect issuer certificates.
	  <br>
	  The <em>cert</em> argument is a list of key-value pairs similar
1778
1779
1780
1781
1782
1783
1784

1785
1786
1787
1788
1789
1790
1791
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792







+







    X509 *peer;
    Tcl_Obj *objPtr;
    Tcl_Channel chan;
    char *channelName, *ciphers;
    int mode;
    const unsigned char *proto;
    unsigned int len;
    int nid;

    dprintf("Called");

    switch (objc) {
	case 2:
	    channelName = Tcl_GetStringFromObj(objv[1], NULL);
	    break;
1844
1845
1846
1847
1848
1849
1850
1851

1852
1853
1854
1855
1856
1857
1858


1859
1860
1861
1862
1863
1864
1865














1866
1867
1868
1869
1870
1871
1872
1845
1846
1847
1848
1849
1850
1851

1852







1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882







-
+
-
-
-
-
-
-
-
+
+







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







    ciphers = (char*)SSL_get_cipher(statePtr->ssl);
    if ((ciphers != NULL) && (strcmp(ciphers, "(NONE)") != 0)) {
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("cipher", -1));
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get_cipher(statePtr->ssl), -1));
    }

    /* Verify the X509 certificate presented by the peer */
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("validation", -1));
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("verification", -1));
    if (SSL_get_verify_result(statePtr->ssl) != X509_V_OK) {
	/* proto = "failed"; */
	proto = REASON();
    } else {
	proto = "ok";
    }
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(proto, -1));
    Tcl_ListObjAppendElement(interp, objPtr,
	Tcl_NewStringObj(X509_verify_cert_error_string(SSL_get_verify_result(statePtr->ssl)), -1));

    /* Report the selected protocol as a result of the negotiation */
    SSL_get0_alpn_selected(statePtr->ssl, &proto, &len);
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("alpn", -1));
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj((char *)proto, (int) len));
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("protocol", -1));
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get_version(statePtr->ssl), -1));

    /* Valid for non-RSA signature and TLS 1.3 */
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("signature_hash", -1));
    if (objc == 2 ? SSL_get_peer_signature_nid(statePtr->ssl, &nid) : SSL_get_signature_nid(statePtr->ssl, &nid)) {
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(OBJ_nid2ln(nid), -1));
    } else {
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("", -1));
    }
    Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("signature_type", -1));
    if (objc == 2 ? SSL_get_peer_signature_type_nid(statePtr->ssl, &nid) : SSL_get_signature_type_nid(statePtr->ssl, &nid)) {
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(OBJ_nid2ln(nid), -1));
    } else {
	Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("", -1));
    }

    Tcl_SetObjResult(interp, objPtr);
    return TCL_OK;
	clientData = clientData;
}

/*
146
147
148
149
150
151
152

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







+







/*
 * Forward declarations
 */
Tcl_ChannelType *Tls_ChannelType(void);
Tcl_Channel     Tls_GetParent(State *statePtr, int maskFlags);

Tcl_Obj         *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert);
Tcl_Obj		*Tls_NewCAObj(Tcl_Interp *interp, const SSL *ssl, int peer);
void            Tls_Error(State *statePtr, char *msg);
void            Tls_Free(char *blockPtr);
void            Tls_Clean(State *statePtr);
int             Tls_WaitForConnect(State *statePtr, int *errorCodePtr, int handshakeFailureIsPermanent);

BIO             *BIO_new_tcl(State* statePtr, int flags);

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18










+







/*
 * Copyright (C) 1997-2000 Sensus Consulting Ltd.
 * Matt Newman <matt@sensus.org>
 * Copyright (C) 2023 Brian O'Hagan
 */
#include <tcl.h>
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1.h>
#include "tlsInt.h"

/*
 *  Ensure these are not macros - known to be defined on Win32
 */
#ifdef min