@@ -21,11 +21,13 @@ * */ #include "tlsInt.h" #include "tclOpts.h" +#include #include +#include /* * External functions */ @@ -37,13 +39,13 @@ (((key) == NULL) ? (char *) NULL : \ Tcl_TranslateFileName(interp, (key), (dsp))) #define REASON() ERR_reason_error_string(ERR_get_error()) static SSL_CTX *CTX_Init(State *statePtr, int isServer, int proto, char *key, - char *certfile, unsigned char *key_asn1, unsigned char *cert_asn1, - int key_asn1_len, int cert_asn1_len, char *CAdir, char *CAfile, - char *ciphers, char *DHparams); + char *certfile, unsigned char *key_asn1, unsigned char *cert_asn1, + int key_asn1_len, int cert_asn1_len, char *CAdir, char *CAfile, + char *ciphers, char *DHparams); static int TlsLibInit(int uninitialize); #define TLS_PROTO_SSL2 0x01 #define TLS_PROTO_SSL3 0x02 @@ -90,19 +92,23 @@ #define OPENSSL_THREAD_DEFINES #include #ifdef OPENSSL_THREADS #include +/* Added */ +#include /* * Threaded operation requires locking callbacks * Based from /crypto/cryptlib.c of OpenSSL and NSOpenSSL. */ static Tcl_Mutex *locks = NULL; static int locksCount = 0; static Tcl_Mutex init_mx; + +# if OPENSSL_VERSION_NUMBER < 0x10100000L void CryptoThreadLockCallback(int mode, int n, const char *file, int line) { if (mode & CRYPTO_LOCK) { /* This debugging is turned off by default -- it's too noisy. */ @@ -129,10 +135,11 @@ dprintf("Returning %lu", ret); return(ret); } +#endif #endif /* OPENSSL_THREADS */ #endif /* TCL_THREADS */ /* @@ -428,11 +435,11 @@ * variable to access the Tcl interpreter. */ static int PasswordCallback(char *buf, int size, int verify) { return -1; - buf = buf; + buf = buf; size = size; verify = verify; } #else static int @@ -474,15 +481,15 @@ Tcl_Release((ClientData) statePtr); if (code == TCL_OK) { char *ret = (char *) Tcl_GetStringResult(interp); if (strlen(ret) < size - 1) { - strncpy(buf, ret, (size_t) size); + strncpy(buf, ret, (size_t) size); Tcl_Release((ClientData) interp); - return (int)strlen(ret); + return (int)strlen(ret); } - } + } Tcl_Release((ClientData) interp); return -1; } #endif @@ -517,66 +524,66 @@ char *cp, buf[BUFSIZ]; int index, verbose = 0; dprintf("Called"); - if (objc < 2 || objc > 3) { + if ((objc < 2) || (objc > 3)) { Tcl_WrongNumArgs(interp, 1, objv, "protocol ?verbose?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj( interp, objv[1], protocols, "protocol", 0, &index) != TCL_OK) { return TCL_ERROR; } - if (objc > 2 && Tcl_GetBooleanFromObj( interp, objv[2], + if ((objc > 2) && Tcl_GetBooleanFromObj( interp, objv[2], &verbose) != TCL_OK) { return TCL_ERROR; } switch ((enum protocol)index) { case TLS_SSL2: -#if defined(NO_SSL2) +#if OPENSSL_VERSION_NUMBER >= 0x10101000L || defined(NO_SSL2) || defined(OPENSSL_NO_SSL2) Tcl_AppendResult(interp, protocols[index], ": protocol not supported", NULL); return TCL_ERROR; #else ctx = SSL_CTX_new(SSLv2_method()); break; #endif case TLS_SSL3: -#if defined(NO_SSL3) +#if defined(NO_SSL3) || defined(OPENSSL_NO_SSL3) Tcl_AppendResult(interp, protocols[index], ": protocol not supported", NULL); return TCL_ERROR; #else ctx = SSL_CTX_new(SSLv3_method()); break; #endif case TLS_TLS1: -#if defined(NO_TLS1) +#if defined(NO_TLS1) || defined(OPENSSL_NO_TLS1) Tcl_AppendResult(interp, protocols[index], ": protocol not supported", NULL); return TCL_ERROR; #else ctx = SSL_CTX_new(TLSv1_method()); break; #endif case TLS_TLS1_1: -#if defined(NO_TLS1_1) +#if defined(NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1) Tcl_AppendResult(interp, protocols[index], ": protocol not supported", NULL); return TCL_ERROR; #else ctx = SSL_CTX_new(TLSv1_1_method()); break; #endif case TLS_TLS1_2: -#if defined(NO_TLS1_2) +#if defined(NO_TLS1_2) || defined(OPENSSL_NO_TLS1_2) Tcl_AppendResult(interp, protocols[index], ": protocol not supported", NULL); return TCL_ERROR; #else ctx = SSL_CTX_new(TLSv1_2_method()); break; #endif case TLS_TLS1_3: -#if defined(NO_TLS1_3) +#if defined(NO_TLS1_3) || defined(OPENSSL_NO_TLS1_3) Tcl_AppendResult(interp, protocols[index], ": protocol not supported", NULL); return TCL_ERROR; #else ctx = SSL_CTX_new(TLS_method()); SSL_CTX_set_min_proto_version (ctx, TLS1_3_VERSION); - SSL_CTX_set_max_proto_version (ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version (ctx, TLS1_3_VERSION); break; #endif default: break; } @@ -605,12 +612,12 @@ for (index = 0; index < sk_SSL_CIPHER_num(sk); index++) { register size_t i; SSL_CIPHER_description( sk_SSL_CIPHER_value( sk, index), buf, sizeof(buf)); for (i = strlen(buf) - 1; i ; i--) { - if (buf[i] == ' ' || buf[i] == '\n' || - buf[i] == '\r' || buf[i] == '\t') { + if ((buf[i] == ' ') || (buf[i] == '\n') || + (buf[i] == '\r') || (buf[i] == '\t')) { buf[i] = '\0'; } else { break; } } @@ -621,11 +628,11 @@ SSL_free(ssl); SSL_CTX_free(ctx); Tcl_SetObjResult( interp, objPtr); return TCL_OK; - clientData = clientData; + clientData = clientData; } /* *------------------------------------------------------------------- * @@ -682,11 +689,11 @@ } else if (ret < 0) { errStr = statePtr->err; Tcl_ResetResult(interp); Tcl_SetErrno(err); - if (!errStr || *errStr == 0) { + if (!errStr || (*errStr == 0)) { errStr = Tcl_PosixError(interp); } Tcl_AppendResult(interp, "handshake failed: ", errStr, (char *) NULL); dprintf("Returning TCL_ERROR with handshake failed: %s", errStr); @@ -701,11 +708,11 @@ dprintf("Returning TCL_OK with data \"%i\"", ret); Tcl_SetObjResult(interp, Tcl_NewIntObj(ret)); return(TCL_OK); - clientData = clientData; + clientData = clientData; } /* *------------------------------------------------------------------- * @@ -755,26 +762,26 @@ int proto = 0; int verify = 0, require = 0, request = 1; dprintf("Called"); -#if defined(NO_TLS1) && defined(NO_TLS1_1) && defined(NO_TLS1_2) && defined(NO_SSL3) && !defined(NO_SSL2) +#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(OPENSSL_NO_SSL2) && defined(NO_TLS1) && defined(NO_TLS1_1) && defined(NO_TLS1_2) && defined(NO_TLS1_3) && defined(NO_SSL3) && !defined(NO_SSL2) ssl2 = 1; #endif -#if defined(NO_TLS1) && defined(NO_TLS1_1) && defined(NO_TLS1_2) && defined(NO_SSL2) && !defined(NO_SSL3) +#if !defined(OPENSSL_NO_SSL3) && defined(NO_TLS1) && defined(NO_TLS1_1) && defined(NO_TLS1_2) && defined(NO_TLS1_3) && defined(NO_SSL2) && !defined(NO_SSL3) ssl3 = 1; #endif -#if defined(NO_TLS1) +#if defined(NO_TLS1) || defined(OPENSSL_NO_TLS1) tls1 = 0; #endif -#if defined(NO_TLS1_1) +#if defined(NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1) tls1_1 = 0; #endif -#if defined(NO_TLS1_2) +#if defined(NO_TLS1_2) || defined(OPENSSL_NO_TLS1_2) tls1_2 = 0; #endif -#if defined(NO_TLS1_3) +#if defined(NO_TLS1_3) || defined(OPENSSL_NO_TLS1_3) tls1_3 = 0; #endif if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "channel ?options?"); @@ -808,11 +815,11 @@ OPTOBJ( "-password", password); OPTBOOL( "-require", require); OPTBOOL( "-request", request); OPTBOOL( "-server", server); #ifndef OPENSSL_NO_TLSEXT - OPTSTR( "-servername", servername); + OPTSTR( "-servername", servername); OPTOBJ( "-alpn", alpn); #endif OPTBOOL( "-ssl2", ssl2); OPTBOOL( "-ssl3", ssl3); @@ -821,11 +828,11 @@ OPTBOOL( "-tls1.2", tls1_2); OPTBOOL( "-tls1.3", tls1_3); OPTBYTE("-cert", cert, cert_len); OPTBYTE("-key", key, key_len); - OPTBAD( "option", "-alpn, -cadir, -cafile, -cert, -certfile, -cipher, -command, -dhparams, -key, -keyfile, -model, -password, -require, -request, -server, -servername, -ssl2, -ssl3, -tls1, -tls1.1, -tls1.2, or tls1.3"); + OPTBAD( "option", "-alpn, -cadir, -cafile, -cert, -certfile, -cipher, -command, -dhparams, -key, -keyfile, -model, -password, -require, -request, -server, -servername, -ssl2, -ssl3, -tls1, -tls1.1, -tls1.2, or -tls1.3"); return TCL_ERROR; } if (request) verify |= SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_PEER; if (request && require) verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; @@ -882,14 +889,14 @@ if (chan == (Tcl_Channel) NULL) { Tls_Free((char *) statePtr); return TCL_ERROR; } - /* - * Make sure to operate on the topmost channel - */ - chan = Tcl_GetTopChannel(chan); + /* + * Make sure to operate on the topmost channel + */ + chan = Tcl_GetTopChannel(chan); if (Tcl_GetChannelType(chan) != Tls_ChannelType()) { Tcl_AppendResult(interp, "bad channel \"", Tcl_GetChannelName(chan), "\": not a TLS channel", NULL); Tls_Free((char *) statePtr); return TCL_ERROR; @@ -950,16 +957,16 @@ return TCL_ERROR; } #ifndef OPENSSL_NO_TLSEXT if (servername) { - if (!SSL_set_tlsext_host_name(statePtr->ssl, servername) && require) { - Tcl_AppendResult(interp, "setting TLS host name extension failed", - (char *) NULL); - Tls_Free((char *) statePtr); - return TCL_ERROR; - } + if (!SSL_set_tlsext_host_name(statePtr->ssl, servername) && require) { + Tcl_AppendResult(interp, "setting TLS host name extension failed", + (char *) NULL); + Tls_Free((char *) statePtr); + return TCL_ERROR; + } } if (alpn) { /* Convert a Tcl list into a protocol-list in wire-format */ unsigned char *protos, *p; unsigned int protoslen = 0; @@ -1030,11 +1037,11 @@ */ dprintf("Returning %s", Tcl_GetChannelName(statePtr->self)); Tcl_SetResult(interp, (char *) Tcl_GetChannelName(statePtr->self), TCL_VOLATILE); return TCL_OK; - clientData = clientData; + clientData = clientData; } /* *------------------------------------------------------------------- * @@ -1081,11 +1088,11 @@ if (Tcl_UnstackChannel(interp, chan) == TCL_ERROR) { return TCL_ERROR; } return TCL_OK; - clientData = clientData; + clientData = clientData; } /* *------------------------------------------------------------------- * @@ -1118,130 +1125,134 @@ Tcl_AppendResult(interp, "no valid protocol selected", NULL); return (SSL_CTX *)0; } /* create SSL context */ -#if defined(NO_SSL2) +#if OPENSSL_VERSION_NUMBER >= 0x10101000L || defined(NO_SSL2) || defined(OPENSSL_NO_SSL2) if (ENABLED(proto, TLS_PROTO_SSL2)) { Tcl_AppendResult(interp, "SSL2 protocol not supported", NULL); return (SSL_CTX *)0; } #endif -#if defined(NO_SSL3) +#if defined(NO_SSL3) || defined(OPENSSL_NO_SSL3) if (ENABLED(proto, TLS_PROTO_SSL3)) { Tcl_AppendResult(interp, "SSL3 protocol not supported", NULL); return (SSL_CTX *)0; } #endif -#if defined(NO_TLS1) +#if defined(NO_TLS1) || defined(OPENSSL_NO_TLS1) if (ENABLED(proto, TLS_PROTO_TLS1)) { Tcl_AppendResult(interp, "TLS 1.0 protocol not supported", NULL); return (SSL_CTX *)0; } #endif -#if defined(NO_TLS1_1) +#if defined(NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1) if (ENABLED(proto, TLS_PROTO_TLS1_1)) { Tcl_AppendResult(interp, "TLS 1.1 protocol not supported", NULL); return (SSL_CTX *)0; } #endif -#if defined(NO_TLS1_2) +#if defined(NO_TLS1_2) || defined(OPENSSL_NO_TLS1_2) if (ENABLED(proto, TLS_PROTO_TLS1_2)) { Tcl_AppendResult(interp, "TLS 1.2 protocol not supported", NULL); return (SSL_CTX *)0; } #endif -#if defined(NO_TLS1_3) +#if defined(NO_TLS1_3) || defined(OPENSSL_NO_TLS1_3) if (ENABLED(proto, TLS_PROTO_TLS1_3)) { Tcl_AppendResult(interp, "TLS 1.3 protocol not supported", NULL); return (SSL_CTX *)0; } #endif switch (proto) { -#if !defined(NO_SSL2) +#if OPENSSL_VERSION_NUMBER < 0x10101000L && !defined(NO_SSL2) && !defined(OPENSSL_NO_SSL2) case TLS_PROTO_SSL2: method = SSLv2_method(); break; #endif -#if !defined(NO_SSL3) +#if !defined(NO_SSL3) && !defined(OPENSSL_NO_SSL3) case TLS_PROTO_SSL3: method = SSLv3_method(); break; #endif -#if !defined(NO_TLS1) +#if !defined(NO_TLS1) && !defined(OPENSSL_NO_TLS1) case TLS_PROTO_TLS1: method = TLSv1_method(); break; #endif -#if !defined(NO_TLS1_1) +#if !defined(NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_1) case TLS_PROTO_TLS1_1: method = TLSv1_1_method(); break; #endif -#if !defined(NO_TLS1_2) +#if !defined(NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_2) case TLS_PROTO_TLS1_2: method = TLSv1_2_method(); break; #endif -#if !defined(NO_TLS1_3) +#if !defined(NO_TLS1_3) && !defined(OPENSSL_NO_TLS1_3) case TLS_PROTO_TLS1_3: - /* - * The version range is constrained below, - * after the context is created. Use the - * generic method here. - */ + /* + * The version range is constrained below, + * after the context is created. Use the + * generic method here. + */ method = TLS_method(); break; #endif default: -#ifdef HAVE_TLS_METHOD - method = TLS_method(); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + /* Negotiate highest available SSL/TLS version */ + method = TLS_method(); #else - method = SSLv23_method(); + method = SSLv23_method(); #endif -#if !defined(NO_SSL2) +#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(NO_SSL2) && !defined(OPENSSL_NO_SSL2) off |= (ENABLED(proto, TLS_PROTO_SSL2) ? 0 : SSL_OP_NO_SSLv2); #endif -#if !defined(NO_SSL3) +#if !defined(NO_SSL3) && !defined(OPENSSL_NO_SSL3) off |= (ENABLED(proto, TLS_PROTO_SSL3) ? 0 : SSL_OP_NO_SSLv3); #endif -#if !defined(NO_TLS1) +#if !defined(NO_TLS1) && !defined(OPENSSL_NO_TLS1) off |= (ENABLED(proto, TLS_PROTO_TLS1) ? 0 : SSL_OP_NO_TLSv1); #endif -#if !defined(NO_TLS1_1) +#if !defined(NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_1) off |= (ENABLED(proto, TLS_PROTO_TLS1_1) ? 0 : SSL_OP_NO_TLSv1_1); #endif -#if !defined(NO_TLS1_2) +#if !defined(NO_TLS1_2) && !defined(OPENSSL_NO_TLS1_2) off |= (ENABLED(proto, TLS_PROTO_TLS1_2) ? 0 : SSL_OP_NO_TLSv1_2); #endif -#if !defined(NO_TLS1_3) +#if !defined(NO_TLS1_3) && !defined(OPENSSL_NO_TLS1_3) off |= (ENABLED(proto, TLS_PROTO_TLS1_3) ? 0 : SSL_OP_NO_TLSv1_3); #endif break; } ctx = SSL_CTX_new(method); if (!ctx) { - return(NULL); + return(NULL); } if (getenv(SSLKEYLOGFILE)) { SSL_CTX_set_keylog_callback(ctx, KeyLogCallback); } -#if !defined(NO_TLS1_3) +#if !defined(NO_TLS1_3) && !defined(OPENSSL_NO_TLS1_3) if (proto == TLS_PROTO_TLS1_3) { - SSL_CTX_set_min_proto_version (ctx, TLS1_3_VERSION); - SSL_CTX_set_max_proto_version (ctx, TLS1_3_VERSION); + SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION); } #endif SSL_CTX_set_app_data( ctx, (void*)interp); /* remember the interpreter */ SSL_CTX_set_options( ctx, SSL_OP_ALL); /* all SSL bug workarounds */ SSL_CTX_set_options( ctx, off); /* all SSL bug workarounds */ +#if OPENSSL_VERSION_NUMBER < 0x10101000L + SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); /* handle new handshakes in background */ +#endif SSL_CTX_sess_set_cache_size( ctx, 128); if (ciphers != NULL) SSL_CTX_set_cipher_list(ctx, ciphers); @@ -1398,11 +1409,11 @@ } /* https://sourceforge.net/p/tls/bugs/57/ */ /* XXX:TODO: Let the user supply values here instead of something that exists on the filesystem */ if ( CAfile != NULL ) { - STACK_OF(X509_NAME) *certNames = SSL_load_client_CA_file( F2N(CAfile, &ds) ); + STACK_OF(X509_NAME) *certNames = SSL_load_client_CA_file( F2N(CAfile, &ds) ); if ( certNames != NULL ) { SSL_CTX_set_client_CA_list(ctx, certNames ); } } @@ -1488,11 +1499,11 @@ Tcl_NewStringObj ("sbits", -1)); Tcl_ListObjAppendElement (interp, objPtr, Tcl_NewIntObj (SSL_get_cipher_bits (statePtr->ssl, NULL))); ciphers = (char*)SSL_get_cipher(statePtr->ssl); - if (ciphers != NULL && strcmp(ciphers, "(NONE)")!=0) { + 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)); } @@ -1510,11 +1521,11 @@ Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(SSL_get_version(statePtr->ssl), -1)); Tcl_SetObjResult( interp, objPtr); return TCL_OK; - clientData = clientData; + clientData = clientData; } /* *------------------------------------------------------------------- * @@ -1536,13 +1547,13 @@ objPtr = Tcl_NewStringObj(OPENSSL_VERSION_TEXT, -1); Tcl_SetObjResult(interp, objPtr); return TCL_OK; - clientData = clientData; - objc = objc; - objv = objv; + clientData = clientData; + objc = objc; + objv = objv; } /* *------------------------------------------------------------------- * @@ -1586,10 +1597,19 @@ BIO *out=NULL; char *k_C="",*k_ST="",*k_L="",*k_O="",*k_OU="",*k_CN="",*k_Email=""; char *keyout,*pemout,*str; int keysize,serial=0,days=365; + +#if OPENSSL_VERSION_NUMBER <= 0x10100000L + RSA *rsa = NULL; +#elif OPENSSL_VERSION_NUMBER < 0x30000000L + BIGNUM *bne = NULL; + RSA *rsa = NULL; +#else + EVP_PKEY_CTX *ctx = NULL; +#endif if ((objc<5) || (objc>6)) { Tcl_WrongNumArgs(interp, 2, objv, "keysize keyfile certfile ?info?"); return TCL_ERROR; } @@ -1640,18 +1660,37 @@ Tcl_SetResult(interp,"Unknown parameter",NULL); return TCL_ERROR; } } } - if ((pkey = EVP_PKEY_new()) != NULL) { - if (!EVP_PKEY_assign_RSA(pkey, - RSA_generate_key(keysize, 0x10001, NULL, NULL))) { - Tcl_SetResult(interp,"Error generating private key",NULL); - EVP_PKEY_free(pkey); - return TCL_ERROR; - } - + +#if OPENSSL_VERSION_NUMBER <= 0x10100000L + pkey = EVP_PKEY_new(); + rsa = RSA_generate_key(keysize, 0x10001, NULL, NULL); + if (pkey == NULL || rsa == NULL || !EVP_PKEY_assign_RSA(pkey, rsa)) { + EVP_PKEY_free(pkey); + /* RSA_free(rsa); freed by EVP_PKEY_free */ +#elif OPENSSL_VERSION_NUMBER < 0x30000000L + bne = BN_new(); + rsa = RSA_new(); + pkey = EVP_PKEY_new(); + if (bne == NULL || rsa == NULL || pkey == NULL || !BN_set_word(bne,RSA_F4) || + !RSA_generate_key_ex(rsa, keysize, bne, NULL) || !EVP_PKEY_assign_RSA(pkey, rsa)) { + EVP_PKEY_free(pkey); + /* RSA_free(rsa); freed by EVP_PKEY_free */ + BN_free(bne); +#else + pkey = EVP_RSA_gen((unsigned int) keysize); + ctx = EVP_PKEY_CTX_new(pkey,NULL); + if (pkey == NULL || ctx == NULL || !EVP_PKEY_keygen_init(ctx) || + !EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keysize) || !EVP_PKEY_keygen(ctx, &pkey)) { + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); +#endif + Tcl_SetResult(interp,"Error generating private key",NULL); + return TCL_ERROR; + } else { if (isStr) { out=BIO_new(BIO_s_mem()); PEM_write_bio_PrivateKey(out,pkey,NULL,NULL,0,NULL,NULL); i=BIO_read(out,buffer,sizeof(buffer)-1); i=(i<0) ? 0 : i; @@ -1661,23 +1700,32 @@ BIO_free(out); } else { out=BIO_new(BIO_s_file()); BIO_write_filename(out,keyout); PEM_write_bio_PrivateKey(out,pkey,NULL,NULL,0,NULL,NULL); + /* PEM_write_bio_RSAPrivateKey(out, rsa, NULL, NULL, 0, NULL, NULL); */ BIO_free_all(out); - } + } if ((cert=X509_new())==NULL) { Tcl_SetResult(interp,"Error generating certificate request",NULL); EVP_PKEY_free(pkey); +#if OPENSSL_VERSION_NUMBER > 0x10100000L && OPENSSL_VERSION_NUMBER < 0x30000000L + BN_free(bne); +#endif return(TCL_ERROR); } X509_set_version(cert,2); ASN1_INTEGER_set(X509_get_serialNumber(cert),serial); +#if OPENSSL_VERSION_NUMBER < 0x10100000L X509_gmtime_adj(X509_get_notBefore(cert),0); X509_gmtime_adj(X509_get_notAfter(cert),(long)60*60*24*days); +#else + X509_gmtime_adj(X509_getm_notBefore(cert),0); + X509_gmtime_adj(X509_getm_notAfter(cert),(long)60*60*24*days); +#endif X509_set_pubkey(cert,pkey); name=X509_get_subject_name(cert); X509_NAME_add_entry_by_txt(name,"C", MBSTRING_ASC, (const unsigned char *) k_C, -1, -1, 0); @@ -1688,13 +1736,16 @@ X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (const unsigned char *) k_CN, -1, -1, 0); X509_NAME_add_entry_by_txt(name,"Email", MBSTRING_ASC, (const unsigned char *) k_Email, -1, -1, 0); X509_set_subject_name(cert,name); - if (!X509_sign(cert,pkey,EVP_sha1())) { + if (!X509_sign(cert,pkey,EVP_sha256())) { X509_free(cert); EVP_PKEY_free(pkey); +#if OPENSSL_VERSION_NUMBER > 0x10100000L && OPENSSL_VERSION_NUMBER < 0x30000000L + BN_free(bne); +#endif Tcl_SetResult(interp,"Error signing certificate",NULL); return TCL_ERROR; } if (isStr) { @@ -1713,13 +1764,13 @@ BIO_free_all(out); } X509_free(cert); EVP_PKEY_free(pkey); - } else { - Tcl_SetResult(interp,"Error generating private key",NULL); - return TCL_ERROR; +#if OPENSSL_VERSION_NUMBER > 0x10100000L && OPENSSL_VERSION_NUMBER < 0x30000000L + BN_free(bne); +#endif } } break; default: break; @@ -1828,14 +1879,14 @@ */ DLLEXPORT int Tls_Init(Tcl_Interp *interp) { const char tlsTclInitScript[] = { #include "tls.tcl.h" - 0x00 + 0x00 }; - dprintf("Called"); + dprintf("Called"); /* * We only support Tcl 8.4 or newer */ if ( @@ -1926,12 +1977,17 @@ dprintf("Asked to uninitialize"); #if defined(OPENSSL_THREADS) && defined(TCL_THREADS) Tcl_MutexLock(&init_mx); +#if OPENSSL_VERSION_NUMBER < 0x10000000L CRYPTO_set_locking_callback(NULL); CRYPTO_set_id_callback(NULL); +#elif OPENSSL_VERSION_NUMBER < 0x10100000L + CRYPTO_set_locking_callback(NULL); + CRYPTO_THREADID_set_callback(NULL) +#endif if (locks) { free(locks); locks = NULL; locksCount = 0; @@ -1957,26 +2013,46 @@ Tcl_MutexLock(&init_mx); #endif initialized = 1; #if defined(OPENSSL_THREADS) && defined(TCL_THREADS) +#if OPENSSL_VERSION_NUMBER < 0x10100000L num_locks = CRYPTO_num_locks(); - locksCount = num_locks; +#else + num_locks = 1; +#endif + locksCount = (int) num_locks; locks = malloc(sizeof(*locks) * num_locks); memset(locks, 0, sizeof(*locks) * num_locks); +#if OPENSSL_VERSION_NUMBER < 0x10000000L CRYPTO_set_locking_callback(CryptoThreadLockCallback); CRYPTO_set_id_callback(CryptoThreadIdCallback); +#elif OPENSSL_VERSION_NUMBER < 0x10100000L + CRYPTO_set_locking_callback(CryptoThreadLockCallback); + CRYPTO_THREADID_set_callback(CryptoThreadIdCallback) +#endif #endif +# if OPENSSL_VERSION_NUMBER < 0x10100000L if (SSL_library_init() != 1) { status = TCL_ERROR; goto done; } +#else + /* Initialize BOTH libcrypto and libssl. */ + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS + | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); +#endif +# if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_load_error_strings(); ERR_load_crypto_strings(); +#else + /* Only initialize libcrypto */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#endif BIO_new_tcl(NULL, 0); #if 0 /* @@ -2001,12 +2077,14 @@ } RAND_seed(rnd_seed, sizeof(rnd_seed)); } while (RAND_status() != 1); #endif +# if OPENSSL_VERSION_NUMBER < 0x10100000L done: +#endif #if defined(OPENSSL_THREADS) && defined(TCL_THREADS) Tcl_MutexUnlock(&init_mx); #endif return(status); }