DTLS: treat bad MAC on Finished as an error

This is not required nor recommended by the protocol, and it's a layering
violation, but it's a know flaw in the protocol that you can't detect a PSK
auth error in any other way, so it is probably the right thing to do.

closes #227
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 8d4b98b..4938964 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -3573,6 +3573,23 @@
             if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
                 ret == MBEDTLS_ERR_SSL_INVALID_MAC )
             {
+                /* Except when waiting for Finished as a bad mac here
+                 * probably means something went wrong in the handshake
+                 * (eg wrong psk used, mitm downgrade attempt, etc.) */
+                if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
+                    ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
+                {
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+                    if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+                    {
+                        mbedtls_ssl_send_alert_message( ssl,
+                                MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+                                MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+                    }
+#endif
+                    return( ret );
+                }
+
 #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
                 if( ssl->conf->badmac_limit != 0 &&
                     ++ssl->badmac_seen >= ssl->conf->badmac_limit )
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index c07c8ca..8d85850 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -2851,6 +2851,13 @@
             -c "skip write certificate$" \
             -s "! Certificate verification was skipped"
 
+run_test    "DTLS wrong PSK: badmac alert" \
+            "$P_SRV dtls=1 psk=abc123 force_ciphersuite=TLS-PSK-WITH-AES-128-GCM-SHA256" \
+            "$P_CLI dtls=1 psk=abc124" \
+            1 \
+            -s "SSL - Verification of the message MAC failed" \
+            -c "SSL - A fatal alert message was received from our peer"
+
 # Tests for receiving fragmented handshake messages with DTLS
 
 requires_gnutls