TLSSend is a email sending program designed to demonstrate multiple methods of sending an email via SMTP.
1. Standard SMTP using port 25.
2. Standard SMTP with PLAIN AUTHENTICATION using port 1025 (May vary with ISP).
3. TLS 1.0 encrypted SMTP through smtp.gmail.com using port 465.
4. TLS 1.0 encrypted SMTP through smtp.gmail.com using STARTTLS and port 587.
5. TLS 1.0 encrypted SMTP through smtp.live.com using STARTTLS and port 587.
6. Yahoo does not support external access to SMTP for freebie accounts.
Normally, email settings would be stored in the registry or an initialization file, but since this is a demonstration program, your specific account details will have to be incorporated into the code.
- Change the generic To: & From: addresses in frmTLS.
- Change the "yourISP" Combo Box items in the frmTLS.Form_Load sub to reflect your own ISP.
- Change the generic account settings in the cmdConnect_Click sub to reflect your own account settings.
This program does not contain any third party controls or libraries, and utilizes the RSA/Schannel library (schannel.dll) that is shipped with all modern Windows Operating Systems. Although the Cryptography routines will work on most Operating Systems, cSocket2 will only work on systems that support dual stack (IPv4/IPv6). This more or less restricts it to Windows Vista or better. For more information on the Cryptographic functions, see: http://www.vbforums.com/showthread.p...-VB6-TLSCrypto
J.A. Coutts
Updated 09/29/2014: See later post for details
Last edited by couttsj; Sep 29th, 2014 at 04:06 PM.
There are 2 ways of sending mail through Gmail. Both use the account name and password Base64 encoded:
strSMTPAcct = "UserID@gmail.com"
strPassword = Bas64.Encode(Chr$(0) & strSMTPAcct & Chr$(0) & "password1")
Using port 465, the entire session is TLS encrypted. Using port 587, the session is started as a standard SMTP session would be, and after the HELO/EHLO response is received from the server, a STARTTLS is issued by the client. After a 220 response from the server, the client negotiates a TLS session and the rest of the SMTP session is encrypted.
J.A. Coutts
Last edited by couttsj; Mar 5th, 2014 at 10:45 PM.
i like your example ist working fine here under Windows 7. But if I test it under Windows 8.1 i got error 0x80090020 at this Line
If CryptCreateHash(hCryptProv, CALG_SCHANNEL_MASTER_HASH, hMasterKey, 0, hMasterHash) = 0 Then
in clsCrypt.ExportMasterKey
Any Idea why it fails under Windows 8.1? Maybe its a Problem with the Crypto-Provider?
I searched, but could not find anything specific to Windows 8. Error 0x80090020 is a very generic error (Internal Error), so it doesn't provide us with a lot of information.
The first thing to do is verify that all the variables passed to the function have a value. You can do this by setting a break point on that particular line, and hovering your mouse above each variable. hMasterHash will be "0" because it is created by this call.
The MasterHash is not really a Hash, it is a PRF. The MasterKey is originally created with the Pre-Master key. The parameters SCHANNEL_ENC_KEY and SCHANNEL_MAC_KEY are set, and the variables CLIENT_RANDOM, & SERVER_RANDOM are added. The constant CALG_SCHANNEL_MASTER_HASH tells SChannel to create the MasterHash. It is possible that there is a problem with one of the parameters, but I am not sure how to verify that.
J.A. Coutts
Addendum: Microsoft added the ability to block specifc algorithms in Windows 8.1/Windows Server 2012 R2. http://technet.microsoft.com/en-us/l...9-9efcff0240ad
Microsoft also considers MD5 as depricated for use with it's own root certificates. What happens if MD5 is blocked and the site you connect to chooses MD5, I have no idea, but it might be worth checking the value of Alg_Hash.
Last edited by couttsj; Apr 8th, 2014 at 01:09 PM.
i checked the function. Everything seems to be set. Down to CryptCreateHash. I tested with gmail and the Server choose SHA1 (so its not using MD5, right).
But as far as I read in the net its that Microsoft disabled RC4. Maybe this is the Problem?
I will check my registry later, to see what is blocked and report back.
i tryed to enable the RC4 with the same Result in CryptCreateHash.
Than i switched to TLS_RSA_WITH_AES_256_CBC_SHA.
Changing this for the ClientHello ( ... Chr$(&H0) & Chr$(&H35) ...) and at
'Set SCHANNEL_ENC_KEY parameters
Algorithm.dwUse = SCHANNEL_ENC_KEY
Algorithm.algid = CALG_AES_256 'CALG_RC4
Algorithm.cBits = 256 '128
Algorithm.dwFlags = 0
Algorithm.dwReserved = 0
If CryptSetKeyParam(hMasterKey, KP_SCHANNEL_ALG, Algorithm, 0) = 0 Then
RaiseEvent Error(Err.LastDllError, CSKP, Routine)
GoTo ReleaseHandles
End If
(Thats all I have to change right?)
But with the same Errorcode in CryptCreateHash (in Windows 8.1 / Windows 7 worked!)
Do you have any more ideas? Iam stuck!
AES is a block cipher and a whole different kettle of fish. TSLSend was only designed for stream ciphers to keep the encrypted length the same as the decrypted length. If you are going to tinker with algorithms, I would suggest that you do it where you can control both ends. TLSCrypto provides that capability, and that is how I eventually got TLS to work.
Can you point me towards any information that RC4 is possibly a problem? The only thing I could find is that Microsoft considers MD5 deprecated for use with asymmetrical Cryptography. All their root Certificates have been switched over to SHA1.
i do not understand very much about cryptography. But I can follow your tls code, so i just tried to change some specs to test if it will work another way with my windows 8.1. Today i did not have much time to investigate futher, tomorrow i hope.
I tryed to enable the RC4 Chipers desribed here http://technet.microsoft.com/en-us/l.../dn303404.aspx. But it did not help me with the problem, the error is the same.
RC4 as the reason of the error was just a guess from my side. Maybe the Problem is somewhere else. I just cant understand why CryptCreateHash raises an error under Windows 8.1 but under Windows 7 it worked.
I tested Internet Explorer from my Win 8.1 against https://www.mikestoolbox.net/ and it does not offer anymore RC4_xxxx. Maybe because it relys on CryptoAPI or SChannel to.
Here is a list of stream ciphers:
A5/1, A5/2, CryptMT, FISH, Grain, HC-256, ISAAC, MUGI, PANAMA, Phelix, Pike, Py, Rabbit, RC4, Salsa20, Scream, SEAL, SNOW, SOBER-128, SOSEMANUK, Trivium, Turing, VEST, WAKE
As you can see, RC4 is the only one in common use. Why Microsoft would choose to block it is beyond me. SChannel only supports RC4 and Diffie-Hellman, and the latter is a block cipher. Block Ciphers are more difficult to implement because they require Initialization Vectors and padding to fill the last block.
i do not understand very much about cryptography. But I can follow your tls code, so i just tried to change some specs to test if it will work another way with my windows 8.1. Today i did not have much time to investigate futher, tomorrow i hope.
I tryed to enable the RC4 Chipers desribed here http://technet.microsoft.com/en-us/l.../dn303404.aspx. But it did not help me with the problem, the error is the same.
Just tested RC4 (as well as AES256) using the MS-CryptoAPI here on a (german) Win8, as well as on a Win8.1 machine.
Both algorithms work - so it's perhaps the initializing of the Crypt-Contexts which is different in my implementation -
I'm using the Unicode-Versions of the Crypto-API-Defs throughout - and found this init-sequence here working very well:
If CryptAcquireContextW(hCtx, 0, 0, Prov, CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) Then
As for a pre-encapsulated AES-implementation which is using the MS-Crypto-approach (in combination with
a block-truncation-implementation I did myself on top of that...
This is available (as well as an ArcFour) conveniently behind the vbRichClient5.cCrypt-Class.
vbRichClient5 is a free available, modern framework for VBClassic, downloadable here: http://vbrichclient.com/#/en/Downloads.htm
With that in place, the block-orientation of AES (padding to a multiple of 16Bytes) is not an
issue anymore - Input of any length comes out encrypted (or decrypted) in the same length.
Below is an example, which also shows, how to work with an AES-InitVector...
Code:
Option Explicit
Private Sub Form_Click()
Cls
AutoRedraw = True
Dim S As String
S = "String-Content, containing Unicode-Chars" & ChrW(8364) '<- "€" sign
Dim B() As Byte
B = S 'perform a lossless UniCode-conversion to a ByteArray
Dim C As cCrypt
Set C = New_c.Crypt 'instantiate the vbRichClient5.cCrypt-Class
'Initialize your own personal 16Byte-InitVector for AES (an optional Param, but recommended to use)
Const StringKeyBasedInitVectorInput As String = "MyInitVectorInitializerString"
Dim InitVector16Bytes() As Byte: InitVector16Bytes = C.MD5(StringKeyBasedInitVectorInput, False)
Debug.Print "Length of InitVector needs to be 16 Bytes:"; UBound(InitVector16Bytes) + 1
'the above MD5 is choosen, since it gives back exactly 16Bytes (128Bit-HashResults) -
'but any "random but unique" Init-Vector would serve, as long as it is 16 Bytes long
Print "Unencrypted ByteLength:"; UBound(B) + 1 'print the un-encrypted length of B
C.AESEncrypt B, "MyEncrKeyAES", AES256, InitVector16Bytes, True '<- last param ensures an SHA-256 Hashing of the Key
Print "The encrypted ByteLength:"; UBound(B) + 1; vbLf 'print the encrypted length of B
Print "Resulting ByteLength is always the same as the input, not a multiple of the AES-"
Print "BlockLength of 16 Bytes, since this implementation is using 'CBC-CS3-truncation',"
Print "as described here: http://en.wikipedia.org/wiki/Ciphertext_stealing"
Print vbLf; "AES-Encrypted content follows:"; vbLf
Print StrConv(B, vbUnicode)
'Now the "inplace" decryption of the B-Content
C.AESDecrypt B, "MyEncrKeyAES", AES256, InitVector16Bytes, True '<- last param ensures an SHA-256 Hashing of the Key
Print vbLf; "The decrypted ByteLength:"; UBound(B) + 1 'print the encrypted length of B
Dim SDecrypted As String
SDecrypted = B 'lossless back-conversion from unicode-bytes to a VB-String
Print "AES-Decrypted string identical to the original one? -> "; S = SDecrypted
Print vbLf; String(255, "-")
Print vbLf; "Just for completeness, an RC4 (ArcFour) test follows:"; vbLf
B = S
Print "Unencrypted ByteLength:"; UBound(B) + 1 'print the un-encrypted length of B
C.ArcFour B, C.SHA256("MyEncrKeyArcFour", False)
Print vbLf; "ArcFour-Encrypted content follows:"; vbLf
Print StrConv(B, vbUnicode)
'Now the "inplace" decryption of the B-Content
C.ArcFour B, C.SHA256("MyEncrKeyArcFour", False)
Print vbLf; "The decrypted ByteLength:"; UBound(B) + 1 'print the encrypted length of B
SDecrypted = B 'lossless back-conversion from unicode-bytes to a VB-String
Print "ArcFour-Decrypted string identical to the original one? -> "; S = SDecrypted
End Sub
Does PROV_RSA_AES contain the additional key derivation algorithms required by the SSL/TLS standard? I was given to understand that SChannel was the only provider to offer that.
I just thought of a feature in clsCrypt that may give us some answers. When the class is initialized, there is a routine that enumerates the supported algorithms. I had no use for it at the moment, so I commented out the results. Just remove the comment and it will list the supported algorithms. This is what my system (Vista SP2) responds with:
Does PROV_RSA_AES contain the additional key derivation algorithms required by the SSL/TLS standard? I was given to understand that SChannel was the only provider to offer that.
My other post was caused by McSchermers "RC4 not working anymore on Win8" - more
thought as a prove, that RC4 is still on board ... but also addressed to you a bit with
regards to "how AES can be forced into a "non-padding-mode" ...
But you're right - the PROV_RSA_AES provider is perhaps less useful in a scenario,
where you can't control both ends - SChannel is there to comply with a *standard*
(and a server on the other end, you have no control over).
FWIW, I've now ran your Test-Routine and the string it prints out on a german Win8 is:
So, the RC4-mode is still on board also with the SChannel-Provider on Win8...
on a german version of Windows that is - not sure if those idiotic "crypto-export-
restrictions" are possibly kicking in on Win-Versions which are shipped to other
countries (which might be a reason for the problem McSchermer has reported).
But can't imagine so, because otherwise it wouldn't have worked with a Win7-
version either.
So RC4 is listed here too. And I do use Server 2012 Esssentials (from a friend) / 2x Windows 8.1 / Windows 7 german although on all maschines I tested. So the Error in CreateCryptHash is not the blocked RC4?! But what else could raise the "Internal Error" from this function, i didnt find anything on the net.
I redownloaded the code again, in case i might have changed something. But still the same error.
Olaf could you please attach a compiled Version of TLS Sendmail, you tested on your Windows 8.1. Thanks in advance.
Last edited by MCSchermer; Apr 14th, 2014 at 04:01 AM.
The TLSSend demonstration program has been modified to use the newer NewSocket and clsCrtpto classes. During the process, it was discovered that I could no longer login to either GMail or Hotmail. Even though they advertise in response to EHLO:
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN
PLAIN AUTHENTICATION was disabled by default, and both 2 Factor Authentication and OAUTH are a pain in the butt to use. I couldn't find any information on PLAIN-CLIENTTOKEN, but it appears to be oriented towards token access without HTML. Token access is a methodology developed by the biggies (Google, Microsoft, Facebook, etc) to allow temporary access to only those parts of a multi-use account necessary to perform the task that you are requesting.
To get GMail working again, I had to go into the settings page on my account and enable "Access for less secure apps". That is of course after resetting my account password. I had to do something similar in Hotmail while I was changing the password, but I don't remember the exact details (I was getting frustrated). I really don't understand what all this fuss is about, because the main reason for implementing TLS in the first place was to prevent password snooping. I suspect that some people use very weak passwords making it easy for them to be guessed, and it has nothing to do with snooping.
While updating TSLSend, support for attachments was added. This was all fine and dandy until I attempted to send a 58K file. It was this point that I discovered the maximum size for a fragment to be sent under an HMAC header is 2^14 or 16,384 bytes. That meant breaking the file up into several chunks. In theory, the same applies to the message, but I have not done anything with that part yet.
I am experiencing the exact problem described by MCSchermer in post #7 when working with the TLSCrypto project from J. A. Coutts (http://www.vbforums.com/showthread.p...-VB6-TLSCrypto). I've posted details there. Are there any other ideas or updates on this issue?
I have confirmed that the same program that runs on 32 bit Vista gets the following error on 64 bit Win 8.1.
&H80090020 in the Create Master Hash call of the ExportMasterKey routine.
Unlike the TLSCrypto routine on my system, the TLSSend routine is fully updated, so the error is not the same. Troubleshooting the TLSSend routine is more or less a trial & error procedure because we can't control both ends, so updating TLSCrypto and using it to troubleshoot is probably the better route to take. Give me a few days.
I need some help on this one. The first thing I thought of was that Microsoft did not like the fact that I was creating the Pre-Master Key myself and importing it, but I found the original program I used to test some of the Crypto calls (source code attached), and it uses the Microsoft recommended methodology:
CryptGenKey(hCryptProv, CALG_TLS1_MASTER, CRYPT_EXPORTABLE, hMasterKey)
However it gets the same error on Win 8.1.
Next I thought that maybe Microsoft doesn't like SHA-1 any more. So I changed the Algorithm.algid to "CALG_SHA_256" with "Algorithm.cBits" of 256, but that produced an error in the "CryptSetKeyParam" call because Schannel doesn't support it.
So then I started searching, and found this tidbit:
--------------------------------------------------------- http://technet.microsoft.com/en-us/l.../dn303404.aspx
Release Notes: Important Issues in Windows 8.1 Preview
Published: June 24, 2013
Applies To: Windows 8.1
Security
RC4 is no longer enabled by default for TLS. Applications (such as Internet Explorer) might fail to connect if they depend on RC4. You can enable RC4 support by configuring these registry keys with the following REG command:
----------------------------------------------------------
But that is for the Preview or Pre-release version, and there is no mention of it in the official release version. Also, when I Enumerate the supported protocols "128 RC4" is included. I could try disabling all other protocols in Firefox, but I believe that Mozilla uses all their own protocols, and I don't know how to do that in IE.
I will post this issue to Technet, but if history is any indication, there is little chance of getting a response. I have run out of ideas.
J.A. Coutts
Addendum: It looks like Microsoft intended to drop support for RC4 in Win 8.1, but changed their minds. When I check the registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
3 new sub keys have been added to enable RC4:
RC4 128/128 "Enabled"=dword:ffffffff
RC4 40/128 "Enabled"=dword:ffffffff
RC4 56/128 "Enabled"=dword:ffffffff
Last edited by couttsj; Nov 15th, 2014 at 02:36 AM.
As expected, there has been no response from MS Technet, except to suggest moving the question to a different forum (which I did).
This particular problem was acknowledged back in July with the failure of Winetest on Windows 8: https://www.winehq.org/pipermail/win...ly/133482.html
and as yet there is no resolution. I have posted the problem to the Winetest forum again, hoping for a response.
If Wikipedia is accurate, http://en.wikipedia.org/wiki/Compari...mplementations
RC4-128 should still be available as fallback:
-------------------------------------
Implementation - SChannel 8.1/2012R2
No Cipher - Disabled by Default
Block cipher with mode of operation
3DES EDE CBC - Yes
AES CBC - Yes
AES GCM - except ECDHE_RSA
AES CCM - Yes
CAMELLIA CBC - No
CAMELLIA GCM - No
SEED CBC - No
ARIA CBC - No
ARIA GCM - No
GOST 28147-89 CTR - No
Stream cipher
CHACHA20 - No
CHACHA20-POLY1305 - No
RC4-128(insecure) - Disabled except as an (insecure) fallback if no other
enabled algorithm works
--------------------------------------
Obviously this is not entirely true, and that is the only stream cipher that Schannel supports. Stream ciphers are a lot easier to work with because the encrypted data length is the same as the unencrypted data length (except for keys), and unfortunately TLSSend was not written to support block ciphers.
On Nov 17, I received this response from MS Technet:
---------------------------------
Hello Coutts,
For this issue, I am trying to involve someone experienced to help look into this thread, this may take soem times and as soon as we get any result, we will post back.
Regards.
----------------------------------
I suspect that the Windows 8/8.1 Schannel routines were rewritten without support for RC4 in the pre-release versions, and as an after thought RC4 was re-enabled when problems surfaced. It looks like the create MASTER HASH routine was missed, but I am just guessing.
J.A. Coutts
Last edited by couttsj; Nov 23rd, 2014 at 03:33 PM.
After getting zero response from Microsoft about the Crypto API problems with Win 8.1, I decided to continue with development using the other Schannel CSP from Microsoft, Diffie Hellman.
The way this one handles key exchange is completely different from RSA, so I basically had to start from scratch, and so far the available information is even less than for RSA. I started with converting the Wine test C++ program for "dssenh.dll". Unfortunately this program does not include a TLS test, so I was left on my own for that part.
Next, I wrote a simulation program to test the key exchange and the creation of the Master keys, and it is attached. When I moved it over to the Win 8.1 machine, it made it through the problem CryptoCreateHash area, but failed when attempting to create the HMAC keys with a &H80090008 Error (Invalid algorithm specified). So far I have not found an algorithm combination that will work on Win 8.1.
Update: The attachment has been updated to support block ciphers such as 3DES.
J.A. Coutts
Last edited by couttsj; Mar 4th, 2015 at 12:56 PM.
More information! Just for the heck of it, I decided to run the Wine test on the Windows 8.1 machine (attached). Four tests failed:
1. RC4/40 Encryption Test.
2. RC4/128 Encryption Test.
3. Verify Signature Test.
4. Key exchange Test.
The Verify Signature Test appears to be a timing issue, as sometimes it works and sometimes it does'nt. The other failed tests do not produce an error, they simply don't provide the right answer. When the algorithm used in the Key exchange Test is changed from CALG_RC4 to CALG_3DES, it works properly.
So it appears that Microsoft has not only recommended that RC4 be disabled, on Win 8.1 they have made it unworkable without producing any errors. When the algorithms are enumerated, it is still listed as a supported algorithm.
It has taken a while, but I have confirmed that Windows 8.1 does indeed support RC4. But with CNG, not CAPI. Attached is a test program that tests 3 of the 8 available Ciphers (including the exchange cipher RSA) using Cryptography API: Next Generation.
I leave it up to you to decide if Microsoft disabled RC4 in CAPI on Windows 8 on purpose to push developers towards CNG.
I am still working on updating my TLS programs, but I am having an extreme amount of difficulty with some of the SSL calls.