The Pulsar Cafe    ·

Intermediate Problem #1: Fingerprinting SMTP Servers

A little bit about intermediate problems


Intermediate problems are those smaller problems you need to solve in the process of putting together some larger system. They are “smaller” in the sense that their solution is only one part of the solution to a bigger problem, but that doesn’t put an upper bound on their complexity or difficulty. Rather, the complexity and difficulty of the intermediate problems puts a lower bound on the complexity and difficulty of the bigger problem. In programming, much of getting big things done is getting little things done.1

If you spend lots of time getting computers to do things, you are constantly solving intermediate problems. And if you don’t remember or record the solutions carefully, you’ll end up having to figure out how to solve some problems more than once. Which is really a bore.

Unfortunately, it didn’t occur to me before I started this blog that I should record all of my intermediate problems and their solutions. Writing down that information is the equivalent of writing the question and answer parts of an average SO post. Not exactly a massive undertaking. And not only will it probably help future me to have a repository of all the little hacks I’ve done over the years, someone else might stumble across a solution here that saves them some time.2

So, here is my first post on an intermediate problem I solved in the process of getting a computer to do something. I hope to start publishing this type of post pretty consistently.

The problem


I have recently been working towards a gnus setup for reading news and doing email. As part of this setup, I’m using the msmtp program and the ProtonMail Bridge for sending mail. In order to use TLS when sending mail, msmtp needs a fingerprint to identify the smtp server it’s communicating with.

The relevant lines in the .msmtprc are

...

tls on
tls_fingerprint $SMTP_SERVER_FINGERPRINT

...

How does one find the fingerprint of an smtp server? I didn’t know this off the top of my head, and it took me a few minutes of googling to find a SO post3 with the answer.

The solution

Use the openssl s_client tool to open a connection to the server and upgrade the connection to use tls. That will give you a big ol’ chunk of data like shown below.

$ openssl s_client -connect $HOST:$PORT -starttls smtp
CONNECTED(00000006)
depth=0 C = CH, O = Proton Technologies AG, OU = ProtonMail, CN = 127.0.0.1
verify error:num=18:self signed certificate
verify return:1
depth=0 C = CH, O = Proton Technologies AG, OU = ProtonMail, CN = 127.0.0.1
verify return:1
---
Certificate chain
 0 s:/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=127.0.0.1
   i:/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=127.0.0.1
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDizCCAnOgAwIBAgIQWaa7NYfPpjw4GQTeQRXW7jANBgkqhkiG9w0BAQsFADBX
MQswCQYDVQQGEwJDSDEfMB0GA1UEChMWUHJvdG9uIFRlY2hub2xvZ2llcyBBRzET
MBEGA1UECxMKUHJvdG9uTWFpbDESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTE4MDIx
MDE2NTQ1OVoXDTE5MDIxMDE2NTQ1OVowVzELMAkGA1UEBhMCQ0gxHzAdBgNVBAoT
FlByb3RvbiBUZWNobm9sb2dpZXMgQUcxEzARBgNVBAsTClByb3Rvbk1haWwxEjAQ
BgNVBAMTCTEyNy4wLjAuMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
ALAjd96Y2aUDtqRc4/TylK2DRXVlO4S1Q52CcANODxykymHJmoO11ySByjdbf929
3wfjr1yk0PsIgKxh/cXFJFEBk5WXpBFsW2EyzKdWXDThuvQUy2MXbeczPHdg7lve
+lAVan70jcrex8OHfb0RzxhKoHzqtXl829i12jkNVk1QxTuuQd/uLWt3HnB+fgpo
JnOBUqLk2zaVQrGpSN/D31AJQKCTncUMC0KT8dVE7YnrEBljpOpPUwgTmRySHkES
6qC+bfOwHyM03Va3rxQZVBcVjWwGg4qRNLjfbP1Wa7+BMjhM/oICNSr3ZD6hp3lX
e9UkopUwaBESyOAoZaBeSrMCAwEAAaNTMFEwDgYDVR0PAQH/BAQDAgKkMB0GA1Ud
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAPBgNVHRMBAf8EBTADAQH/MA8GA1Ud
EQQIMAaHBH8AAAEwDQYJKoZIhvcNAQELBQADggEBAFmYFi3MqIR7dXu3nXxFFeWr
wC2L6EI/OtxyJAzod8POo0t5Dzovv3gqRzbiYR1XMcaFSnAPNopAYqCWPH1aPjVR
Z3AJJmKw4q5TYHewlQwR+ha3nGpxG3PQQxIA6R91xrpTBHQ/6GjMpmxYYy3axfVU
GYemSoq036IDCbSuoWXQ8eCCAdSZ3Imax619tBMshSWgqQM2eYL8jZW6xdS2HsTQ
FsjhEOFBWU30iGkzZyiuwrkLJgpAVgWzqnTeOdngHmmRV5BrUPNqzuyl6vjja5HS
rk0WyQa/OWvmXy36fKvnrAwCTOzX8o/hgeUMhjFujdLBroV54VZaNcSg/2yAIK8=
-----END CERTIFICATE-----
subject=/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=127.0.0.1
issuer=/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=127.0.0.1
---
Acceptable client certificate CA names
/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=127.0.0.1
---
SSL handshake has read 1791 bytes and written 491 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 787D078EE0EC446568A8940B608DD1EF24845F34308F9A78E30FECCB453391FE
    Session-ID-ctx:
    Master-Key: B2591A2D79925C5C720BD673D2837C8A8753DFC7EDFF4899D28D798734A7F6602CD276F7542E48641E0D420ADBB05225
    TLS session ticket:
    0000 - fa 3e 3b 1e 86 bc 72 1c-0e c6 09 84 01 aa 91 f3   .>;...r.........
    0010 - 74 5f 5f cd b8 12 57 f1-73 c6 83 31 e0 d7 b3 ad   t__...W.s..1....
    0020 - a1 f8 23 28 3d 44 92 9e-c0 ed 4e 9d ef be 5b c9   ..#(=D....N...[.
    0030 - 3d 41 42 29 08 9f 2f 6a-58 52 88 5a 2e f1 82 70   =AB)../jXR.Z...p
    0040 - 07 71 df f7 82 13 b6 50-45 6d e9 f5 c2 26 61 1a   .q.....PEm...&a.
    0050 - fa 0e e5 a7 8e 23 34 9a-1e d8 65 4f 29 f0 1a 9f   .....#4...eO)...
    0060 - fa 68 82 1d ff 7e 2e 1e-12 a8 a0 3b 12 f2 02 7f   .h...~.....;....
    0070 - 1f e9 a6 85 79 a5 14 6e-                          ....y..n

    Start Time: 1521155643
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
250 AUTH PLAIN LOGIN

You can then pipe that data to the openssl x509 tool which we use to calculate the fingerprint. The -noout option tells the program not to display the full certificate.

$ openssl s_client -connect localhost:1025 -starttls smtp \
    | openssl x509 -fingerprint -noout
SHA1 Fingerprint=4D:51:6F:12:5E:5F:45:4A:8B:DE:D0:64:FC:D5:3A:60:48:1C:EE:26

If you want just the fingerprint value, you can tack on another filter:

$ openssl s_client -connect localhost:1025 -starttls smtp \
    | openssl x509 -fingerprint -noout
    | cut -d'=' -f2
4D:51:6F:12:5E:5F:45:4A:8B:DE:D0:64:FC:D5:3A:60:48:1C:EE:26


1: To underscore how important solving intermediate problems is to getting things done, I point out that Stack Overflow runs a business helping programmers find answers to their intermediate problems.

2: There is an expected value calculation to be done here that involves the chance one of my posts helps someone building something that will hurt people. That term could have a weight of negative infinity which I think would lead to a Pascal’s Wager type situation. I also think I can discard that because any solutions I post here will be accessible somewhere else on the internet. I’m not doing foundational research on agent design.

3: Surprise! Providing solutions to intermediate problems since 2008.

comments powered by Disqus