Results 1 to 20 of 20

Thread: Test TLS 1.3 with VB6

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    Test TLS 1.3 with VB6

    Troubleshooting a TLS 1.3 connection is not easy. Because I was having difficulty getting "curve25519" to work properly in Win 10/11, I decided to implement a simulation program that I could step through.

    Even though "ECDH_P256" and "curve25519" are both theoretically ECDH algorithms, there are slight differences. This is a result of the way that MS handles X22519 in relation to the other ECDH algorithms. ECDH_P256, ECDH_P384, and ECDH_P512 fit well into the MS nomenclature, but X25519 does not. There was originally a distrust in CISA as to the provision of back doors in the protocols, so X25519 was adopted as an alternative. X25519 is not supported in Windows versions prior to part way through Win 10. In theory, X25519 is faster than the others, but I cannot substantiate that, at least not from a client perspective using VB6.

    In the attached program, I have retained the networking class and module for a couple of reasons. There are a few routines in them that are still used, and it shows the similarity between the network code and the command buttons that I have used in the simulation. The network code is found in the sub TCP.

    The ECDH_P256 routine simulates an actual connection to the Gmail SMTP server. The network traffic was recorded using PacketVB, while DebugPrintByte statements recorded the various calculation results in the Client.

    The X25519 routine parallels the Simple 1-RTT Handshake routine in RFC 8448. To simplify the comparison, I have included a text file (RTT_HS.txt), that restructures the text to better coincide with our program.

    In naming the variables for the simulation, "X" is used for X25519 related items, "P" is used for ECDH_P256, "C" is used for Client, and "S" is used to represent Server related items. It is hopeful that this simulation will help VB6 programmers better understand TLS 1.3.

    J.A. Coutts
    Updated: 06/18/2025 - See post #2 for details

    Updated: 09/04/2025 - See post #20 for details
    Attached Files Attached Files
    Last edited by couttsj; Sep 4th, 2025 at 04:14 PM.

  2. #2

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  3. #3
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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>

  4. #4

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  5. #5
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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>

  6. #6

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  7. #7
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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“Vn-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>

  8. #8

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  9. #9
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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>

  10. #10

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  11. #11
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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>

  12. #12

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  13. #13
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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>

  14. #14

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    Re: Test TLS 1.3 with VB6

    Quote Originally Posted by wqweto View Post
    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.
    Last edited by couttsj; Jul 15th, 2025 at 05:56 PM.

  15. #15

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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:
    Code:
     08
       00 
          00 02
             00 00
    Does anyone have any idea what BCrypt is looking for in the way of Authentication Data?

    J A. Coutts

  16. #16

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  17. #17
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    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.

  18. #18

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

  19. #19

  20. #20

    Thread Starter
    Frenzied Member
    Join Date
    Dec 2012
    Posts
    1,674

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width