Smtp-send-message and tls version

The code below works for sending emails, but I'm getting messages from AWS SES saying that those messages are being sent with tls 1.0 or 1.1 which is deprecated and will be unavailable soon. If I understand it correctly, this should be controlled by #:tls-encode ports->ssl-ports and default to 'auto. It seems as if it is negotiating the lowest security that is common between the client and server.

I see some parameters that look like it might let me force 'tls12 or 'tls13, but I'm not clear on how to get that into this function. Ideally I'd rather not force a particular version of tls and instead just use the highest version it can negotiate.

Any suggestions or examples that I might have overlooked?

(define (send-invite to-email title body)
  (smtp-send-message
   server-address
   from-address
   (list to-email)
   (replace-field "To" to-email
                  (replace-field "Subject" title
                                 email-header))
   body
   #:port-no 587
   #:auth-user smtp-user
   #:auth-passwd smtp-passwd
   #:tls-encode ports->ssl-ports))

This looks like a problem in the net-lib package. In net/smtp, the smtp-send-message* function calls its tls-encode argument with 'tls as the protocol argument (#:encrypt), but the symbol 'tls means "TLS 1.0 exactly".

You can work around this issue by defining a wrapper function that overrides the bogus protocol argument, such as one of the following:

(define (secure-workaround-tls-encode r w
                                      #:mode mode
                                      #:encrypt _ignored-encrypt
                                      #:close-original? close-original?)
  (ports->ssl-ports r w
                    #:mode mode
                    #:encrypt 'secure
                    #:close-original? close-original?))

(define (insecure-workaround-tls-encode r w
                                        #:mode mode
                                        #:encrypt _ignored-encrypt
                                        #:close-original? close-original?)
  (ports->ssl-ports r w
                    #:mode mode
                    #:encrypt 'auto
                    #:close-original? close-original?))

and then pass {insecure,secure}-workaround-tls-encode as the #:tls-encode argument.

Note that 'auto selects the latest compatible version of TLS but skips steps necessary for TLS to be secure, so 'auto is insecure without further setup. Use 'secure if you care about security.

1 Like