jetmore / swaks

Swaks - Swiss Army Knife for SMTP
http://jetmore.org/john/code/swaks/
GNU General Public License v2.0
847 stars 86 forks source link

enhance TLS cert debugging #83

Open jetmore opened 5 months ago

jetmore commented 5 months ago

v20240103.0 improved certificate debugging a great deal. Prior to that release, only one cert was printed for debug. After, every cert that was directly provided (as opposed to being pulled from the local trust store) was displayed. Additionally, notAfter, commonName, and serverAltName for each cert were presented. (these changes apply to both local and peer cert, but this ticket is focusing only on peer certs)

For example, consider this command:

../../swaks \
    --to user@host1.nodns.test.swaks.net \
    --from recip@host1.nodns.test.swaks.net \
    --helo hserver \
    --tls \
    --tls-ca-path ../certs \
    --tls-verify-target signed-intermediate.example.com \
    --pipe "../server/smtp-server.pl --silent --domain pipe   --cert ../certs/signed-intermediate-partial-chain.pem   --key  ../certs/signed-intermediate.example.com.key part-0000-connect-standard.txt   part-0101-ehlo-all.txt   part-0203-starttls-basic-verify.txt   part-0105-ehlo-post-tls-info.txt   part-1000-mail-basic.txt   part-1100-rcpt-basic-accept.txt   part-2500-data-accept-basic.txt   part-3000-shutdown-accept.txt   "

signed-intermediate-partial-chain.pem contains the cert for signed-intermediate.example.com and also the intermediate cert, but not the root cert

Prior to v20240103.0, the interesting part would have looked like:

=== TLS peer DN="/C=US/ST=Indiana/O=Swaks Development (signed-intermediate.example.com, with-SAN)/CN=signed-intermediate.example.com/emailAddress=proj-swaks@jetmore.net"

Of note, this does not show the client information, does not show any expiration or SAN information, and only shows a single cert even if a chain is presented.

After v20240103.0 the output now looks like this:

=== TLS peer[0]   subject=[/C=US/ST=Indiana/O=Swaks Development (signed-intermediate.example.com, with-SAN)/CN=signed-intermediate.example.com/emailAddress=proj-swaks@jetmore.net]
===               commonName=[signed-intermediate.example.com], subjectAltName=[DNS:signed-intermediate.example.com] notAfter=[2033-09-15T22:49:58Z]
=== TLS peer[1]   subject=[/C=US/ST=Indiana/O=Swaks Development (ca-intermediate, without-SAN)/emailAddress=proj-swaks@jetmore.net]
===               commonName=[], subjectAltName=[] notAfter=[2033-09-15T22:49:32Z]
=== TLS peer certificate passed CA verification, passed host verification (using host signed-intermediate.example.com to verify)

This is better but not perfect. The primary goal of this ticket is that every part of the ca trust chain (including the ones in the local trust store) be printed during this debug, not just certs that were sent by the server. Openssl has to have access to this information. I've gotten close to it before using set_verify but I could never quite make it work right.

TO BE DONE: show example of openssl verifying the chain including the root cert out of the trusted store TO BE DONE: show example of what I'd like swkas output to look like (root ca info printed, provided or trusted for each, verification status for each)