Exemplo n.º 1
0
/**
 * gnutls_pkcs11_privkey_status:
 * @key: Holds the key
 *
 * Checks the status of the private key token.
 *
 * Returns: this function will return non-zero if the token 
 * holding the private key is still available (inserted), and zero otherwise.
 * 
 * Since: 3.1.9
 *
 **/
int gnutls_pkcs11_privkey_status(gnutls_pkcs11_privkey_t key)
{
	ck_rv_t rv;
	int ret;
	struct pkcs11_session_info _sinfo;
	struct pkcs11_session_info *sinfo;
	ck_object_handle_t obj;
	struct ck_session_info session_info;
	
	PKCS11_CHECK_INIT;

	if (key->sinfo.init != 0) {
		sinfo = &key->sinfo;
		obj = key->obj;
	} else {
		sinfo = &_sinfo;
		memset(sinfo, 0, sizeof(*sinfo));
		FIND_OBJECT(sinfo, &key->pin, obj, key);
	}

	rv = (sinfo->module)->C_GetSessionInfo(sinfo->pks, &session_info);
	if (rv != CKR_OK) {
		ret = 0;
		goto cleanup;
	}
	ret = 1;

      cleanup:
	if (sinfo != &key->sinfo)
		pkcs11_close_session(sinfo);

	return ret;
}
Exemplo n.º 2
0
/* callback function to be passed in _gnutls_pkcs11_check_init().
 * It is run, only when a fork has been detected, and data have
 * been re-initialized. In that case we reset the session and re-open
 * the object. */
static int reopen_privkey_session(void * _privkey)
{
	int ret;
	gnutls_pkcs11_privkey_t privkey = _privkey;

	memset(&privkey->sinfo, 0, sizeof(privkey->sinfo));
	privkey->ref = 0;
	FIND_OBJECT(privkey);

	return 0;
}
Exemplo n.º 3
0
/**
 * gnutls_pkcs11_privkey_import_url:
 * @pkey: The private key
 * @url: a PKCS 11 url identifying the key
 * @flags: Or sequence of GNUTLS_PKCS11_OBJ_* flags
 *
 * This function will "import" a PKCS 11 URL identifying a private
 * key to the #gnutls_pkcs11_privkey_t type. In reality since
 * in most cases keys cannot be exported, the private key structure
 * is being associated with the available operations on the token.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey,
				 const char *url, unsigned int flags)
{
	int ret;
	struct ck_attribute *attr;
	struct ck_attribute a[4];
	ck_key_type_t key_type;
	ck_bool_t reauth = 0;

	PKCS11_CHECK_INIT;

	memset(&pkey->sinfo, 0, sizeof(pkey->sinfo));

	if (pkey->url) {
		gnutls_free(pkey->url);
		pkey->url = NULL;
	}

	if (pkey->uinfo) {
		p11_kit_uri_free(pkey->uinfo);
		pkey->uinfo = NULL;
	}

	pkey->url = gnutls_strdup(url);
	if (pkey->url == NULL)
		return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);

	ret = pkcs11_url_to_info(pkey->url, &pkey->uinfo, flags|GNUTLS_PKCS11_OBJ_FLAG_EXPECT_PRIVKEY);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	pkey->flags = flags;

	attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_CLASS);
	if (!attr || attr->value_len != sizeof(ck_object_class_t) ||
	    *(ck_object_class_t *) attr->value != CKO_PRIVATE_KEY) {
		gnutls_assert();
		ret = GNUTLS_E_INVALID_REQUEST;
		goto cleanup;
	}

	attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_ID);
	if (!attr) {
		attr = p11_kit_uri_get_attribute(pkey->uinfo, CKA_LABEL);
		if (!attr) {
			gnutls_assert();
			ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
			goto cleanup;
		}
	}

	FIND_OBJECT(pkey);

	pkey->pk_algorithm = GNUTLS_PK_UNKNOWN;
	a[0].type = CKA_KEY_TYPE;
	a[0].value = &key_type;
	a[0].value_len = sizeof(key_type);

	if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1)
	    == CKR_OK) {
		pkey->pk_algorithm = key_type_to_pk(key_type);
	}

	if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN) {
		_gnutls_debug_log
		    ("Cannot determine PKCS #11 key algorithm\n");
		ret = GNUTLS_E_UNKNOWN_ALGORITHM;
		goto cleanup;
	}

	a[0].type = CKA_ALWAYS_AUTHENTICATE;
	a[0].value = &reauth;
	a[0].value_len = sizeof(reauth);

	if (pkcs11_get_attribute_value(pkey->sinfo.module, pkey->sinfo.pks, pkey->ref, a, 1)
	    == CKR_OK) {
		pkey->reauth = reauth;
	}

	ret = 0;

	return ret;

      cleanup:
	if (pkey->uinfo != NULL) {
		p11_kit_uri_free(pkey->uinfo);
		pkey->uinfo = NULL;
	}
	gnutls_free(pkey->url);
	pkey->url = NULL;

	return ret;
}
Exemplo n.º 4
0
/*-
 * _gnutls_pkcs11_privkey_decrypt_data:
 * @key: Holds the key
 * @flags: should be 0 for now
 * @ciphertext: holds the data to be signed
 * @plaintext: will contain the plaintext, allocated with gnutls_malloc()
 *
 * This function will decrypt the given data using the public key algorithm
 * supported by the private key. 
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
				    unsigned int flags,
				    const gnutls_datum_t * ciphertext,
				    gnutls_datum_t * plaintext)
{
	ck_rv_t rv;
	int ret;
	struct ck_mechanism mech;
	unsigned long siglen;
	ck_object_handle_t obj;
	struct pkcs11_session_info _sinfo;
	struct pkcs11_session_info *sinfo;

	PKCS11_CHECK_INIT;

	if (key->sinfo.init != 0) {
		sinfo = &key->sinfo;
		obj = key->obj;
	} else {
		sinfo = &_sinfo;
		memset(sinfo, 0, sizeof(*sinfo));
		FIND_OBJECT(sinfo, &key->pin, obj, key);
	}

	if (key->pk_algorithm != GNUTLS_PK_RSA)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	mech.mechanism = CKM_RSA_PKCS;
	mech.parameter = NULL;
	mech.parameter_len = 0;

	/* Initialize signing operation; using the private key discovered
	 * earlier. */
	rv = pkcs11_decrypt_init(sinfo->module, sinfo->pks, &mech, obj);
	if (rv != CKR_OK) {
		gnutls_assert();
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	/* Work out how long the plaintext must be: */
	rv = pkcs11_decrypt(sinfo->module, sinfo->pks, ciphertext->data,
			    ciphertext->size, NULL, &siglen);
	if (rv != CKR_OK) {
		gnutls_assert();
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	plaintext->data = gnutls_malloc(siglen);
	plaintext->size = siglen;

	rv = pkcs11_decrypt(sinfo->module, sinfo->pks, ciphertext->data,
			    ciphertext->size, plaintext->data, &siglen);
	if (rv != CKR_OK) {
		gnutls_free(plaintext->data);
		gnutls_assert();
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	plaintext->size = siglen;

	ret = 0;

      cleanup:
	if (key->sinfo.init == 0)
		pkcs11_close_session(sinfo);

	return ret;
}
Exemplo n.º 5
0
/**
 * gnutls_pkcs11_privkey_import_url:
 * @pkey: The structure to store the parsed key
 * @url: a PKCS 11 url identifying the key
 * @flags: sequence of GNUTLS_PKCS_PRIVKEY_*
 *
 * This function will "import" a PKCS 11 URL identifying a private
 * key to the #gnutls_pkcs11_privkey_t structure. In reality since
 * in most cases keys cannot be exported, the private key structure
 * is being associated with the available operations on the token.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs11_privkey_import_url(gnutls_pkcs11_privkey_t pkey,
				 const char *url, unsigned int flags)
{
	int ret;
	struct ck_attribute *attr;
	ck_object_handle_t obj;
	struct ck_attribute a[4];
	ck_key_type_t key_type;
	struct pkcs11_session_info sinfo;

	PKCS11_CHECK_INIT;

	memset(&sinfo, 0, sizeof(sinfo));

	ret = pkcs11_url_to_info(url, &pkey->info);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	pkey->flags = flags;

	attr = p11_kit_uri_get_attribute(pkey->info, CKA_CLASS);
	if (!attr || attr->value_len != sizeof(ck_object_class_t) ||
	    *(ck_object_class_t *) attr->value != CKO_PRIVATE_KEY) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	attr = p11_kit_uri_get_attribute(pkey->info, CKA_ID);
	if (!attr || !attr->value_len) {
		attr = p11_kit_uri_get_attribute(pkey->info, CKA_LABEL);
		if (!attr || !attr->value_len) {
			gnutls_assert();
			return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		}
	}

	FIND_OBJECT(&sinfo, &pkey->pin, obj, pkey);

	a[0].type = CKA_KEY_TYPE;
	a[0].value = &key_type;
	a[0].value_len = sizeof(key_type);

	if (pkcs11_get_attribute_value(sinfo.module, sinfo.pks, obj, a, 1)
	    == CKR_OK) {
		pkey->pk_algorithm = mech_to_pk(key_type);
		if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN) {
			_gnutls_debug_log
			    ("Cannot determine PKCS #11 key algorithm\n");
			ret = GNUTLS_E_UNKNOWN_ALGORITHM;
			goto cleanup;
		}
	}

	ret = 0;

	if (pkey->sinfo.init)
		pkcs11_close_session(&pkey->sinfo);

	if (sinfo.tinfo.max_session_count != 1) {
		/* We do not keep the session open in tokens that can 
		 * only support a single session.
		 */
		memcpy(&pkey->sinfo, &sinfo, sizeof(pkey->sinfo));
		pkey->obj = obj;
		return ret;
	}

      cleanup:
	pkcs11_close_session(&sinfo);

	return ret;
}
Exemplo n.º 6
0
/*-
 * _gnutls_pkcs11_privkey_sign_hash:
 * @key: Holds the key
 * @hash: holds the data to be signed (should be output of a hash)
 * @signature: will contain the signature allocated with gnutls_malloc()
 *
 * This function will sign the given data using a signature algorithm
 * supported by the private key. It is assumed that the given data
 * are the output of a hash function.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
				 const gnutls_datum_t * hash,
				 gnutls_datum_t * signature)
{
	ck_rv_t rv;
	int ret;
	struct ck_mechanism mech;
	gnutls_datum_t tmp = { NULL, 0 };
	unsigned long siglen;
	struct pkcs11_session_info _sinfo;
	struct pkcs11_session_info *sinfo;
	ck_object_handle_t obj;

	PKCS11_CHECK_INIT;

	if (key->sinfo.init != 0) {
		sinfo = &key->sinfo;
		obj = key->obj;
	} else {
		sinfo = &_sinfo;
		memset(sinfo, 0, sizeof(*sinfo));
		FIND_OBJECT(sinfo, &key->pin, obj, key);
	}

	mech.mechanism = pk_to_mech(key->pk_algorithm);
	mech.parameter = NULL;
	mech.parameter_len = 0;

	/* Initialize signing operation; using the private key discovered
	 * earlier. */
	rv = pkcs11_sign_init(sinfo->module, sinfo->pks, &mech, obj);
	if (rv != CKR_OK) {
		gnutls_assert();
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	/* Work out how long the signature must be: */
	rv = pkcs11_sign(sinfo->module, sinfo->pks, hash->data, hash->size,
			 NULL, &siglen);
	if (rv != CKR_OK) {
		gnutls_assert();
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}

	tmp.data = gnutls_malloc(siglen);
	tmp.size = siglen;

	rv = pkcs11_sign(sinfo->module, sinfo->pks, hash->data, hash->size,
			 tmp.data, &siglen);
	if (rv != CKR_OK) {
		gnutls_assert();
		ret = pkcs11_rv_to_err(rv);
		goto cleanup;
	}


	if (key->pk_algorithm == GNUTLS_PK_EC
	    || key->pk_algorithm == GNUTLS_PK_DSA) {
		unsigned int hlen = siglen / 2;
		gnutls_datum_t r, s;

		if (siglen % 2 != 0) {
			gnutls_assert();
			ret = GNUTLS_E_PK_SIGN_FAILED;
			goto cleanup;
		}

		r.data = tmp.data;
		r.size = hlen;

		s.data = &tmp.data[hlen];
		s.size = hlen;

		ret = _gnutls_encode_ber_rs_raw(signature, &r, &s);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		gnutls_free(tmp.data);
		tmp.data = NULL;
	} else {
		signature->size = siglen;
		signature->data = tmp.data;
	}

	ret = 0;

      cleanup:
	if (sinfo != &key->sinfo)
		pkcs11_close_session(sinfo);
	if (ret < 0)
		gnutls_free(tmp.data);

	return ret;
}
Exemplo n.º 7
0
GenericLayout *Theme::getLayoutById( const string &id )
{
    FIND_OBJECT( GenericLayoutPtr, m_layouts );
}
Exemplo n.º 8
0
CtrlGeneric *Theme::getControlById( const string &id )
{
    FIND_OBJECT( CtrlGenericPtr, m_controls );
}
Exemplo n.º 9
0
TopWindow *Theme::getWindowById( const string &id )
{
    FIND_OBJECT( TopWindowPtr, m_windows );
}
Exemplo n.º 10
0
Popup *Theme::getPopupById( const string &id )
{
    FIND_OBJECT( PopupPtr, m_popups );
}
/*-
 * _gnutls_pkcs11_privkey_decrypt_data:
 * @key: Holds the key
 * @flags: should be 0 for now
 * @ciphertext: holds the data to be signed
 * @plaintext: will contain the plaintext, allocated with gnutls_malloc()
 *
 * This function will decrypt the given data using the public key algorithm
 * supported by the private key. 
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_pkcs11_privkey_decrypt_data (gnutls_pkcs11_privkey_t key,
                                    unsigned int flags,
                                    const gnutls_datum_t * ciphertext,
                                    gnutls_datum_t * plaintext)
{
  ck_rv_t rv;
  int ret;
  struct ck_mechanism mech;
  unsigned long siglen;
  struct ck_function_list *module;
  ck_session_handle_t pks;
  ck_object_handle_t obj;

  FIND_OBJECT (module, pks, obj, key);

  if (key->pk_algorithm != GNUTLS_PK_RSA)
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

  mech.mechanism = CKM_RSA_PKCS;
  mech.parameter = NULL;
  mech.parameter_len = 0;

  /* Initialize signing operation; using the private key discovered
   * earlier. */
  rv = pkcs11_decrypt_init (module, pks, &mech, obj);
  if (rv != CKR_OK)
    {
      gnutls_assert ();
      ret = pkcs11_rv_to_err (rv);
      goto cleanup;
    }

  /* Work out how long the plaintext must be: */
  rv = pkcs11_decrypt (module, pks, ciphertext->data, ciphertext->size,
                         NULL, &siglen);
  if (rv != CKR_OK)
    {
      gnutls_assert ();
      ret = pkcs11_rv_to_err (rv);
      goto cleanup;
    }

  plaintext->data = gnutls_malloc (siglen);
  plaintext->size = siglen;

  rv = pkcs11_decrypt (module, pks, ciphertext->data, ciphertext->size,
                         plaintext->data, &siglen);
  if (rv != CKR_OK)
    {
      gnutls_free (plaintext->data);
      gnutls_assert ();
      ret = pkcs11_rv_to_err (rv);
      goto cleanup;
    }

  plaintext->size = siglen;

  ret = 0;

cleanup:
  pkcs11_close_session (module, pks);

  return ret;
}
/**
 * gnutls_pkcs11_privkey_import_url:
 * @pkey: The structure to store the parsed key
 * @url: a PKCS 11 url identifying the key
 * @flags: sequence of GNUTLS_PKCS_PRIVKEY_*
 *
 * This function will "import" a PKCS 11 URL identifying a private
 * key to the #gnutls_pkcs11_privkey_t structure. In reality since
 * in most cases keys cannot be exported, the private key structure
 * is being associated with the available operations on the token.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_pkcs11_privkey_import_url (gnutls_pkcs11_privkey_t pkey,
                                  const char *url, unsigned int flags)
{
  int ret;
  struct ck_function_list *module;
  struct ck_attribute *attr;
  ck_session_handle_t pks;
  ck_object_handle_t obj;
  struct ck_attribute a[4];
  ck_key_type_t key_type;

  ret = pkcs11_url_to_info (url, &pkey->info);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  pkey->flags = flags;

  attr = p11_kit_uri_get_attribute (pkey->info, CKA_CLASS);
  if (!attr || attr->value_len != sizeof (ck_object_class_t) ||
      *(ck_object_class_t*)attr->value != CKO_PRIVATE_KEY)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  attr = p11_kit_uri_get_attribute (pkey->info, CKA_ID);
  if (!attr || !attr->value_len)
    {
      attr = p11_kit_uri_get_attribute (pkey->info, CKA_LABEL);
      if (!attr || !attr->value_len)
        {
          gnutls_assert ();
          return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
        }
    }

  FIND_OBJECT (module, pks, obj, pkey);
  a[0].type = CKA_KEY_TYPE;
  a[0].value = &key_type;
  a[0].value_len = sizeof (key_type);

  if (pkcs11_get_attribute_value (module, pks, obj, a, 1) == CKR_OK)
    {
      pkey->pk_algorithm = mech_to_pk(key_type);
      if (pkey->pk_algorithm == GNUTLS_PK_UNKNOWN)
        {
          _gnutls_debug_log("Cannot determine PKCS #11 key algorithm\n");
          ret = GNUTLS_E_UNKNOWN_ALGORITHM;
          goto cleanup;
        }
    }

  ret = 0;

cleanup:
  pkcs11_close_session (module, pks);

  return ret;
}
/*-
 * _gnutls_pkcs11_privkey_sign_hash:
 * @key: Holds the key
 * @hash: holds the data to be signed (should be output of a hash)
 * @signature: will contain the signature allocated with gnutls_malloc()
 *
 * This function will sign the given data using a signature algorithm
 * supported by the private key. It is assumed that the given data
 * are the output of a hash function.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 -*/
int
_gnutls_pkcs11_privkey_sign_hash (gnutls_pkcs11_privkey_t key,
                                  const gnutls_datum_t * hash,
                                  gnutls_datum_t * signature)
{
  ck_rv_t rv;
  int ret;
  struct ck_mechanism mech;
  unsigned long siglen;
  struct ck_function_list *module;
  ck_session_handle_t pks;
  ck_object_handle_t obj;

  FIND_OBJECT (module, pks, obj, key);

  mech.mechanism = pk_to_mech(key->pk_algorithm);
  mech.parameter = NULL;
  mech.parameter_len = 0;

  /* Initialize signing operation; using the private key discovered
   * earlier. */
  rv = pkcs11_sign_init (module, pks, &mech, obj);
  if (rv != CKR_OK)
    {
      gnutls_assert ();
      ret = pkcs11_rv_to_err (rv);
      goto cleanup;
    }

  /* Work out how long the signature must be: */
  rv = pkcs11_sign (module, pks, hash->data, hash->size, NULL, &siglen);
  if (rv != CKR_OK)
    {
      gnutls_assert ();
      ret = pkcs11_rv_to_err (rv);
      goto cleanup;
    }

  signature->data = gnutls_malloc (siglen);
  signature->size = siglen;

  rv = pkcs11_sign (module, pks, hash->data, hash->size, signature->data, &siglen);
  if (rv != CKR_OK)
    {
      gnutls_free (signature->data);
      gnutls_assert ();
      ret = pkcs11_rv_to_err (rv);
      goto cleanup;
    }

  signature->size = siglen;
  
  if (key->pk_algorithm == GNUTLS_PK_EC || key->pk_algorithm == GNUTLS_PK_DSA)
    {
      bigint_t r,s;

      if (siglen % 2 != 0)
        {
          gnutls_assert();
          ret = GNUTLS_E_PK_SIGN_FAILED;
          goto cleanup;
        }

      ret = read_rs(&r, &s, signature->data, signature->size);
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }
      
      gnutls_free(signature->data);
      ret = _gnutls_encode_ber_rs (signature, r, s);
      _gnutls_mpi_release(&r);
      _gnutls_mpi_release(&s);
      
      if (ret < 0)
        {
          gnutls_assert();
          goto cleanup;
        }
    }

  ret = 0;

cleanup:
  pkcs11_close_session (module, pks);

  return ret;
}