unsigned int pkcs11_obj_flags_to_int(unsigned int flags);
int
-_gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
- const gnutls_datum_t * hash,
- gnutls_datum_t * signature);
+_gnutls_pkcs11_privkey_sign(gnutls_pkcs11_privkey_t key,
+ const gnutls_sign_entry_st *se,
+ const gnutls_datum_t * hash,
+ gnutls_datum_t * signature,
+ gnutls_x509_spki_st *spki_params);
int
_gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key,
return CKM_DSA;
else if (pk == GNUTLS_PK_EC)
return CKM_ECDSA;
- else
+ else if (pk == GNUTLS_PK_RSA)
return CKM_RSA_PKCS;
+ else if (pk == GNUTLS_PK_RSA_PSS)
+ return CKM_RSA_PKCS_PSS;
+ else
+ return -1;
}
static inline int pk_to_key_type(gnutls_pk_algorithm_t pk)
return CKK_DSA;
else if (pk == GNUTLS_PK_EC)
return CKK_ECDSA;
- else
+ else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA)
return CKK_RSA;
+ else
+ return -1;
}
static inline gnutls_pk_algorithm_t key_type_to_pk(ck_key_type_t m)
} else if (pk == GNUTLS_PK_EC) {
*type = CKK_ECDSA;
return CKM_ECDSA_KEY_PAIR_GEN;
- } else {
+ } else if (pk == GNUTLS_PK_RSA_PSS || pk == GNUTLS_PK_RSA) {
*type = CKK_RSA;
return CKM_RSA_PKCS_KEY_PAIR_GEN;
+ } else {
+ *type = -1;
+ return -1;
}
}
expr; \
}
+struct hash_mappings_st {
+ gnutls_digest_algorithm_t id;
+ unsigned long phash; /* pkcs11 hash ID */
+ unsigned long mgf_id;
+};
+
+
+#ifndef CKG_MGF1_SHA224
+# define CKG_MGF1_SHA224 0x00000005UL
+# define CKG_MGF1_SHA256 0x00000002UL
+# define CKG_MGF1_SHA384 0x00000003UL
+# define CKG_MGF1_SHA512 0x00000004UL
+
+struct ck_rsa_pkcs_pss_params {
+ ck_mechanism_type_t hash_alg;
+ /* ck_rsa_pkcs_mgf_type_t is not defined in old versions of p11-kit */
+ unsigned long mgf;
+ unsigned long s_len;
+};
+#endif
+
+static const struct hash_mappings_st hash_mappings[] =
+{
+ {.id = GNUTLS_DIG_SHA224,
+ .phash = CKM_SHA224,
+ .mgf_id = CKG_MGF1_SHA224
+ },
+ {.id = GNUTLS_DIG_SHA256,
+ .phash = CKM_SHA256,
+ .mgf_id = CKG_MGF1_SHA256
+ },
+ {.id = GNUTLS_DIG_SHA384,
+ .phash = CKM_SHA384,
+ .mgf_id = CKG_MGF1_SHA384
+ },
+ {.id = GNUTLS_DIG_SHA512,
+ .phash = CKM_SHA512,
+ .mgf_id = CKG_MGF1_SHA512
+ }
+};
+
+static const struct hash_mappings_st *hash_to_map(gnutls_digest_algorithm_t hash)
+{
+ unsigned i;
+ for (i=0;i<sizeof(hash_mappings)/sizeof(hash_mappings[0]);i++) {
+ if (hash == hash_mappings[i].id)
+ return &hash_mappings[i];
+ }
+ return NULL;
+}
+
/*-
* _gnutls_pkcs11_privkey_sign_hash:
* @key: Holds the key
* negative error value.
-*/
int
-_gnutls_pkcs11_privkey_sign_hash(gnutls_pkcs11_privkey_t key,
- const gnutls_datum_t * hash,
- gnutls_datum_t * signature)
+_gnutls_pkcs11_privkey_sign(gnutls_pkcs11_privkey_t key,
+ const gnutls_sign_entry_st *se,
+ const gnutls_datum_t * hash,
+ gnutls_datum_t * signature,
+ gnutls_x509_spki_st *spki_params)
{
ck_rv_t rv;
int ret;
struct pkcs11_session_info *sinfo;
unsigned req_login = 0;
unsigned login_flags = SESSION_LOGIN|SESSION_CONTEXT_SPECIFIC;
+ struct ck_rsa_pkcs_pss_params rsa_pss_params;
PKCS11_CHECK_INIT_PRIVKEY(key);
sinfo = &key->sinfo;
- mech.mechanism = pk_to_mech(key->pk_algorithm);
- mech.parameter = NULL;
- mech.parameter_len = 0;
+ if (se->pk == GNUTLS_PK_RSA_PSS) {
+ const struct hash_mappings_st *map = hash_to_map(se->hash);
+
+ if (map == NULL)
+ return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
+
+ rsa_pss_params.hash_alg = map->phash;
+ rsa_pss_params.mgf = map->mgf_id;
+ rsa_pss_params.s_len = spki_params->salt_size;
+
+ mech.mechanism = CKM_RSA_PKCS_PSS;
+ mech.parameter = &rsa_pss_params;
+ mech.parameter_len = sizeof(rsa_pss_params);
+ } else {
+ ret = pk_to_mech(se->pk);
+
+ if (ret == -1)
+ return gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM);
+
+ mech.mechanism = ret;
+ mech.parameter = NULL;
+ mech.parameter_len = 0;
+ }
ret = gnutls_mutex_lock(&key->mutex);
if (ret != 0)
* earlier. */
REPEAT_ON_INVALID_HANDLE(rv = pkcs11_sign_init(sinfo->module, sinfo->pks, &mech, key->ref));
if (rv != CKR_OK) {
+ _gnutls_debug_log("p11: %s\n", pkcs11_strerror(rv));
gnutls_assert();
ret = pkcs11_rv_to_err(rv);
goto cleanup;
*
* 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
*
**/
ck_rv_t rv;
int ret;
struct ck_session_info session_info;
-
+
PKCS11_CHECK_INIT_PRIVKEY(key);
REPEAT_ON_INVALID_HANDLE(rv = (key->sinfo.module)->C_GetSessionInfo(key->sinfo.pks, &session_info));
* @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.
+ * supported by the private key.
*
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.
* This function will generate a private key in the specified
* by the @url token. The private key will be generate within
* the token and will not be exportable. This function will
- * store the DER-encoded public key in the SubjectPublicKeyInfo format
+ * store the DER-encoded public key in the SubjectPublicKeyInfo format
* in @pubkey. The @pubkey should be deinitialized using gnutls_free().
*
* Note that when generating an elliptic curve key, the curve
pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);
switch (pk) {
+ case GNUTLS_PK_RSA_PSS:
case GNUTLS_PK_RSA: {
gnutls_datum_t m, e;
switch (pk) {
case GNUTLS_PK_RSA:
+ case GNUTLS_PK_RSA_PSS:
{
ret = _gnutls_params_get_rsa_raw(&key->params, &m, &e, &d, &p,
cleanup:
switch (pk) {
+ case GNUTLS_PK_RSA_PSS:
case GNUTLS_PK_RSA:
{
gnutls_free(m.data);
unsigned flags,
gnutls_x509_spki_st *params)
{
- switch (key->type) {
-#ifdef ENABLE_PKCS11
- case GNUTLS_PRIVKEY_PKCS11:
- break;
-#endif
- case GNUTLS_PRIVKEY_EXT:
- break;
- case GNUTLS_PRIVKEY_X509: {
- unsigned salt_size = 0;
- gnutls_pk_algorithm_t key_pk;
- unsigned bits;
-
- if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS) {
- if (!GNUTLS_PK_IS_RSA(pk))
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- pk = GNUTLS_PK_RSA_PSS;
- }
+ unsigned salt_size = 0;
+ unsigned bits = 0;
+ gnutls_pk_algorithm_t key_pk;
- key_pk = gnutls_x509_privkey_get_pk_algorithm2(key->key.x509, &bits);
- if (!(key_pk == pk ||
- (key_pk == GNUTLS_PK_RSA && pk == GNUTLS_PK_RSA_PSS))) {
- gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
- }
+ if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS) {
+ if (!GNUTLS_PK_IS_RSA(pk))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ pk = GNUTLS_PK_RSA_PSS;
+ }
- if (pk == GNUTLS_PK_RSA_PSS) {
- const mac_entry_st *me;
+ key_pk = gnutls_privkey_get_pk_algorithm(key, &bits);
+ if (!(key_pk == pk ||
+ (key_pk == GNUTLS_PK_RSA && pk == GNUTLS_PK_RSA_PSS))) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
- me = hash_to_entry(dig);
- if (unlikely(me == NULL))
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ if (pk == GNUTLS_PK_RSA_PSS) {
+ const mac_entry_st *me;
- if (params->pk == GNUTLS_PK_RSA)
- salt_size = 0;
- else if (params->pk == GNUTLS_PK_RSA_PSS) {
- if (dig != params->rsa_pss_dig) {
- gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
- }
+ me = hash_to_entry(dig);
+ if (unlikely(me == NULL))
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- salt_size = params->salt_size;
+ if (params->pk == GNUTLS_PK_RSA)
+ salt_size = 0;
+ else if (params->pk == GNUTLS_PK_RSA_PSS) {
+ if (dig != params->rsa_pss_dig) {
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
}
- if (!(flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE))
- salt_size = _gnutls_find_rsa_pss_salt_size(bits, me,
- salt_size);
+ salt_size = params->salt_size;
}
- params->salt_size = salt_size;
+ if (!(flags & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE))
+ salt_size = _gnutls_find_rsa_pss_salt_size(bits, me, salt_size);
- break;
- }
- default:
- gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
+ params->salt_size = salt_size;
+ params->rsa_pss_dig = dig;
}
+
params->pk = pk;
- params->rsa_pss_dig = dig;
return 0;
}
switch (key->type) {
#ifdef ENABLE_PKCS11
case GNUTLS_PRIVKEY_PKCS11:
- return _gnutls_pkcs11_privkey_sign_hash(key->key.pkcs11,
- data, signature);
+ return _gnutls_pkcs11_privkey_sign(key->key.pkcs11, se,
+ data, signature,
+ params);
#endif
case GNUTLS_PRIVKEY_X509:
return _gnutls_pk_sign(pk, signature, data,