/** * gnutls_openpgp_privkey_get_subkey_pk_algorithm: * @key: is an OpenPGP key * @idx: is the subkey index * @bits: if bits is non null it will hold the size of the parameters' in bits * * This function will return the public key algorithm of a subkey of an OpenPGP * certificate. * * If bits is non null, it should have enough size to hold the parameters * size in bits. For RSA the bits returned is the modulus. * For DSA the bits returned are of the public exponent. * * Returns: a member of the #gnutls_pk_algorithm_t enumeration on * success, or a negative error code on error. * * Since: 2.4.0 **/ gnutls_pk_algorithm_t gnutls_openpgp_privkey_get_subkey_pk_algorithm(gnutls_openpgp_privkey_t key, unsigned int idx, unsigned int *bits) { cdk_packet_t pkt; int algo; if (!key) { gnutls_assert(); return GNUTLS_PK_UNKNOWN; } if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) return gnutls_openpgp_privkey_get_pk_algorithm(key, bits); pkt = _get_secret_subkey(key, idx); algo = 0; if (pkt) { if (bits) *bits = cdk_pk_get_nbits(pkt->pkt.secret_key->pk); algo = pkt->pkt.secret_key->pubkey_algo; if (is_RSA(algo)) algo = GNUTLS_PK_RSA; else if (is_DSA(algo)) algo = GNUTLS_PK_DSA; else algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM; } return algo; }
/** * gnutls_privkey_get_pk_algorithm: * @key: should contain a #gnutls_privkey_t type * @bits: If set will return the number of bits of the parameters (may be NULL) * * This function will return the public key algorithm of a private * key and if possible will return a number of bits that indicates * the security parameter of the key. * * Returns: a member of the #gnutls_pk_algorithm_t enumeration on * success, or a negative error code on error. * * Since: 2.12.0 **/ int gnutls_privkey_get_pk_algorithm(gnutls_privkey_t key, unsigned int *bits) { switch (key->type) { #ifdef ENABLE_OPENPGP case GNUTLS_PRIVKEY_OPENPGP: return gnutls_openpgp_privkey_get_pk_algorithm(key->key.openpgp, bits); #endif #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: return gnutls_pkcs11_privkey_get_pk_algorithm(key->key.pkcs11, bits); #endif case GNUTLS_PRIVKEY_X509: if (bits) *bits = _gnutls_mpi_get_nbits(key->key.x509-> params.params[0]); return gnutls_x509_privkey_get_pk_algorithm(key->key.x509); case GNUTLS_PRIVKEY_EXT: if (bits) *bits = 0; return key->pk_algorithm; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } }
/*- * _gnutls_openpgp_privkey_decrypt_data: * @key: Holds the key * @flags: (0) for now * @ciphertext: holds the data to be decrypted * @plaintext: will contain newly allocated plaintext * * This function will sign the given hash using the private key. You * should use gnutls_openpgp_privkey_set_preferred_key_id() before * calling this function to set the subkey to use. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. -*/ int _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, unsigned int flags, const gnutls_datum_t * ciphertext, gnutls_datum_t * plaintext) { int result, i; gnutls_pk_params_st params; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; char buf[2*GNUTLS_OPENPGP_KEYID_SIZE+1]; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); if (result == 0) { uint32_t kid[2]; KEYID_IMPORT (kid, keyid); _gnutls_hard_log("Decrypting using PGP key ID %s\n", _gnutls_bin2hex(keyid, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL)); result = _gnutls_openpgp_privkey_get_mpis (key, kid, ¶ms); i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL); } else { _gnutls_hard_log("Decrypting using master PGP key\n"); pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, NULL, ¶ms); } if (result < 0) { gnutls_assert (); return result; } result = _gnutls_pk_decrypt (pk_algorithm, plaintext, ciphertext, ¶ms); gnutls_pk_params_clear(¶ms); gnutls_pk_params_release(¶ms); if (result < 0) return gnutls_assert_val(result); return 0; }
/** * gnutls_openpgp_privkey_sign_hash: * @key: Holds the key * @hash: holds the data to be signed * @signature: will contain newly allocated signature * * This function will sign the given hash using the private key. You * should use gnutls_openpgp_privkey_set_preferred_key_id() before * calling this function to set the subkey to use. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. * * Deprecated: Use gnutls_privkey_sign_hash() instead. */ int gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key, const gnutls_datum_t * hash, gnutls_datum_t * signature) { int result, i; bigint_t params[MAX_PRIV_PARAMS_SIZE]; int params_size = MAX_PRIV_PARAMS_SIZE; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); if (result == 0) { uint32_t kid[2]; int idx; KEYID_IMPORT (kid, keyid); idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, kid, params, ¶ms_size); } else { pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, NULL, params, ¶ms_size); } if (result < 0) { gnutls_assert (); return result; } result = _gnutls_soft_sign (pk_algorithm, params, params_size, hash, signature); for (i = 0; i < params_size; i++) _gnutls_mpi_release (¶ms[i]); if (result < 0) { gnutls_assert (); return result; } return 0; }
/** * gnutls_privkey_import_openpgp: * @pkey: The private key * @key: The private key to be imported * @flags: should be zero * * This function will import the given private key to the abstract * #gnutls_privkey_t structure. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_privkey_import_openpgp (gnutls_privkey_t pkey, gnutls_openpgp_privkey_t key, unsigned int flags) { pkey->key.openpgp = key; pkey->type = GNUTLS_PRIVKEY_OPENPGP; pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); pkey->flags = flags; return 0; }
/** * gnutls_openpgp_privkey_sec_param: * @key: a key structure * * This function will return the security parameter appropriate with * this private key. * * Returns: On success, a valid security parameter is returned otherwise * %GNUTLS_SEC_PARAM_UNKNOWN is returned. * * Since: 2.12.0 **/ gnutls_sec_param_t gnutls_openpgp_privkey_sec_param(gnutls_openpgp_privkey_t key) { gnutls_pk_algorithm_t algo; unsigned int bits; algo = gnutls_openpgp_privkey_get_pk_algorithm(key, &bits); if (algo == GNUTLS_PK_UNKNOWN) { gnutls_assert(); return GNUTLS_SEC_PARAM_UNKNOWN; } return gnutls_pk_bits_to_sec_param(algo, bits); }
/** * gnutls_privkey_import_openpgp: * @pkey: The private key * @key: The private key to be imported * @flags: Flags for the import * * This function will import the given private key to the abstract * #gnutls_privkey_t structure. * * The #gnutls_openpgp_privkey_t object must not be deallocated * during the lifetime of this structure. The subkey set as * preferred will be used, or the master key otherwise. * * @flags might be zero or one of %GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE * and %GNUTLS_PRIVKEY_IMPORT_COPY. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.12.0 **/ int gnutls_privkey_import_openpgp(gnutls_privkey_t pkey, gnutls_openpgp_privkey_t key, unsigned int flags) { int ret, idx; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; ret = check_if_clean(pkey); if (ret < 0) { gnutls_assert(); return ret; } if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) { ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key); if (ret < 0) { gnutls_openpgp_privkey_deinit(pkey->key.openpgp); return gnutls_assert_val(ret); } } else pkey->key.openpgp = key; pkey->type = GNUTLS_PRIVKEY_OPENPGP; ret = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid); if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) { pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL); } else { if (ret < 0) return gnutls_assert_val(ret); idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm(key, idx, NULL); } pkey->flags = flags; return 0; }
/** * gnutls_openpgp_privkey_sign_hash: * @key: Holds the key * @hash: holds the data to be signed * @signature: will contain newly allocated signature * * This function will sign the given hash using the private key. You * should use gnutls_openpgp_privkey_set_preferred_key_id() before * calling this function to set the subkey to use. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Deprecated: Use gnutls_privkey_sign_hash() instead. */ int gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key, const gnutls_datum_t * hash, gnutls_datum_t * signature) { int result; gnutls_pk_params_st params; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; char buf[2 * GNUTLS_OPENPGP_KEYID_SIZE + 1]; if (key == NULL) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_openpgp_privkey_get_preferred_key_id(key, keyid); if (result == 0) { uint32_t kid[2]; int idx; KEYID_IMPORT(kid, keyid); _gnutls_hard_log("Signing using PGP key ID %s\n", _gnutls_bin2hex(keyid, GNUTLS_OPENPGP_KEYID_SIZE, buf, sizeof(buf), NULL)); idx = gnutls_openpgp_privkey_get_subkey_idx(key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm(key, idx, NULL); result = _gnutls_openpgp_privkey_get_mpis(key, kid, ¶ms); } else { _gnutls_hard_log("Signing using master PGP key\n"); pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL); result = _gnutls_openpgp_privkey_get_mpis(key, NULL, ¶ms); } if (result < 0) { gnutls_assert(); return result; } result = _gnutls_pk_sign(pk_algorithm, signature, hash, ¶ms); gnutls_pk_params_clear(¶ms); gnutls_pk_params_release(¶ms); if (result < 0) { gnutls_assert(); return result; } return 0; }
/*- * _gnutls_openpgp_privkey_decrypt_data: * @key: Holds the key * @flags: zero for now * @ciphertext: holds the data to be decrypted * @plaintext: will contain newly allocated plaintext * * This function will sign the given hash using the private key. You * should use gnutls_openpgp_privkey_set_preferred_key_id() before * calling this function to set the subkey to use. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. -*/ int _gnutls_openpgp_privkey_decrypt_data (gnutls_openpgp_privkey_t key, unsigned int flags, const gnutls_datum_t * ciphertext, gnutls_datum_t * plaintext) { int result, i; bigint_t params[MAX_PRIV_PARAMS_SIZE]; int params_size = MAX_PRIV_PARAMS_SIZE; int pk_algorithm; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } result = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); if (result == 0) { uint32_t kid[2]; KEYID_IMPORT (kid, keyid); result = _gnutls_openpgp_privkey_get_mpis (key, kid, params, ¶ms_size); i = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, i, NULL); } else { pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (key, NULL); result = _gnutls_openpgp_privkey_get_mpis (key, NULL, params, ¶ms_size); } if (result < 0) { gnutls_assert (); return result; } if (pk_algorithm != GNUTLS_PK_RSA) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } result = _gnutls_pkcs1_rsa_decrypt (plaintext, ciphertext, params, params_size, 2); for (i = 0; i < params_size; i++) _gnutls_mpi_release (¶ms[i]); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* Copies a gnutls_openpgp_privkey_t to a gnutls_privkey structure. */ int _gnutls_openpgp_privkey_to_gkey (gnutls_privkey * dest, gnutls_openpgp_privkey_t src) { int ret = 0; gnutls_openpgp_keyid_t keyid; char err_buf[33]; if (dest == NULL || src == NULL) { gnutls_assert (); return GNUTLS_E_CERTIFICATE_ERROR; } dest->params_size = MAX_PRIV_PARAMS_SIZE; ret = gnutls_openpgp_privkey_get_preferred_key_id (src, keyid); if (ret == 0) { int idx; uint32_t kid32[2]; _gnutls_debug_log ("Importing Openpgp key and using openpgp sub key: %s\n", _gnutls_bin2hex (keyid, sizeof (keyid), err_buf, sizeof (err_buf))); KEYID_IMPORT (kid32, keyid); idx = gnutls_openpgp_privkey_get_subkey_idx (src, keyid); if (idx < 0) { gnutls_assert (); return idx; } dest->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (src, idx, NULL); ret = _gnutls_openpgp_privkey_get_mpis (src, kid32, dest->params, &dest->params_size); } else { _gnutls_debug_log ("Importing Openpgp key and using main openpgp key.\n"); dest->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm (src, NULL); ret = _gnutls_openpgp_privkey_get_mpis (src, NULL, dest->params, &dest->params_size); } if (ret < 0) { gnutls_assert (); return ret; } return 0; }