Gmail SMTP在ClientHello上关闭套接字,使用十六进制15 03 01 00 02 02 16

问题描述 投票:0回答:1

我正在构建自己的SMTP客户端(在WinAPI中使用C ++,但这不重要)。首先,我在端口25连接到smtp.gmail.com。它响应

220 smtp.gmail.com ESMTP f191sm4468458ite.4 - gsmtp

我发送EHLO消息,然后我收到

250-smtp.gmail.com at your service, [<I blocked out my IP here>]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8

现在,我发送STARTTLS。响应:

220 2.0.0 Ready to start TLS

看起来不错,所以在这一点上我假设我开始按照RFC5246中的指定发送ClientHello。所以我发送以下hexes(将它们编码为字节后):

03 03 5a 9e 49 ff

前两个应该是ProtocolVersion,两个uint8字节与33。然后,接下来的四个字节应该是当前的UTC客户端纪元时间,作为大端的UNIX uint32。但在我发送剩余的ClientHello之前,Gmail的SMTP会立即关闭套接字

15 03 01 00 02 02 16

我不知道如何在RFC或其他方面找到有关此错误的信息。它似乎不是一个警报,因为RFC状态警报应该以1或2的字节开头.Gmail的SMTP响应意味着什么,我在前6个字节中做错了什么?

c++ ssl winapi smtp tls1.2
1个回答
3
投票

根据RFC 5246 Section 6.2.1,消息的结构是

struct {
    uint8 major;
    uint8 minor;
} ProtocolVersion;

enum {
    change_cipher_spec(20), alert(21), handshake(22),
    application_data(23), (255)
} ContentType;

struct {
    ContentType type;
    ProtocolVersion version;
    uint16 length;
    opaque fragment[TLSPlaintext.length];
} TLSPlaintext;

使用此,接收的消息可以解释为

15 : type = alert
03 : version.major = 3
01 : version.minor = 1
00
02 : length = 2
02 : fragment[0] = 0x02
16 : fragment[1] = 0x16

现在您可以使用RFC 5246 Section 7.2来解码片段部分。

02 : level = fatal
16 : description = record_overflow

您的错误似乎是您发送了ClientHello而没有将其包装在TLSPlaintext中。

当我试图将03 03 5a 9e 49 ff解释为TLSPlaintext时,它将是

03 : type = ?
03 : version.major = 3
5a : version.minor = 90
9e
49 : length = 0x9e49
ff : fragment[0] = 0xff

根据record_overflowRFC 5246 Section 7.2.2的描述,length字段不能超过2 ^ 14 + 2048字节,但0x9e49超过此限制。这应该是你得到这个错误的原因。

© www.soinside.com 2019 - 2024. All rights reserved.