Check-in [17ee565eed]
EuroTcl/OpenACS 11 - 12 JULY 2024, VIENNA
Overview
Comment:Changed Tls_NewX509Obj to not use stack space for all and certificate buffers. This reduces the possibility of a stack overflow.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tls-1.8
Files: files | file ages | folders
SHA3-256: 17ee565eedfaa786265161b68db7e24a221ff9234deda9c3d2fe0e5f979e2583
User & Date: bohagan on 2024-06-25 22:22:16
Other Links: branch diff | manifest | tags
Context
2024-06-28
18:50
Refactored Tls_NewX509Obj to use Tcl_Size, common var names, added function descriptions, etc. check-in: 1bf152a55d user: bohagan tags: tls-1.8
2024-06-25
22:22
Changed Tls_NewX509Obj to not use stack space for all and certificate buffers. This reduces the possibility of a stack overflow. check-in: 17ee565eed user: bohagan tags: tls-1.8
2024-06-23
03:11
Documentation updates to add info on certificate validation needs and more debug info. check-in: e4794cbb74 user: bohagan tags: tls-1.8
Changes

Modified generic/tls.c from [bba2dae983] to [d36478ef49].

374
375
376
377
378
379
380
381

382
383
384
385
386
387
388
374
375
376
377
378
379
380

381
382
383
384
385
386
387
388







-
+








    /* Create command to eval with fn, chan, depth, cert info list, status, and error args */
    cmdPtr = Tcl_DuplicateObj(statePtr->vcmd);
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("verify", -1));
    Tcl_ListObjAppendElement(interp, cmdPtr,
	Tcl_NewStringObj(Tcl_GetChannelName(statePtr->self), -1));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(depth));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tls_NewX509Obj(interp, cert));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tls_NewX509Obj(interp, cert, 0));
    Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(ok));
    Tcl_ListObjAppendElement(interp, cmdPtr,
	Tcl_NewStringObj((char*)X509_verify_cert_error_string(err), -1));

    /* Prevent I/O while callback is in progress */
    /* statePtr->flags |= TLS_TCL_CALLBACK; */

2182
2183
2184
2185
2186
2187
2188
2189

2190
2191
2192
2193
2194
2195
2196
2182
2183
2184
2185
2186
2187
2188

2189
2190
2191
2192
2193
2194
2195
2196







-
+







    if (objc == 2) {
	peer = SSL_get_peer_certificate(statePtr->ssl);
    } else {
	peer = SSL_get_certificate(statePtr->ssl);
    }
    /* Get X509 certificate info */
    if (peer) {
	objPtr = Tls_NewX509Obj(interp, peer);
	objPtr = Tls_NewX509Obj(interp, peer, 1);
	if (objc == 2) {
	    X509_free(peer);
	    peer = NULL;
	}
    } else {
	objPtr = Tcl_NewListObj(0, NULL);
    }

Modified generic/tlsInt.h from [acd84d3ddd] to [991758417a].

209
210
211
212
213
214
215
216

217
218
219
220
221
222
223
209
210
211
212
213
214
215

216
217
218
219
220
221
222
223







-
+








/*
 * Forward declarations
 */
const 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_NewX509Obj(Tcl_Interp *interp, X509 *cert, int all);
Tcl_Obj		*Tls_NewCAObj(Tcl_Interp *interp, const SSL *ssl, int peer);
void            Tls_Error(State *statePtr, const char *msg);
void            Tls_Free(tls_free_type *blockPtr);
void            Tls_Clean(State *statePtr);
int             Tls_WaitForConnect(State *statePtr, int *errorCodePtr, int handshakeFailureIsPermanent);

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

Modified generic/tlsX509.c from [ea8ff7e7c8] to [36eeb56077].

367
368
369
370
371
372
373
374

375
376
377
378
379
380
381
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381







-
+







 *		A Tcl List Object representing the provided
 *		X509 certificate.
 *
 *------------------------------------------------------*
 */

Tcl_Obj*
Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert) {
Tls_NewX509Obj(Tcl_Interp *interp, X509 *cert, int all) {
    Tcl_Obj *certPtr = Tcl_NewListObj(0, NULL);
    BIO *bio = BIO_new(BIO_s_mem());
    int mdnid, pknid, bits, len;
    unsigned int ulen;
    uint32_t xflags;
    char buffer[BUFSIZ];
    unsigned char md[EVP_MAX_MD_SIZE];
592
593
594
595
596
597
598




599
600
601







602

603

604

605
606
607
608





609
610
611
612
613
592
593
594
595
596
597
598
599
600
601
602



603
604
605
606
607
608
609
610
611
612
613

614
615



616
617
618
619
620
621
622
623
624
625







+
+
+
+
-
-
-
+
+
+
+
+
+
+

+

+
-
+

-
-
-
+
+
+
+
+





        unsigned char *string = X509_alias_get0(cert, &len);
	LAPPEND_STR(interp, certPtr, "alias", (char *) string, (Tcl_Size) len);
        string = X509_keyid_get0(cert, &len);
	LAPPEND_STR(interp, certPtr, "keyId", (char *) string, (Tcl_Size) len);
    }

    /* Certificate and dump all data */
    if (all) {
	Tcl_Obj *allObj = Tcl_NewByteArrayObj(NULL, 0);
	Tcl_Obj *certObj = Tcl_NewByteArrayObj(NULL, 0);
	unsigned char *allStr, *certStr;
    {
	char certStr[CERT_STR_SIZE];


	if (allObj == NULL || certObj == NULL) {
	    Tcl_DecrRefCount(allObj);
	    BIO_free(bio);
	    return certPtr;
	}

	/* Get certificate */
	certStr = Tcl_SetByteArrayLength(certObj, CERT_STR_SIZE);
	len = BIO_to_Buffer(PEM_write_bio_X509(bio, cert), bio, certStr, CERT_STR_SIZE);
	Tcl_SetByteArrayLength(certObj, len);
	LAPPEND_STR(interp, certPtr, "certificate", certStr, (Tcl_Size) len);
	LAPPEND_OBJ(interp, certPtr, "certificate", certObj)

	/* Get all cert info */
	len = BIO_to_Buffer(X509_print_ex(bio, cert, flags, 0), bio, certStr, CERT_STR_SIZE);
	LAPPEND_STR(interp, certPtr, "all", certStr, (Tcl_Size) len);
	/* Get all info on certificate */
	allStr = Tcl_SetByteArrayLength(allObj, CERT_STR_SIZE * 2);
	len = BIO_to_Buffer(X509_print_ex(bio, cert, flags, 0), bio, allStr, CERT_STR_SIZE * 2);
	Tcl_SetByteArrayLength(allObj, len);
	LAPPEND_OBJ(interp, certPtr, "all", allObj)
    }

    BIO_free(bio);
    return certPtr;
}