示例#1
0
int
pkcs11_init_tls_session(pkcs11h_certificate_t certificate,
    struct tls_root_ctx * const ssl_ctx)
{
  int ret = 1;

  X509 *x509 = NULL;
  RSA *rsa = NULL;
  pkcs11h_openssl_session_t openssl_session = NULL;

  if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL)
    {
      msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
      goto cleanup;
    }

  /*
   * Will be released by openssl_session
   */
  certificate = NULL;

  if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL)
    {
      msg (M_WARN, "PKCS#11: Unable get rsa object");
      goto cleanup;
    }

  if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL)
    {
      msg (M_WARN, "PKCS#11: Unable get certificate object");
      goto cleanup;
    }

  if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa))
    {
      msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
      goto cleanup;
    }

  if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509))
    {
      msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
      goto cleanup;
    }
  ret = 0;

cleanup:
  /*
   * Certificate freeing is usually handled by openssl_session.
   * If something went wrong, creating the session we have to do it manually.
   */
  if (certificate != NULL) {
    pkcs11h_certificate_freeCertificate (certificate);
    certificate = NULL;
  }

  /*
   * openssl objects have reference
   * count, so release them
   */
  if (x509 != NULL)
    {
      X509_free (x509);
      x509 = NULL;
    }

  if (rsa != NULL)
    {
      RSA_free (rsa);
      rsa = NULL;
    }

  if (openssl_session != NULL)
    {
      pkcs11h_openssl_freeSession (openssl_session);
      openssl_session = NULL;
    }
  return ret;
}
EVP_PKEY *
pkcs11h_openssl_session_getEVP (
	IN const pkcs11h_openssl_session_t openssl_session
) {
	X509 *x509 = NULL;
	EVP_PKEY *evp = NULL;
	EVP_PKEY *ret = NULL;

	_PKCS11H_ASSERT (openssl_session!=NULL);
	_PKCS11H_ASSERT (!openssl_session->initialized);
	_PKCS11H_ASSERT (openssl_session!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getEVP - entry openssl_session=%p",
		(void *)openssl_session
	);

	/*
	 * Dup x509 so RSA will not hold session x509
	 */
	if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
		goto cleanup;
	}

	if ((evp = X509_get_pubkey (x509)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
		goto cleanup;
	}

	if (0) {
	}
#ifndef OPENSSL_NO_RSA
	else if (EVP_PKEY_id (evp) == EVP_PKEY_RSA) {
		if (!__pkcs11h_openssl_session_setRSA(openssl_session, evp)) {
			goto cleanup;
		}
	}
#endif
#ifndef OPENSSL_NO_RSA
	else if (EVP_PKEY_id (evp) == EVP_PKEY_DSA) {
		if (!__pkcs11h_openssl_session_setDSA(openssl_session, evp)) {
			goto cleanup;
		}
	}
#endif
#ifdef __ENABLE_EC
	else if (evp->type == EVP_PKEY_EC) {
		if (!__pkcs11h_openssl_session_setECDSA(openssl_session, evp)) {
			goto cleanup;
		}
	}
#endif
	else {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm %d", EVP_PKEY_id (evp));
		goto cleanup;
	}

#if defined(ENABLE_PKCS11H_THREADING)
	_pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock);
#endif
	openssl_session->reference_count++;
#if defined(ENABLE_PKCS11H_THREADING)
	_pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock);
#endif

	openssl_session->initialized = TRUE;

	ret = evp;
	evp = NULL;

cleanup:

	/*
	 * openssl objects have reference
	 * count, so release them
	 */
	if (evp != NULL) {
		EVP_PKEY_free (evp);
		evp = NULL;
	}

	if (x509 != NULL) {
		X509_free (x509);
		x509 = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getEVP - return ret=%p",
		(void *)ret
	);

	return ret;
}