RFC: fully secure SMTP connection for "hg email"

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sun Mar 17 11:42:10 CDT 2013


Hi, devels

We can use secure connection to SMTP server by setting "[smtp] tls" to
starttls or smtps for "hg email".

But, AFAIK, the certificate of SMTP server isn't verified as same as
verification for HTTPS connection at push/pull operations. This may
cause man-in-the-middle security problem.

To connect to SMTP server safely via (maybe untrustable) networks, the
certificate of it should be verified: e.g. mail transmission via GMail
account.

So, I tried to verify the certificate of SMTP server before
authentication/transmission step of SMTP, but it seems to be difficult
to do so as same as verification for HTTPS connection, because:

  - in smtplib, "ssl.wrap_socket()" is invoked for STARTTLS/SMTPS
    without explicit "cert_reqs" argument, so default value
    "CERT_NONE" is used for it:

      http://hg.python.org/cpython/file/59292f366b53/Lib/smtplib.py#l635
      http://hg.python.org/cpython/file/59292f366b53/Lib/smtplib.py#l874

  - "cert_reqs=CERT_NONE"(= no validation required) causes that the
    certificate gotten by "getpeercert()" on "ssl.SSLSocket" is always
    empty, even though the certificate is received from the peer:

      http://docs.python.org/2/library/ssl.html#ssl.SSLSocket.getpeercert
      http://hg.python.org/cpython/file/b878df1d23b1/Modules/_ssl.c#l1048

  - in the other hand, "getpeercert(True)" on "ssl.SSLSocket" always
    returns DER-encoded form of the entire certificate, if it is
    received from peer, even though "ssl.SSLSocket" is created with
    "cert_req=CERT_NONE", so

  - the certificate of SMTP server can be verified:

    - not in "cacerts" way, 
    - but in "hostfingerprint" way

What should we do for secure SMTP connection ?

  1. it is already secure enough, because the certificate of SMTP
     server is verified, in fact

     please tell me what I overlooked :-)

  2. verify the certificate of SMTP server

     2.1. only in "hostfingerprint" way

          this is easy to implement, but users should confirm
          fingerprint of peer cert and put it into configuration.

          it should bore users already having cacerts (e.g.
          Mercurial/TortoiseHg on Windows bundle it)

     2.2. also in "cacerts" way

          Are there any good ideas for it ?

          I have only one un-smart idea below:

            make another SSL connection with "cert_req=CERT_REQUIRED"
            to verify in "cacerts" way. then, compare fingerprint of
            the certificates gotten from this connection and one
            gotten from SMTP connection

  3. do nothing any more in Mercurial

     for fully secure SMTP connection, users should use some external
     tools supporting STARTTLS/SMTPS with valid cacerts

     it should bore users, especially on Windows (for limited/un-easy
     options)

----------------------------------------------------------------------
[FUJIWARA Katsunori]                             foozy at lares.dti.ne.jp


More information about the Mercurial-devel mailing list