Re: Test TLS 1.3 with VB6
Verification of GMail POP3 and SMTP accounts has been added to TLS_Test. The Account Name and Password are fictitious, so you will have to change those to get the proper results. The password is a 16 byte password supplied by Google as part of GMails 2 factor authentication. It has been tested using both "ECDH_P256" and "X25519".
The last obstacle encountered to get X25519 to work with MS was the order in the Client Hello extension "Supported Groups". I had assumed (wrongly) that the Public Key being identified and provided in the "Keyshare" extension only had to be included in the "Supported Groups" extension. By trial and error I discovered that it had to be at the top of the list to avoid a non-explanatory Fatal Alert. That doesn't make a lot of sense to me.
Once connected to the server, POP3 on Port 995 and SMTP on Port 465 pretty much follow the standards. The one exception I am aware of with GMail is the lack of support for the "STAT" and LIST" commands. GMail will not return information on messages that it considers to have been read. For this reason, I use the Web based program to delete messages.
The noticeable differences between X25519 and the other ECDH protocols is:
1. The Public and Private key blobs for X25519 use the full 64 bytes with the last 32 bytes being zero.
2. The first and last bits of the Private key portion must be adjusted. Wqweto calls this clamping, and can be seen in the GetXKeys sub.
3. For X25519, BCryptOpenAlgorithmProvider requires a pointer to "ECDH" rather than the Key Algorithm name.
4. It also requires the use of BCryptSetProperty, which fails if you try to use it with the other ECC keys.
5. When calculating the KeyShare, the other keys require an extra byte (&H04) in front of the buffer. X25519 does not. See function GetKeyShare for details. TLS 1.3 does not support compression, but for some obscure reason the &H04 is used to indicate no compression.
Even though I have finally got X25519 to work with GMail, Fastmail still returns a non-explanatory Fatal Alert 40 and Fastmail Help has not been very helpful. They are unwilling or unable to tell me what it doesn't like about the Client Hello.
J.A. Coutts
Re: Test TLS 1.3 with VB6
Your ClientHello procedure is in a shoddy state with multiple HexToByte blobs which remain black magic. You do realize that TLS packets are nested chunks which are type and length prefixed, yet there are no helper procedures to aid you generate these correctly while the source code remaining readable.
Compare with this code:
Code:
'--- Record Header
pvBufferWriteRecordStart uOutput, TLS_CONTENT_TYPE_HANDSHAKE, uCtx
'--- Handshake Header
lMessagePos = uOutput.Size
pvBufferWriteLong uOutput, TLS_HANDSHAKE_CLIENT_HELLO
pvBufferWriteBlockStart uOutput, Size:=3
pvBufferWriteLong uOutput, TLS_LOCAL_LEGACY_VERSION, Size:=2
If pvArraySize(.LocalExchRandom) = 0 Then
pvTlsGetRandom .LocalExchRandom, TLS_HELLO_RANDOM_SIZE
End If
pvBufferWriteArray uOutput, .LocalExchRandom
'--- Legacy Session ID
pvBufferWriteBlockStart uOutput
If .HelloRetryRequest Then
pvBufferWriteArray uOutput, .RemoteSessionID
ElseIf pvArraySize(.LocalSessionID) = 0 And (.LocalFeatures And ucsTlsSupportTls12) <> 0 Then
'--- non-empty for TLS 1.2 compatibility
pvTlsGetRandom baTemp, TLS_HELLO_RANDOM_SIZE
pvBufferWriteArray uOutput, baTemp
Else
pvBufferWriteArray uOutput, .LocalSessionID
End If
pvBufferWriteBlockEnd uOutput
'--- Cipher Suites
pvBufferWriteBlockStart uOutput, Size:=2
For Each vElem In pvTlsGetSortedCipherSuites(.LocalFeatures)
pvBufferWriteLong uOutput, vElem, Size:=2
Next
pvBufferWriteBlockEnd uOutput
'--- Legacy Compression Methods
pvBufferWriteBlockStart uOutput
pvBufferWriteLong uOutput, TLS_COMPRESS_NULL
pvBufferWriteBlockEnd uOutput
'--- Extensions
pvBufferWriteBlockStart uOutput, Size:=2
If LenB(.RemoteHostName) <> 0 Then
'--- Extension - Server Name
pvBufferWriteLong uOutput, TLS_EXTENSION_SERVER_NAME, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteLong uOutput, TLS_SERVER_NAME_TYPE_HOSTNAME '--- FQDN
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteString uOutput, .RemoteHostName
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
End If
If LenB(.AlpnProtocols) <> 0 Then
'--- Extension - ALPN
pvBufferWriteLong uOutput, TLS_EXTENSION_ALPN, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
For Each vElem In Split(.AlpnProtocols, "|")
pvBufferWriteBlockStart uOutput
pvBufferWriteString uOutput, Left$(vElem, 255)
pvBufferWriteBlockEnd uOutput
Next
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
End If
'--- Extension - Supported Groups
pvBufferWriteLong uOutput, TLS_EXTENSION_SUPPORTED_GROUPS, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
If pvCryptoIsSupported(ucsTlsAlgoExchX25519) Then
pvBufferWriteLong uOutput, TLS_GROUP_X25519, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoExchSecp256r1) Then
pvBufferWriteLong uOutput, TLS_GROUP_SECP256R1, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoExchSecp384r1) Then
pvBufferWriteLong uOutput, TLS_GROUP_SECP384R1, Size:=2
End If
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
'--- Extension - OCSP Status Request
pvArrayByte baTemp, 0, TLS_EXTENSION_STATUS_REQUEST, 0, 5, 1, 0, 0, 0, 0
pvBufferWriteArray uOutput, baTemp
If (.LocalFeatures And ucsTlsSupportTls12) <> 0 Then
'--- Extension - EC Point Formats
pvArrayByte baTemp, 0, TLS_EXTENSION_EC_POINT_FORMAT, 0, 2, 1, 0
pvBufferWriteArray uOutput, baTemp '--- uncompressed only
'--- Extension - Extended Master Secret
pvArrayByte baTemp, 0, TLS_EXTENSION_EXTENDED_MASTER_SECRET, 0, 0
pvBufferWriteArray uOutput, baTemp '--- supported
'--- Extension - Encrypt-then-MAC
pvArrayByte baTemp, 0, TLS_EXTENSION_ENCRYPT_THEN_MAC, 0, 0
pvBufferWriteArray uOutput, baTemp '--- supported
'--- Extension - Renegotiation Info
pvBufferWriteLong uOutput, TLS_EXTENSION_RENEGOTIATION_INFO, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput
pvBufferWriteArray uOutput, .LocalLegacyVerifyData
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
'--- Extension - Session Ticket
pvBufferWriteLong uOutput, TLS_EXTENSION_SESSION_TICKET, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteLong uOutput, 0, Size:=4
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteArray uOutput, .LocalSessionTicket
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
End If
'--- Extension - Signature Algorithms
pvBufferWriteLong uOutput, TLS_EXTENSION_SIGNATURE_ALGORITHMS, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
If pvCryptoIsSupported(ucsTlsAlgoExchSecp256r1) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_ECDSA_SECP256R1_SHA256, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoExchSecp384r1) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_ECDSA_SECP384R1_SHA384, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoExchSecp521r1) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_ECDSA_SECP521R1_SHA512, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoPaddingPss) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PSS_RSAE_SHA256, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PSS_RSAE_SHA384, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PSS_RSAE_SHA512, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PSS_PSS_SHA256, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PSS_PSS_SHA384, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PSS_PSS_SHA512, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoPaddingPkcs) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PKCS1_SHA224, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PKCS1_SHA256, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PKCS1_SHA384, Size:=2
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PKCS1_SHA512, Size:=2
End If
'--- legacy SHA-1 based signatures
If pvCryptoIsSupported(ucsTlsAlgoDigestSha1) Then
If pvCryptoIsSupported(ucsTlsAlgoPaddingPkcs) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_RSA_PKCS1_SHA1, Size:=2
End If
If pvCryptoIsSupported(ucsTlsAlgoExchSecp256r1) Or pvCryptoIsSupported(ucsTlsAlgoExchSecp384r1) Then
pvBufferWriteLong uOutput, TLS_SIGNATURE_ECDSA_SHA1, Size:=2
End If
End If
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
If (.LocalFeatures And ucsTlsSupportTls13) <> 0 Then
'--- Extension - Post Handshake Auth
pvArrayByte baTemp, 0, TLS_EXTENSION_POST_HANDSHAKE_AUTH, 0, 0
pvBufferWriteArray uOutput, baTemp '--- supported
'--- Extension - Key Share
pvBufferWriteLong uOutput, TLS_EXTENSION_KEY_SHARE, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteLong uOutput, .ExchGroup, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteArray uOutput, .LocalExchPublic
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
'--- Extension - Supported Versions
pvBufferWriteLong uOutput, TLS_EXTENSION_SUPPORTED_VERSIONS, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput
pvBufferWriteLong uOutput, TLS_PROTOCOL_VERSION_TLS13, Size:=2
If (.LocalFeatures And ucsTlsSupportTls12) <> 0 Then
pvBufferWriteLong uOutput, TLS_PROTOCOL_VERSION_TLS12, Size:=2
End If
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
If .HelloRetryRequest And SearchCollection(.RemoteExtensions, "#" & TLS_EXTENSION_COOKIE) Then
'--- Extension - Cookie
pvBufferWriteLong uOutput, TLS_EXTENSION_COOKIE, Size:=2
pvBufferWriteBlockStart uOutput, Size:=2
pvBufferWriteBlockStart uOutput
pvBufferWriteArray uOutput, .HelloRetryCookie
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
End If
End If
pvBufferWriteBlockEnd uOutput
pvBufferWriteBlockEnd uOutput
pvTlsAppendHandshakeHash uCtx, uOutput.Data, lMessagePos, uOutput.Size - lMessagePos
pvBufferWriteRecordEnd uOutput, uCtx
The nested structure is apparent with each pvBufferWriteXxxStart is matched by pvBufferWriteXxxEnd. The latter calculates number of bytes emitted since matching pvBufferWriteXxxStart and puts this in the header. This prevents whole class of errors with wrong chunk sizes.
Everything in TLS in specified in RFCs. There is no undocumented 04 byte for uncompressed point format for NIST Curves. It's documented enum with 02/03 meaning compressed encoding with positive/negative Y coordinate of the point.
RFC 8422 documents that staring with TLS 1.2 the protocol only supports uncompressed encoding for points on NIST Curves.
cheers,
</wqw>
Re: Test TLS 1.3 with VB6
Wqweto;
I agree that the ClientHello function is not very streamlined, but it was put together under pressure. In my opinion, The committee that put together TLS 1.3 did an excellent job considering what they had to work with. But the result is very fractured and fragmented.
When my Internet supplier (Telus) suddenly farmed out their email service to GMail after a significant outage, I had to move quickly to put together something that would interface with GMail. I did not trust cloud storage (and still don't), so that meant maintaining my own database and interfacing directly with GMail POP3 and SMTP servers. The Client Hello function was simply a way of recreating what already worked. That was all fine and dandy until Fastmail decided to move the functional POBox system over to their own system. They receive email addressed to POBox, forward it to Telus (GMail), and flag it as deleted. After the move, I was suddenly swamped with spam/scam because GMail used the Sender address instead of the return address I provided when someone with a GMail address replied to one of my emails. That allowed hackers to learn my real address, so I decided to move the sending of email over to Fastmail and change the Telus (GMail) account name.
Since then, both Fastmail and GMail have improved their spam detection, but I was already well into trying to get Fastmail to send emails. With GMail, there were lots of third parties who could provide advice on how to access the GMail servers. Such was not the case with Fastmail, and their Help Desk has been less than helpful. From the very beginning I decided to use perfect forward secrecy (PFS) only to improve security and to try and reduce the complex fragmented nature of TLS. It has not been easy and I sincerely appreciate the help you have provided.
J.A. Coutts
Re: Test TLS 1.3 with VB6
You realistically cannot expect any mail provider helpdesk to answer questions about TLS errors their hosts return. Even their admins don't understand the intricacies of CH packets as implemented in TLS 1.3 as they use ready-made distro packages which ship with their own TLS libraries (e.g. openssl) so admins mostly configure the distro POP3/IMAP/SMTP service and have no internal knowledge about TLS support of the particular postfix version they are using.
Anyway, for SMTP clients Windows ships with SChannel so that one will not have to reimplement TLS with each new version of the protocol which gets standardized.
cheers,
</wqw>
Re: Test TLS 1.3 with VB6
By trial and error I was able to reduce the GMail Client Hello to 196 bytes. So I tried the same thing with Fastmail using the Client Hello produced by OpenSSL. It contained everything but the kitchen sink (329 bytes), but it got me past the Fatal Alerts. (original shown with lower case hex)
Code:
16 03 01 01 44 - Header (len=329)
01 00 01 40 - Client Hello (len=325)
03 03 - Version (not used)
8c 53 b2 92 9e b5 14 d2 38 15 52 3e 04 3d 02 6d - Client Random (not used)
5a 89 5f e6 07 78 9f 98 ad f2 78 b1 53 26 67 60
20 Session ID (not used)
7f b7 c0 39 92 12 ee 2d 80 8a 50 51 e0 a3 0d 0a
0b 2c 3f 8a fa f3 c8 38 df f3 61 fd e1 7c 24 c7
00 3e - Supported Cipher Suites (len=62)
13 02 - TLS_AES_256_GCM_SHA384
13 03 - TLS_CHACHA20_POLY1305_SHA256
13 01 - TLS_AES_128_GCM_SHA256
c0 2c - (not supported)
c0 30 - (not supported)
00 9f - (not supported)
cc a9 - (not supported)
cc a8 - (not supported)
cc aa - (not supported)
c0 2b - (not supported)
c0 2f - (not supported)
00 9e - (not supported)
c0 24 - (not supported)
c0 28 - (not supported)
00 6b - (not supported)
c0 23 - (not supported)
c0 27 - (not supported)
00 67 - (not supported)
c0 0a - (not supported)
c0 14 - (not supported)
00 39 - (not supported)
c0 09 - (not supported)
c0 13 - (not supported)
00 33 - (not supported)
00 9d - (not supported)
00 9c - (not supported)
00 3d - (not supported)
00 3c - (not supported)
00 35 - (not supported)
00 2f - (not supported)
00 ff - (not supported)
01 - Compression Support (Len=1) (not used)
00 - Compression Support None
00 b9 - Extension len=185
00 00 - Type (Server Name)
00 16 - Length (22)
00 14 - Server Name Indication (Len=20)
00 - Server Name Type (host_name)
00 11 - Server Name Indication (Len=17)
73 6d 74 70 2e 66 61 73 74 6d 61 69 6c 2e 63 6f 6d
(smtp.fastmail.com)
00 0b - EC points format
00 04 - len=4
03 - len=3
00 - uncompressed
01 - ANSI X.962 prime
02 - ANSI X.962 char2
00 0a - Type
00 16 - Length (22)
00 14 - Length (20)
00 1d - X25519
00 17 - Elliptic curve: secp256r1
00 1e - X448
00 19 - Elliptic curve: secp521r1
00 18 - Elliptic curve: secp384r1
01 00 - Elliptic curve: ffdhe2048
01 01 - Elliptic curve: ffdhe3072
01 02 - Elliptic curve: ffdhe4096
01 03 - Elliptic curve: ffdhe6144
01 04 - Elliptic curve: ffdhe8192
00 23 - Type (SessionTicket TLS)
00 00 - Length (0)
00 16 - Encrypt then MAC
00 00 - Length (0)
00 17 - Extended master secret
00 00 - Length (0)
00 0d - signature algorithms
00 30 - Length (48)
00 2e - Length (46)
04 03 - ecdsa_secp256r1_sha256
05 03 - ecdsa_secp384r1_sha384
06 03 - ecdsa_secp521r1_sha512
08 07 - ED25519
08 08 - ED448
08 09 - RSA-PSS-PSS-SHA256
08 0a - RSA-PSS-PSS-SHA384
08 0b - RSA-PSS-PSS-SHA512
08 04 - RSA-PSS-RSAE-SHA256
08 05 - RSA-PSS-RSAE-SHA384
08 06 - RSA-PSS-RSAE-SHA512
04 01 - RSA-PKCS1-SHA256
05 01 - RSA-PKCS1-SHA384
06 01 - RSA-PKCS1-SHA512
03 03 -
02 03 -
03 01 -
02 01 -
03 02 -
02 02 -
04 02 -
05 02 -
06 02 -
00 2b - supported versions
00 09 - Length (9)
08 - Length (8)
03 04 - TLS 1.3
03 03 - TLS 1.2
03 02 - TLS 1.1
03 01 - TLS 1.0
00 2d - psk key exchange modes
00 02 - Length (2)
01 - Length (1)
01 - PSK with DHE
00 33 - Type (key share)
00 26 - Length (38)
00 24 - Length (36)
00 1d - x25519
00 20 - len=32
f3 82 e1 a9 19 38 75 ec eb 45 4f 85 be dd e0 3c
1f 14 59 97 7c b3 c1 5c e4 89 18 54 1a 71 1f 2f
Whenever I tried to remove some of the unused parts such as the supported versions, the Fatal Alert was all I got back. How did OpenSSL know to use all that unnecessary stuff, and why does Fastmail not accept anything less?
J.A. Coutts
Re: Test TLS 1.3 with VB6
I'm sending a 281 bytes CH and this works fine with smtp.fastmail.com:465. Don't see anything extraordinary with their TLS server support like bogus Client Hello Retries etc.
Code:
0000 - 16 03 03 01 14 01 00 01 10 03 03 b3 6b bf c7 db |...........³k¿ÇÛ|
0010 - 8c 99 bc 22 ad 9c 62 0f 1c 94 fe 0e d1 e8 2f ea |Œ™¼"*œb..”þ.Ñè/ê|
0020 - 36 9e 40 e2 5e 60 71 28 f4 3c 31 20 a7 cd 5a 86 |6ž@â^`q(ô<1 §ÍZ†|
0030 - 99 f8 37 55 39 0b a9 01 6a 12 4a 32 7a 31 97 7a |™ø7U9.©.j.J2z1—z|
0040 - 19 f8 33 e2 ca dc f7 58 c7 8e 3a ad 00 22 13 01 |.ø3âÊÜ÷XÇŽ:*."..|
0050 - 13 02 13 03 c0 2b c0 2f c0 2c c0 30 cc a9 cc a8 |....À+À/À,À0̨̩|
0060 - c0 09 c0 13 c0 0a c0 14 00 9c 00 9d 00 2f 00 35 |À.À.À.À..œ../.5|
0070 - 01 00 00 a5 00 00 00 16 00 14 00 00 11 73 6d 74 |...¥.........smt|
0080 - 70 2e 66 61 73 74 6d 61 69 6c 2e 63 6f 6d 00 0a |p.fastmail.com..|
0090 - 00 08 00 06 00 1d 00 17 00 18 00 05 00 05 01 00 |................|
00a0 - 00 00 00 00 0b 00 02 01 00 00 17 00 00 00 16 00 |................|
00b0 - 00 ff 01 00 01 00 00 23 00 06 00 00 00 00 00 00 |.ÿ.....#........|
00c0 - 00 0d 00 1e 00 1c 04 03 05 03 08 04 08 05 08 06 |................|
00d0 - 08 09 08 0a 08 0b 03 01 04 01 05 01 06 01 02 01 |................|
00e0 - 02 03 00 31 00 00 00 33 00 26 00 24 00 1d 00 20 |...1...3.&.$... |
00f0 - f5 3f 8b e1 fd 47 6b c4 62 e5 8a c7 48 5c 41 92 |õ?‹áýGkÄbåŠÇH\A’|
0100 - 12 62 93 56 81 6e 2d 58 a2 4c 44 31 11 be 7b 31 |.b“Vn-X¢LD1.¾{1|
0110 - 00 2b 00 05 04 03 04 03 03 |.+.......|
Decoded by wireshark:
Code:
Transmission Control Protocol, Src Port: 2320, Dst Port: 465, Seq: 1, Ack: 1, Len: 281
Transport Layer Security
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 276
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 272
Version: TLS 1.2 (0x0303)
Random: 2c9feed4303f2698c1ccdbcc5e521cea4a981fc6908eb51a813050b9651960a5
Session ID Length: 32
Session ID: 11340abfd65eb017209a4b7c28ee1b9e8c5160ada31f0558ee3ca2bc81eeb046
Cipher Suites Length: 34
Cipher Suites (17 suites)
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Compression Methods Length: 1
Compression Methods (1 method)
Compression Method: null (0)
Extensions Length: 165
Extension: server_name (len=22) name=smtp.fastmail.com
Type: server_name (0)
Length: 22
Server Name Indication extension
Server Name list length: 20
Server Name Type: host_name (0)
Server Name length: 17
Server Name: smtp.fastmail.com
Extension: supported_groups (len=8)
Type: supported_groups (10)
Length: 8
Supported Groups List Length: 6
Supported Groups (3 groups)
Supported Group: x25519 (0x001d)
Supported Group: secp256r1 (0x0017)
Supported Group: secp384r1 (0x0018)
Extension: status_request (len=5)
Type: status_request (5)
Length: 5
Certificate Status Type: OCSP (1)
Responder ID list Length: 0
Request Extensions Length: 0
Extension: ec_point_formats (len=2)
Type: ec_point_formats (11)
Length: 2
EC point formats Length: 1
Elliptic curves point formats (1)
EC point format: uncompressed (0)
Extension: extended_master_secret (len=0)
Type: extended_master_secret (23)
Length: 0
Extension: encrypt_then_mac (len=0)
Type: encrypt_then_mac (22)
Length: 0
Extension: renegotiation_info (len=1)
Type: renegotiation_info (65281)
Length: 1
Renegotiation Info extension
Renegotiation info extension length: 0
Extension: session_ticket (len=6)
Type: session_ticket (35)
Length: 6
Session Ticket: 000000000000
Extension: signature_algorithms (len=30)
Type: signature_algorithms (13)
Length: 30
Signature Hash Algorithms Length: 28
Signature Hash Algorithms (14 algorithms)
Signature Algorithm: ecdsa_secp256r1_sha256 (0x0403)
Signature Hash Algorithm Hash: SHA256 (4)
Signature Hash Algorithm Signature: ECDSA (3)
Signature Algorithm: ecdsa_secp384r1_sha384 (0x0503)
Signature Hash Algorithm Hash: SHA384 (5)
Signature Hash Algorithm Signature: ECDSA (3)
Signature Algorithm: rsa_pss_rsae_sha256 (0x0804)
Signature Hash Algorithm Hash: Unknown (8)
Signature Hash Algorithm Signature: SM2 (4)
Signature Algorithm: rsa_pss_rsae_sha384 (0x0805)
Signature Hash Algorithm Hash: Unknown (8)
Signature Hash Algorithm Signature: Unknown (5)
Signature Algorithm: rsa_pss_rsae_sha512 (0x0806)
Signature Hash Algorithm Hash: Unknown (8)
Signature Hash Algorithm Signature: Unknown (6)
Signature Algorithm: rsa_pss_pss_sha256 (0x0809)
Signature Hash Algorithm Hash: Unknown (8)
Signature Hash Algorithm Signature: Unknown (9)
Signature Algorithm: rsa_pss_pss_sha384 (0x080a)
Signature Hash Algorithm Hash: Unknown (8)
Signature Hash Algorithm Signature: Unknown (10)
Signature Algorithm: rsa_pss_pss_sha512 (0x080b)
Signature Hash Algorithm Hash: Unknown (8)
Signature Hash Algorithm Signature: Unknown (11)
Signature Algorithm: SHA224 RSA (0x0301)
Signature Hash Algorithm Hash: SHA224 (3)
Signature Hash Algorithm Signature: RSA (1)
Signature Algorithm: rsa_pkcs1_sha256 (0x0401)
Signature Hash Algorithm Hash: SHA256 (4)
Signature Hash Algorithm Signature: RSA (1)
Signature Algorithm: rsa_pkcs1_sha384 (0x0501)
Signature Hash Algorithm Hash: SHA384 (5)
Signature Hash Algorithm Signature: RSA (1)
Signature Algorithm: rsa_pkcs1_sha512 (0x0601)
Signature Hash Algorithm Hash: SHA512 (6)
Signature Hash Algorithm Signature: RSA (1)
Signature Algorithm: rsa_pkcs1_sha1 (0x0201)
Signature Hash Algorithm Hash: SHA1 (2)
Signature Hash Algorithm Signature: RSA (1)
Signature Algorithm: ecdsa_sha1 (0x0203)
Signature Hash Algorithm Hash: SHA1 (2)
Signature Hash Algorithm Signature: ECDSA (3)
Extension: post_handshake_auth (len=0)
Type: post_handshake_auth (49)
Length: 0
Extension: key_share (len=38) x25519
Type: key_share (51)
Length: 38
Key Share extension
Client Key Share Length: 36
Key Share Entry: Group: x25519, Key Exchange length: 32
Group: x25519 (29)
Key Exchange Length: 32
Key Exchange: fba6cde9ee8dc02b85002dab7f8114e5606ae91c25e383dc04a33c9fb393f75b
Extension: supported_versions (len=5) TLS 1.3, TLS 1.2
Type: supported_versions (43)
Length: 5
Supported Versions length: 4
Supported Version: TLS 1.3 (0x0304)
Supported Version: TLS 1.2 (0x0303)
The size of the handshake packet is determined more by the number of ciphersuites supported and the number of signatures supported -- these lists take up most of the space.
cheers,
</wqw>
Re: Test TLS 1.3 with VB6
I am having better success with your version of Client Hello. So far I have eliminated the following without encountering a Fatal Alert:
Code:
00 05 - status_request
00 05 - len=5
01 - OCSP?
00 00 - Responder ID list Length=0
00 00 - Request Extensions Length=0
00 0B - ec_point_formats
00 02 - len=2
01 - len=1
00 - none
00 17 - extended_master_secret
00 00 - len=0
00 16 - encrypt_then_mac
00 00 - len=0
FF 01 - renegotiation_info
00 01 - len=1
00 len=0
00 23 - session_ticket
00 06 - len=6
00 00 00 00 00 00
00 31 - post_handshake_auth
00 00
I would like to eliminate anything to do with TLS 1.2, so I will continue to work on it.
J.A. Coutts
Re: Test TLS 1.3 with VB6
Yes, these are mostly TLS 1.2 extensions I'm including for backcompat with 1.2 servers. You can reduce ciphersuites and signature types supported but keep the ones they choose to use initially.
cheers,
</wqw>
Re: Test TLS 1.3 with VB6
Well, I got it down to 146 bytes. SessionID was trimmed to zero length, 14 cipher suites were eliminated, EC point formats was eliminated, 11 signature algorithms were eliminated, and TLS 1.2 support was deleted.
Code:
01 00 00 92 - Header (len=146)
03 03 - TLS 1.2 (not used)
7B 40 26 42 36 29 EA ED 7D BB 00 8E E6 0F 63 60 - Client Random
0C 40 E2 EE 9C 8D D8 D1 CA EC 59 4F F7 4F 6D FD (not used)
00 - SessionID (len=0) (not used)
00 06 = Cipher Suites (len=4)
13 01 - TLS_AES_128_GCM_SHA256
13 02 - TLS_AES_256_GCM_SHA384
13 03 - TLS_CHACHA20_POLY1305_SHA256
01 - Compression
00 - len=0 (not used)
00 63 - Exstensions (len=99)
00 00 - Server Name
00 16 - len=22
00 14 - len=20
00 - host
00 11 - len=17
73 6D 74 70 2E 66 61 73 74 6D 61 69 6C 2E 63 6F 6D
(smtp.fastmail.com)
00 0A - supported groups
00 08 - len=8
00 06 - len=6
00 1D - X25519
00 17 - secp256r1
00 18 - secp384r1
00 0D - signature_algorithms
00 08 = len=8
00 06 = len=6
04 03 - ecdsa_secp256r1_sha256
05 03 - ecdsa_secp384r1_sha384
08 04 - rsa_pss_rsae_sha256
00 33 - key_share
00 26 - len=38
00 24 - len=36
00 1D - X25519
00 20 - len=32
11 25 13 48 67 06 35 2D 13 50 A5 76 81 20 A9 A3
0F 3B E8 5B 67 3A D2 8A A3 09 0C 37 4E 31 0E 6D
00 2B - Supported Versions
00 03 - len=3
02 - len=2
03 04 - TLS 1.3
The interesting part of the signature algorithms is that I has to delete each algorithm one at a time before testing for it to work, and when I got to "rsa_pss_rsae_sha256", I received a Fatal Alert. I have no explanation for this behaviour, and I presume that "rsa_pss_rsae_sha256" is a required algorithm.
The next problem I have to work on is the fact that upon receiving the certificate, my code returns "Handshake Authentication Error".
J.A. Coutts
Re: Test TLS 1.3 with VB6
The signature algorithm advertised by the client must be compatible with the server's certificate. Rarely the servers are deciding whether to use RSA vs ECDSA certificate based on client's supported signature algorithms.
So in this case rsa_pss_rsae_sha256 works because fastmail.com is using RSA based certificate and openssl supports RSA-PSS signature scheme.
FYI, older Crypto API does not support PSS (newer CNG does) so I had to reimplement PSS signature scheme in pure VB6 based on RFC 8017 to support these signatures in VbAsyncSocket. I can safely say that signatures support consumed well over half the development time and it is the most trickier part of the TLS spec.
cheers,
</wqw>
Re: Test TLS 1.3 with VB6
Fastmail sends a 23 byte encrypted record before the Certificate that GMail does not. It appears to be the cause of the Authentication error.
Any idea what it is?
J.A. Coutts
Re: Test TLS 1.3 with VB6
It's coming as HandshakeType = 8 i.e. encrypted_extensions. Seems to be an empty list here which is redundand traffic but mostly harmless.
cheers,
</wqw>
Re: Test TLS 1.3 with VB6
Quote:
Originally Posted by
wqweto
It's coming as
HandshakeType = 8 i.e.
encrypted_extensions. Seems to be an empty list here which is redundand traffic but mostly harmless.
cheers,
</wqw>
How can you tell that it is a type 8? I can't even get it to Decrypt properly. I recorded the encrypted record, the hsReadKey, and the hsReadIV. Then I created a simulation program and tried several different ways to Decrypt it with no success.
Code:
hsReadKey:
6F F5 E4 07 BB 0A 09 84 DE 39 AD 48 47 8F 12 12
hsReadIV:
A5 51 1E 23 B7 88 A4 DE FB FC 98 E5
Encrypted:
80 22 24 77 6D 7A 59 0B 8A CF 85 83 DA 23 30 FE
D6 BA C7 33 73 FA 7B
Decrypted:
5D C8 CA 8C 96 BA
Record Authenticated:
0B 8A CF 85 83 DA 23 30 FE D6 BA C7 33 73 FA 7B
J.A. Coutts
Addendum: 07/16/2025
By ignoring the error, the above results were achieved.
Re: Test TLS 1.3 with VB6
I am still struggling with the Encrypted Extensions sent by Fastmail. Regardless of what I do, the handshake decryption returns Error 0XC000A002 (STATUS_AUTH_TAG_MISMATCH). The code I am using works great with GMail. The difference between the two is that GMail sends the Encrypted Extensions, Certificate, and Finished records in one compacted record, and Fastmail sends them in separate records.
I suspect that the AuthData is not what BCryptDecrypt is expecting, but my attempts to figure out how the AuthTag is calculated were very frustrating because of all the different options available.
Code:
2A 2D FD 5F E6 5D 51 77 0C 86 01 0E F8 B9 2D 44 - hsWriteKey
2B D5 5A F6 46 FF 68 2A D0 6F 01 EA - hsWriteIV
1D AF 3F 07 E9 B8 74 42 DA 7D 2D 88 15 B0 4C 8D - hsReadKey
56 9C E2 58 1B 9A E2 C8 0D 8E 51 28 - hsReadIV
17 03 03 00 17 EF 6B 48 29 E7 AE 0D B4 50 24 F2 - Complete Record
27 F3 5A A7 21 4E 8E 6E 38 9F 4F 3E
17 03 03 00 17 - Header (not Encrypted)
EF 6B 48 29 E7 AE - Encrypted Data
0D - Data type (Encrypted)
B4 50 24 F2 27 F3 5A A7 21 4E 8E 6E 38 9F 4F 3E - AuthTag (not Encrypted)
My best guess as to what the decrypted 6 bytes should look like is:
Does anyone have any idea what BCrypt is looking for in the way of Authentication Data?
J A. Coutts
Re: Test TLS 1.3 with VB6
Using the values provided here (https://tls13.xargs.org/), I was able to locate one of the problems with Encrypted Extensions. To provide for the ability to add extra characters to an encrypted record, TLS 1.3 adds a non zero character (Record Type) to the record to be encrypted. This is because the encryption itself can contain zeros, and a non zero character is needed to act as a separator between the data and the zero buffering.
When GMail sends a combined record, the entire record is sent using the character 0x17 in the Record Header, and this is the character that must be used as the Record Type to verify the Encrypted Extensions as well as the Certificate, Certificate Verify, and Finished records.
When a separate Encrypted Extensions record is sent by the server, 0x17 is used in the header to identify it as an encrypted record, but 0x16 is used as the extra Record Type (handshake record). This is the character that must be used to verify the record.
J.A. Coutts
Re: Test TLS 1.3 with VB6
Handshake records (0x16) are not encrypted while Application Data records (0x17) are always encrypted which is what probably made the difference in your case.
Re: Test TLS 1.3 with VB6
It turns out that using 0x16 as the added non zero character was not the problem at all. I had requested 1301 (AES GCM 128) as my preferred cryptographic suite. What I failed to notice was that Fastmail responded with 1302 (AES GCM 256) instead. My routines were not yet capable of adjusting to other suites, and removing 1302 as an option, Fastmail simply went to 1303. The only way to get it to use 1301 was to make that the only available option.
I do intend to support other options in the future, but in this case I was after the fastest method. It takes less then a second to check for new mail, and the extra security provided by 1302 or 1303 is not worth the time and effort. Every connection to the server provides a new set of keys.
The problem I have now is that SMTP is returning "500 5.5.2 Error: bad syntax". Since this has nothing to do with TLS 1.3, I will post this problem separately if necessary.
J.A. Coutts
Re: Test TLS 1.3 with VB6
AES-256+GCM impl in h/w often is faster than AES-128+GCM in h/w (so called AES-NI)
Re: Test TLS 1.3 with VB6
The TLS_Test program has been updated to reflect the addition of Account Verification on Fastmail. It works, but I am not completely happy with the code I had to use to get Fastmail to function properly, as the "QUIT" command produces a Syntax Error that I have not been able to resolve.
On both sites (GMail & Fastmail) I have provided fictitious credentials which will not verify. To get it to produce positive results, you must change strSMTPAcct, strSender, & strPW to real values. In both cases the Password is a 16 byte variable provided by each site as part of 2 Factor Authentication.
J.A. Coutts