CA_SSL_EKCB_DTLS = 1
}CASslEkcbProtocol_t;
-typedef OCStackResult (*UserConfirmNoCertCallback)(void * ctx);
+/**
+ *@enum CACertificateVerificationStatus_t
+ * type of certificate status info to be used when invoking
+ * certificate verification status info callback
+ */
+typedef enum
+{
+ CA_CERTIFICATE_VERIFY_SUCCESS_MUTUAL = 0,
+ CA_CERTIFICATE_VERIFY_NO_CERT,
+ CA_CERTIFICATE_VERIFY_FAILED
+} CACertificateVerificationStatus_t;
+
+/**
+ * Callback function type for certificate verification status.
+ * @param[in] status Certificate verification status info.
+ */
+typedef void (*CertificateVerificationCallback_t)(CACertificateVerificationStatus_t status);
/**
* This internal callback is used by CA layer to
CAResult_t CASetSslExportKeysCallback(SslExportKeysCallback_t exportKeysCb,
CASslEkcbProtocol_t protocol, CASslEkcbRole_t role);
-void CAsetNoCertConfirmCallback(UserConfirmNoCertCallback noCertCallback);
+
+void CAsetCertificateVerificationCallback(CertificateVerificationCallback_t noCertCallback);
#endif //__WITH_TLS__ or __WITH_DTLS__
static CAgetPkixInfoHandler g_getPkixInfoCallback = NULL;
/**
- * Function pointer to get user confirmation in case of client's certificate absence
+ * Callback to inform in case of client's certificate absence
*/
-static UserConfirmNoCertCallback g_noCertConfirmCallback = NULL;
-
-/**
- * Function pointer to get user confirmation in case of client's certificate absence
- */
-static int g_noCertConfirmState = OC_STACK_METHOD_NOT_ALLOWED;
+static CertificateVerificationCallback_t g_CertificateVerificationCallback = NULL;
/**
* @var g_setupPkContextCallback
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
}
-void CAsetNoCertConfirmCallback(UserConfirmNoCertCallback noCertCallback)
+void CAsetCertificateVerificationCallback(CertificateVerificationCallback_t certVerifyStatusCallback)
{
OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
- g_noCertConfirmCallback = noCertCallback;
+ g_CertificateVerificationCallback = certVerifyStatusCallback;
OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
}
ret = mbedtls_ssl_handshake_step(&peer->ssl);
}
uint32_t flags = mbedtls_ssl_get_verify_result(&peer->ssl);
- if (MBEDTLS_SSL_IS_SERVER == peer->ssl.conf->endpoint &&
- MBEDTLS_X509_BADCERT_MISSING == flags)
- {
- if (OC_STACK_METHOD_NOT_ALLOWED == g_noCertConfirmState)
- {
- g_noCertConfirmState = g_noCertConfirmCallback(NULL);
- if (OC_STACK_OK == g_noCertConfirmState)
- {
- OIC_LOG_V(DEBUG, NET_SSL_TAG, "Absent peer's cert: user confirmation received");
- }
- else if (OC_STACK_USER_DENIED_REQ == g_noCertConfirmState)
- {
- OIC_LOG_V(DEBUG, NET_SSL_TAG, "Absent peer's cert: user denial received");
- SSL_CHECK_FAIL(peer, MBEDTLS_SSL_ALERT_LEVEL_FATAL, "Handshake error", 1,
- CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
- }
- }
- }
if (0 != flags &&
((MBEDTLS_SSL_IS_CLIENT == peer->ssl.conf->endpoint) ||
(MBEDTLS_SSL_IS_SERVER == peer->ssl.conf->endpoint && MBEDTLS_X509_BADCERT_MISSING != flags)))
OIC_LOG_BUFFER(ERROR, NET_SSL_TAG, (const uint8_t *) &flags, sizeof(flags));
SSL_CHECK_FAIL(peer, flags, "Cert verification failed", 1,
CA_STATUS_FAILED, GetAlertCode(flags));
-
}
SSL_CHECK_FAIL(peer, ret, "Handshake error", 1, CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
if (MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC == peer->ssl.state)
void * userIdPos = NULL;
const mbedtls_x509_crt * peerCert = mbedtls_ssl_get_peer_cert(&peer->ssl);
ret = (NULL == peerCert ? -1 : 0);
+ if (g_CertificateVerificationCallback)
+ {
+ uint32_t flags = mbedtls_ssl_get_verify_result(&peer->ssl);
+ if (!flags)
+ {
+ g_CertificateVerificationCallback(CA_CERTIFICATE_VERIFY_SUCCESS_MUTUAL);
+ }
+ else if (MBEDTLS_X509_BADCERT_MISSING == flags)
+ {
+ g_CertificateVerificationCallback(CA_CERTIFICATE_VERIFY_NO_CERT);
+ }
+ else
+ {
+ g_CertificateVerificationCallback(CA_CERTIFICATE_VERIFY_FAILED);
+ }
+ }
//SSL_CHECK_FAIL(peer, ret, "Failed to retrieve cert", 1,
// CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_NO_CERT);
if (0 == ret)
#include "pkix_interface.h"
#include "hw_emul/hw_interface.h"
#include "oxmverifycommon.h"
+#include "casecurityinterface.h"
#define TAG "SAMPLE_MANUFACTURER_CERT"
return OC_STACK_OK;
}
-OCStackResult confirmNoCertCB(void * ctx)
+void confirmNoCertCB(CACertificateVerificationStatus_t status)
{
- OC_UNUSED(ctx);
- for (;;)
+ if (CA_CERTIFICATE_VERIFY_SUCCESS_MUTUAL == status)
{
- int userConfirm;
-
- printf(" > Peer has no cert!\n");
- printf(" > Press 1 for confirmation\n");
- printf(" > Press 0 otherwise\n");
-
- for (int ret=0; 1!=ret; )
- {
- ret = scanf("%d", &userConfirm);
- for (; 0x20<=getchar(); ); // for removing overflow garbage
- // '0x20<=code' is character region
- }
- if (1 == userConfirm)
- {
- break;
- }
- else if (0 == userConfirm)
- {
- return OC_STACK_USER_DENIED_REQ;
- }
- printf(" Entered Wrong Number. Please Enter Again\n");
+ printf(" > Peer certificate verification successful");
}
- return OC_STACK_OK;
+ else if (CA_CERTIFICATE_VERIFY_NO_CERT == status)
+ {
+ printf(" > Peer has not provided certificate\n");
+ }
+ else if (CA_CERTIFICATE_VERIFY_FAILED == status)
+ {
+ printf(" > Peer certificate verification failed\n");
+ }
+ return;
}
FILE* server_fopen(const char *path, const char *mode)
OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
SetUserConfirmCB(NULL, confirmCB);
- CAsetNoCertConfirmCallback(confirmNoCertCB);
+ CAsetCertificateVerificationCallback(confirmNoCertCB);
OCRegisterPersistentStorageHandler(&ps);