mIRC Home    About    Download    Register    News    Help

Print Thread
Extra options for certificates #269593 12/11/21 10:39 PM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
These are feature requests related to user-created certificates, a topic of which I admit my knowledge of the topic is limited. But there's not much on this forum discussing them. Some of these changes might be bordering on bug fixes.

1. Not sure which is the simplest way to extend $sslcertsha256 to support other hashes. SwiftIRC uses the sha256 fingerprint returned by $sslcertsha256, but Libera.Chat wants to know the sha512 fingerprint instead. Even though I never set up a NickServ account at Snoonet, /whois showed me the md5 fingerprint of the certificate I'd just created before I connected to them, and I didn't have the login method set to SASL External, so I'm assuming that's the fingerprint they want for SASL External. Maybe allow $sslcertsha256 to have an optional parameter where we can give it another hashname, and the default is sha256 without it?

$sslcertsha256(md5) $sslcertsha256(sha512) etc

The need for a new identifier may not be critical since many networks supporting SASL External have the /whois reply show us the fingerprint of the certificate we're broadcasting when we connected. But Rizon's /whois just tells us that we're using a client certificate without showing us the fingerprint. And, at Libera we can use "/NickServ cert add" and it will automagically add the fingerprint for the certificate broadcasted when we connected.

2. Could there be documentation in /help for how to use the certificate mIRC creates? The F1 /help has little mention of certificates, with the topic for the connect/options/SSL dialog linking to a webpage that makes no mention of certificates.

3a. The SASL External protocol does not use the NickServ password like SASL Plain does, so the password box below the 'Login method' in the serverlist editor should have the password grey'ed out unless the dropdown is selecting one of the other 3 choices who actually do use the password.

3b. The box for entering the password, below the 'Login Method' dropdown, shows only bullet symbols when inputting the password, so I'm sure many SASL Plain users would find it helpful if there were a checkbox to the side of the dialog which could be checked to see the password text while entering it. I understand there can be security reasons for not showing the password that's been previously entered, but at the very least it could allow people to see the password while it's being entered. That avoids people 'solving' the problem by typing their password into an editbox so they can inspect it before copypasting it in the entry box.

4. After being confused for a while, I finally figured out that SASL External apparently doesn't work if connecting to a non-SSL port, so it would help avoid user confusion if that were included in any /help documentation about certificates, and/or giving an FYI message when saving the serverlist edit while the port/login-method don't appear to be compatible.

5. When having mIRC create our certificate instead of using OpenSSL.exe directly, is there a mirc.ini setting to allow people to define the RSA key size for the certificate that mIRC makes?

The CertFP instructions at Libera.Chat is asking people to create an RSA 4096 certificate, but as far as i can tell, mIRC creates only 2048's - though Libera will accept those. I'm guessing the 2048 choice is a 'one size fits all' that a larger group of networks on the serverlist will support.

6. It would be great if the serverlist editor allows entering a local certificate that overrides the universal certificate that was created in connect/options/SSL, or a serverlist checkbox to prevent the universal certificate from even being broadcast to specific networks.

It appears that, once we've configured mIRC to have a universal certificate, the only choices are to allow that universal certificate to be broadcast to all other networks, or use the /server -k scripting command to override that by telling it to broacast a different local certificate to that network, or to avoid using an SSL port because that blocks the certificate from being enabled at that network - though the public certificate may or may not be sent to the server in the failed handshake.

With this behavior of not letting us connect to any SSL port without broadcasting a certificate, once we've isntalled a universal certificate that we're only using at 1 network for SASL External, it allows us to be fingerprinted so all other networks can identify us across repeated visits regardless of which IP address or nick we're using. In effect it creates a universal cookie that all networks can see.

Currently, this can be avoided only with the /server command, and only partially.

/server servername +port -l external -k filename.pem

... lets us use a local certificate at that network while a different network uses the universal certificate, but I don't see anything in the serverlist editor which lets us do the same. While a universal certificate has been installed, these following attempts to block it from being used at 1 specific network all fail.

This attempt halted the script:

/server servername +port -k NoSuchFile.pem

This attempt didn't halt the script, but it refuses to connect at all:

/server servername +port -k FileWithoutCertificate.pem

This attempt just ignored the -k switch and used the universal certificate:

/server servername +port -k

Probably the last one is the most appropriate syntax which would connect to an SSL port without broadcasting any certificate at all, since the intent of using -k is obviously to not want to use the universal certificate.

If it's considered a problem that using -k %variable could have unwanted results due to the variable being $null, that could be avoided by using $$+(%variable) or by using a different switch following -k %variable, which causes a missing -k parameter to trigger a syntax error

So it seems the only way to have an SASL External certificate used by 1 network without forcing all other networks using a +SSL port to broadcast a certificate is to have mIRC create a certificate, where the menu immediately tries to use it as the universal certificate. We'd then clear that certificate from being displayed in the options menu as the universal certificate. Then, we can't connect to that 1 network using the serverlist, and must instead use a script in order to connect to them using /server -k file.pem

I know there can be uses for broadcasting certificates other than for SASL External. I once had admin privileges at a network, where the OPER command wouldn't work unless I was connecting from a specific IP address. I'm guessing by now the ircd's have settings to use a certificate to validate us instead. However, that shouldn't be a reason for all other users to broadcast the certificate 'cookie' to all other networks too.

Since a local certificate would be server related, it seems more appropriate for that to be kept in the serverlist instead of mirc.ini, probably in a new [section] of servers.ini, where there would be new choices to either define a local certificate for that network, or to avoid having the universal certificate being broadcast to that network, which I'd think should be the default choice anyway.

Re: Extra options for certificates [Re: maroon] #269791 26/01/22 10:32 PM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
Update to the original suggestions.

#1. $sslhash provides most of Item#1. I know it seems kinda silly to support md5 here, but as I mentioned in the original feature suggestion, Snoonet uses the md5 fingerprint. This is just an observation, as I don't use Snoonet, but I know people who do.

#5. I see we can now create RSA certs at 3 different lengths. It would be great if the new $sslhash has additional .prop to give additional info about the active cert:

* expiration date
* type and bit length

Since an RSA key can be created by OpenSSL, the bit length doesn't necessarily match one of the choices offered by mIRC.

#6. Related to avoiding being fingerprinted by an installed certificate being broadcast at all networks even if it's not being used for SASL at all networks. I had mentioned that anti-fingerprinting behavior is somewhat available in the /server -k switch, except that requires creating another certificate in order to broadcast a different fingerprint.

It would also be great if the anti fingerprinting behavior of /server -k could also be in a sockopen switch, as I've been informed that when I install an RSA cert into mIRC, that it's also being used for all /sockopen -e connections too.

Re: Extra options for certificates [Re: maroon] #269798 28/01/22 08:58 AM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
Additional detail on item 3b above, password entry box hidden behind black bullets.

Using SASL password to login has become more popular recently, probably due to some large channels beginning to require people being registered before entry, and for some reason the password to nickserv is often being lagged enough that they attempt to autojoin before the password is accepted by nickserv.

This has resulted in several noobs coming into channel for help because their SASL password wasn't being accepted. It seems that occasionally the problem was them trying to connect to the SSL port without the + in front of the port number, but more often their problem was solved by my having them fire up notepad so they can type their nick:password into a blank notepad then copypaste it into the serverlist edit window, having typed it in a window where they can see what they're doing.

I can understand the need to hide the password on an ongoing basis, but it seems reasonable that an exception can be made while people are in the process of entering their password. One person was having so much trouble with trying to input his SASL password that it ended up being easier to talk him through creating an RSA certificate and having him use that method.

Re: Extra options for certificates [Re: maroon] #269961 24/02/22 07:56 PM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
Additional detail about certificate expiration.
I tested to see how mirc and the server would handle this. I created a certificate set to expire in half an hour, then I logged in and added the fingerprint to my nickserv account, and then re-logged-in to confirm that libera.chat would accept the cert.

Then I waited for the certificate to expire.
When the expiration time had arrived, I tried to login again, and this time I was correctly not authenticated.

However, I looked among the status window messages during the failure, and nowhere did mIRC tell me that the certificate had expired. I don't expect mIRC to refuse to use the certificate after it expires, since it's possible for servers to accept certificates after they expire the way some IRC networks have expected us to use their SSL certificates after theirs expired, however it would be great if mIRC shows us our own certificate's expiration date if the SASL cert handshake failed after we used an expired cert.

Also, having some kind of .expiration property for $sslhash would allow us to alert ourselves of a soon-coming expiration date

Re: Extra options for certificates [Re: maroon] #270372 13/06/22 07:00 PM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
Feedback on the new certificate options.

I see that it's now possible to have a server ignore the global certificate by going to the serverlist and unchecking 'use global certificate' without defining one for that entry. However, if there's now a way to do the same thing with the /server command, I don't see it. If I use the /server command with -key $null for a server not in the serverlist, it will either use the global certificate, or it will go to the [recent] section of servers.ini to use a setting from there.

If I use alt+E to look at the serverlist, it lies to me as if my current server connection is in the serverlist when it's not really there, giving it a label like $network $servertarget. And, if I try to delete it from the serverlist menu, it always comes back again.

Some issues remain from the https://forums.mirc.com/ubbthreads.php/ubb/showflat/Number/263699/ thread, where using the /server command to connect to a server that's not in the serverlist means that you can't find info about the current connection because $server($servertarget) is blank. The only way to figure out what certificate you're actually using is to use $sslhash(sha512,p) then compare that against a saved list of fingerprints. Maybe having $server(-1) return properties for whatever is the active connection.

Something else that could be confusing to users is that $server().property is returning things it gets by looking at the serverlist instead of looking at the current connection. For example, when the current connection is in the serverlist, $server($servertarget).cert returns the name of the certificate listed for that serverlist entry in servers.ini, but you'd need to use $server($servertarget).certglobal to see whether that certificate is being used or not. The only way to see what the global certificate is, is to check $readini($mircini,ssl,key)

However, if you edit the serverlist or the config for the global cert after you've connected, neither $readini($mircini,ssl,key) or $server($servertarget).cert or $server($servertarget).certglobal are guaranteed to tell you what cert.pem was used to connect to the active server window.

--

There still isn't a way for people to know how long until their cert expires, and for finding out how long the cert has been used, they can only use the filename.pem's timestamp. The certs are being created with a 3 year lifetime, which is the max time generally accepted for certificates, but some people might want to change them anually. I tested the new beta with a certificate that's expired, and mIRC silently uses it in the handshake which will fail.

The script below is a quick/dirty attempt to examine a .pem to see when it expires or was issued. If there's more than 1 certificate in the file, it sees just the 1st one.

$CertExpire(client.pem) returns the number of days until it expires, with a negative number indicating that it expired
$CertExpire(client.pem,i) returns the number of days since it was issued.

I noticed that cacert.pem contains a certificate that's expiring in Jan 2028, which is the same expiration date contained in the cacert.pem back in v7.45 too, so it look like users of all versions will eventually need a new cacert.pem
Code
/*
{
  $CertExpire( [filename.pem] , [i] ) by maroon 2022

  By default, this looks at filename stored as the global cert in mirc.ini
  but you can set $1 to be another filename instead

  It assumes the file contains a Certificate in .pem format, then makes a very simplistic check
  to see if there's a valid expiration timestamp. If so, it compares against the current time
  to see how long until the certificate expires, returning a float containing the number of days
  until the cert expires. If it returns a negative number, the cert has expired.

  If $2 is 'i' it instead returns the number of days since the cert was issued

  mIRC seesm to issue certs with approximately 3 years of life from when they were created,
  but it doesn't offer syntax to warn when your cert has expired or will expire soon
  In addition to that, some users may wish to change certificates more often than 3 year intervals

  Examples:
  $certexpire
  result: number of days until the global certificate expires
  $certexpire(libera.pem)
  result: number of days until the certificate in libera.pem expires
  $certexpire(libera.pem,i)
  result: number of days since the certificate in libera.pem was first valid
}
*/

certexpire {
  var %f $readini($mircini,ssl,key)
  if ($isfile($1)) var %f $1
  var %i $read(%f,ntw,-*-BEGIN CERTIFICATE-*-)
  if (!%i) goto syntax | var %i 1 + $readn
  bunset &maroon.cert
  while (1) {
    var %a $read(%f,nt,%i) | if (!$regex(%a,^[a-zA-Z0-9/+]+=*$)) break
    bset -t &maroon.cert $calc(1+$bvar(&maroon.cert,0)) %a | inc %i
  }
  if (!$bvar(&maroon.cert,0)) goto syntax | noop $decode(&maroon.cert,bm)
  var %i 1
  :findtime
  ; 0x30 0x1e 0x17 0x0d
  var %a $bfind(&maroon.cert,%i,48 30 23 13)
  if (!%a) goto syntax
  var %notbefore $bvar(&maroon.cert,$calc(%a + 4   ),13).text
  var %notafter  $bvar(&maroon.cert,$calc(%a + 4+15),13).text
  if ( !$regex(foo,%notbefore $+ %notafter,^\d{12}Z\d{12}Z$)) goto findtime
  if ( $bvar(&maroon.cert,$calc(%a + 17-1),3 ) != 90 23 13) { inc %i | goto findtime }
  var %expire $regsubex(foo,20xx/xx/xx xx:xx:xx,/(x)/g,$mid(%notafter ,\n,1) )
  var %issued $regsubex(foo,20xx/xx/xx xx:xx:xx,/(x)/g,$mid(%notbefore,\n,1) )
  var %expire $ctime( %expire )  , %now $gmt , %issued $ctime( %issued )
  ;echo -a $asctime(%now) vs $asctime(%expire) vs $asctime(%issued)
  var %days $calc(  (%expire - %now)/86400 )
  if ($2 == i) { var %days $calc( (%now - %issued)/86400 )
  echo -sc info Cert %f issued %days days ago | return %days }
  if (%days < 0) echo -s 8,13 Cert %f expired %days ago!
  elseif (%days <= 31) echo 4 -s Cert %f expires in %days days!
  else echo -sc info Cert %f expires in %days days
  return %days
  :syntax
  echo -sc info days until expire: *$certexpire( [filename] , [i]) default=client.pem i=$2=days since issued
}

Re: Extra options for certificates [Re: maroon] #270374 14/06/22 08:02 AM
Joined: Dec 2002
Posts: 5,152
Khaled Offline
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,152
Thanks for the feedback.

Quote
I see that it's now possible to have a server ignore the global certificate by going to the serverlist and unchecking 'use global certificate' without defining one for that entry. However, if there's now a way to do the same thing with the /server command, I don't see it. If I use the /server command with -key $null for a server not in the serverlist, it will either use the global certificate, or it will go to the [recent] section of servers.ini to use a setting from there.

I will add this in the next beta.

Quote
If I use alt+E to look at the serverlist, it lies to me as if my current server connection is in the serverlist when it's not really there, giving it a label like $network $servertarget. And, if I try to delete it from the serverlist menu, it always comes back again.

Beta v7.68.1159 changes:
6.Item 20, changed. In cases where the current status window
server does not exist in the servers list, the server address
is added temporarily to the servers list in the connect dialog
and selected, since pressing okay in the connect dialog will
set the status window server. If you edit the server, it becomes
permanent.

Quote
The only way to figure out what certificate you're actually using is to use $sslhash(sha512,p) then compare that against a saved list of fingerprints. Maybe having $server(-1) return properties for whatever is the active connection.

The beta supports $sslkeyfile to return the active certificate file for the current connection.

Re: Extra options for certificates [Re: Khaled] #270377 14/06/22 11:45 PM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
$sslkeyfile was not mentioned in the beta announce post, nor was it in beta.txt. Are there any other identifiers which were added?

Quote

26.Added $server() properties: certglobal, cert, nickglobal, nick, anick, user, email, encoding.


This works only for a server that's actually in the server list. If you use the /server command to connect to a server for the 1st time, none of the above are working because they're not in the server list. That's why I was thinking that something like $server(-1) could be something to look at the current connection, regardless whether or not it's in the serverlist.

Quote

Extended per server entry in servers.ini to include the new settings. Note that GROUP: is required even if the group is not set.


The way I read the above, the entry for a server in servers.ini always must contain the GROUP: tag, however creating a server while leaving the groupname blank creates an entry without the GROUP: tag. Both of the following items appear identically in the dropdown list.

n155=foobarSERVER:irc.foo.bar:6667
n156=random serverSERVER:irc.foo.bar:6667GROUP:foobar

Quote

Beta v7.68.1159 changes:
6.Item 20, changed. In cases where the current status window server does not exist in the servers list, the server address is added temporarily to the servers list in the connect dialog and selected, since pressing okay in the connect dialog will set the status window server. If you edit the server, it becomes permanent.


The way I read the above, the intent is that the current $servertarget is made permanent only if that specific item is edited. However, I was finding that a brand new server sometimes was having $server($servertarget) being blank sometimes, and later it was returning $servertarget. It turned out that using the alt+E window to add another unrelated server to the serverlist was also adding the current 'temporary' item to servers.ini also. $server($servertarget) was returning $servertarget once I used the menu to add irc.foo.bar to the serverlist even though I was not editing the 'fake' item for the current connection.

Re: Extra options for certificates [Re: maroon] #270379 15/06/22 07:06 AM
Joined: Dec 2002
Posts: 5,152
Khaled Offline
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,152
Quote
$sslkeyfile was not mentioned in the beta announce post, nor was it in beta.txt. Are there any other identifiers which were added?

Arnie says that he can neither confirm nor deny this possibility.

Quote
The way I read the above, the entry for a server in servers.ini always must contain the GROUP: tag, however creating a server while leaving the groupname blank creates an entry without the GROUP: tag. Both of the following items appear identically in the dropdown list.

n155=foobarSERVER:irc.foo.bar:6667
n156=random serverSERVER:irc.foo.bar:6667GROUP:foobar

You are mixing up two different issues here.

The first is that GROUP: is needed in the servers.ini server definition if the extra options are used. This is already handled by the code. I mentioned this only in case a scripter wanted to write to the servers.ini using their own script.

The second is the way the items appear in the listbox in the connect dialog. This is not related to the group definition. It is a legacy behaviour relating to how the "random server" description is handled. There are actually some other word combinations that do the same thing. This cannot be changed.

Re: Extra options for certificates [Re: Khaled] #270407 22/06/22 03:39 AM
Joined: Jan 2004
Posts: 1,807
maroon Offline OP
Hoopy frood
OP Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,807
* Warning: SSL private certificate 'C:\path\EXPIRED4.PEM' has expired (notbeforedate-noteafterdate)

I'm seeing this only when using an expired cert to connect to something that's already in the serverlist, even if it's using an expired global cert.

When the global cert is Expired4.pem, I see this warning only when connecting to a servername that's already in the serverlist. When irc.us.libera.chat is not in the serverlist, "/server irc.us.libera.chat" does not show the green warning even though it uses the expired global cert expired4.pem

"/server irc.us.libera.chat -k expired4.pem" won't show an error even when I'm overriding a valid cert to use an expired one, becuase irc.us.libera.chat isn't in the serverlist.

is there an event that gets triggered by the green warning message? because the green text is easy to miss amongst all the activity at a typical connection.

Re: Extra options for certificates [Re: maroon] #270409 22/06/22 08:06 AM
Joined: Dec 2002
Posts: 5,152
Khaled Offline
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,152
Quote
/server irc.us.libera.chat -k expired4.pem

You need to use -key to specify the key filename, and you need to specify that it is an SSL server, so that the SSL certificate is used. When I use the following:

/server irc.us.libera.chat +7000 -key expired.pem

It works as expected for me and shows the SSL expired certificate warning.