我正在构建自己的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字节,3
和3
。然后,接下来的四个字节应该是当前的UTC客户端纪元时间,作为大端的UNIX uint32。但在我发送剩余的ClientHello之前,Gmail的SMTP会立即用
15 03 01 00 02 02 16
我不确定如何在RFC或其他方面找到有关此错误的信息。它似乎不是一个警报,因为RFC状态警报应该以1或2的字节开头.Gmail的SMTP响应意味着什么,我在前6个字节中做错了什么?
答案 0 :(得分: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
根据RFC 5246 Section 7.2.2中record_overflow
的说明,length
字段不能超过2 ^ 14 + 2048字节,但0x9e49超出此限制。这应该是你遇到这个错误的原因。