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
        <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>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>






    </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







|
|






>
>
>
>
>
>







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>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
	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>


    <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>








|
>







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>. 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

	<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.
	</dd>

	<br>

<!--	This form of callback is disabled.

	<dt>







|
|
>
|







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>
	  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
	<br>
-->

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

	</dd>

	<br>

	<dt>
	  <strong>info</strong> <em>channel major minor message</em>
	</dt>







|
>







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>
	  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

	<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.
	</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>.
	  <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







|
|
|
|









|
>
|







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>
	  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 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
    X509 *peer;
    Tcl_Obj *objPtr;
    Tcl_Channel chan;
    char *channelName, *ciphers;
    int mode;
    const unsigned char *proto;
    unsigned int len;


    dprintf("Called");

    switch (objc) {
	case 2:
	    channelName = Tcl_GetStringFromObj(objv[1], NULL);
	    break;







>







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
    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));
    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));


    /* 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));















    Tcl_SetObjResult(interp, objPtr);
    return TCL_OK;
	clientData = clientData;
}

/*







|
<
<
<
<
<
<
|
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>







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("verification", -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
/*
 * Forward declarations
 */
Tcl_ChannelType *Tls_ChannelType(void);
Tcl_Channel     Tls_GetParent(State *statePtr, int maskFlags);

Tcl_Obj         *Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert);

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);








>







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
/*
 * Copyright (C) 1997-2000 Sensus Consulting Ltd.
 * Matt Newman <[email protected]>
 * 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/asn1.h>
#include "tlsInt.h"

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










>







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 <[email protected]>
 * 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