Add accessors to config DN hints for cert request

mbedtls_ssl_conf_dn_hints()
mbedtls_ssl_set_hs_dn_hints()

Signed-off-by: Glenn Strauss <gstrauss@gluelogic.com>
diff --git a/ChangeLog.d/mbedtls_ssl_dn_hint.txt b/ChangeLog.d/mbedtls_ssl_dn_hint.txt
new file mode 100644
index 0000000..f569a36
--- /dev/null
+++ b/ChangeLog.d/mbedtls_ssl_dn_hint.txt
@@ -0,0 +1,3 @@
+Features
+   * Add accessors to configure DN hints for certificate request:
+     mbedtls_ssl_conf_dn_hints() and mbedtls_ssl_set_hs_dn_hints()
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index 79d7ddd..d55fdb4 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1494,6 +1494,10 @@
 #if defined(MBEDTLS_SSL_SRV_C)
     mbedtls_ssl_hs_cb_t MBEDTLS_PRIVATE(f_cert_cb);  /*!< certificate selection callback */
 #endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+    const mbedtls_x509_crt *MBEDTLS_PRIVATE(dn_hints);/*!< acceptable client cert issuers    */
+#endif
 };
 
 struct mbedtls_ssl_context
@@ -3126,6 +3130,26 @@
                                mbedtls_x509_crt *ca_chain,
                                mbedtls_x509_crl *ca_crl );
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+/**
+ * \brief          Set DN hints sent to client in CertificateRequest message
+ *
+ * \note           If not set, subject distinguished names (DNs) are taken
+ *                 from \c mbedtls_ssl_conf_ca_chain()
+ *                 or \c mbedtls_ssl_set_hs_ca_chain())
+ *
+ * \param conf     SSL configuration
+ * \param crt      crt chain whose subject DNs are issuer DNs of client certs
+ *                 from which the client should select client peer certificate.
+ */
+static inline
+void mbedtls_ssl_conf_dn_hints( mbedtls_ssl_config *conf,
+                                const mbedtls_x509_crt *crt )
+{
+    conf->MBEDTLS_PRIVATE(dn_hints) = crt;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+
 #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
 /**
  * \brief          Set the trusted certificate callback.
@@ -3650,6 +3674,21 @@
                                   mbedtls_x509_crt *ca_chain,
                                   mbedtls_x509_crl *ca_crl );
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+/**
+ * \brief          Set DN hints sent to client in CertificateRequest message
+ *
+ * \note           Same as \c mbedtls_ssl_conf_dn_hints() but for use within
+ *                 the SNI callback or the certificate selection callback.
+ *
+ * \param ssl      SSL context
+ * \param crt      crt chain whose subject DNs are issuer DNs of client certs
+ *                 from which the client should select client peer certificate.
+ */
+void mbedtls_ssl_set_hs_dn_hints( mbedtls_ssl_context *ssl,
+                                  const mbedtls_x509_crt *crt );
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+
 /**
  * \brief          Set authmode for the current handshake.
  *
diff --git a/library/ssl_misc.h b/library/ssl_misc.h
index 119826f..8230163 100644
--- a/library/ssl_misc.h
+++ b/library/ssl_misc.h
@@ -850,6 +850,9 @@
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
     const unsigned char *sni_name;      /*!< raw SNI                        */
     size_t sni_name_len;                /*!< raw SNI len                    */
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+    const mbedtls_x509_crt *dn_hints;   /*!< acceptable client cert issuers */
+#endif
 #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
 };
 
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 5fa02d2..1969738 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -1472,6 +1472,14 @@
     ssl->handshake->sni_ca_crl     = ca_crl;
 }
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+void mbedtls_ssl_set_hs_dn_hints( mbedtls_ssl_context *ssl,
+                                  const mbedtls_x509_crt *crt)
+{
+    ssl->handshake->dn_hints = crt;
+}
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
+
 void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
                                   int authmode )
 {
diff --git a/library/ssl_tls12_server.c b/library/ssl_tls12_server.c
index 21e5cda..0952872 100644
--- a/library/ssl_tls12_server.c
+++ b/library/ssl_tls12_server.c
@@ -2489,6 +2489,16 @@
          *       `mbedtls_ssl_conf_ca_cb()`, then the
          *       CertificateRequest is currently left empty. */
 
+#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+        if( ssl->handshake->dn_hints != NULL )
+            crt = ssl->handshake->dn_hints;
+        else
+#endif
+        if( ssl->conf->dn_hints != NULL )
+            crt = ssl->conf->dn_hints;
+        else
+#endif
 #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
         if( ssl->handshake->sni_ca_chain != NULL )
             crt = ssl->handshake->sni_ca_chain;