Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Fix various compiler warnings (like -Wconversion and -Wc++-compat) |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk | main | tls-2.0 |
| Files: | files | file ages | folders |
| SHA3-256: |
9a7e09fccad3e00df8d71929d6136700 |
| User & Date: | jan.nijtmans 2025-10-16 09:33:11 |
Context
|
2025-10-17
| ||
| 07:16 | Minor spacing check-in: e831e54d8b user: jan.nijtmans tags: trunk, main, tls-2.0 | |
|
2025-10-16
| ||
| 09:33 | Fix various compiler warnings (like -Wconversion and -Wc++-compat) check-in: 9a7e09fcca user: jan.nijtmans tags: trunk, main, tls-2.0 | |
|
2025-10-13
| ||
| 21:56 | Fixes to demos to add 'package prefer latest', use updated TCL website URL, etc. check-in: 9a625532b9 user: bohagan tags: trunk, main, tls-2.0 | |
Changes
Changes to generic/tls.c.
| ︙ | ︙ | |||
231 232 233 234 235 236 237 |
size_t len, /* Protocol message length */
SSL *ssl, /* SSL context */
void *arg) /* Client state for TLS socket */
{
State *statePtr = (State*)arg;
Tcl_Interp *interp = statePtr->interp;
Tcl_Obj *cmdPtr;
| | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
size_t len, /* Protocol message length */
SSL *ssl, /* SSL context */
void *arg) /* Client state for TLS socket */
{
State *statePtr = (State*)arg;
Tcl_Interp *interp = statePtr->interp;
Tcl_Obj *cmdPtr;
const char *ver, *type;
BIO *bio;
char buffer[15000];
Tcl_Size blen = 0;
buffer[0] = 0;
dprintf("Called");
|
| ︙ | ︙ | |||
496 497 498 499 500 501 502 | * Side effects: * none * *------------------------------------------------------------------- */ void KeyLogCallback( | | | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
* Side effects:
* none
*
*-------------------------------------------------------------------
*/
void KeyLogCallback(
TCL_UNUSED(const SSL *), /* Client state for TLS socket */
const char *line) /* Key data to be logged */
{
char *str = getenv(SSLKEYLOGFILE);
FILE *fd;
dprintf("Called");
|
| ︙ | ︙ | |||
711 712 713 714 715 716 717 |
dprintf("Called");
if (ssl == NULL || arg == NULL) {
return SSL_TLSEXT_ERR_NOACK;
}
/* Select protocol */
| | | 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
dprintf("Called");
if (ssl == NULL || arg == NULL) {
return SSL_TLSEXT_ERR_NOACK;
}
/* Select protocol */
if (SSL_select_next_proto((unsigned char **) out, outlen, statePtr->protos, (unsigned)statePtr->protos_len,
in, inlen) == OPENSSL_NPN_NEGOTIATED) {
/* Match found */
res = SSL_TLSEXT_ERR_OK;
} else {
/* OPENSSL_NPN_NO_OVERLAP = No overlap, so use first item from client protocol list */
res = SSL_TLSEXT_ERR_NOACK;
}
|
| ︙ | ︙ | |||
932 933 934 935 936 937 938 |
/* Check if there is sufficient data to extract */
if (remaining <= 2) {
*alert = SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER;
return SSL_CLIENT_HELLO_ERROR;
}
/* Extract the length of the supplied list of names. */
| | | | 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
/* Check if there is sufficient data to extract */
if (remaining <= 2) {
*alert = SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER;
return SSL_CLIENT_HELLO_ERROR;
}
/* Extract the length of the supplied list of names. */
len = (size_t)(*(p++) << 8);
len += *(p++);
if (len + 2 != remaining) {
*alert = SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER;
return SSL_CLIENT_HELLO_ERROR;
}
remaining = len;
/* The list in practice only has a single element, so we only consider the first one. */
if (remaining == 0 || *p++ != TLSEXT_NAMETYPE_host_name) {
*alert = SSL_R_TLSV1_ALERT_INTERNAL_ERROR;
return SSL_CLIENT_HELLO_ERROR;
}
remaining--;
/* Now we can finally pull out the byte array with the actual hostname. */
if (remaining <= 2) {
*alert = SSL_R_TLSV1_ALERT_INTERNAL_ERROR;
return SSL_CLIENT_HELLO_ERROR;
}
len = (size_t)(*(p++) << 8);
len += *(p++);
if (len + 2 > remaining) {
*alert = SSL_R_TLSV1_ALERT_INTERNAL_ERROR;
return SSL_CLIENT_HELLO_ERROR;
}
remaining = len;
servername = (const char *)p;
|
| ︙ | ︙ | |||
1639 1640 1641 1642 1643 1644 1645 |
}
/* Enable Application-Layer Protocol Negotiation. Examples are: http/1.0,
http/1.1, h2, h3, ftp, imap, pop3, xmpp-client, xmpp-server, mqtt, irc, etc. */
if (alpn) {
/* Convert a TCL list into a protocol-list in wire-format */
unsigned char *protos = NULL, *p;
| | | | | | 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 |
}
/* Enable Application-Layer Protocol Negotiation. Examples are: http/1.0,
http/1.1, h2, h3, ftp, imap, pop3, xmpp-client, xmpp-server, mqtt, irc, etc. */
if (alpn) {
/* Convert a TCL list into a protocol-list in wire-format */
unsigned char *protos = NULL, *p;
size_t protos_len = 0;
Tcl_Size cnt, i;
int res = TCL_OK;
Tcl_Obj **list;
if (Tcl_ListObjGetElements(interp, alpn, &cnt, &list) != TCL_OK) {
Tls_Free((tls_free_type *) statePtr);
return TCL_ERROR;
}
/* Determine the memory required for the protocol-list */
for (i = 0; i < cnt; i++) {
Tcl_GetStringFromObj(list[i], &len);
if (len > 255) {
Tcl_AppendResult(interp, "ALPN protocol names too long", (char *)NULL);
Tcl_SetErrorCode(interp, "TLS", "IMPORT", "ALPN", "FAILED", (char *)NULL);
res = TCL_ERROR;
goto done;
}
protos_len += 1 + (size_t)len;
}
/* Build the complete protocol-list */
protos = (unsigned char *)ckalloc(protos_len);
/* protocol-lists consist of 8-bit length-prefixed, byte strings */
for (i = 0, p = protos; i < cnt; i++) {
char *str = Tcl_GetStringFromObj(list[i], &len);
*p++ = (unsigned char) len;
memcpy(p, str, (size_t) len);
p += len;
}
/* SSL_set_alpn_protos makes a copy of the protocol-list */
/* Note: This function reverses the return value convention */
if (SSL_set_alpn_protos(statePtr->ssl, protos, (unsigned)protos_len)) {
Tcl_AppendResult(interp, "Set ALPN protocols failed: ", GET_ERR_REASON(), (char *)NULL);
Tcl_SetErrorCode(interp, "TLS", "IMPORT", "ALPN", "FAILED", (char *)NULL);
res = TCL_ERROR;
}
done: for (i = 0; i < cnt; i++) {
Tcl_IncrRefCount(list[i]);
|
| ︙ | ︙ | |||
1916 1917 1918 1919 1920 1921 1922 |
if (Tcl_ReadChars(in, buf, -1, 0) < 0) {
Tcl_Close(interp, in);
goto cleanup;
}
Tcl_Close(interp, in);
data = (const void *) Tcl_GetByteArrayFromObj(buf, &len);
| | | 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 |
if (Tcl_ReadChars(in, buf, -1, 0) < 0) {
Tcl_Close(interp, in);
goto cleanup;
}
Tcl_Close(interp, in);
data = (const void *) Tcl_GetByteArrayFromObj(buf, &len);
bio = BIO_new_mem_buf(data, (int)len);
if (bio == NULL) {
goto cleanup;
}
/* Where the certs go */
store = SSL_CTX_get_cert_store(ctx);
if (store == NULL) {
|
| ︙ | ︙ | |||
2022 2023 2024 2025 2026 2027 2028 |
char *ciphersuites, /* List of cipher suites */
int level, /* Security level */
char *DHparams) /* DH parameters */
{
Tcl_Interp *interp = statePtr->interp;
SSL_CTX *ctx = NULL;
Tcl_DString ds;
| > | | 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 |
char *ciphersuites, /* List of cipher suites */
int level, /* Security level */
char *DHparams) /* DH parameters */
{
Tcl_Interp *interp = statePtr->interp;
SSL_CTX *ctx = NULL;
Tcl_DString ds;
uint64_t off = 0;
int abort = 0;
int load_private_key;
const SSL_METHOD *method;
dprintf("Called");
if (!proto) {
Tcl_AppendResult(interp, "no valid protocol selected", (char *)NULL);
|
| ︙ | ︙ | |||
2452 2453 2454 2455 2456 2457 2458 |
X509 *peer;
Tcl_Obj *objPtr;
Tcl_Channel chan;
char *channelName, *ciphers;
int mode;
const unsigned char *proto;
unsigned int len;
| | > | 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 |
X509 *peer;
Tcl_Obj *objPtr;
Tcl_Channel chan;
char *channelName, *ciphers;
int mode;
const unsigned char *proto;
unsigned int len;
int nid;
long res;
dprintf("Called");
if (objc < 2 || objc > 3 || (objc == 3 && !strcmp(Tcl_GetString(objv[1]), "-local"))) {
Tcl_WrongNumArgs(interp, 1, objv, "?-local? channel");
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
2797 2798 2799 2800 2801 2802 2803 |
LAPPEND_STR(interp, objPtr, "expansion", "none", -1);
#endif
}
/* Server info */
{
long mode = SSL_CTX_get_session_cache_mode(statePtr->ctx);
| | | 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 |
LAPPEND_STR(interp, objPtr, "expansion", "none", -1);
#endif
}
/* Server info */
{
long mode = SSL_CTX_get_session_cache_mode(statePtr->ctx);
const char *msg;
if (mode & SSL_SESS_CACHE_OFF) {
msg = "off";
} else if (mode & SSL_SESS_CACHE_CLIENT) {
msg = "client";
} else if (mode & SSL_SESS_CACHE_SERVER) {
msg = "server";
|
| ︙ | ︙ | |||
3392 3393 3394 3395 3396 3397 3398 | * Side effects: * Shutdown SSL library * *------------------------------------------------------* */ void TlsLibShutdown( | | | 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 |
* Side effects:
* Shutdown SSL library
*
*------------------------------------------------------*
*/
void TlsLibShutdown(
TCL_UNUSED(ClientData))
{
dprintf("Called");
BIO_cleanup();
}
/*
|
| ︙ | ︙ |
Changes to generic/tlsBIO.c.
| ︙ | ︙ | |||
316 317 318 319 320 321 322 |
dprintf("Got BIO_CTRL_CLOSE");
/* Returns BIO_CLOSE, BIO_NOCLOSE, or <0 for failure. */
ret = BIO_get_shutdown(bio);
break;
case BIO_CTRL_SET_CLOSE:
/* man - Set the close on BIO_free() flag. Implements BIO_set_close. */
dprintf("Got BIO_SET_CLOSE");
| | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
dprintf("Got BIO_CTRL_CLOSE");
/* Returns BIO_CLOSE, BIO_NOCLOSE, or <0 for failure. */
ret = BIO_get_shutdown(bio);
break;
case BIO_CTRL_SET_CLOSE:
/* man - Set the close on BIO_free() flag. Implements BIO_set_close. */
dprintf("Got BIO_SET_CLOSE");
BIO_set_shutdown(bio, (int)num);
/* Returns 1 on success or <=0 for failure. */
ret = 1;
break;
case BIO_CTRL_PENDING:
/* opt - Return number of bytes in chan waiting to be read. Implements BIO_pending. */
dprintf("Got BIO_CTRL_PENDING");
/* Return the amount of pending data or 0 for error. */
|
| ︙ | ︙ |
Changes to generic/tlsIO.c.
| ︙ | ︙ | |||
87 88 89 90 91 92 93 |
* Side effects:
* Closes the socket for the channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsCloseProc(
ClientData instanceData, /* Connection state info */
| | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
* Side effects:
* Closes the socket for the channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsCloseProc(
ClientData instanceData, /* Connection state info */
TCL_UNUSED(Tcl_Interp *)) /* Tcl interpreter to report errors to */
{
State *statePtr = (State *) instanceData;
dprintf("Close(%p)", (void *) statePtr);
/* Send "close notify" shutdown notification. Will return 0 if in progress,
and 1 when complete. Only closes the write direction of the connection;
|
| ︙ | ︙ |
Changes to generic/tlsInt.h.
| ︙ | ︙ | |||
205 206 207 208 209 210 211 | int vflags; /* Verify flags */ SSL *ssl; /* Struct for SSL processing */ SSL_CTX *ctx; /* SSL Context */ BIO *bio; /* Struct for SSL processing */ BIO *p_bio; /* Parent BIO (that is layered on Tcl_Channel) */ | | | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | int vflags; /* Verify flags */ SSL *ssl; /* Struct for SSL processing */ SSL_CTX *ctx; /* SSL Context */ BIO *bio; /* Struct for SSL processing */ BIO *p_bio; /* Parent BIO (that is layered on Tcl_Channel) */ size_t protos_len; /* Length of protos */ unsigned char *protos; /* List of supported protocols in protocol format */ const char *err; } State; #ifdef USE_TCL_STUBS #ifndef Tcl_StackChannel |
| ︙ | ︙ |
Changes to generic/tlsX509.c.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 |
const char *hex = "0123456789abcdef";
if (resultObj == NULL) {
return NULL;
}
for (int i = 0; i < ilen; i++) {
| | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
const char *hex = "0123456789abcdef";
if (resultObj == NULL) {
return NULL;
}
for (int i = 0; i < ilen; i++) {
*dptr++ = (unsigned char)hex[(*iptr>>4)&0xF];
*dptr++ = (unsigned char)hex[(*iptr++)&0xF];
}
return resultObj;
}
/*
*-----------------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
209 210 211 212 213 214 215 | * Purpose string * * Side effects: * None * *----------------------------------------------------------------------------- */ | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
* Purpose string
*
* Side effects:
* None
*
*-----------------------------------------------------------------------------
*/
const char *Tls_x509Purpose(X509 *cert) {
const char *purpose = NULL;
if (X509_check_purpose(cert, X509_PURPOSE_SSL_CLIENT, 0) > 0) {
purpose = "SSL Client";
} else if (X509_check_purpose(cert, X509_PURPOSE_SSL_SERVER, 0) > 0) {
purpose = "SSL Server";
} else if (X509_check_purpose(cert, X509_PURPOSE_NS_SSL_SERVER, 0) > 0) {
purpose = "MSS SSL Server";
|
| ︙ | ︙ | |||
298 299 300 301 302 303 304 |
Tcl_Size len;
char buffer[1024];
if (resultObj == NULL) {
return NULL;
}
| | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
Tcl_Size len;
char buffer[1024];
if (resultObj == NULL) {
return NULL;
}
if ((names = (STACK_OF(GENERAL_NAME) *)X509_get_ext_d2i(cert, nid, NULL, NULL)) != NULL) {
for (int i=0; i < sk_GENERAL_NAME_num(names); i++) {
const GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
len = BIO_to_Buffer(name && GENERAL_NAME_print(bio, (GENERAL_NAME *) name), bio, buffer, 1024);
LAPPEND_STR(interp, resultObj, NULL, buffer, len);
}
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
|
| ︙ | ︙ | |||
392 393 394 395 396 397 398 |
STACK_OF(DIST_POINT) *crl;
Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL);
if (resultObj == NULL) {
return NULL;
}
| | | | 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
STACK_OF(DIST_POINT) *crl;
Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL);
if (resultObj == NULL) {
return NULL;
}
if ((crl = (STACK_OF(DIST_POINT) *)X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL)) != NULL) {
for (int i=0; i < sk_DIST_POINT_num(crl); i++) {
DIST_POINT *dp = sk_DIST_POINT_value(crl, i);
DIST_POINT_NAME *distpoint = dp->distpoint;
if (distpoint->type == 0) {
/* full-name GENERALIZEDNAME */
for (int j = 0; j < sk_GENERAL_NAME_num(distpoint->name.fullname); j++) {
GENERAL_NAME *gen = sk_GENERAL_NAME_value(distpoint->name.fullname, j);
int type;
ASN1_STRING *uri = (ASN1_STRING *)GENERAL_NAME_get0_value(gen, &type);
if (type == GEN_URI) {
LAPPEND_STR(interp, resultObj, (char *) NULL, (char *) ASN1_STRING_get0_data(uri), (Tcl_Size) ASN1_STRING_length(uri));
}
}
} else if (distpoint->type == 1) {
/* relative-name X509NAME */
STACK_OF(X509_NAME_ENTRY) *sk_relname = distpoint->name.relativename;
|
| ︙ | ︙ | |||
479 480 481 482 483 484 485 |
Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL);
unsigned char *buf;
if (resultObj == NULL) {
return NULL;
}
| | | | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL);
unsigned char *buf;
if (resultObj == NULL) {
return NULL;
}
if ((ads = (STACK_OF(ACCESS_DESCRIPTION) *)X509_get_ext_d2i(cert, NID_info_access, NULL, NULL)) != NULL) {
for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(ads); i++) {
ad = (ACCESS_DESCRIPTION *)sk_ACCESS_DESCRIPTION_value(ads, i);
if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers && ad->location) {
if (ad->location->type == GEN_URI) {
Tcl_Size len = (Tcl_Size) ASN1_STRING_to_UTF8(&buf, ad->location->d.uniformResourceIdentifier);
Tcl_ListObjAppendElement(interp, resultObj, Tcl_NewStringObj((char *) buf, len));
OPENSSL_free(buf);
break;
}
|
| ︙ | ︙ | |||
520 521 522 523 524 525 526 |
Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL);
BIO *bio = BIO_new(BIO_s_mem());
int mdnid, pknid, bits;
Tcl_Size len;
unsigned int ulen;
uint32_t xflags;
unsigned long flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT;
| | | | 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
Tcl_Obj *resultObj = Tcl_NewListObj(0, NULL);
BIO *bio = BIO_new(BIO_s_mem());
int mdnid, pknid, bits;
Tcl_Size len;
unsigned int ulen;
uint32_t xflags;
unsigned long flags = XN_FLAG_RFC2253 | ASN1_STRFLGS_UTF8_CONVERT;
flags &= ~(unsigned long)ASN1_STRFLGS_ESC_MSB;
char *buffer = (char *)ckalloc(BUFSIZ > EVP_MAX_MD_SIZE ? BUFSIZ : EVP_MAX_MD_SIZE);
dprintf("Called");
if (interp == NULL || cert == NULL || bio == NULL || resultObj == NULL || buffer == NULL) {
Tcl_DecrRefCount(resultObj);
BIO_free(bio);
if (buffer != NULL) ckfree(buffer);
|
| ︙ | ︙ |