/** * 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_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; }
/* Returns the public key of the private key (if possible) */ int _gnutls_privkey_get_public_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params) { int ret; gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm(key, NULL); switch (key->type) { #ifdef ENABLE_OPENPGP case GNUTLS_PRIVKEY_OPENPGP: { gnutls_pk_params_st tmp_params; uint32_t kid[2]; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; ret = gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp, keyid); if (ret == 0) { KEYID_IMPORT(kid, keyid); ret = _gnutls_openpgp_privkey_get_mpis(key-> key. openpgp, kid, &tmp_params); } else ret = _gnutls_openpgp_privkey_get_mpis(key-> key. openpgp, NULL, &tmp_params); if (ret < 0) { gnutls_assert(); return ret; } ret = privkey_to_pubkey(pk, &tmp_params, params); gnutls_pk_params_release(&tmp_params); } break; #endif case GNUTLS_PRIVKEY_X509: ret = privkey_to_pubkey(pk, &key->key.x509->params, params); break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } return ret; }
/* Returns the public key of the private key (if possible) */ int _gnutls_privkey_get_mpis(gnutls_privkey_t key, gnutls_pk_params_st * params) { int ret; switch (key->type) { #ifdef ENABLE_OPENPGP case GNUTLS_PRIVKEY_OPENPGP: { uint32_t kid[2]; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; ret = gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp, keyid); if (ret == 0) { KEYID_IMPORT(kid, keyid); ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid, params); } else ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL, params); if (ret < 0) { gnutls_assert(); return ret; } } break; #endif case GNUTLS_PRIVKEY_X509: ret = _gnutls_pk_params_copy(params, &key->key.x509->params); break; #ifdef ENABLE_PKCS11 case GNUTLS_PRIVKEY_PKCS11: { gnutls_pubkey_t pubkey; ret = _pkcs11_privkey_get_pubkey(key->key.pkcs11, &pubkey, 0); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_pubkey_get_mpis(pubkey, params); gnutls_pubkey_deinit(pubkey); break; } #endif default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } return ret; }
/** * 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_get_pk_algorithm: * @key: is an OpenPGP key * @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 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_pk_algorithm (gnutls_openpgp_privkey_t key, unsigned int *bits) { cdk_packet_t pkt; int algo = 0, ret; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; if (!key) { gnutls_assert (); return GNUTLS_PK_UNKNOWN; } ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); if (ret == 0) { int idx; idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX) { algo = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, bits); return algo; } } pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY); if (pkt) { if (bits) *bits = cdk_pk_get_nbits (pkt->pkt.secret_key->pk); algo = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo); } return algo; }
/** * 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; }
/* Returns the public key of the private key (if possible) */ int _gnutls_privkey_get_public_mpis (gnutls_privkey_t key, bigint_t * params, int *params_size) { int ret; gnutls_pk_algorithm_t pk = gnutls_privkey_get_pk_algorithm (key, NULL); switch (key->type) { #ifdef ENABLE_OPENPGP case GNUTLS_PRIVKEY_OPENPGP: { bigint_t tmp_params[MAX_PRIV_PARAMS_SIZE]; int tmp_params_size = MAX_PRIV_PARAMS_SIZE; uint32_t kid[2], i; gnutls_openpgp_keyid_t keyid; ret = gnutls_openpgp_privkey_get_preferred_key_id (key->key.openpgp, keyid); if (ret == 0) { KEYID_IMPORT (kid, keyid); ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, kid, tmp_params, &tmp_params_size); } else ret = _gnutls_openpgp_privkey_get_mpis (key->key.openpgp, NULL, tmp_params, &tmp_params_size); if (ret < 0) { gnutls_assert (); return ret; } ret = privkey_to_pubkey (pk, tmp_params, tmp_params_size, params, params_size); for (i = 0; i < tmp_params_size; i++) _gnutls_mpi_release (&tmp_params[i]); } break; #endif case GNUTLS_PRIVKEY_X509: ret = privkey_to_pubkey (pk, key->key.x509->params, key->key.x509->params_size, params, params_size); break; default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } return ret; }
/*- * _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; }