예제 #1
0
result_t X509Cert::load(const mbedtls_x509_crt *crt)
{
    if (m_root)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    int32_t ret;

    ret = mbedtls_x509_crt_parse_der(&m_crt, crt->raw.p, crt->raw.len);
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    return 0;
}
예제 #2
0
파일: tcp.c 프로젝트: rsalveti/zephyr
static int setup_cert(struct net_app_ctx *ctx, void *cert)
{
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
	mbedtls_ssl_conf_psk(&ctx->tls.mbedtls.conf,
			     client_psk, sizeof(client_psk),
			     (const unsigned char *)client_psk_id,
			     sizeof(client_psk_id) - 1);
#endif

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	{
		mbedtls_x509_crt *ca_cert = cert;
		int ret;

		ret = mbedtls_x509_crt_parse_der(ca_cert,
						 ca_certificate,
						 sizeof(ca_certificate));
		if (ret != 0) {
			NET_ERR("mbedtls_x509_crt_parse_der failed "
				"(-0x%x)", -ret);
			return ret;
		}

		mbedtls_ssl_conf_ca_chain(&ctx->tls.mbedtls.conf,
					  ca_cert, NULL);

		/* In this example, we skip the certificate checks. In real
		 * life scenarios, one should always verify the certificates.
		 */
		mbedtls_ssl_conf_authmode(&ctx->tls.mbedtls.conf,
					  MBEDTLS_SSL_VERIFY_REQUIRED);

		mbedtls_ssl_conf_cert_profile(&ctx->tls.mbedtls.conf,
					    &mbedtls_x509_crt_profile_default);
#define VERIFY_CERTS 0
#if VERIFY_CERTS
		mbedtls_ssl_conf_authmode(&ctx->tls.mbedtls.conf,
					  MBEDTLS_SSL_VERIFY_OPTIONAL);
#else
		;
#endif /* VERIFY_CERTS */
	}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

	return 0;
}
예제 #3
0
result_t X509Cert::load(Buffer_base *derCert)
{
    if (m_root)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    int32_t ret;

    exlib::string crt;
    derCert->toString(crt);

    ret = mbedtls_x509_crt_parse_der(&m_crt, (const unsigned char *)crt.c_str(),
                                     crt.length());
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    return 0;
}
예제 #4
0
파일: ssl.c 프로젝트: jonasmalacofilho/neko
static value cert_add_der( value cert, value data ){
	mbedtls_x509_crt *crt;
	int r;
	val_check(data,string);
	if( !val_is_null(cert) ){
		val_check_kind(cert,k_cert);
		crt = val_cert(cert);
		if( !crt )
			neko_error();
	}else{
		crt = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt));
		mbedtls_x509_crt_init( crt );
		cert = alloc_abstract(k_cert, crt);
		val_gc(cert,free_cert);
	}
	if( (r = mbedtls_x509_crt_parse_der(crt, (const unsigned char*)val_string(data), val_strlen(data))) < 0 )
		return ssl_error(r);
	return cert;
}
예제 #5
0
파일: main.c 프로젝트: rsalveti/zephyr
int setup_cert(struct net_app_ctx *ctx, void *cert)
{
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
	mbedtls_ssl_conf_psk(&ctx->tls.mbedtls.conf,
			client_psk, sizeof(client_psk),
			(const unsigned char *)client_psk_id,
			sizeof(client_psk_id) - 1);
#endif

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	{
		mbedtls_x509_crt *ca_cert = cert;
		int ret;

		ret = mbedtls_x509_crt_parse_der(ca_cert,
				ca_certificate,
				sizeof(ca_certificate));
		if (ret != 0) {
			NET_ERR("mbedtls_x509_crt_parse_der failed "
					"(-0x%x)", -ret);
			return ret;
		}

		/* mbedtls_x509_crt_verify() should be called to verify the
		 * cerificate in the real cases
		 */

		mbedtls_ssl_conf_ca_chain(&ctx->tls.mbedtls.conf,
				ca_cert, NULL);

		mbedtls_ssl_conf_authmode(&ctx->tls.mbedtls.conf,
				MBEDTLS_SSL_VERIFY_REQUIRED);

		mbedtls_ssl_conf_cert_profile(&ctx->tls.mbedtls.conf,
				&mbedtls_x509_crt_profile_default);
	}
#endif /* MBEDTLS_X509_CRT_PARSE_C */

	return 0;
}
예제 #6
0
result_t X509Cert::loadRootCerts()
{
    if (m_rootLoaded)
        return 0;
    m_rootLoaded = true;

    _cert *pca = g_root_ca;
    int32_t ret;

    while (pca->size)
    {
        ret = mbedtls_x509_crt_parse_der(&m_crt,
                                         (const unsigned char *)pca->data,
                                         pca->size);
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        pca++;
    }

    return 0;
}
예제 #7
0
result_t X509Cert::loadFile(exlib::string filename)
{
    if (m_root)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    result_t hr;
    exlib::string data;
    int32_t ret;

    hr = fs_base::ac_readFile(filename, data);
    if (hr < 0)
        return hr;

    if (qstrstr(data.c_str(), "BEGIN CERTIFICATE") ||
            qstrstr(data.c_str(), "CKO_CERTIFICATE"))
        return load(data.c_str());

    ret = mbedtls_x509_crt_parse_der(&m_crt, (const unsigned char *)data.c_str(),
                                     data.length());
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    return 0;
}
예제 #8
0
static CURLcode
mbed_connect_step2(struct connectdata *conn,
                   int sockindex)
{
  int ret;
  struct SessionHandle *data = conn->data;
  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
  const mbedtls_x509_crt *peercert;

#ifdef HAS_ALPN
  const char* next_protocol;
#endif

  char errorbuf[128];
  errorbuf[0] = 0;

  conn->recv[sockindex] = mbed_recv;
  conn->send[sockindex] = mbed_send;

  ret = mbedtls_ssl_handshake(&connssl->ssl);

  if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
    connssl->connecting_state = ssl_connect_2_reading;
    return CURLE_OK;
  }
  else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
    connssl->connecting_state = ssl_connect_2_writing;
    return CURLE_OK;
  }
  else if(ret) {
#ifdef MBEDTLS_ERROR_C
    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
    failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s",
          -ret, errorbuf);
    return CURLE_SSL_CONNECT_ERROR;
  }

  infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
        mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl)
    );

  ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);

  if(ret && data->set.ssl.verifypeer) {
    if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
      failf(data, "Cert verify failed: BADCERT_EXPIRED");

    if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
      failf(data, "Cert verify failed: BADCERT_REVOKED");
      return CURLE_SSL_CACERT;
    }

    if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
      failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");

    if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
      failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");

    return CURLE_PEER_FAILED_VERIFICATION;
  }

  peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl);

  if(peercert && data->set.verbose) {
    const size_t bufsize = 16384;
    char *buffer = malloc(bufsize);

    if(!buffer)
      return CURLE_OUT_OF_MEMORY;

    if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0)
      infof(data, "Dumping cert info:\n%s\n", buffer);
    else
      infof(data, "Unable to dump certificate information.\n");

    free(buffer);
  }

  if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
    int size;
    CURLcode result;
    mbedtls_x509_crt *p;
    unsigned char pubkey[PUB_DER_MAX_BYTES];

    if(!peercert || !peercert->raw.p || !peercert->raw.len) {
      failf(data, "Failed due to missing peer certificate");
      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
    }

    p = calloc(1, sizeof(*p));

    if(!p)
      return CURLE_OUT_OF_MEMORY;

    mbedtls_x509_crt_init(p);

    /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
       needs a non-const key, for now.
       https://github.com/ARMmbed/mbedtls/issues/396 */
    if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
      failf(data, "Failed copying peer certificate");
      mbedtls_x509_crt_free(p);
      free(p);
      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
    }

    size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);

    if(size <= 0) {
      failf(data, "Failed copying public key from peer certificate");
      mbedtls_x509_crt_free(p);
      free(p);
      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
    }

    /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
    result = Curl_pin_peer_pubkey(data,
                                  data->set.str[STRING_SSL_PINNEDPUBLICKEY],
                                  &pubkey[PUB_DER_MAX_BYTES - size], size);
    if(result) {
      mbedtls_x509_crt_free(p);
      free(p);
      return result;
    }

    mbedtls_x509_crt_free(p);
    free(p);
  }

#ifdef HAS_ALPN
  if(conn->bits.tls_enable_alpn) {
    next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl);

    if(next_protocol) {
      infof(data, "ALPN, server accepted to use %s\n", next_protocol);
#ifdef USE_NGHTTP2
      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
                  NGHTTP2_PROTO_VERSION_ID_LEN) &&
         !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) {
        conn->negnpn = CURL_HTTP_VERSION_2;
      }
      else
#endif
        if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
           !next_protocol[ALPN_HTTP_1_1_LENGTH]) {
          conn->negnpn = CURL_HTTP_VERSION_1_1;
        }
    }
    else {
      infof(data, "ALPN, server did not agree to a protocol\n");
    }
  }
#endif

  connssl->connecting_state = ssl_connect_3;
  infof(data, "SSL connected\n");

  return CURLE_OK;
}
예제 #9
0
파일: ssl.c 프로젝트: jonasmalacofilho/neko
static value cert_load_defaults(){
#if defined(NEKO_WINDOWS)
	value v;
	HCERTSTORE store;
	PCCERT_CONTEXT cert;
	mbedtls_x509_crt *chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt));
	mbedtls_x509_crt_init( chain );
	if( store = CertOpenSystemStore(0, (LPCSTR)"Root") ){
		cert = NULL;
		while( cert = CertEnumCertificatesInStore(store, cert) )
			mbedtls_x509_crt_parse_der( chain, (unsigned char *)cert->pbCertEncoded, cert->cbCertEncoded );
		CertCloseStore(store, 0);
	}
	v = alloc_abstract(k_cert, chain);
	val_gc(v,free_cert);
	return v;
#elif defined(NEKO_MAC)
	CFMutableDictionaryRef search;
	CFArrayRef result;
	SecKeychainRef keychain;
	SecCertificateRef item;
	CFDataRef dat;
	value v;
	mbedtls_x509_crt *chain = NULL;

	// Load keychain
	if( SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",&keychain) != errSecSuccess )
		return val_null;

	// Search for certificates
	search = CFDictionaryCreateMutable( NULL, 0, NULL, NULL );
	CFDictionarySetValue( search, kSecClass, kSecClassCertificate );
	CFDictionarySetValue( search, kSecMatchLimit, kSecMatchLimitAll );
	CFDictionarySetValue( search, kSecReturnRef, kCFBooleanTrue );
	CFDictionarySetValue( search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL) );
	if( SecItemCopyMatching( search, (CFTypeRef *)&result ) == errSecSuccess ){
		CFIndex n = CFArrayGetCount( result );
		for( CFIndex i = 0; i < n; i++ ){
			item = (SecCertificateRef)CFArrayGetValueAtIndex( result, i );

			// Get certificate in DER format
			dat = SecCertificateCopyData( item );
			if( dat ){
				if( chain == NULL ){
					chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt));
					mbedtls_x509_crt_init( chain );
				}
				mbedtls_x509_crt_parse_der( chain, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat) );
				CFRelease( dat );
			}
		}
	}
	CFRelease(keychain);
	if( chain != NULL ){
		v = alloc_abstract(k_cert, chain);
		val_gc(v,free_cert);
		return v;
	}else{
		return val_null;
	}
#else
	return val_null;
#endif
}
예제 #10
0
int main( void )
{
    int ret = exit_ok;
    mbedtls_net_context server_fd;
    struct sockaddr_in addr;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt ca;
#endif

    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_ssl_context ssl;
    mbedtls_ssl_config conf;
    mbedtls_ctr_drbg_init( &ctr_drbg );

    /*
     * 0. Initialize and setup stuff
     */
    mbedtls_net_init( &server_fd );
    mbedtls_ssl_init( &ssl );
    mbedtls_ssl_config_init( &conf );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt_init( &ca );
#endif

    mbedtls_entropy_init( &entropy );
    if( mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                       (const unsigned char *) pers, strlen( pers ) ) != 0 )
    {
        ret = ctr_drbg_seed_failed;
        goto exit;
    }

    if( mbedtls_ssl_config_defaults( &conf,
                MBEDTLS_SSL_IS_CLIENT,
                MBEDTLS_SSL_TRANSPORT_STREAM,
                MBEDTLS_SSL_PRESET_DEFAULT ) != 0 )
    {
        ret = ssl_config_defaults_failed;
        goto exit;
    }

    mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );

#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
    mbedtls_ssl_conf_psk( &conf, psk, sizeof( psk ),
                (const unsigned char *) psk_id, sizeof( psk_id ) - 1 );
#endif

#if defined(MBEDTLS_X509_CRT_PARSE_C)
    if( mbedtls_x509_crt_parse_der( &ca, ca_cert, sizeof( ca_cert ) ) != 0 )
    {
        ret = x509_crt_parse_failed;
        goto exit;
    }

    mbedtls_ssl_conf_ca_chain( &conf, &ca, NULL );
    mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED );
#endif

    if( mbedtls_ssl_setup( &ssl, &conf ) != 0 )
    {
        ret = ssl_setup_failed;
        goto exit;
    }

#if defined(MBEDTLS_X509_CRT_PARSE_C)
    if( mbedtls_ssl_set_hostname( &ssl, HOSTNAME ) != 0 )
    {
        ret = hostname_failed;
        goto exit;
    }
#endif

    /*
     * 1. Start the connection
     */
    memset( &addr, 0, sizeof( addr ) );
    addr.sin_family = AF_INET;

    ret = 1; /* for endianness detection */
    addr.sin_port = *((char *) &ret) == ret ? PORT_LE : PORT_BE;
    addr.sin_addr.s_addr = *((char *) &ret) == ret ? ADDR_LE : ADDR_BE;
    ret = 0;

    if( ( server_fd.fd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
    {
        ret = socket_failed;
        goto exit;
    }

    if( connect( server_fd.fd,
                (const struct sockaddr *) &addr, sizeof( addr ) ) < 0 )
    {
        ret = connect_failed;
        goto exit;
    }

    mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );

    if( mbedtls_ssl_handshake( &ssl ) != 0 )
    {
        ret = ssl_handshake_failed;
        goto exit;
    }

    /*
     * 2. Write the GET request and close the connection
     */
    if( mbedtls_ssl_write( &ssl, (const unsigned char *) GET_REQUEST,
                         sizeof( GET_REQUEST ) - 1 ) <= 0 )
    {
        ret = ssl_write_failed;
        goto exit;
    }

    mbedtls_ssl_close_notify( &ssl );

exit:
    mbedtls_net_free( &server_fd );

    mbedtls_ssl_free( &ssl );
    mbedtls_ssl_config_free( &conf );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt_free( &ca );
#endif

    return( ret );
}
예제 #11
0
void tls_client(void)
{
	int ret = exit_ok;
	struct tcp_context ctx;

	ctx.timeout = MBEDTLS_NETWORK_TIMEOUT;

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_x509_crt ca;
#endif

	mbedtls_entropy_context entropy;
	mbedtls_ctr_drbg_context ctr_drbg;
	mbedtls_ssl_context ssl;
	mbedtls_ssl_config conf;
	mbedtls_ctr_drbg_init(&ctr_drbg);

	mbedtls_platform_set_printf(PRINT);

	/*
	 * 0. Initialize and setup stuff
	 */
	mbedtls_ssl_init(&ssl);
	mbedtls_ssl_config_init(&conf);
#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_x509_crt_init(&ca);
#endif

	mbedtls_printf("\n  . Seeding the random number generator...");
	mbedtls_entropy_init(&entropy);
	mbedtls_entropy_add_source(&entropy, entropy_source, NULL,
				   MBEDTLS_ENTROPY_MAX_GATHER,
				   MBEDTLS_ENTROPY_SOURCE_STRONG);

	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
				  (const unsigned char *)pers,
				  strlen(pers)) != 0) {
		ret = ctr_drbg_seed_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n",
		     -ret);
		goto exit;
	}
	mbedtls_printf(" ok\n");

	mbedtls_printf("  . Setting up the SSL/TLS structure...");
	if (mbedtls_ssl_config_defaults(&conf,
					MBEDTLS_SSL_IS_CLIENT,
					MBEDTLS_SSL_TRANSPORT_STREAM,
					MBEDTLS_SSL_PRESET_DEFAULT) != 0) {
		ret = ssl_config_defaults_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_config_defaults returned -0x%x\n\n",
		     -ret);
		goto exit;
	}

	mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);

#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
	mbedtls_memory_buffer_alloc_init(heap, sizeof(heap));
#endif

#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
	mbedtls_ssl_conf_psk(&conf, psk, sizeof(psk),
			     (const unsigned char *)psk_id, sizeof(psk_id) - 1);
#endif

#if defined(MBEDTLS_X509_CRT_PARSE_C)
	if (mbedtls_x509_crt_parse_der(&ca, ca_cert, sizeof(ca_cert)) != 0) {
		ret = x509_crt_parse_failed;
		mbedtls_printf
		    (" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n",
		     -ret);
		goto exit;
	}

	mbedtls_ssl_conf_ca_chain(&conf, &ca, NULL);
	mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
#endif

	if (mbedtls_ssl_setup(&ssl, &conf) != 0) {
		ret = ssl_setup_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_setup returned -0x%x\n\n", -ret);
		goto exit;
	}
#if defined(MBEDTLS_X509_CRT_PARSE_C)
	if (mbedtls_ssl_set_hostname(&ssl, HOSTNAME) != 0) {
		ret = hostname_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n",
		     ret);
		goto exit;
	}
#endif
	mbedtls_printf(" ok\n");

	/*
	 * 1. Start the connection
	 */

	mbedtls_printf("  . Connecting to tcp %s...", SERVER_ADDR);

	if (tcp_set_local_addr(&ctx, LOCAL_ADDR) != 0) {
		printk("tcp set_local_addr error\n");
		goto exit;
	}

	if (tcp_init(&ctx, SERVER_ADDR, SERVER_PORT) != 0) {
		ret = connect_failed;
		mbedtls_printf(" failed\n  ! tcp_init returned -0x%x\n\n",
			       -ret);
		goto exit;
	}

	mbedtls_printf(" ok\n");

	mbedtls_ssl_set_bio(&ssl, &ctx, tcp_tx, tcp_rx, NULL);

	mbedtls_printf("  . Performing the SSL/TLS handshake...");
	if (mbedtls_ssl_handshake(&ssl) != 0) {
		ret = ssl_handshake_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n",
		     -ret);
		goto exit;
	}
	mbedtls_printf(" ok\n");

	/*
	 * 2. Write the GET request and close the connection
	 */
	mbedtls_printf("  > Write to server:");
	if (mbedtls_ssl_write(&ssl, (const unsigned char *)GET_REQUEST,
			      sizeof(GET_REQUEST) - 1) <= 0) {
		ret = ssl_write_failed;
		mbedtls_printf
		    (" failed\n  ! mbedtls_ssl_write returned -0x%x\n\n", -ret);
		goto exit;
	}
	mbedtls_printf(" ok\n");

	mbedtls_printf("  . Closing the connection...");
	mbedtls_ssl_close_notify(&ssl);
	mbedtls_printf(" done\n");
exit:

	mbedtls_ssl_free(&ssl);
	mbedtls_ssl_config_free(&conf);
	mbedtls_ctr_drbg_free(&ctr_drbg);
	mbedtls_entropy_free(&entropy);
#if defined(MBEDTLS_X509_CRT_PARSE_C)
	mbedtls_x509_crt_free(&ca);
#endif

}
예제 #12
0
result_t X509Cert::load(exlib::string txtCert)
{
    if (m_root)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    int32_t ret;

    if (qstrstr(txtCert.c_str(), "BEGIN CERTIFICATE"))
    {
        ret = mbedtls_x509_crt_parse(&m_crt, (const unsigned char *)txtCert.c_str(),
                                     txtCert.length() + 1);
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        return 0;
    }

    _parser p(txtCert);
    QuickArray<std::pair<exlib::string, exlib::string> > values;
    std::map<exlib::string, bool> verifies;
    std::map<exlib::string, bool> certs;

    while (!p.end())
    {
        exlib::string cka_label;
        exlib::string cka_value;
        exlib::string cka_serial;
        exlib::string _value;
        bool in_multiline = false, in_obj = false;
        bool is_cert = false;
        bool is_trust = false;
        bool is_value = false;
        bool is_serial = false;
        bool is_ca = false;
        bool is_verify = false;

        while (!p.end())
        {
            exlib::string line;
            exlib::string cmd, type, value;

            p.getLine(line);
            _parser p1(line);

            p1.skipSpace();
            if (p1.get() == '#')
                continue;

            if (in_multiline)
            {
                if (p1.get() == '\\')
                {
                    while (p1.get() == '\\')
                    {
                        char ch1, ch2, ch3;

                        p1.skip();

                        ch1 = p1.getChar();
                        if (ch1 < '0' || ch1 > '7')
                            break;

                        ch2 = p1.getChar();
                        if (ch2 < '0' || ch2 > '7')
                            break;

                        ch3 = p1.getChar();
                        if (ch3 < '0' || ch3 > '7')
                            break;

                        ch1 = (ch1 - '0') * 64 + (ch2 - '0') * 8 + (ch3 - '0');
                        _value.append(&ch1, 1);
                    }
                    continue;
                }

                p1.getWord(cmd);
                if ((cmd == "END"))
                {
                    if (is_value)
                        cka_value = _value;
                    else if (is_serial)
                        cka_serial = _value;

                    in_multiline = false;
                }

                continue;
            }

            p1.getWord(cmd);

            p1.skipSpace();
            p1.getWord(type);
            if ((type == "MULTILINE_OCTAL"))
            {
                in_multiline = true;
                _value.resize(0);

                is_value = is_cert && (cmd == "CKA_VALUE");
                is_serial = (cmd == "CKA_SERIAL_NUMBER");
                continue;
            }

            p1.skipSpace();
            p1.getLeft(value);

            if (!in_obj)
            {
                if ((cmd == "CKA_CLASS"))
                {
                    in_obj = true;
                    is_cert = (value == "CKO_CERTIFICATE");
                    is_trust = (value == "CKO_NSS_TRUST");
                }
                continue;
            }

            if ((cmd == "CKA_LABEL"))
                cka_label = value;
            else if (is_trust && (cmd == "CKA_TRUST_SERVER_AUTH"))
            {
                is_ca = (value == "CKT_NSS_TRUSTED_DELEGATOR");
                is_verify = (value == "CKT_NSS_MUST_VERIFY_TRUST");
            }

            if (cmd.empty())
                break;
        }

        if (!cka_label.empty())
        {
            if (is_trust)
            {
                if (is_ca)
                    certs.insert(std::pair<exlib::string, bool>(cka_label + cka_serial, true));
                if (is_verify)
                    verifies.insert(std::pair<exlib::string, bool>(cka_label + cka_serial, true));
            }
            else if (is_cert && !cka_value.empty())
                values.append(std::pair<exlib::string, exlib::string>(cka_label + cka_serial, cka_value));
        }
    }

    bool is_loaded = false;
    int32_t i;

    for (i = 0; i < (int32_t)values.size(); i++)
    {
        std::pair<exlib::string, exlib::string> &c = values[i];
        std::map<exlib::string, bool>::iterator it_trust;

        it_trust = verifies.find(c.first);
        if (it_trust != verifies.end())
        {
            ret = mbedtls_x509_crt_parse_der(&m_crt,
                                             (const unsigned char *)c.second.c_str(),
                                             c.second.length());
            if (ret != 0)
                return CHECK_ERROR(_ssl::setError(ret));

            is_loaded = true;
        }
    }

    for (i = 0; i < (int32_t)values.size(); i++)
    {
        std::pair<exlib::string, exlib::string> &c = values[i];
        std::map<exlib::string, bool>::iterator it_trust;

        it_trust = certs.find(c.first);
        if (it_trust != certs.end())
        {
            ret = mbedtls_x509_crt_parse_der(&m_crt,
                                             (const unsigned char *)c.second.c_str(),
                                             c.second.length() );
            if (ret != 0)
                return CHECK_ERROR(_ssl::setError(ret));

            is_loaded = true;
        }
    }

    if (!is_loaded)
        return CHECK_ERROR(_ssl::setError(MBEDTLS_ERR_X509_INVALID_FORMAT));

    return 0;
}