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


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
depth=0 C = CH, O = Proton Technologies AG, OU = ProtonMail, CN =
verify error:num=18:self signed certificate
verify return:1
depth=0 C = CH, O = Proton Technologies AG, OU = ProtonMail, CN =
verify return:1
Certificate chain
 0 s:/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=
   i:/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=
Server certificate
subject=/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=
issuer=/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=
Acceptable client certificate CA names
/C=CH/O=Proton Technologies AG/OU=ProtonMail/CN=
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
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 787D078EE0EC446568A8940B608DD1EF24845F34308F9A78E30FECCB453391FE
    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)

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

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