예제 #1
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static int
are_attributes_empty (P11KitUri *uri)
{
	return (p11_kit_uri_get_attribute (uri, CKA_LABEL) == NULL &&
	        p11_kit_uri_get_attribute (uri, CKA_ID) == NULL &&
	        p11_kit_uri_get_attribute (uri, CKA_CLASS) == NULL);
}
예제 #2
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_parse_with_empty_id (void)
{
	CK_ATTRIBUTE_PTR attr;
	P11KitUri *uri;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:id=;type=cert", P11_KIT_URI_FOR_ANY, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	attr = p11_kit_uri_get_attribute (uri, CKA_ID);
	assert_ptr_not_null (attr);

	p11_kit_uri_free (uri);

	/* really empty */

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:type=cert", P11_KIT_URI_FOR_ANY, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	attr = p11_kit_uri_get_attribute (uri, CKA_ID);
	assert (attr == NULL);

	p11_kit_uri_free (uri);
}
예제 #3
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_parse_with_label_and_new_klass (void)
{
	CK_ATTRIBUTE_PTR attr;
	P11KitUri *uri;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label;type=cert", P11_KIT_URI_FOR_ANY, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	attr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == strlen ("Test Label"));
	assert (memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0);

	attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == sizeof (CK_OBJECT_CLASS));
	assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_CERTIFICATE);

	p11_kit_uri_free (uri);
}
예제 #4
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_get_set_attribute (void)
{
	CK_ATTRIBUTE attr;
	CK_ATTRIBUTE_PTR ptr;
	P11KitUri *uri;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
	assert_ptr_eq (NULL, ptr);

	ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL);
	assert_num_eq (P11_KIT_URI_OK, ret);

	ret = p11_kit_uri_clear_attribute (uri, CKA_COLOR);
	assert_num_eq (P11_KIT_URI_NOT_FOUND, ret);

	attr.type = CKA_LABEL;
	attr.pValue = "Test";
	attr.ulValueLen = 4;

	ret = p11_kit_uri_set_attribute (uri, &attr);
	assert_num_eq (P11_KIT_URI_OK, ret);

	/* We can set other attributes */
	attr.type = CKA_COLOR;
	ret = p11_kit_uri_set_attribute (uri, &attr);
	assert_num_eq (P11_KIT_URI_OK, ret);

	/* And get them too */
	ptr = p11_kit_uri_get_attribute (uri, CKA_COLOR);
	assert_ptr_not_null (ptr);

	ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
	assert_ptr_not_null (ptr);

	assert (ptr->type == CKA_LABEL);
	assert (ptr->ulValueLen == 4);
	assert (memcmp (ptr->pValue, "Test", 4) == 0);

	ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL);
	assert_num_eq (P11_KIT_URI_OK, ret);

	ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
	assert_ptr_eq (NULL, ptr);

	p11_kit_uri_free (uri);
}
예제 #5
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_parse_parse_unknown_object_type (void)
{
	P11KitUri *uri;
	CK_ATTRIBUTE_PTR attr;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:type=unknown", P11_KIT_URI_FOR_OBJECT, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
	assert_ptr_eq (NULL, attr);

	p11_kit_uri_free (uri);
}
예제 #6
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_parse_secret_key (void)
{
	P11KitUri *uri;
	CK_ATTRIBUTE_PTR attr;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:type=secret-key", P11_KIT_URI_FOR_OBJECT, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == sizeof (CK_OBJECT_CLASS));
	assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_SECRET_KEY);

	p11_kit_uri_free (uri);
}
예제 #7
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_parse_with_id (void)
{
	CK_ATTRIBUTE_PTR attr;
	P11KitUri *uri;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:id=%54%45%53%54%00", P11_KIT_URI_FOR_OBJECT, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	/* Note that there's a NULL in the attribute (end) */
	attr = p11_kit_uri_get_attribute (uri, CKA_ID);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == 5);
	assert (memcmp (attr->pValue, "TEST", 5) == 0);


	p11_kit_uri_free (uri);
}
예제 #8
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_parse_with_label (void)
{
	CK_ATTRIBUTE_PTR attr;
	P11KitUri *uri;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label", P11_KIT_URI_FOR_ANY, uri);
	assert_num_eq (P11_KIT_URI_OK, ret);

	assert (is_module_empty (uri));
	assert (is_slot_empty (uri));
	assert (is_token_empty (uri));

	attr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == strlen ("Test Label"));
	assert (memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0);

	p11_kit_uri_free (uri);
}
예제 #9
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;
}
예제 #10
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;
}
예제 #11
0
/**
 * p11_kit_uri_format:
 * @uri: The URI.
 * @uri_type: The type of URI that should be produced.
 * @string: Location to store a newly allocated string.
 *
 * Format a PKCS\#11 URI into a string.
 *
 * Fields which are zeroed out will not be included in the resulting string.
 * Attributes which are not present will also not be included.
 *
 * The uri_type of URI specified limits the different parts of the resulting
 * URI. To format a URI containing all possible information use
 * %P11_KIT_URI_FOR_ANY
 *
 * The resulting string should be freed with free().
 *
 * Returns: %P11_KIT_URI_OK if the URI was formatted successfully.
 *     %P11_KIT_URI_NO_MEMORY if memory allocation failed.
 */
int
p11_kit_uri_format (P11KitUri *uri, P11KitUriType uri_type, char **string)
{
	char *result = NULL;
	size_t length = 0;
	int is_first = 1;

	result = malloc (128);
	if (!result)
		return P11_KIT_URI_NO_MEMORY;

	length = P11_KIT_URI_SCHEME_LEN;
	memcpy (result, P11_KIT_URI_SCHEME, length);
	result[length] = ':';
	result[++length] = 0;

	if ((uri_type & P11_KIT_URI_FOR_MODULE) == P11_KIT_URI_FOR_MODULE) {
		if (!format_struct_string (&result, &length, &is_first, "library-description",
		                           uri->module.libraryDescription,
		                           sizeof (uri->module.libraryDescription)) ||
		    !format_struct_string (&result, &length, &is_first, "library-manufacturer",
		                           uri->module.manufacturerID,
		                           sizeof (uri->module.manufacturerID))) {
			free (result);
			return P11_KIT_URI_NO_MEMORY;
		}
	}

	if ((uri_type & P11_KIT_URI_FOR_MODULE_WITH_VERSION) == P11_KIT_URI_FOR_MODULE_WITH_VERSION) {
		if (!format_struct_version (&result, &length, &is_first, "library-version",
		                            &uri->module.libraryVersion)) {
			free (result);
			return P11_KIT_URI_NO_MEMORY;
		}
	}

	if ((uri_type & P11_KIT_URI_FOR_TOKEN) == P11_KIT_URI_FOR_TOKEN) {
		if (!format_struct_string (&result, &length, &is_first, "model",
		                           uri->token.model,
		                           sizeof (uri->token.model)) ||
		    !format_struct_string (&result, &length, &is_first, "manufacturer",
		                           uri->token.manufacturerID,
		                           sizeof (uri->token.manufacturerID)) ||
		    !format_struct_string (&result, &length, &is_first, "serial",
		                           uri->token.serialNumber,
		                           sizeof (uri->token.serialNumber)) ||
		    !format_struct_string (&result, &length, &is_first, "token",
		                           uri->token.label,
		                           sizeof (uri->token.label))) {
			free (result);
			return P11_KIT_URI_NO_MEMORY;
		}
	}

	if ((uri_type & P11_KIT_URI_FOR_OBJECT) == P11_KIT_URI_FOR_OBJECT) {
		if (!format_attribute_string (&result, &length, &is_first, "id",
		                              p11_kit_uri_get_attribute (uri, CKA_ID)) ||
		    !format_attribute_string (&result, &length, &is_first, "object",
		                              p11_kit_uri_get_attribute (uri, CKA_LABEL))) {
			free (result);
			return P11_KIT_URI_NO_MEMORY;
		}

		if (!format_attribute_class (&result, &length, &is_first, "object-type",
		                             p11_kit_uri_get_attribute (uri, CKA_CLASS))) {
			free (result);
			return P11_KIT_URI_NO_MEMORY;
		}
	}

	if (uri->pin_source) {
		format_encode_string (&result, &length, &is_first, "pin-source",
		                      (const unsigned char*)uri->pin_source,
		                      strlen (uri->pin_source));
	}

	*string = result;
	return P11_KIT_URI_OK;
}
/**
 * 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;
}
예제 #13
0
파일: test-uri.c 프로젝트: p11-glue/p11-kit
static void
test_uri_build_with_attributes (void)
{
	char *string = NULL;
	P11KitUri *uri;
	P11KitUri *check;
	CK_OBJECT_CLASS klass;
	CK_ATTRIBUTE_PTR attr;
	CK_ATTRIBUTE at;
	int ret;

	uri = p11_kit_uri_new ();
	assert_ptr_not_null (uri);

	at.type = CKA_LABEL;
	at.pValue = "The Label";
	at.ulValueLen = 9;
	ret = p11_kit_uri_set_attribute (uri, &at);
	assert_num_eq (P11_KIT_URI_OK, ret);

	at.type = CKA_ID;
	at.pValue = "HELLO";
	at.ulValueLen = 5;
	ret = p11_kit_uri_set_attribute (uri, &at);
	assert_num_eq (P11_KIT_URI_OK, ret);

	klass = CKO_DATA;
	at.type = CKA_CLASS;
	at.pValue = &klass;
	at.ulValueLen = sizeof (klass);
	ret = p11_kit_uri_set_attribute (uri, &at);
	assert_num_eq (P11_KIT_URI_OK, ret);

	ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
	assert_num_eq (P11_KIT_URI_OK, ret);

	check = p11_kit_uri_new ();
	assert_ptr_not_null (check);

	ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_ANY, check);
	assert_num_eq (P11_KIT_URI_OK, ret);

	attr = p11_kit_uri_get_attribute (check, CKA_LABEL);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == 9);
	assert (memcmp (attr->pValue, "The Label", attr->ulValueLen) == 0);

	attr = p11_kit_uri_get_attribute (check, CKA_CLASS);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == sizeof (klass));
	assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == klass);

	attr = p11_kit_uri_get_attribute (check, CKA_ID);
	assert_ptr_not_null (attr);
	assert (attr->ulValueLen == 5);
	assert (memcmp (attr->pValue, "HELLO", attr->ulValueLen) == 0);

	p11_kit_uri_free (check);

	assert (strstr (string, "object=The%20Label") != NULL);
	assert (strstr (string, "type=data") != NULL);
	assert (strstr (string, "id=%48%45%4c%4c%4f") != NULL);

	free (string);
	p11_kit_uri_free (uri);
}