mbedTLS two-way authentication process with the AWS function (milestone function)

IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params)
{
  if(NULL == pNetwork)
  {
    return NULL_VALUE_ERROR;
  }

  if(NULL != params)
  {
    _iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation,
                                params->pDevicePrivateKeyLocation, params->pDestinationURL,
                                params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag);
  }

  int ret = 0;
  const char *pers = "aws_iot_tls_wrapper";
#if 0 // 2k should be large enough! Not needed anyway.
#ifdef msg_debug
  unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1];
#endif
#endif // 0
  TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams);

  mbedtls_platform_set_calloc_free( heap_alloc , heap_free);
  mbedtls_ssl_config_init(&(tlsDataParams->conf));
  mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg));
  mbedtls_x509_crt_init(&(tlsDataParams->cacert));
  mbedtls_x509_crt_init(&(tlsDataParams->clicert));
  mbedtls_pk_init(&(tlsDataParams->pkey));
  mbedtls_debug_set_threshold(1);
  mbedtls_ssl_conf_dbg( &(tlsDataParams->conf), my_debug, stdout );


  msg_debug("\n  . Seeding the random number generator...");
  mbedtls_entropy_init(&(tlsDataParams->entropy));

  if( (ret = mbedtls_entropy_add_source( &(tlsDataParams->entropy), mbedtls_hardware_poll ,
                                         (void*)&hrng, 1, MBEDTLS_ENTROPY_SOURCE_STRONG) ) != 0 )
  {
    mbedtls_printf( " failed\n  ! mbedtls_entropy_add_source returned %d\n", ret );
    return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
  }



  if((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy),
                                  (const unsigned char *) pers, strlen(pers))) != 0)
  {
    msg_error(" failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret);
    return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
  }



  msg_debug("  . Loading the CA root certificate ...");
  ret = mbedtls_x509_crt_parse(&(tlsDataParams->cacert), (unsigned char const *) pNetwork->tlsConnectParams.pRootCALocation, strlen(pNetwork->tlsConnectParams.pRootCALocation) + 1);
  if(ret < 0)
  {
    msg_error(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x while parsing root cert\n\n", -ret);
    return NETWORK_X509_ROOT_CRT_PARSE_ERROR;
  }
  msg_debug(" ok (%d skipped)\n", ret);

  msg_debug("  . Loading the client cert. and key...");
  ret = mbedtls_x509_crt_parse(&(tlsDataParams->clicert), (unsigned char const *) pNetwork->tlsConnectParams.pDeviceCertLocation, strlen(pNetwork->tlsConnectParams.pDeviceCertLocation) + 1);
  if(ret != 0)
  {
    msg_error(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x while parsing device cert\n\n", -ret);
    return NETWORK_X509_DEVICE_CRT_PARSE_ERROR;
  }
#ifdef   FIREWALL_MBEDLIB
  ret = mbedtls_firewall_pk_parse_key(&(tlsDataParams->pkey), (unsigned char const *) pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, (size_t) 0 , (unsigned char const *)"", 0);
  /* the key is converted to an RSA structure here :  pk_parse_key_pkcs1_der
     the info pointer are change in pk_wrap.c*/
  extern mbedtls_pk_info_t mbedtls_firewall_info;
  (tlsDataParams->pkey).pk_info = &mbedtls_firewall_info;
#else
  ret = mbedtls_pk_parse_key(&(tlsDataParams->pkey), (unsigned char const *) pNetwork->tlsConnectParams.pDevicePrivateKeyLocation, strlen(pNetwork->tlsConnectParams.pDevicePrivateKeyLocation) + 1, (unsigned char const *)"", 0);
#endif

  if(ret != 0)
  {
    msg_error(" failed\n  !  mbedtls_pk_parse_key returned -0x%x while parsing private key\n\n", -ret);
    msg_debug(" path : %s ", pNetwork->tlsConnectParams.pDevicePrivateKeyLocation);
    return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR;
  }
  msg_debug(" ok\n");
  char portBuffer[6];
  snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort);
  msg_debug("  . Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer);

  if( (ret = net_sock_create(hnet, (net_sockhnd_t *)&tlsDataParams->server_fd.fd, NET_PROTO_TCP)) != NET_OK )
  {
    msg_error(" failed to create a TCP socket  ! net_sock_create %d\n", ret);
    return SSL_CONNECTION_ERROR;
  }

   if( (ret = net_sock_setopt(tlsDataParams->server_fd.fd, "sock_noblocking", NULL, 0)) != NET_OK )
   {
     msg_error(" failed to set the TCP socket noblocking ! net_sock_setopt %d\n", ret);
      return SSL_CONNECTION_ERROR;
   }
  
  if( (ret = net_sock_open(tlsDataParams->server_fd.fd, pNetwork->tlsConnectParams.pDestinationURL, pNetwork->tlsConnectParams.DestinationPort, 0) ) != NET_OK)
  {
    msg_error(" failed to connect to %s  ! net_sock_open returned %d\n", pNetwork->tlsConnectParams.pDestinationURL, ret);
    return SSL_CONNECTION_ERROR;
  }

  msg_debug("  . Setting up the SSL/TLS structure...");

  if((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
  {
    msg_error(" failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n", -ret);
    return SSL_CONNECTION_ERROR;

  }

#ifndef MOSQUITTO
  mbedtls_ssl_conf_cert_profile( &(tlsDataParams->conf), &mbedtls_x509_crt_amazon_suite );
#endif
  mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL);
  if(pNetwork->tlsConnectParams.ServerVerificationFlag == true)
  {
    mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED);
  }
  else
  {
    mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL);
  }
  mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg));

  mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL);
  if((ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey))) !=
      0)
  {
    msg_error(" failed\n  ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret);
    return SSL_CONNECTION_ERROR;
  }

  mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms);

  if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0)
  {
    msg_error(" failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret);
    return SSL_CONNECTION_ERROR;
  }
#ifdef MOSQUITTO
  /* If the server IP address cannot be resolved from a hostname, the expected server common name must be set manually. */ 
  char *common_name = "gnbiotsrv";
#else
  char *common_name = pNetwork->tlsConnectParams.pDestinationURL;
#endif
  if((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), common_name )) != 0)
  {
    msg_error(" failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
    return SSL_CONNECTION_ERROR;
  }
  msg_debug("\n\nSSL state connect : %d ", tlsDataParams->ssl.state);
  mbedtls_ssl_set_bio(&(tlsDataParams->ssl), (void*) tlsDataParams->server_fd.fd, mbedtls_net_send, mbedtls_net_recv, NULL);
  msg_debug(" ok\n");

  msg_debug("\n\nSSL state connect : %d ", tlsDataParams->ssl.state);
  msg_debug("  . Performing the SSL/TLS handshake...");
  while((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0)
  {
    if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
    {
      msg_error(" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n", -ret);
      if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED)
      {
        msg_error("    Unable to verify the server's certificate. "
                  "Either it is invalid,\n"
                  "    or you didn't set ca_file or ca_path "
                  "to an appropriate value.\n"
                  "    Alternatively, you may want to use "
                  "auth_mode=optional for testing purposes.\n");
      }
      return SSL_CONNECTION_ERROR;
    }
  }

  msg_debug(" ok\n    [ Protocol is %s ]\n    [ Ciphersuite is %s ]\n", mbedtls_ssl_get_version(&(tlsDataParams->ssl)),
            mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl)));
  if((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0)
  {
    msg_debug("    [ Record expansion is %d ]\n", ret);
  }
  else
  {
    msg_debug("    [ Record expansion is unknown (compression) ]\n");
  }

  msg_debug("  . Verifying peer X.509 certificate...");

  if(pNetwork->tlsConnectParams.ServerVerificationFlag == true)
  {
    if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0)
    {
      char vrfy_buf[512];
      msg_error(" failed\n");
      mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", tlsDataParams->flags);
      msg_error("%s\n", vrfy_buf);
      ret = SSL_CONNECTION_ERROR;
    }
    else
    {
      msg_debug(" ok\n");
      ret = SUCCESS;
    }
  }
  else
  {
    msg_debug(" Server Verification skipped\n");
    ret = SUCCESS;
  }

#if 0
#ifdef msg_debug
  if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL)
  {
    msg_debug("  . Peer certificate information    ...\n");
    mbedtls_x509_crt_info((char *) buf, sizeof(buf) - 1, "      ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)));
    msg_debug("%s\n", buf);
  }
#endif
#endif // 0
  mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), IOT_SSL_READ_TIMEOUT);

  return (IoT_Error_t) ret;
}

 

Guess you like

Origin blog.csdn.net/nicholas_duan/article/details/92799308