Bug 1634158 - Update RNP source from git as of 2020-05-06. r=kaie
Using update_rnp.sh. Revision: eabaa5d07ae453c44dfa272f25ad7b5e41c8e5fb --HG-- extra : rebase_source : e0aa4b42ef566c98f91629a56707ca87fd25947f extra : histedit_source : a8e4c98f8f2a97fde14bd4bc564304e31592dbcf
This commit is contained in:
Родитель
1d68def8c0
Коммит
a089e7e968
|
@ -1,7 +1,7 @@
|
|||
Directory ./rnp contains a copy of rnp which has been obtained from:
|
||||
https://github.com/rnpgp/rnp
|
||||
|
||||
[commit 5f41ee12433d070d96d75b715d81b7af60104856]
|
||||
[commit eabaa5d07ae453c44dfa272f25ad7b5e41c8e5fb]
|
||||
|
||||
For licensing information, please refer to the included documentation.
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ pacman -Syu --noconfirm --needed
|
|||
# Then most likely you'll need to close msys console and run it agian:
|
||||
pacman -Syu --noconfirm --needed
|
||||
# Install packages
|
||||
pacman --noconfirm -S --needed tar zlib-devel libbz2-devel git automake autoconf libtool automake-wrapper gnupg2 make pkgconfig mingw64/mingw-w64-x86_64-cmake mingw64/mingw-w64-x86_64-gcc mingw64/mingw-w64-x86_64-json-c mingw64/mingw-w64-x86_64-libbotan mingw64/mingw-w64-x86_64-python2
|
||||
pacman --noconfirm -S --needed tar zlib-devel libbz2-devel git automake autoconf libtool automake-wrapper gnupg2 make pkgconfig mingw64/mingw-w64-x86_64-cmake mingw64/mingw-w64-x86_64-gcc mingw64/mingw-w64-x86_64-json-c mingw64/mingw-w64-x86_64-libbotan mingw64/mingw-w64-x86_64-python3
|
||||
----
|
||||
|
||||
Then clone the repository, say to rnp folder, and:
|
||||
|
|
|
@ -155,7 +155,14 @@ size_t rnp_key_store_get_key_count(const rnp_key_store_t *);
|
|||
pgp_key_t *rnp_key_store_get_key(const rnp_key_store_t *, size_t);
|
||||
list rnp_key_store_get_keys(const rnp_key_store_t *);
|
||||
|
||||
pgp_key_t *rnp_key_store_add_key(rnp_key_store_t *, pgp_key_t *);
|
||||
/**
|
||||
* @brief Add key to the keystore, copying it.
|
||||
*
|
||||
* @param keyring allocated keyring, cannot be NULL.
|
||||
* @param key key to be added, cannot be NULL.
|
||||
* @return pointer to the added key or NULL if failed.
|
||||
*/
|
||||
pgp_key_t *rnp_key_store_add_key(rnp_key_store_t *keyring, pgp_key_t *key);
|
||||
|
||||
pgp_key_t *rnp_key_store_import_key(rnp_key_store_t *,
|
||||
pgp_key_t *,
|
||||
|
@ -171,6 +178,10 @@ pgp_key_t *rnp_key_store_import_key(rnp_key_store_t *,
|
|||
*/
|
||||
pgp_key_t *rnp_key_store_get_signer_key(rnp_key_store_t *store, const pgp_signature_t *sig);
|
||||
|
||||
pgp_sig_import_status_t rnp_key_store_import_key_signature(rnp_key_store_t * keyring,
|
||||
pgp_key_t * key,
|
||||
const pgp_signature_t *sig);
|
||||
|
||||
/**
|
||||
* @brief Import revocation or direct-key signature to the keyring.
|
||||
*
|
||||
|
|
|
@ -340,6 +340,7 @@ typedef enum {
|
|||
*/
|
||||
|
||||
typedef enum {
|
||||
PGP_SIG_SUBPKT_UNKNOWN = 0,
|
||||
PGP_SIG_SUBPKT_CREATION_TIME = 2, /* signature creation time */
|
||||
PGP_SIG_SUBPKT_EXPIRATION_TIME = 3, /* signature expiration time */
|
||||
PGP_SIG_SUBPKT_EXPORT_CERT = 4, /* exportable certification */
|
||||
|
|
|
@ -856,6 +856,27 @@ rnp_result_t rnp_key_export_revocation(rnp_key_handle_t key,
|
|||
const char * code,
|
||||
const char * reason);
|
||||
|
||||
/**
|
||||
* @brief revoke a key or subkey by generating and adding revocation signature.
|
||||
* @param key key or subkey to be revoked. For primary key must have secret key, otherwise
|
||||
* keyrings will be searched for the authorized to issue revocation signatures
|
||||
* secret key. For subkey keyrings must have primary secret key.
|
||||
* If secret key is locked then password will be asked via password provider.
|
||||
* @param flags currently must be 0.
|
||||
* @param hash hash algorithm used to calculate signature. Pass NULL for default algorithm
|
||||
* selection.
|
||||
* @param code reason for revocation code. Possible values: 'no', 'superseded', 'compromised',
|
||||
* 'retired'. May be NULL - then 'no' value will be used.
|
||||
* @param reason textual representation of the reason for revocation. May be NULL or empty
|
||||
* string.
|
||||
* @return RNP_SUCCESS on success, or any other value on error
|
||||
*/
|
||||
rnp_result_t rnp_key_revoke(rnp_key_handle_t key,
|
||||
uint32_t flags,
|
||||
const char * hash,
|
||||
const char * code,
|
||||
const char * reason);
|
||||
|
||||
/** remove a key from keyring(s)
|
||||
* Note: you need to call rnp_save_keys() to write updated keyring(s) out.
|
||||
* Other handles of the same key should not be used after this call.
|
||||
|
@ -1206,6 +1227,18 @@ rnp_result_t rnp_key_get_creation(rnp_key_handle_t key, uint32_t *result);
|
|||
*/
|
||||
rnp_result_t rnp_key_get_expiration(rnp_key_handle_t key, uint32_t *result);
|
||||
|
||||
/**
|
||||
* @brief Set the key's expiration time in seconds.
|
||||
* Note: this will require re-signing, which requires availability of the secret key (or
|
||||
* secret primary key for the subkey). If the secret key is locked then may ask for
|
||||
* key's password via FFI callback.
|
||||
*
|
||||
* @param key key's handle.
|
||||
* @param expiry expiration time in seconds (or 0 if key doesn't expire).
|
||||
* @return RNP_SUCCESS or error code on failure.
|
||||
*/
|
||||
rnp_result_t rnp_key_set_expiration(rnp_key_handle_t key, uint32_t expiry);
|
||||
|
||||
/**
|
||||
* @brief Check whether key is revoked.
|
||||
*
|
||||
|
@ -1347,8 +1380,6 @@ rnp_result_t rnp_key_is_sub(rnp_key_handle_t key, bool *result);
|
|||
rnp_result_t rnp_key_have_secret(rnp_key_handle_t key, bool *result);
|
||||
rnp_result_t rnp_key_have_public(rnp_key_handle_t key, bool *result);
|
||||
|
||||
/* TODO: function to add a userid to a key */
|
||||
|
||||
/** Get the information about key packets in JSON string.
|
||||
* Note: this will not work for G10 keys.
|
||||
*
|
||||
|
@ -1662,8 +1693,6 @@ rnp_result_t rnp_op_verify_signature_get_times(rnp_op_verify_signature_t sig,
|
|||
uint32_t * create,
|
||||
uint32_t * expires);
|
||||
|
||||
/* TODO define functions for encrypt+sign */
|
||||
|
||||
/**
|
||||
* @brief Free buffer allocated by a function in this header.
|
||||
*
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define PACKAGE_STRING "rnp 0.13.1+git20200402.5f41ee12.MZLA"
|
||||
#define PACKAGE_STRING "rnp 0.13.1+git20200506.eabaa5d0.MZLA"
|
||||
#define PACKAGE_BUGREPORT "https://bugzilla.mozilla.org/enter_bug.cgi?product=Thunderbird"
|
||||
|
||||
#undef HAVE_BZLIB_H
|
||||
|
|
|
@ -132,10 +132,7 @@ load_generated_g10_key(pgp_key_t * dst,
|
|||
if (rnp_key_store_get_key_count(key_store) != 1) {
|
||||
goto end;
|
||||
}
|
||||
memcpy(dst, rnp_key_store_get_key(key_store, 0), sizeof(*dst));
|
||||
// we don't want the key store to free the internal key data
|
||||
rnp_key_store_remove_key(key_store, (pgp_key_t *) rnp_key_store_get_key(key_store, 0));
|
||||
ok = true;
|
||||
ok = !pgp_key_copy(dst, rnp_key_store_get_key(key_store, 0), false);
|
||||
end:
|
||||
rnp_key_store_free(key_store);
|
||||
src_close(&memsrc);
|
||||
|
@ -331,6 +328,18 @@ keygen_primary_merge_defaults(rnp_keygen_primary_desc_t *desc)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pgp_key_mark_valid(pgp_key_t *key)
|
||||
{
|
||||
key->valid = true;
|
||||
key->validated = true;
|
||||
for (size_t i = 0; i < pgp_key_get_subsig_count(key); i++) {
|
||||
pgp_subsig_t *sub = pgp_key_get_subsig(key, i);
|
||||
sub->validated = true;
|
||||
sub->valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
pgp_generate_primary_key(rnp_keygen_primary_desc_t *desc,
|
||||
bool merge_defaults,
|
||||
|
@ -408,22 +417,16 @@ pgp_generate_primary_key(rnp_keygen_primary_desc_t *desc,
|
|||
}
|
||||
|
||||
/* mark it as valid */
|
||||
primary_pub->valid = true;
|
||||
primary_pub->validated = true;
|
||||
primary_sec->valid = true;
|
||||
primary_sec->validated = true;
|
||||
|
||||
ok = true;
|
||||
pgp_key_mark_valid(primary_pub);
|
||||
pgp_key_mark_valid(primary_sec);
|
||||
/* refresh key's data */
|
||||
ok = pgp_key_refresh_data(primary_pub) && pgp_key_refresh_data(primary_sec);
|
||||
end:
|
||||
// free any user preferences
|
||||
pgp_free_user_prefs(&desc->cert.prefs);
|
||||
// we don't need this as we have loaded the encrypted key into primary_sec
|
||||
transferable_key_destroy(&tkeysec);
|
||||
transferable_key_destroy(&tkeypub);
|
||||
if (!ok) {
|
||||
pgp_key_free_data(primary_pub);
|
||||
pgp_key_free_data(primary_sec);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -545,18 +548,13 @@ pgp_generate_subkey(rnp_keygen_subkey_desc_t * desc,
|
|||
break;
|
||||
}
|
||||
|
||||
subkey_pub->valid = true;
|
||||
subkey_pub->validated = true;
|
||||
subkey_sec->valid = true;
|
||||
subkey_sec->validated = true;
|
||||
ok = true;
|
||||
pgp_key_mark_valid(subkey_pub);
|
||||
pgp_key_mark_valid(subkey_sec);
|
||||
ok = pgp_subkey_refresh_data(subkey_pub, primary_pub) &&
|
||||
pgp_subkey_refresh_data(subkey_sec, primary_sec);
|
||||
end:
|
||||
transferable_subkey_destroy(&tskeysec);
|
||||
transferable_subkey_destroy(&tskeypub);
|
||||
if (!ok) {
|
||||
pgp_key_free_data(subkey_pub);
|
||||
pgp_key_free_data(subkey_sec);
|
||||
}
|
||||
if (decrypted_primary_seckey) {
|
||||
free_key_pkt(decrypted_primary_seckey);
|
||||
free(decrypted_primary_seckey);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -54,6 +54,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include "pass-provider.h"
|
||||
#include <rekey/rnp_key_store.h>
|
||||
#include "crypto/symmetric.h"
|
||||
|
@ -61,15 +62,16 @@
|
|||
|
||||
/* describes a user's key */
|
||||
struct pgp_key_t {
|
||||
list uids; /* list of user ids as (char*) */
|
||||
list packets; /* list of raw packets as pgp_rawpacket_t */
|
||||
list subsigs; /* list of signatures as pgp_subsig_t */
|
||||
list revokes; /* list of signature revocations pgp_revoke_t */
|
||||
std::vector<pgp_userid_t> uids; /* array of user ids */
|
||||
std::vector<pgp_rawpacket_t> packets; /* array of key packets */
|
||||
std::vector<pgp_subsig_t> subsigs; /* array of key signatures */
|
||||
std::vector<pgp_revoke_t> revokes; /* array of revocations */
|
||||
list subkey_grips; /* list of subkey grips (for primary keys) as uint8_t[20] */
|
||||
uint8_t * primary_grip; /* grip of primary key (for subkeys) */
|
||||
time_t expiration; /* key expiration time, if available */
|
||||
pgp_key_pkt_t pkt; /* pubkey/seckey data packet */
|
||||
uint8_t key_flags; /* key flags */
|
||||
uint8_t primary_grip[PGP_KEY_GRIP_SIZE]; /* grip of primary key (for subkeys) */
|
||||
bool primary_grip_set;
|
||||
time_t expiration; /* key expiration time, if available */
|
||||
pgp_key_pkt_t pkt; /* pubkey/seckey data packet */
|
||||
uint8_t key_flags; /* key flags */
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
pgp_fingerprint_t fingerprint;
|
||||
uint8_t grip[PGP_KEY_GRIP_SIZE];
|
||||
|
@ -80,9 +82,15 @@ struct pgp_key_t {
|
|||
pgp_key_store_format_t format; /* the format of the key in packets[0] */
|
||||
bool valid; /* this key is valid and usable */
|
||||
bool validated; /* this key was validated */
|
||||
};
|
||||
|
||||
struct pgp_key_t *pgp_key_new(void);
|
||||
~pgp_key_t();
|
||||
pgp_key_t() = default;
|
||||
pgp_key_t &operator=(pgp_key_t &&);
|
||||
/* make sure we use only empty constructor/move operator */
|
||||
pgp_key_t(const pgp_key_t &src) = delete;
|
||||
pgp_key_t(pgp_key_t &&src) = delete;
|
||||
pgp_key_t &operator=(const pgp_key_t &) = delete;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create pgp_key_t object from the OpenPGP key packet.
|
||||
|
@ -93,20 +101,6 @@ struct pgp_key_t *pgp_key_new(void);
|
|||
*/
|
||||
bool pgp_key_from_pkt(pgp_key_t *key, const pgp_key_pkt_t *pkt);
|
||||
|
||||
/** free the internal data of a key *and* the key structure itself
|
||||
*
|
||||
* @param key the key
|
||||
**/
|
||||
void pgp_key_free(pgp_key_t *);
|
||||
|
||||
/** free the internal data of a key
|
||||
*
|
||||
* This does *not* free the key structure itself.
|
||||
*
|
||||
* @param key the key
|
||||
**/
|
||||
void pgp_key_free_data(pgp_key_t *);
|
||||
|
||||
/**
|
||||
* @brief Copy key, optionally copying only the public key part.
|
||||
*
|
||||
|
@ -236,9 +230,9 @@ const uint8_t *pgp_key_get_primary_grip(const pgp_key_t *key);
|
|||
*
|
||||
* @param key subkey
|
||||
* @param grip buffer with grip, should not be NULL
|
||||
* @return true on success or false otherwise (key is not subkey, or allocation failed)
|
||||
* @return void
|
||||
*/
|
||||
bool pgp_key_set_primary_grip(pgp_key_t *key, const uint8_t *grip);
|
||||
void pgp_key_set_primary_grip(pgp_key_t *key, const uint8_t *grip);
|
||||
|
||||
/**
|
||||
* @brief Link key with subkey via primary_grip and subkey_grips list
|
||||
|
@ -251,9 +245,11 @@ bool pgp_key_link_subkey_grip(pgp_key_t *key, pgp_key_t *subkey);
|
|||
|
||||
size_t pgp_key_get_userid_count(const pgp_key_t *);
|
||||
|
||||
pgp_userid_t *pgp_key_get_userid(const pgp_key_t *, size_t);
|
||||
const pgp_userid_t *pgp_key_get_userid(const pgp_key_t *, size_t);
|
||||
|
||||
pgp_revoke_t *pgp_key_get_userid_revoke(const pgp_key_t *, size_t userid);
|
||||
pgp_userid_t *pgp_key_get_userid(pgp_key_t *, size_t);
|
||||
|
||||
const pgp_revoke_t *pgp_key_get_userid_revoke(const pgp_key_t *, size_t userid);
|
||||
|
||||
bool pgp_key_has_userid(const pgp_key_t *, const char *);
|
||||
|
||||
|
@ -263,7 +259,9 @@ pgp_revoke_t *pgp_key_add_revoke(pgp_key_t *);
|
|||
|
||||
size_t pgp_key_get_revoke_count(const pgp_key_t *);
|
||||
|
||||
pgp_revoke_t *pgp_key_get_revoke(const pgp_key_t *, size_t);
|
||||
const pgp_revoke_t *pgp_key_get_revoke(const pgp_key_t *, size_t);
|
||||
|
||||
pgp_revoke_t *pgp_key_get_revoke(pgp_key_t *key, size_t idx);
|
||||
|
||||
void revoke_free(pgp_revoke_t *revoke);
|
||||
|
||||
|
@ -271,7 +269,40 @@ pgp_subsig_t *pgp_key_add_subsig(pgp_key_t *);
|
|||
|
||||
size_t pgp_key_get_subsig_count(const pgp_key_t *);
|
||||
|
||||
pgp_subsig_t *pgp_key_get_subsig(const pgp_key_t *, size_t);
|
||||
const pgp_subsig_t *pgp_key_get_subsig(const pgp_key_t *, size_t);
|
||||
pgp_subsig_t * pgp_key_get_subsig(pgp_key_t *, size_t);
|
||||
|
||||
bool pgp_subsig_from_signature(pgp_subsig_t *subsig, const pgp_signature_t *sig);
|
||||
|
||||
bool pgp_key_has_signature(const pgp_key_t *key, const pgp_signature_t *sig);
|
||||
|
||||
pgp_subsig_t *pgp_key_replace_signature(pgp_key_t * key,
|
||||
pgp_signature_t *oldsig,
|
||||
pgp_signature_t *newsig);
|
||||
|
||||
/**
|
||||
* @brief Get the latest valid self-signature with information about the primary key,
|
||||
* containing the specified subpacket. It could be userid certification or direct-key
|
||||
* signature.
|
||||
*
|
||||
* @param key key which should be searched for signature.
|
||||
* @param subpkt subpacket type. Pass 0 to return just latest signature.
|
||||
* @return pointer to signature object or NULL if failed/not found.
|
||||
*/
|
||||
pgp_subsig_t *pgp_key_latest_selfsig(pgp_key_t *key, pgp_sig_subpacket_type_t subpkt);
|
||||
|
||||
/**
|
||||
* @brief Get the latest valid subkey binding.
|
||||
*
|
||||
* @param subkey subkey which should be searched for signature.
|
||||
* @param validated set to true whether binding signature must be validated
|
||||
* @return pointer to signature object or NULL if failed/not found.
|
||||
*/
|
||||
pgp_subsig_t *pgp_key_latest_binding(pgp_key_t *subkey, bool validated);
|
||||
|
||||
bool pgp_key_refresh_data(pgp_key_t *key);
|
||||
|
||||
bool pgp_subkey_refresh_data(pgp_key_t *sub, pgp_key_t *key);
|
||||
|
||||
void pgp_subsig_free(pgp_subsig_t *subsig);
|
||||
|
||||
|
@ -285,7 +316,8 @@ pgp_rawpacket_t *pgp_key_add_uid_rawpacket(pgp_key_t *key, const pgp_userid_pkt_
|
|||
|
||||
size_t pgp_key_get_rawpacket_count(const pgp_key_t *);
|
||||
|
||||
pgp_rawpacket_t *pgp_key_get_rawpacket(const pgp_key_t *, size_t);
|
||||
pgp_rawpacket_t * pgp_key_get_rawpacket(pgp_key_t *, size_t);
|
||||
const pgp_rawpacket_t *pgp_key_get_rawpacket(const pgp_key_t *, size_t);
|
||||
|
||||
/**
|
||||
* @brief Get the number of pgp key's subkeys.
|
||||
|
@ -412,6 +444,13 @@ bool pgp_key_add_userid_certified(pgp_key_t * key,
|
|||
pgp_hash_alg_t hash_alg,
|
||||
rnp_selfsig_cert_info_t *cert);
|
||||
|
||||
bool pgp_key_set_expiration(pgp_key_t *key, pgp_key_t *signer, uint32_t expiry);
|
||||
|
||||
bool pgp_subkey_set_expiration(pgp_key_t *sub,
|
||||
pgp_key_t *primsec,
|
||||
pgp_key_t *secsub,
|
||||
uint32_t expiry);
|
||||
|
||||
bool pgp_key_write_packets(const pgp_key_t *key, pgp_dest_t *dst);
|
||||
|
||||
/**
|
||||
|
@ -458,6 +497,10 @@ pgp_key_t *find_suitable_key(pgp_op_t op,
|
|||
*/
|
||||
pgp_hash_alg_t pgp_hash_adjust_alg_to_key(pgp_hash_alg_t hash, const pgp_key_pkt_t *pubkey);
|
||||
|
||||
rnp_result_t pgp_key_validate(pgp_key_t *key, rnp_key_store_t *keyring);
|
||||
void pgp_key_validate_subkey(pgp_key_t *subkey, pgp_key_t *key);
|
||||
|
||||
void pgp_key_validate(pgp_key_t *key, rnp_key_store_t *keyring);
|
||||
|
||||
void pgp_key_revalidate_updated(pgp_key_t *key, rnp_key_store_t *keyring);
|
||||
|
||||
#endif // RNP_PACKET_KEY_H
|
||||
|
|
|
@ -1085,15 +1085,8 @@ do_load_keys(rnp_ffi_t ffi,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if ((tmpret = pgp_key_copy(&keycp, key, false))) {
|
||||
FFI_LOG(ffi, "Failed to copy secret key");
|
||||
ret = tmpret;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!rnp_key_store_add_key(ffi->secring, &keycp)) {
|
||||
if (!rnp_key_store_add_key(ffi->secring, key)) {
|
||||
FFI_LOG(ffi, "Failed to add secret key");
|
||||
pgp_key_free_data(&keycp);
|
||||
ret = RNP_ERROR_GENERIC;
|
||||
goto done;
|
||||
}
|
||||
|
@ -1118,14 +1111,12 @@ do_load_keys(rnp_ffi_t ffi,
|
|||
|
||||
if (key_needs_conversion(key, ffi->pubring)) {
|
||||
FFI_LOG(ffi, "This key format conversion is not yet supported");
|
||||
pgp_key_free_data(&keycp);
|
||||
ret = RNP_ERROR_NOT_IMPLEMENTED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!rnp_key_store_add_key(ffi->pubring, &keycp)) {
|
||||
FFI_LOG(ffi, "Failed to add public key");
|
||||
pgp_key_free_data(&keycp);
|
||||
ret = RNP_ERROR_GENERIC;
|
||||
goto done;
|
||||
}
|
||||
|
@ -1467,14 +1458,8 @@ done:
|
|||
static bool
|
||||
copy_store_keys(rnp_ffi_t ffi, rnp_key_store_t *dest, rnp_key_store_t *src)
|
||||
{
|
||||
pgp_key_t keycp = {};
|
||||
for (list_item *key = list_front(rnp_key_store_get_keys(src)); key; key = list_next(key)) {
|
||||
if (pgp_key_copy(&keycp, (pgp_key_t *) key, false)) {
|
||||
FFI_LOG(ffi, "failed to create key copy");
|
||||
return false;
|
||||
}
|
||||
if (!rnp_key_store_add_key(dest, &keycp)) {
|
||||
pgp_key_free_data(&keycp);
|
||||
if (!rnp_key_store_add_key(dest, (pgp_key_t *) key)) {
|
||||
FFI_LOG(ffi, "failed to add key to the store");
|
||||
return false;
|
||||
}
|
||||
|
@ -3282,6 +3267,51 @@ rnp_key_export_revocation(rnp_key_handle_t key,
|
|||
return ret;
|
||||
}
|
||||
|
||||
rnp_result_t
|
||||
rnp_key_revoke(
|
||||
rnp_key_handle_t key, uint32_t flags, const char *hash, const char *code, const char *reason)
|
||||
{
|
||||
if (!key || !key->ffi) {
|
||||
return RNP_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (flags) {
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
|
||||
pgp_key_t *exkey = get_key_prefer_public(key);
|
||||
if (!exkey) {
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
pgp_key_t *revoker = rnp_key_get_revoker(key);
|
||||
if (!revoker) {
|
||||
FFI_LOG(key->ffi, "Revoker secret key not found");
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
|
||||
pgp_signature_t *sig = NULL;
|
||||
rnp_result_t ret =
|
||||
rnp_key_get_revocation(key->ffi, exkey, revoker, hash, code, reason, &sig);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
pgp_sig_import_status_t pub_status = PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY;
|
||||
pgp_sig_import_status_t sec_status = PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY;
|
||||
if (key->pub) {
|
||||
pub_status = rnp_key_store_import_key_signature(key->ffi->pubring, key->pub, sig);
|
||||
}
|
||||
if (key->sec) {
|
||||
sec_status = rnp_key_store_import_key_signature(key->ffi->secring, key->sec, sig);
|
||||
}
|
||||
free_signature(sig);
|
||||
free(sig);
|
||||
|
||||
if ((pub_status == PGP_SIG_IMPORT_STATUS_UNKNOWN) ||
|
||||
(sec_status == PGP_SIG_IMPORT_STATUS_UNKNOWN)) {
|
||||
return RNP_ERROR_GENERIC;
|
||||
}
|
||||
return RNP_SUCCESS;
|
||||
}
|
||||
|
||||
rnp_result_t
|
||||
rnp_key_remove(rnp_key_handle_t key, uint32_t flags)
|
||||
{
|
||||
|
@ -3295,7 +3325,6 @@ rnp_key_remove(rnp_key_handle_t key, uint32_t flags)
|
|||
if (!key->ffi->pubring || !key->pub) {
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
pgp_key_free_data(key->pub);
|
||||
if (!rnp_key_store_remove_key(key->ffi->pubring, key->pub)) {
|
||||
return RNP_ERROR_KEY_NOT_FOUND;
|
||||
}
|
||||
|
@ -3305,7 +3334,6 @@ rnp_key_remove(rnp_key_handle_t key, uint32_t flags)
|
|||
if (!key->ffi->secring || !key->sec) {
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
pgp_key_free_data(key->sec);
|
||||
if (!rnp_key_store_remove_key(key->ffi->secring, key->sec)) {
|
||||
return RNP_ERROR_KEY_NOT_FOUND;
|
||||
}
|
||||
|
@ -3738,10 +3766,10 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
rnp_action_keygen_t keygen_desc = {};
|
||||
char * identifier_type = NULL;
|
||||
char * identifier = NULL;
|
||||
pgp_key_t primary_pub = {0};
|
||||
pgp_key_t primary_sec = {0};
|
||||
pgp_key_t sub_pub = {0};
|
||||
pgp_key_t sub_sec = {0};
|
||||
pgp_key_t primary_pub = {};
|
||||
pgp_key_t primary_sec = {};
|
||||
pgp_key_t sub_pub = {};
|
||||
pgp_key_t sub_sec = {};
|
||||
json_object * jsoprimary = NULL;
|
||||
json_object * jsosub = NULL;
|
||||
json_tokener_error error;
|
||||
|
@ -3812,12 +3840,10 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
primary_pub = (pgp_key_t){0};
|
||||
if (!rnp_key_store_add_key(ffi->pubring, &sub_pub)) {
|
||||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
sub_pub = (pgp_key_t){0};
|
||||
}
|
||||
/* add key/subkey protection */
|
||||
if (keygen_desc.primary.protection.symm_alg &&
|
||||
|
@ -3842,12 +3868,10 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
primary_sec = (pgp_key_t){0};
|
||||
if (!rnp_key_store_add_key(ffi->secring, &sub_sec)) {
|
||||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
sub_sec = (pgp_key_t){0};
|
||||
} else if (jsoprimary && !jsosub) { // generating primary only
|
||||
keygen_desc.primary.keygen.crypto.rng = &ffi->rng;
|
||||
if (!parse_keygen_primary(jsoprimary, &keygen_desc)) {
|
||||
|
@ -3870,7 +3894,6 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
primary_pub = (pgp_key_t){0};
|
||||
}
|
||||
/* encrypt secret key if specified */
|
||||
if (keygen_desc.primary.protection.symm_alg &&
|
||||
|
@ -3886,7 +3909,6 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
primary_sec = (pgp_key_t){0};
|
||||
} else if (jsosub) { // generating subkey only
|
||||
if (!ffi->pubring) {
|
||||
ret = RNP_ERROR_NULL_POINTER;
|
||||
|
@ -3951,7 +3973,6 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
sub_pub = (pgp_key_t){0};
|
||||
}
|
||||
/* encrypt subkey if specified */
|
||||
if (keygen_desc.subkey.protection.symm_alg &&
|
||||
|
@ -3967,7 +3988,6 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
sub_sec = (pgp_key_t){0};
|
||||
} else {
|
||||
// nothing to generate...
|
||||
ret = RNP_ERROR_BAD_PARAMETERS;
|
||||
|
@ -3976,10 +3996,6 @@ rnp_generate_key_json(rnp_ffi_t ffi, const char *json, char **results)
|
|||
|
||||
ret = RNP_SUCCESS;
|
||||
done:
|
||||
pgp_key_free_data(&primary_pub);
|
||||
pgp_key_free_data(&primary_sec);
|
||||
pgp_key_free_data(&sub_pub);
|
||||
pgp_key_free_data(&sub_sec);
|
||||
json_object_put(jso);
|
||||
free(identifier_type);
|
||||
free(identifier);
|
||||
|
@ -4628,7 +4644,6 @@ rnp_op_generate_execute(rnp_op_generate_t op)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
pub = {};
|
||||
|
||||
/* encrypt secret key if requested */
|
||||
if (op->password) {
|
||||
|
@ -4648,7 +4663,6 @@ rnp_op_generate_execute(rnp_op_generate_t op)
|
|||
ret = RNP_ERROR_OUT_OF_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
sec = {};
|
||||
ret = RNP_SUCCESS;
|
||||
done:
|
||||
if (op->password) {
|
||||
|
@ -4657,17 +4671,13 @@ done:
|
|||
op->password = NULL;
|
||||
}
|
||||
if (ret && op->gen_pub) {
|
||||
pgp_key_free_data(op->gen_pub);
|
||||
rnp_key_store_remove_key(op->ffi->pubring, op->gen_pub);
|
||||
op->gen_pub = NULL;
|
||||
}
|
||||
if (ret && op->gen_sec) {
|
||||
pgp_key_free_data(op->gen_sec);
|
||||
rnp_key_store_remove_key(op->ffi->secring, op->gen_sec);
|
||||
op->gen_sec = NULL;
|
||||
}
|
||||
pgp_key_free_data(&sec);
|
||||
pgp_key_free_data(&pub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5172,7 +5182,7 @@ rnp_uid_is_revoked(rnp_uid_handle_t uid, bool *result)
|
|||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
|
||||
pgp_revoke_t *revoke = pgp_key_get_userid_revoke(uid->key, uid->idx);
|
||||
const pgp_revoke_t *revoke = pgp_key_get_userid_revoke(uid->key, uid->idx);
|
||||
*result = revoke != NULL;
|
||||
return RNP_SUCCESS;
|
||||
}
|
||||
|
@ -5441,6 +5451,49 @@ rnp_key_get_expiration(rnp_key_handle_t handle, uint32_t *result)
|
|||
return RNP_SUCCESS;
|
||||
}
|
||||
|
||||
rnp_result_t
|
||||
rnp_key_set_expiration(rnp_key_handle_t key, uint32_t expiry)
|
||||
{
|
||||
if (!key) {
|
||||
return RNP_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
pgp_key_t *pkey = get_key_prefer_public(key);
|
||||
if (!pkey) {
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
pgp_key_t *skey = get_key_require_secret(key);
|
||||
if (!skey) {
|
||||
FFI_LOG(key->ffi, "Secret key required.");
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
|
||||
if (pgp_key_is_primary_key(pkey)) {
|
||||
bool res = pgp_key_set_expiration(pkey, skey, expiry);
|
||||
return res ? RNP_SUCCESS : RNP_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
/* for subkey we need primary key */
|
||||
const uint8_t *grip = pgp_key_get_primary_grip(pkey);
|
||||
if (!grip) {
|
||||
FFI_LOG(key->ffi, "Primary key grip not available.");
|
||||
return RNP_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
|
||||
pgp_key_request_ctx_t request = {};
|
||||
request.secret = true;
|
||||
request.search.type = PGP_KEY_SEARCH_GRIP;
|
||||
memcpy(request.search.by.grip, grip, PGP_KEY_GRIP_SIZE);
|
||||
pgp_key_t *prim_sec = pgp_request_key(&key->ffi->key_provider, &request);
|
||||
if (!prim_sec) {
|
||||
FFI_LOG(key->ffi, "Primary secret key not found.");
|
||||
return RNP_ERROR_KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
bool res = pgp_subkey_set_expiration(pkey, prim_sec, skey, expiry);
|
||||
return res ? RNP_SUCCESS : RNP_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
rnp_result_t
|
||||
rnp_key_get_revocation_reason(rnp_key_handle_t handle, char **result)
|
||||
{
|
||||
|
@ -6233,7 +6286,7 @@ key_to_json(json_object *jso, rnp_key_handle_t handle, uint32_t flags)
|
|||
return RNP_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
// revoked
|
||||
json_object *jsorevoked = json_object_new_boolean(key->revoked ? TRUE : FALSE);
|
||||
json_object *jsorevoked = json_object_new_boolean(key->revoked ? true : false);
|
||||
if (!jsorevoked) {
|
||||
return RNP_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -6298,7 +6351,7 @@ key_to_json(json_object *jso, rnp_key_handle_t handle, uint32_t flags)
|
|||
}
|
||||
json_object_object_add(jso, "public key", jsopublic);
|
||||
json_object_object_add(
|
||||
jsopublic, "present", json_object_new_boolean(have_pub ? TRUE : FALSE));
|
||||
jsopublic, "present", json_object_new_boolean(have_pub ? true : false));
|
||||
if (flags & RNP_JSON_PUBLIC_MPIS) {
|
||||
json_object *jsompis = json_object_new_object();
|
||||
if (!jsompis) {
|
||||
|
@ -6317,7 +6370,7 @@ key_to_json(json_object *jso, rnp_key_handle_t handle, uint32_t flags)
|
|||
}
|
||||
json_object_object_add(jso, "secret key", jsosecret);
|
||||
json_object_object_add(
|
||||
jsosecret, "present", json_object_new_boolean(have_sec ? TRUE : FALSE));
|
||||
jsosecret, "present", json_object_new_boolean(have_sec ? true : false));
|
||||
if (have_sec) {
|
||||
bool locked = pgp_key_is_locked(handle->sec);
|
||||
if (flags & RNP_JSON_SECRET_MPIS) {
|
||||
|
@ -6335,13 +6388,13 @@ key_to_json(json_object *jso, rnp_key_handle_t handle, uint32_t flags)
|
|||
}
|
||||
}
|
||||
}
|
||||
json_object *jsolocked = json_object_new_boolean(locked ? TRUE : FALSE);
|
||||
json_object *jsolocked = json_object_new_boolean(locked ? true : false);
|
||||
if (!jsolocked) {
|
||||
return RNP_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
json_object_object_add(jsosecret, "locked", jsolocked);
|
||||
json_object *jsoprotected =
|
||||
json_object_new_boolean(pgp_key_is_protected(handle->sec) ? TRUE : FALSE);
|
||||
json_object_new_boolean(pgp_key_is_protected(handle->sec) ? true : false);
|
||||
if (!jsoprotected) {
|
||||
return RNP_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -6658,7 +6711,7 @@ key_iter_get_item(const rnp_identifier_iterator_t it, char *buf, size_t buf_len)
|
|||
}
|
||||
break;
|
||||
case PGP_KEY_SEARCH_USERID: {
|
||||
pgp_userid_t *uid = pgp_key_get_userid(key, it->uididx);
|
||||
const pgp_userid_t *uid = pgp_key_get_userid(key, it->uididx);
|
||||
if (!uid) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -378,6 +378,8 @@ typedef struct pgp_subsig_t {
|
|||
uint8_t trustamount; /* amount of trust */
|
||||
uint8_t key_flags; /* key flags for certification/direct key sig */
|
||||
pgp_user_prefs_t prefs; /* user preferences for certification sig */
|
||||
bool validated; /* signature was validated */
|
||||
bool valid; /* signature was validated and is valid */
|
||||
} pgp_subsig_t;
|
||||
|
||||
typedef struct pgp_userid_t {
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
#define RNP_VERSION_PATCH 1
|
||||
|
||||
#define RNP_VERSION_STRING "0.13.1"
|
||||
#define RNP_VERSION_STRING_FULL "0.13.1+git20200402.5f41ee12.MZLA"
|
||||
#define RNP_VERSION_STRING_FULL "0.13.1+git20200506.eabaa5d0.MZLA"
|
||||
|
||||
#define RNP_VERSION_COMMIT_TIMESTAMP 1585833163
|
||||
#define RNP_VERSION_COMMIT_TIMESTAMP 1588776848
|
||||
|
||||
// using a 32-bit version with 10 bits per component
|
||||
#define RNP_VERSION_COMPONENT_MASK 0x3ff
|
||||
|
|
|
@ -1104,7 +1104,7 @@ rnp_key_store_g10_from_src(rnp_key_store_t * key_store,
|
|||
const pgp_key_provider_t *key_provider)
|
||||
{
|
||||
const pgp_key_t *pubkey = NULL;
|
||||
pgp_key_t key = {0};
|
||||
pgp_key_t key = {};
|
||||
pgp_key_pkt_t seckey = {};
|
||||
pgp_source_t memsrc = {};
|
||||
bool ret = false;
|
||||
|
@ -1168,7 +1168,6 @@ done:
|
|||
src_close(&memsrc);
|
||||
if (!ret) {
|
||||
free_key_pkt(&seckey);
|
||||
pgp_key_free_data(&key);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -67,100 +67,23 @@ __RCSID("$NetBSD: keyring.c,v 1.50 2011/06/25 00:37:44 agc Exp $");
|
|||
#include "key_store_pgp.h"
|
||||
#include "pgp-key.h"
|
||||
|
||||
static pgp_map_t ss_rr_code_map[] = {
|
||||
{PGP_REVOCATION_NO_REASON, "No reason specified"},
|
||||
{PGP_REVOCATION_SUPERSEDED, "Key is superseded"},
|
||||
{PGP_REVOCATION_COMPROMISED, "Key material has been compromised"},
|
||||
{PGP_REVOCATION_RETIRED, "Key is retired and no longer used"},
|
||||
{PGP_REVOCATION_NO_LONGER_VALID, "User ID information is no longer valid"},
|
||||
{0x00, NULL}, /* this is the end-of-array marker */
|
||||
};
|
||||
|
||||
bool
|
||||
rnp_key_add_signature(pgp_key_t *key, const pgp_signature_t *sig)
|
||||
{
|
||||
pgp_subsig_t *subsig = NULL;
|
||||
uint8_t * algs = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
if (!(subsig = pgp_key_add_subsig(key))) {
|
||||
pgp_subsig_t *subsig = pgp_key_add_subsig(key);
|
||||
if (!subsig) {
|
||||
RNP_LOG("Failed to add subsig");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* add signature rawpacket */
|
||||
if (!pgp_key_add_sig_rawpacket(key, sig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* setup subsig and key from signature */
|
||||
if (!pgp_subsig_from_signature(subsig, sig)) {
|
||||
return false;
|
||||
}
|
||||
subsig->uid = pgp_key_get_userid_count(key) - 1;
|
||||
if (!copy_signature_packet(&subsig->sig, sig)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (signature_has_key_expiration(&subsig->sig)) {
|
||||
key->expiration = signature_get_key_expiration(&subsig->sig);
|
||||
}
|
||||
if (signature_has_trust(&subsig->sig)) {
|
||||
signature_get_trust(&subsig->sig, &subsig->trustlevel, &subsig->trustamount);
|
||||
}
|
||||
if (signature_get_primary_uid(&subsig->sig)) {
|
||||
key->uid0 = pgp_key_get_userid_count(key) - 1;
|
||||
key->uid0_set = 1;
|
||||
}
|
||||
|
||||
if (signature_get_preferred_symm_algs(&subsig->sig, &algs, &count) &&
|
||||
!pgp_user_prefs_set_symm_algs(&subsig->prefs, algs, count)) {
|
||||
RNP_LOG("failed to alloc symm algs");
|
||||
return false;
|
||||
}
|
||||
if (signature_get_preferred_hash_algs(&subsig->sig, &algs, &count) &&
|
||||
!pgp_user_prefs_set_hash_algs(&subsig->prefs, algs, count)) {
|
||||
RNP_LOG("failed to alloc hash algs");
|
||||
return false;
|
||||
}
|
||||
if (signature_get_preferred_z_algs(&subsig->sig, &algs, &count) &&
|
||||
!pgp_user_prefs_set_z_algs(&subsig->prefs, algs, count)) {
|
||||
RNP_LOG("failed to alloc z algs");
|
||||
return false;
|
||||
}
|
||||
if (signature_has_key_flags(&subsig->sig)) {
|
||||
subsig->key_flags = signature_get_key_flags(&subsig->sig);
|
||||
key->key_flags = subsig->key_flags;
|
||||
}
|
||||
if (signature_has_key_server_prefs(&subsig->sig)) {
|
||||
uint8_t ks_pref = signature_get_key_server_prefs(&subsig->sig);
|
||||
if (!pgp_user_prefs_set_ks_prefs(&subsig->prefs, &ks_pref, 1)) {
|
||||
RNP_LOG("failed to alloc ks prefs");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (signature_has_key_server(&subsig->sig)) {
|
||||
subsig->prefs.key_server = (uint8_t *) signature_get_key_server(&subsig->sig);
|
||||
}
|
||||
if (signature_has_revocation_reason(&subsig->sig)) {
|
||||
/* not sure whether this logic is correct - we should check signature type? */
|
||||
pgp_revoke_t *revocation = NULL;
|
||||
if (!pgp_key_get_userid_count(key)) {
|
||||
/* revoke whole key */
|
||||
key->revoked = 1;
|
||||
revocation = &key->revocation;
|
||||
revoke_free(revocation);
|
||||
} else {
|
||||
/* revoke the user id */
|
||||
if (!(revocation = pgp_key_add_revoke(key))) {
|
||||
RNP_LOG("failed to add revoke");
|
||||
return false;
|
||||
}
|
||||
revocation->uid = pgp_key_get_userid_count(key) - 1;
|
||||
}
|
||||
signature_get_revocation_reason(&subsig->sig, &revocation->code, &revocation->reason);
|
||||
if (!strlen(revocation->reason)) {
|
||||
free(revocation->reason);
|
||||
revocation->reason = strdup(pgp_str_from_map(revocation->code, ss_rr_code_map));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -189,15 +112,11 @@ rnp_key_store_add_transferable_subkey(rnp_key_store_t * keyring,
|
|||
}
|
||||
|
||||
/* add it to the storage */
|
||||
if (!rnp_key_store_add_key(keyring, &skey)) {
|
||||
bool res = rnp_key_store_add_key(keyring, &skey);
|
||||
if (!res) {
|
||||
RNP_LOG("Failed to add subkey to key store.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return true;
|
||||
error:
|
||||
pgp_key_free_data(&skey);
|
||||
return false;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -252,36 +171,39 @@ rnp_key_store_add_transferable_key(rnp_key_store_t *keyring, pgp_transferable_ke
|
|||
return false;
|
||||
}
|
||||
|
||||
/* temporary disable key validation */
|
||||
keyring->disable_validation = true;
|
||||
|
||||
/* add key to the storage before subkeys */
|
||||
if (!(addkey = rnp_key_store_add_key(keyring, &key))) {
|
||||
addkey = rnp_key_store_add_key(keyring, &key);
|
||||
if (!addkey) {
|
||||
RNP_LOG("Failed to add key to key store.");
|
||||
goto error;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* add subkeys */
|
||||
for (list_item *skey = list_front(tkey->subkeys); skey; skey = list_next(skey)) {
|
||||
pgp_transferable_subkey_t *subkey = (pgp_transferable_subkey_t *) skey;
|
||||
if (!rnp_key_store_add_transferable_subkey(keyring, subkey, addkey)) {
|
||||
RNP_LOG("Failed to add subkey to key store.");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* now validate/refresh the whole key with subkeys */
|
||||
keyring->disable_validation = false;
|
||||
pgp_key_revalidate_updated(addkey, keyring);
|
||||
return true;
|
||||
error:
|
||||
if (addkey) {
|
||||
/* during key addition all fields are copied so will be cleaned below */
|
||||
rnp_key_store_remove_key(keyring, addkey);
|
||||
pgp_key_free_data(addkey);
|
||||
} else {
|
||||
pgp_key_free_data(&key);
|
||||
}
|
||||
/* during key addition all fields are copied so will be cleaned below */
|
||||
rnp_key_store_remove_key(keyring, addkey);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
rnp_key_from_transferable_key(pgp_key_t *key, pgp_transferable_key_t *tkey)
|
||||
{
|
||||
memset(key, 0, sizeof(*key));
|
||||
*key = {};
|
||||
/* create key */
|
||||
if (!pgp_key_from_pkt(key, &tkey->key)) {
|
||||
return false;
|
||||
|
@ -289,21 +211,18 @@ rnp_key_from_transferable_key(pgp_key_t *key, pgp_transferable_key_t *tkey)
|
|||
|
||||
/* add direct-key signatures */
|
||||
if (!rnp_key_add_signatures(key, tkey->signatures)) {
|
||||
goto error;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* add userids and their signatures */
|
||||
for (list_item *uid = list_front(tkey->userids); uid; uid = list_next(uid)) {
|
||||
pgp_transferable_userid_t *tuid = (pgp_transferable_userid_t *) uid;
|
||||
if (!rnp_key_add_transferable_userid(key, tuid)) {
|
||||
goto error;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
error:
|
||||
pgp_key_free_data(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -311,7 +230,7 @@ rnp_key_from_transferable_subkey(pgp_key_t * subkey,
|
|||
pgp_transferable_subkey_t *tskey,
|
||||
pgp_key_t * primary)
|
||||
{
|
||||
memset(subkey, 0, sizeof(*subkey));
|
||||
*subkey = {};
|
||||
|
||||
/* create key */
|
||||
if (!pgp_key_from_pkt(subkey, &tskey->subkey)) {
|
||||
|
@ -321,17 +240,15 @@ rnp_key_from_transferable_subkey(pgp_key_t * subkey,
|
|||
/* add subkey binding signatures */
|
||||
if (!rnp_key_add_signatures(subkey, tskey->signatures)) {
|
||||
RNP_LOG("failed to add subkey signatures");
|
||||
goto error;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* setup key grips if primary is available */
|
||||
if (primary && !pgp_key_link_subkey_grip(primary, subkey)) {
|
||||
goto error;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
error:
|
||||
pgp_key_free_data(subkey);
|
||||
return false;
|
||||
}
|
||||
|
||||
rnp_result_t
|
||||
|
@ -378,7 +295,7 @@ rnp_key_write_packets_stream(const pgp_key_t *key, pgp_dest_t *dst)
|
|||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < pgp_key_get_rawpacket_count(key); i++) {
|
||||
pgp_rawpacket_t *pkt = pgp_key_get_rawpacket(key, i);
|
||||
const pgp_rawpacket_t *pkt = pgp_key_get_rawpacket(key, i);
|
||||
if (!pkt->raw || !pkt->length) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -244,7 +244,7 @@ void
|
|||
rnp_key_store_clear(rnp_key_store_t *keyring)
|
||||
{
|
||||
for (list_item *key = list_front(keyring->keys); key; key = list_next(key)) {
|
||||
pgp_key_free_data((pgp_key_t *) key);
|
||||
((pgp_key_t *) key)->~pgp_key_t();
|
||||
}
|
||||
list_destroy(&keyring->keys);
|
||||
|
||||
|
@ -338,9 +338,14 @@ rnp_key_store_merge_subkey(pgp_key_t *dst, const pgp_key_t *src, pgp_key_t *prim
|
|||
} else if (pgp_key_is_secret(src) && !pgp_key_is_locked(src)) {
|
||||
tmpkey.pkt.material = src->pkt.material;
|
||||
}
|
||||
/* copy validity status */
|
||||
tmpkey.valid = dst->valid && src->valid;
|
||||
/* we may safely leave validated status only if both merged subkeys are valid && validated.
|
||||
* Otherwise we'll need to revalidate. For instance, one validated but invalid subkey may
|
||||
* add revocation signature, or valid subkey may add binding to the invalid one. */
|
||||
tmpkey.validated = dst->validated && src->validated && tmpkey.valid;
|
||||
|
||||
pgp_key_free_data(dst);
|
||||
*dst = tmpkey;
|
||||
*dst = std::move(tmpkey);
|
||||
res = true;
|
||||
done:
|
||||
transferable_subkey_destroy(&dstkey);
|
||||
|
@ -406,9 +411,14 @@ rnp_key_store_merge_key(pgp_key_t *dst, const pgp_key_t *src)
|
|||
} else if (pgp_key_is_secret(src) && !pgp_key_is_locked(src)) {
|
||||
tmpkey.pkt.material = src->pkt.material;
|
||||
}
|
||||
/* copy validity status */
|
||||
tmpkey.valid = dst->valid && src->valid;
|
||||
/* We may safely leave validated status only if both merged keys are valid && validated.
|
||||
* Otherwise we'll need to revalidate. For instance, one validated but invalid key may add
|
||||
* revocation signature, or valid key may add certification to the invalid one. */
|
||||
tmpkey.validated = dst->validated && src->validated && tmpkey.valid;
|
||||
|
||||
pgp_key_free_data(dst);
|
||||
*dst = tmpkey;
|
||||
*dst = std::move(tmpkey);
|
||||
res = true;
|
||||
done:
|
||||
transferable_key_destroy(&dstkey);
|
||||
|
@ -437,7 +447,7 @@ rnp_key_store_refresh_subkey_grips(rnp_key_store_t *keyring, pgp_key_t *key)
|
|||
}
|
||||
|
||||
for (unsigned i = 0; i < pgp_key_get_subsig_count(skey); i++) {
|
||||
pgp_subsig_t *subsig = pgp_key_get_subsig(skey, i);
|
||||
const pgp_subsig_t *subsig = pgp_key_get_subsig(skey, i);
|
||||
|
||||
if (subsig->sig.type != PGP_SIG_SUBKEY) {
|
||||
continue;
|
||||
|
@ -464,76 +474,91 @@ rnp_key_store_refresh_subkey_grips(rnp_key_store_t *keyring, pgp_key_t *key)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* add a key to keyring */
|
||||
pgp_key_t *
|
||||
rnp_key_store_add_key(rnp_key_store_t *keyring, pgp_key_t *srckey)
|
||||
static pgp_key_t *
|
||||
rnp_key_store_add_subkey(rnp_key_store_t *keyring, pgp_key_t *srckey, pgp_key_t *oldkey)
|
||||
{
|
||||
pgp_key_t *added_key = NULL;
|
||||
pgp_key_t *primary = rnp_key_store_get_primary_key(keyring, srckey);
|
||||
if (!primary && oldkey) {
|
||||
primary = rnp_key_store_get_primary_key(keyring, oldkey);
|
||||
}
|
||||
|
||||
RNP_DLOG("rnp_key_store_add_key");
|
||||
assert(pgp_key_get_type(srckey) && pgp_key_get_version(srckey));
|
||||
added_key = rnp_key_store_get_key_by_grip(keyring, pgp_key_get_grip(srckey));
|
||||
|
||||
if (added_key) {
|
||||
/* we cannot merge G10 keys - so just return it */
|
||||
if (srckey->format == PGP_KEY_STORE_G10) {
|
||||
pgp_key_free_data(srckey);
|
||||
return added_key;
|
||||
}
|
||||
|
||||
bool mergeres = false;
|
||||
if (oldkey) {
|
||||
/* in case we already have key let's merge it in */
|
||||
if (pgp_key_is_subkey(added_key)) {
|
||||
pgp_key_t *primary = rnp_key_store_get_primary_key(keyring, added_key);
|
||||
if (!primary) {
|
||||
primary = rnp_key_store_get_primary_key(keyring, srckey);
|
||||
}
|
||||
if (!primary) {
|
||||
RNP_LOG("no primary key for subkey");
|
||||
}
|
||||
mergeres = rnp_key_store_merge_subkey(added_key, srckey, primary);
|
||||
} else {
|
||||
mergeres = rnp_key_store_merge_key(added_key, srckey);
|
||||
}
|
||||
|
||||
if (!mergeres) {
|
||||
RNP_LOG("failed to merge key or subkey");
|
||||
if (!rnp_key_store_merge_subkey(oldkey, srckey, primary)) {
|
||||
RNP_LOG("failed to merge subkey");
|
||||
return NULL;
|
||||
}
|
||||
added_key->valid = added_key->valid && srckey->valid;
|
||||
added_key->validated = added_key->validated && srckey->validated && added_key->valid;
|
||||
|
||||
pgp_key_free_data(srckey);
|
||||
} else {
|
||||
added_key = (pgp_key_t *) list_append(&keyring->keys, srckey, sizeof(*srckey));
|
||||
if (!added_key) {
|
||||
oldkey = (pgp_key_t *) list_append(&keyring->keys, NULL, sizeof(*srckey));
|
||||
if (!oldkey) {
|
||||
RNP_LOG("allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
/* primary key may be added after subkeys, so let's handle this case correctly */
|
||||
if (pgp_key_is_primary_key(added_key) &&
|
||||
!rnp_key_store_refresh_subkey_grips(keyring, added_key)) {
|
||||
RNP_LOG("failed to refresh subkey grips");
|
||||
if (pgp_key_copy(oldkey, srckey, false)) {
|
||||
RNP_LOG("key copying failed");
|
||||
list_remove((list_item *) oldkey);
|
||||
return NULL;
|
||||
}
|
||||
if (primary && !pgp_key_link_subkey_grip(primary, oldkey)) {
|
||||
RNP_LOG("failed to link subkey grip");
|
||||
}
|
||||
}
|
||||
|
||||
RNP_DLOG("keyc %lu", (long unsigned) rnp_key_store_get_key_count(keyring));
|
||||
/* validate all added keys if not disabled */
|
||||
if (!keyring->disable_validation && !added_key->validated) {
|
||||
pgp_key_validate(added_key, keyring);
|
||||
if (!keyring->disable_validation && !oldkey->validated) {
|
||||
pgp_key_validate_subkey(oldkey, primary);
|
||||
}
|
||||
if (!pgp_subkey_refresh_data(oldkey, primary)) {
|
||||
RNP_LOG("Failed to refresh subkey data");
|
||||
}
|
||||
return oldkey;
|
||||
}
|
||||
|
||||
/* validate/re-validate all subkeys as well */
|
||||
if (pgp_key_is_primary_key(added_key)) {
|
||||
for (list_item *grip = list_front(added_key->subkey_grips); grip;
|
||||
grip = list_next(grip)) {
|
||||
pgp_key_t *subkey = rnp_key_store_get_key_by_grip(keyring, (uint8_t *) grip);
|
||||
if (subkey) {
|
||||
pgp_key_validate(subkey, keyring);
|
||||
}
|
||||
}
|
||||
/* add a key to keyring */
|
||||
pgp_key_t *
|
||||
rnp_key_store_add_key(rnp_key_store_t *keyring, pgp_key_t *srckey)
|
||||
{
|
||||
assert(pgp_key_get_type(srckey) && pgp_key_get_version(srckey));
|
||||
pgp_key_t *added_key = rnp_key_store_get_key_by_grip(keyring, pgp_key_get_grip(srckey));
|
||||
/* we cannot merge G10 keys - so just return it */
|
||||
if (added_key && (srckey->format == PGP_KEY_STORE_G10)) {
|
||||
return added_key;
|
||||
}
|
||||
/* different processing for subkeys */
|
||||
if (pgp_key_is_subkey(srckey)) {
|
||||
return rnp_key_store_add_subkey(keyring, srckey, added_key);
|
||||
}
|
||||
|
||||
if (added_key) {
|
||||
if (!rnp_key_store_merge_key(added_key, srckey)) {
|
||||
RNP_LOG("failed to merge key");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
added_key = (pgp_key_t *) list_append(&keyring->keys, NULL, sizeof(*srckey));
|
||||
if (!added_key) {
|
||||
RNP_LOG("allocation failed");
|
||||
return NULL;
|
||||
}
|
||||
if (pgp_key_copy(added_key, srckey, false)) {
|
||||
RNP_LOG("key copying failed");
|
||||
list_remove((list_item *) added_key);
|
||||
return NULL;
|
||||
}
|
||||
/* primary key may be added after subkeys, so let's handle this case correctly */
|
||||
if (!rnp_key_store_refresh_subkey_grips(keyring, added_key)) {
|
||||
RNP_LOG("failed to refresh subkey grips");
|
||||
}
|
||||
}
|
||||
|
||||
RNP_DLOG("keyc %lu", (long unsigned) rnp_key_store_get_key_count(keyring));
|
||||
/* validate all added keys if not disabled or already validated */
|
||||
if (!keyring->disable_validation && !added_key->validated) {
|
||||
pgp_key_revalidate_updated(added_key, keyring);
|
||||
} else if (!pgp_key_refresh_data(added_key)) {
|
||||
RNP_LOG("Failed to refresh key data");
|
||||
}
|
||||
return added_key;
|
||||
}
|
||||
|
||||
|
@ -555,13 +580,18 @@ rnp_key_store_import_key(rnp_key_store_t * keyring,
|
|||
}
|
||||
exkey = rnp_key_store_get_key_by_grip(keyring, pgp_key_get_grip(srckey));
|
||||
expackets = exkey ? pgp_key_get_rawpacket_count(exkey) : 0;
|
||||
if (!(exkey = rnp_key_store_add_key(keyring, &keycp))) {
|
||||
keyring->disable_validation = true;
|
||||
exkey = rnp_key_store_add_key(keyring, &keycp);
|
||||
keyring->disable_validation = false;
|
||||
if (!exkey) {
|
||||
RNP_LOG("failed to add key to the keyring");
|
||||
pgp_key_free_data(&keycp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
changed = pgp_key_get_rawpacket_count(exkey) > expackets;
|
||||
if (changed) {
|
||||
/* this will revalidated primary key with all subkeys */
|
||||
pgp_key_revalidate_updated(exkey, keyring);
|
||||
}
|
||||
if (status) {
|
||||
*status = changed ?
|
||||
(expackets ? PGP_KEY_IMPORT_STATUS_UPDATED : PGP_KEY_IMPORT_STATUS_NEW) :
|
||||
|
@ -588,43 +618,97 @@ rnp_key_store_get_signer_key(rnp_key_store_t *store, const pgp_signature_t *sig)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static pgp_sig_import_status_t
|
||||
rnp_key_store_import_subkey_signature(rnp_key_store_t * keyring,
|
||||
pgp_key_t * key,
|
||||
const pgp_signature_t *sig)
|
||||
{
|
||||
pgp_sig_type_t sigtype = signature_get_type(sig);
|
||||
if ((sigtype != PGP_SIG_SUBKEY) && (sigtype != PGP_SIG_REV_SUBKEY)) {
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
const uint8_t *prim_grip = pgp_key_get_primary_grip(key);
|
||||
pgp_key_t * primary = rnp_key_store_get_signer_key(keyring, sig);
|
||||
if (!prim_grip || !primary) {
|
||||
RNP_LOG("No primary grip or primary key");
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY;
|
||||
}
|
||||
if (memcmp(pgp_key_get_grip(primary), prim_grip, PGP_KEY_GRIP_SIZE)) {
|
||||
RNP_LOG("Wrong subkey signature's signer.");
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
pgp_key_t tmpkey = {};
|
||||
if (!pgp_key_from_pkt(&tmpkey, &key->pkt) || !rnp_key_add_signature(&tmpkey, sig) ||
|
||||
!pgp_subkey_refresh_data(&tmpkey, primary)) {
|
||||
RNP_LOG("Failed to add signature to the key.");
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
size_t expackets = pgp_key_get_rawpacket_count(key);
|
||||
key = rnp_key_store_add_key(keyring, &tmpkey);
|
||||
if (!key) {
|
||||
RNP_LOG("Failed to add key with imported sig to the keyring");
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
return (pgp_key_get_rawpacket_count(key) > expackets) ? PGP_SIG_IMPORT_STATUS_NEW :
|
||||
PGP_SIG_IMPORT_STATUS_UNCHANGED;
|
||||
}
|
||||
|
||||
pgp_sig_import_status_t
|
||||
rnp_key_store_import_key_signature(rnp_key_store_t * keyring,
|
||||
pgp_key_t * key,
|
||||
const pgp_signature_t *sig)
|
||||
{
|
||||
if (pgp_key_is_subkey(key)) {
|
||||
return rnp_key_store_import_subkey_signature(keyring, key, sig);
|
||||
}
|
||||
pgp_sig_type_t sigtype = signature_get_type(sig);
|
||||
if ((sigtype != PGP_SIG_DIRECT) && (sigtype != PGP_SIG_REV_KEY)) {
|
||||
RNP_LOG("Wrong signature type: %d", (int) sigtype);
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
pgp_key_t tmpkey = {};
|
||||
if (!pgp_key_from_pkt(&tmpkey, &key->pkt) || !rnp_key_add_signature(&tmpkey, sig) ||
|
||||
!pgp_key_refresh_data(&tmpkey)) {
|
||||
RNP_LOG("Failed to add signature to the key.");
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
size_t expackets = pgp_key_get_rawpacket_count(key);
|
||||
key = rnp_key_store_add_key(keyring, &tmpkey);
|
||||
if (!key) {
|
||||
RNP_LOG("Failed to add key with imported sig to the keyring");
|
||||
return PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
}
|
||||
return (pgp_key_get_rawpacket_count(key) > expackets) ? PGP_SIG_IMPORT_STATUS_NEW :
|
||||
PGP_SIG_IMPORT_STATUS_UNCHANGED;
|
||||
}
|
||||
|
||||
pgp_key_t *
|
||||
rnp_key_store_import_signature(rnp_key_store_t * keyring,
|
||||
const pgp_signature_t * sig,
|
||||
pgp_sig_import_status_t *status)
|
||||
{
|
||||
pgp_key_t * res_key = NULL;
|
||||
pgp_key_t tmpkey = {};
|
||||
pgp_sig_import_status_t res_status = PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
pgp_sig_type_t sigtype = signature_get_type(sig);
|
||||
size_t expackets = 0;
|
||||
pgp_sig_import_status_t tmp_status = PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
if (!status) {
|
||||
status = &tmp_status;
|
||||
}
|
||||
*status = PGP_SIG_IMPORT_STATUS_UNKNOWN;
|
||||
|
||||
pgp_sig_type_t sigtype = signature_get_type(sig);
|
||||
/* we support only direct-key and key revocation signatures here */
|
||||
if ((sigtype != PGP_SIG_DIRECT) && (sigtype != PGP_SIG_REV_KEY)) {
|
||||
goto done;
|
||||
}
|
||||
res_key = rnp_key_store_get_signer_key(keyring, sig);
|
||||
if (!res_key) {
|
||||
res_status = PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY;
|
||||
goto done;
|
||||
}
|
||||
if (!pgp_key_from_pkt(&tmpkey, &res_key->pkt) || !rnp_key_add_signature(&tmpkey, sig)) {
|
||||
goto done;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
expackets = pgp_key_get_rawpacket_count(res_key);
|
||||
if (!(res_key = rnp_key_store_add_key(keyring, &tmpkey))) {
|
||||
RNP_LOG("failed to add key with imported sig to the keyring");
|
||||
goto done;
|
||||
}
|
||||
res_status = (pgp_key_get_rawpacket_count(res_key) > expackets) ?
|
||||
PGP_SIG_IMPORT_STATUS_NEW :
|
||||
PGP_SIG_IMPORT_STATUS_UNCHANGED;
|
||||
done:
|
||||
pgp_key_free_data(&tmpkey);
|
||||
if (status) {
|
||||
*status = res_status;
|
||||
pgp_key_t *res_key = rnp_key_store_get_signer_key(keyring, sig);
|
||||
if (!res_key || !pgp_key_is_primary_key(res_key)) {
|
||||
*status = PGP_SIG_IMPORT_STATUS_UNKNOWN_KEY;
|
||||
return NULL;
|
||||
}
|
||||
*status = rnp_key_store_import_key_signature(keyring, res_key, sig);
|
||||
return res_key;
|
||||
}
|
||||
|
||||
|
@ -635,6 +719,7 @@ rnp_key_store_remove_key(rnp_key_store_t *keyring, const pgp_key_t *key)
|
|||
if (!list_is_member(keyring->keys, (list_item *) key)) {
|
||||
return false;
|
||||
}
|
||||
key->~pgp_key_t();
|
||||
list_remove((list_item *) key);
|
||||
return true;
|
||||
}
|
||||
|
@ -731,7 +816,7 @@ rnp_key_store_get_primary_key(const rnp_key_store_t *keyring, const pgp_key_t *s
|
|||
}
|
||||
|
||||
for (unsigned i = 0; i < pgp_key_get_subsig_count(subkey); i++) {
|
||||
pgp_subsig_t *subsig = pgp_key_get_subsig(subkey, i);
|
||||
const pgp_subsig_t *subsig = pgp_key_get_subsig(subkey, i);
|
||||
if (subsig->sig.type != PGP_SIG_SUBKEY) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -937,11 +937,6 @@ init_armored_dst(pgp_dest_t *dst, pgp_dest_t *writedst, pgp_armored_msg_t msgtyp
|
|||
/* armor header */
|
||||
dst_write(writedst, hdr, strlen(hdr));
|
||||
armor_write_eol(param);
|
||||
/* version string */
|
||||
strncpy(hdr, "Version: " PACKAGE_STRING, sizeof(hdr));
|
||||
hdr[sizeof(hdr) - 1] = '\0';
|
||||
dst_write(writedst, hdr, strlen(hdr));
|
||||
armor_write_eol(param);
|
||||
/* empty line */
|
||||
armor_write_eol(param);
|
||||
|
||||
|
|
|
@ -52,6 +52,10 @@ src_read(pgp_source_t *src, void *buf, size_t len, size_t *readres)
|
|||
pgp_source_cache_t *cache = src->cache;
|
||||
bool readahead = cache ? cache->readahead : false;
|
||||
|
||||
if (src->error) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (src->eof || (len == 0)) {
|
||||
*readres = 0;
|
||||
return true;
|
||||
|
@ -137,6 +141,9 @@ bool
|
|||
src_peek(pgp_source_t *src, void *buf, size_t len, size_t *peeked)
|
||||
{
|
||||
pgp_source_cache_t *cache = src->cache;
|
||||
if (src->error) {
|
||||
return false;
|
||||
}
|
||||
if (!cache || (len > sizeof(cache->buf))) {
|
||||
return false;
|
||||
}
|
||||
|
@ -220,6 +227,7 @@ src_skip(pgp_source_t *src, size_t len)
|
|||
|
||||
void *buf = calloc(1, std::min((size_t) PGP_INPUT_CACHE_SIZE, len));
|
||||
if (!buf) {
|
||||
src->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -353,6 +353,54 @@ transferable_key_add_userid(pgp_transferable_key_t *key, const char *userid)
|
|||
return tuid;
|
||||
}
|
||||
|
||||
bool
|
||||
signature_calculate_certification(const pgp_key_pkt_t * key,
|
||||
const pgp_userid_pkt_t *uid,
|
||||
pgp_signature_t * sig,
|
||||
const pgp_key_pkt_t * signer)
|
||||
{
|
||||
if (!key || !uid || !sig || !signer) {
|
||||
RNP_LOG("NULL parameter(s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
rng_t rng = {};
|
||||
if (!rng_init(&rng, RNG_SYSTEM)) {
|
||||
RNP_LOG("RNG init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
pgp_hash_t hash = {};
|
||||
bool res = signature_fill_hashed_data(sig) &&
|
||||
signature_hash_certification(sig, key, uid, &hash) &&
|
||||
!signature_calculate(sig, &signer->material, &hash, &rng);
|
||||
rng_destroy(&rng);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
signature_calculate_direct(const pgp_key_pkt_t *key,
|
||||
pgp_signature_t * sig,
|
||||
const pgp_key_pkt_t *signer)
|
||||
{
|
||||
if (!key || !sig || !signer) {
|
||||
RNP_LOG("NULL parameter(s)");
|
||||
return false;
|
||||
}
|
||||
|
||||
rng_t rng = {};
|
||||
if (!rng_init(&rng, RNG_SYSTEM)) {
|
||||
RNP_LOG("RNG init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
pgp_hash_t hash = {};
|
||||
bool res = signature_fill_hashed_data(sig) && signature_hash_direct(sig, key, &hash) &&
|
||||
!signature_calculate(sig, &signer->material, &hash, &rng);
|
||||
rng_destroy(&rng);
|
||||
return res;
|
||||
}
|
||||
|
||||
pgp_signature_t *
|
||||
transferable_userid_certify(const pgp_key_pkt_t * key,
|
||||
pgp_transferable_userid_t * userid,
|
||||
|
@ -362,10 +410,8 @@ transferable_userid_certify(const pgp_key_pkt_t * key,
|
|||
{
|
||||
pgp_signature_t sig = {};
|
||||
pgp_signature_t * res = NULL;
|
||||
pgp_hash_t hash = {};
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
pgp_fingerprint_t keyfp;
|
||||
rng_t rng = {};
|
||||
const pgp_user_prefs_t *prefs = NULL;
|
||||
|
||||
if (!key || !userid || !signer || !cert) {
|
||||
|
@ -373,11 +419,6 @@ transferable_userid_certify(const pgp_key_pkt_t * key,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!rng_init(&rng, RNG_SYSTEM)) {
|
||||
RNP_LOG("RNG init failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pgp_keyid(keyid, sizeof(keyid), signer)) {
|
||||
RNP_LOG("failed to calculate keyid");
|
||||
goto end;
|
||||
|
@ -446,36 +487,25 @@ transferable_userid_certify(const pgp_key_pkt_t * key,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!signature_fill_hashed_data(&sig) ||
|
||||
!signature_hash_certification(&sig, key, &userid->uid, &hash) ||
|
||||
signature_calculate(&sig, &signer->material, &hash, &rng)) {
|
||||
if (!signature_calculate_certification(key, &userid->uid, &sig, signer)) {
|
||||
RNP_LOG("failed to calculate signature");
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = (pgp_signature_t *) list_append(&userid->signatures, &sig, sizeof(sig));
|
||||
end:
|
||||
rng_destroy(&rng);
|
||||
if (!res) {
|
||||
free_signature(&sig);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool calculate_primary_binding(const pgp_key_pkt_t *key,
|
||||
const pgp_key_pkt_t *subkey,
|
||||
pgp_hash_alg_t halg,
|
||||
pgp_signature_t * sig,
|
||||
pgp_hash_t * hash,
|
||||
rng_t * rng);
|
||||
|
||||
bool
|
||||
calculate_primary_binding(const pgp_key_pkt_t *key,
|
||||
const pgp_key_pkt_t *subkey,
|
||||
pgp_hash_alg_t halg,
|
||||
pgp_signature_t * sig,
|
||||
pgp_hash_t * hash,
|
||||
rng_t * rng)
|
||||
static bool
|
||||
signature_calculate_primary_binding(const pgp_key_pkt_t *key,
|
||||
const pgp_key_pkt_t *subkey,
|
||||
pgp_hash_alg_t halg,
|
||||
pgp_signature_t * sig,
|
||||
pgp_hash_t * hash,
|
||||
rng_t * rng)
|
||||
{
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
bool res = false;
|
||||
|
@ -514,40 +544,90 @@ end:
|
|||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
signature_calculate_binding(const pgp_key_pkt_t *key,
|
||||
const pgp_key_pkt_t *sub,
|
||||
pgp_signature_t * sig,
|
||||
bool subsign)
|
||||
{
|
||||
pgp_hash_t hash = {};
|
||||
pgp_hash_t hashcp = {};
|
||||
rng_t rng = {};
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
|
||||
if (pgp_keyid(keyid, sizeof(keyid), key)) {
|
||||
RNP_LOG("failed to calculate keyid");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rng_init(&rng, RNG_SYSTEM)) {
|
||||
RNP_LOG("RNG init failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = false;
|
||||
if (!signature_fill_hashed_data(sig) || !signature_hash_binding(sig, key, sub, &hash) ||
|
||||
!pgp_hash_copy(&hashcp, &hash)) {
|
||||
RNP_LOG("failed to hash signature");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (signature_calculate(sig, &key->material, &hash, &rng)) {
|
||||
RNP_LOG("failed to calculate signature");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* unhashed subpackets. Primary key binding signature and issuer key id */
|
||||
if (subsign) {
|
||||
pgp_signature_t embsig = {};
|
||||
bool embres;
|
||||
|
||||
if (!signature_calculate_primary_binding(
|
||||
key, sub, sig->halg, &embsig, &hashcp, &rng)) {
|
||||
RNP_LOG("failed to calculate primary key binding signature");
|
||||
goto end;
|
||||
}
|
||||
embres = signature_set_embedded_sig(sig, &embsig);
|
||||
free_signature(&embsig);
|
||||
if (!embres) {
|
||||
RNP_LOG("failed to add primary key binding signature");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* add keyid since it should (probably) be after the primary key binding if any */
|
||||
if (!signature_set_keyid(sig, keyid)) {
|
||||
RNP_LOG("failed to set issuer key id");
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = true;
|
||||
end:
|
||||
pgp_hash_finish(&hashcp, NULL);
|
||||
rng_destroy(&rng);
|
||||
return res;
|
||||
}
|
||||
|
||||
pgp_signature_t *
|
||||
transferable_subkey_bind(const pgp_key_pkt_t * key,
|
||||
pgp_transferable_subkey_t * subkey,
|
||||
pgp_hash_alg_t hash_alg,
|
||||
const rnp_selfsig_binding_info_t *binding)
|
||||
{
|
||||
pgp_signature_t sig = {};
|
||||
pgp_signature_t * res = NULL;
|
||||
pgp_hash_t hash = {};
|
||||
pgp_hash_t hashcp = {};
|
||||
pgp_key_flags_t realkf = (pgp_key_flags_t) 0;
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
pgp_fingerprint_t keyfp;
|
||||
rng_t rng = {};
|
||||
|
||||
if (!key || !subkey || !binding) {
|
||||
RNP_LOG("invalid parameters");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!rng_init(&rng, RNG_SYSTEM)) {
|
||||
RNP_LOG("RNG init failed");
|
||||
pgp_fingerprint_t keyfp;
|
||||
if (pgp_fingerprint(&keyfp, key)) {
|
||||
RNP_LOG("failed to calculate keyfp");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pgp_keyid(keyid, sizeof(keyid), key)) {
|
||||
RNP_LOG("failed to calculate keyid");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (pgp_fingerprint(&keyfp, key)) {
|
||||
RNP_LOG("failed to calculate keyfp");
|
||||
goto end;
|
||||
}
|
||||
pgp_signature_t sig = {};
|
||||
pgp_signature_t *res = NULL;
|
||||
pgp_key_flags_t realkf = (pgp_key_flags_t) 0;
|
||||
|
||||
sig.version = PGP_V4;
|
||||
sig.halg = pgp_hash_adjust_alg_to_key(hash_alg, key);
|
||||
|
@ -572,49 +652,17 @@ transferable_subkey_bind(const pgp_key_pkt_t * key,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!signature_fill_hashed_data(&sig) ||
|
||||
!signature_hash_binding(&sig, key, &subkey->subkey, &hash) ||
|
||||
!pgp_hash_copy(&hashcp, &hash)) {
|
||||
RNP_LOG("failed to hash signature");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (signature_calculate(&sig, &key->material, &hash, &rng)) {
|
||||
RNP_LOG("failed to calculate signature");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* unhashed subpackets. Primary key binding signature and issuer key id */
|
||||
realkf = (pgp_key_flags_t) binding->key_flags;
|
||||
if (!realkf) {
|
||||
realkf = pgp_pk_alg_capabilities(key->alg);
|
||||
}
|
||||
if (realkf & PGP_KF_SIGN) {
|
||||
pgp_signature_t embsig = {};
|
||||
bool embres;
|
||||
|
||||
if (!calculate_primary_binding(
|
||||
key, &subkey->subkey, hash_alg, &embsig, &hashcp, &rng)) {
|
||||
RNP_LOG("failed to calculate primary key binding signature");
|
||||
goto end;
|
||||
}
|
||||
embres = signature_set_embedded_sig(&sig, &embsig);
|
||||
free_signature(&embsig);
|
||||
if (!embres) {
|
||||
RNP_LOG("failed to add primary key binding signature");
|
||||
goto end;
|
||||
}
|
||||
realkf = pgp_pk_alg_capabilities(subkey->subkey.alg);
|
||||
}
|
||||
|
||||
if (!signature_set_keyid(&sig, keyid)) {
|
||||
RNP_LOG("failed to set issuer key id");
|
||||
if (!signature_calculate_binding(key, &subkey->subkey, &sig, realkf & PGP_KF_SIGN)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
res = (pgp_signature_t *) list_append(&subkey->signatures, &sig, sizeof(sig));
|
||||
end:
|
||||
pgp_hash_finish(&hashcp, NULL);
|
||||
rng_destroy(&rng);
|
||||
if (!res) {
|
||||
free_signature(&sig);
|
||||
}
|
||||
|
@ -629,19 +677,13 @@ transferable_key_revoke(const pgp_key_pkt_t *key,
|
|||
{
|
||||
pgp_signature_t * sig = NULL;
|
||||
bool res = false;
|
||||
pgp_hash_t hash = {};
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
pgp_fingerprint_t keyfp;
|
||||
rng_t rng = {};
|
||||
|
||||
if (!key || !signer || !revoke) {
|
||||
RNP_LOG("invalid parameters");
|
||||
return NULL;
|
||||
}
|
||||
if (!rng_init(&rng, RNG_SYSTEM)) {
|
||||
RNP_LOG("RNG init failed");
|
||||
return NULL;
|
||||
}
|
||||
sig = (pgp_signature_t *) calloc(1, sizeof(*sig));
|
||||
if (!sig) {
|
||||
RNP_LOG("allocation failed");
|
||||
|
@ -678,14 +720,15 @@ transferable_key_revoke(const pgp_key_pkt_t *key,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (!signature_fill_hashed_data(sig) || !signature_hash_direct(sig, key, &hash) ||
|
||||
signature_calculate(sig, &signer->material, &hash, &rng)) {
|
||||
RNP_LOG("failed to calculate signature");
|
||||
goto end;
|
||||
if (is_primary_key_pkt(key->tag)) {
|
||||
res = signature_calculate_direct(key, sig, signer);
|
||||
} else {
|
||||
res = signature_calculate_binding(signer, key, sig, false);
|
||||
}
|
||||
if (!res) {
|
||||
RNP_LOG("failed to calculate signature");
|
||||
}
|
||||
res = true;
|
||||
end:
|
||||
rng_destroy(&rng);
|
||||
if (!res && sig) {
|
||||
free_signature(sig);
|
||||
free(sig);
|
||||
|
|
|
@ -123,4 +123,18 @@ rnp_result_t encrypt_secret_key(pgp_key_pkt_t *key, const char *password, rng_t
|
|||
|
||||
void forget_secret_key_fields(pgp_key_material_t *key);
|
||||
|
||||
bool signature_calculate_certification(const pgp_key_pkt_t * key,
|
||||
const pgp_userid_pkt_t *uid,
|
||||
pgp_signature_t * sig,
|
||||
const pgp_key_pkt_t * signer);
|
||||
|
||||
bool signature_calculate_direct(const pgp_key_pkt_t *key,
|
||||
pgp_signature_t * sig,
|
||||
const pgp_key_pkt_t *signer);
|
||||
|
||||
bool signature_calculate_binding(const pgp_key_pkt_t *key,
|
||||
const pgp_key_pkt_t *sub,
|
||||
pgp_signature_t * sig,
|
||||
bool subsign);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -637,13 +637,14 @@ encrypted_src_read_cfb(pgp_source_t *src, void *buf, size_t len, size_t *readres
|
|||
uint8_t mdcbuf[MDC_V1_SIZE];
|
||||
if (param->has_mdc) {
|
||||
size_t mdcread = 0;
|
||||
/* make sure there are always 20 bytes left on input */
|
||||
/* make sure there are always 22 bytes left on input */
|
||||
if (!src_peek(param->pkt.readsrc, mdcbuf, MDC_V1_SIZE, &mdcread) ||
|
||||
(mdcread + read < MDC_V1_SIZE)) {
|
||||
RNP_LOG("wrong mdc read state");
|
||||
return false;
|
||||
}
|
||||
if (mdcread < MDC_V1_SIZE) {
|
||||
src_skip(param->pkt.readsrc, mdcread);
|
||||
size_t mdcsub = MDC_V1_SIZE - mdcread;
|
||||
memmove(&mdcbuf[mdcsub], mdcbuf, mdcread);
|
||||
memcpy(mdcbuf, (uint8_t *) buf + read - mdcsub, mdcsub);
|
||||
|
|
|
@ -93,7 +93,7 @@ signature_add_subpkt(pgp_signature_t * sig,
|
|||
}
|
||||
|
||||
if (reuse && (subpkt = signature_get_subpkt(sig, type))) {
|
||||
free(subpkt->data);
|
||||
free_signature_subpkt(subpkt);
|
||||
memset(subpkt, 0, sizeof(*subpkt));
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,6 @@ signature_add_subpkt(pgp_signature_t * sig,
|
|||
|
||||
subpkt->type = type;
|
||||
subpkt->len = datalen;
|
||||
|
||||
return subpkt;
|
||||
}
|
||||
|
||||
|
@ -871,6 +870,7 @@ signature_fill_hashed_data(pgp_signature_t *sig)
|
|||
}
|
||||
|
||||
if (res) {
|
||||
free(sig->hashed_data);
|
||||
/* get ownership on body data */
|
||||
sig->hashed_data = hbody.data;
|
||||
sig->hashed_len = hbody.len;
|
||||
|
@ -1178,34 +1178,13 @@ signature_check_certification(pgp_signature_info_t * sinfo,
|
|||
const pgp_key_pkt_t * key,
|
||||
const pgp_userid_pkt_t *uid)
|
||||
{
|
||||
pgp_hash_t hash = {};
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
rnp_result_t res = RNP_ERROR_SIGNATURE_INVALID;
|
||||
pgp_hash_t hash = {};
|
||||
|
||||
if (!signature_hash_certification(sinfo->sig, key, uid, &hash)) {
|
||||
return RNP_ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
res = signature_check(sinfo, &hash);
|
||||
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* check key expiration time, only for self-signature. While sinfo->expired tells about
|
||||
the signature expiry, we'll use it for bkey expiration as well */
|
||||
if (signature_get_keyid(sinfo->sig, keyid) &&
|
||||
!memcmp(keyid, pgp_key_get_keyid(sinfo->signer), PGP_KEY_ID_SIZE)) {
|
||||
uint32_t expiry = signature_get_key_expiration(sinfo->sig);
|
||||
uint32_t now = time(NULL);
|
||||
|
||||
if (expiry && (key->creation_time + expiry < now)) {
|
||||
RNP_LOG("key expired %d seconds ago", (int) now - expiry - key->creation_time);
|
||||
sinfo->expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return signature_check(sinfo, &hash);
|
||||
}
|
||||
|
||||
rnp_result_t
|
||||
|
@ -1228,19 +1207,6 @@ signature_check_binding(pgp_signature_info_t *sinfo,
|
|||
|
||||
res = signature_check(sinfo, &hash);
|
||||
|
||||
/* check subkey expiration time. While sinfo->expired tells about the signature expiry,
|
||||
we'll use it for subkey expiration as well */
|
||||
if (!res) {
|
||||
uint32_t expiry = signature_get_key_expiration(sinfo->sig);
|
||||
uint32_t now = time(NULL);
|
||||
|
||||
if (expiry && (subkey->creation_time + expiry < now)) {
|
||||
RNP_LOG("subkey expired %d seconds ago",
|
||||
(int) now - expiry - subkey->creation_time);
|
||||
sinfo->expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* check primary key binding signature if any */
|
||||
if (!res && (signature_get_key_flags(sinfo->sig) & PGP_KF_SIGN)) {
|
||||
res = RNP_ERROR_SIGNATURE_INVALID;
|
||||
|
|
|
@ -697,6 +697,7 @@ cli_rnp_print_key_info(FILE *fp, rnp_ffi_t ffi, rnp_key_handle_t key, bool psecr
|
|||
const char * header = NULL;
|
||||
bool secret = false;
|
||||
bool primary = false;
|
||||
bool revoked = false;
|
||||
uint32_t bits = 0;
|
||||
int64_t create = 0;
|
||||
uint32_t expiry = 0;
|
||||
|
@ -712,11 +713,11 @@ cli_rnp_print_key_info(FILE *fp, rnp_ffi_t ffi, rnp_key_handle_t key, bool psecr
|
|||
return;
|
||||
}
|
||||
if (!(pkts = json_tokener_parse(json))) {
|
||||
fprintf(fp, "Key JSON error");
|
||||
fprintf(fp, "Key JSON error.\n");
|
||||
goto done;
|
||||
}
|
||||
if (!(keypkt = json_object_array_get_idx(pkts, 0))) {
|
||||
fprintf(fp, "Key JSON error");
|
||||
fprintf(fp, "Key JSON error.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -750,6 +751,11 @@ cli_rnp_print_key_info(FILE *fp, rnp_ffi_t ffi, rnp_key_handle_t key, bool psecr
|
|||
ptimestr(buf, sizeof(buf), expire_time);
|
||||
fprintf(fp, " [%s %s]", expire_time <= now ? "EXPIRED" : "EXPIRES", buf);
|
||||
}
|
||||
/* key is revoked */
|
||||
(void) rnp_key_is_revoked(key, &revoked);
|
||||
if (revoked) {
|
||||
fprintf(fp, " [REVOKED]");
|
||||
}
|
||||
/* fingerprint */
|
||||
fprintf(fp, "\n %s\n", json_obj_get_str(keypkt, "fingerprint"));
|
||||
/* user ids */
|
||||
|
@ -1733,6 +1739,74 @@ done:
|
|||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
cli_rnp_revoke_key(cli_rnp_t *rnp, const char *key)
|
||||
{
|
||||
std::vector<rnp_key_handle_t> keys;
|
||||
if (!cli_rnp_keys_matching_string(rnp, keys, key, CLI_SEARCH_SUBKEYS)) {
|
||||
ERR_MSG("Key matching '%s' not found.", key);
|
||||
return false;
|
||||
}
|
||||
rnp_cfg_t * cfg = cli_rnp_cfg(rnp);
|
||||
bool res = false;
|
||||
bool revoked = false;
|
||||
rnp_result_t ret = 0;
|
||||
|
||||
if (keys.size() > 1) {
|
||||
ERR_MSG("Ambiguous input: too many keys found for '%s'.", key);
|
||||
goto done;
|
||||
}
|
||||
if (rnp_key_is_revoked(keys[0], &revoked)) {
|
||||
ERR_MSG("Error getting key revocation status.");
|
||||
goto done;
|
||||
}
|
||||
if (revoked && !rnp_cfg_getbool(cfg, CFG_FORCE)) {
|
||||
ERR_MSG("Error: key '%s' is revoked already. Use --force to generate another "
|
||||
"revocation signature.",
|
||||
key);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = rnp_key_revoke(keys[0],
|
||||
0,
|
||||
rnp_cfg_getstr(cfg, CFG_HASH),
|
||||
rnp_cfg_getstr(cfg, CFG_REV_TYPE),
|
||||
rnp_cfg_getstr(cfg, CFG_REV_REASON));
|
||||
if (ret) {
|
||||
ERR_MSG("Failed to revoke a key: error %d", (int) ret);
|
||||
goto done;
|
||||
}
|
||||
res = cli_rnp_save_keyrings(rnp);
|
||||
/* print info about the revoked key */
|
||||
if (res) {
|
||||
bool subkey = false;
|
||||
char *grip = NULL;
|
||||
if (rnp_key_is_sub(keys[0], &subkey)) {
|
||||
ERR_MSG("Failed to get key info");
|
||||
goto done;
|
||||
}
|
||||
ret =
|
||||
subkey ? rnp_key_get_primary_grip(keys[0], &grip) : rnp_key_get_grip(keys[0], &grip);
|
||||
if (ret || !grip) {
|
||||
ERR_MSG("Failed to get primary key grip.");
|
||||
goto done;
|
||||
}
|
||||
clear_key_handles(keys);
|
||||
if (!cli_rnp_keys_matching_string(rnp, keys, grip, CLI_SEARCH_SUBKEYS_AFTER)) {
|
||||
ERR_MSG("Failed to search for revoked key.");
|
||||
rnp_buffer_destroy(grip);
|
||||
goto done;
|
||||
}
|
||||
rnp_buffer_destroy(grip);
|
||||
for (auto handle : keys) {
|
||||
cli_rnp_print_key_info(rnp->userio_out, rnp->ffi, handle, false, false);
|
||||
}
|
||||
}
|
||||
done:
|
||||
clear_key_handles(keys);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
cli_rnp_add_key(cli_rnp_t *rnp)
|
||||
{
|
||||
|
|
|
@ -118,6 +118,7 @@ bool cli_rnp_keys_matching_strings(cli_rnp_t * rnp,
|
|||
int flags);
|
||||
bool cli_rnp_export_keys(cli_rnp_t *rnp, const char *filter);
|
||||
bool cli_rnp_export_revocation(cli_rnp_t *rnp, const char *key);
|
||||
bool cli_rnp_revoke_key(cli_rnp_t *rnp, const char *key);
|
||||
bool cli_rnp_add_key(cli_rnp_t *rnp);
|
||||
bool cli_rnp_dump_file(cli_rnp_t *rnp);
|
||||
bool cli_rnp_armor_file(cli_rnp_t *rnp);
|
||||
|
|
|
@ -50,6 +50,7 @@ extern const char *rnp_keys_progname;
|
|||
const char *usage = "--help OR\n"
|
||||
"\t--export-key [options] OR\n"
|
||||
"\t--export-rev [options] OR\n"
|
||||
"\t--revoke-key [options] OR\n"
|
||||
"\t--generate-key [options] OR\n"
|
||||
"\t--import, --import-keys, --import-sigs [options] OR\n"
|
||||
"\t--list-keys [options] OR\n"
|
||||
|
@ -84,6 +85,7 @@ struct option options[] = {
|
|||
{"generate-key", optional_argument, NULL, CMD_GENERATE_KEY},
|
||||
{"export-rev", no_argument, NULL, CMD_EXPORT_REV},
|
||||
{"export-revocation", no_argument, NULL, CMD_EXPORT_REV},
|
||||
{"revoke-key", no_argument, NULL, CMD_REVOKE_KEY},
|
||||
/* debugging commands */
|
||||
{"help", no_argument, NULL, CMD_HELP},
|
||||
{"version", no_argument, NULL, CMD_VERSION},
|
||||
|
@ -385,6 +387,13 @@ rnp_cmd(cli_rnp_t *rnp, optdefs_t cmd, const char *f)
|
|||
}
|
||||
return cli_rnp_export_revocation(rnp, f);
|
||||
}
|
||||
case CMD_REVOKE_KEY: {
|
||||
if (!f) {
|
||||
ERR_MSG("You need to specify key or subkey to revoke.");
|
||||
return false;
|
||||
}
|
||||
return cli_rnp_revoke_key(rnp, f);
|
||||
}
|
||||
case CMD_VERSION:
|
||||
print_praise();
|
||||
return true;
|
||||
|
@ -415,6 +424,7 @@ setoption(rnp_cfg_t *cfg, optdefs_t *cmd, int val, const char *arg)
|
|||
case CMD_LIST_KEYS:
|
||||
case CMD_EXPORT_KEY:
|
||||
case CMD_EXPORT_REV:
|
||||
case CMD_REVOKE_KEY:
|
||||
case CMD_IMPORT:
|
||||
case CMD_IMPORT_KEYS:
|
||||
case CMD_IMPORT_SIGS:
|
||||
|
|
|
@ -16,6 +16,7 @@ typedef enum {
|
|||
CMD_IMPORT_SIGS,
|
||||
CMD_GENERATE_KEY,
|
||||
CMD_EXPORT_REV,
|
||||
CMD_REVOKE_KEY,
|
||||
CMD_VERSION,
|
||||
CMD_HELP,
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ find_package(JSON-C 0.11 REQUIRED)
|
|||
# Note that we do this call early because Google Test will also do
|
||||
# this but with less strict version requirements, which will cause
|
||||
# problems for us.
|
||||
find_package(PythonInterp 2.7 EXACT)
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
find_package(GnuPG 2.2 COMPONENTS gpg gpgconf)
|
||||
|
||||
include(GoogleTest)
|
||||
|
@ -91,6 +91,7 @@ add_executable(rnp_tests
|
|||
utils-list.cpp
|
||||
utils-rnpcfg.cpp
|
||||
issues/1030.cpp
|
||||
issues/1115.cpp
|
||||
)
|
||||
|
||||
target_include_directories(rnp_tests
|
||||
|
@ -135,7 +136,7 @@ function(add_cli_test suite)
|
|||
set(_test_name cli_tests-${suite})
|
||||
add_test(
|
||||
NAME ${_test_name}
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/cli_tests.py" -v -d "${suite}"
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/cli_tests.py" -v -d "${suite}"
|
||||
)
|
||||
set(_env)
|
||||
list(APPEND _env
|
||||
|
@ -152,7 +153,7 @@ function(add_cli_test suite)
|
|||
endfunction()
|
||||
# get a list of test suites
|
||||
execute_process(
|
||||
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/cli_tests.py" -ls
|
||||
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/cli_tests.py" -ls
|
||||
RESULT_VARIABLE _ec
|
||||
OUTPUT_VARIABLE suitelist
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
|
|
|
@ -34,17 +34,14 @@ def raise_err(msg, log = None):
|
|||
raise CLIError(msg, log)
|
||||
|
||||
def size_to_readable(num, suffix = 'B'):
|
||||
for unit in ['','K','M','G','T','P','E','Z']:
|
||||
for unit in ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z']:
|
||||
if abs(num) < 1024.0:
|
||||
return "%3.1f%s%s" % (num, unit, suffix)
|
||||
num /= 1024.0
|
||||
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||
|
||||
def list_upto(lst, count):
|
||||
res = lst[:]
|
||||
while len(res) < count:
|
||||
res = res + lst[:]
|
||||
return res[:count]
|
||||
return (list(lst)*(count//len(lst)+1))[:count]
|
||||
|
||||
def pswd_pipe(password):
|
||||
pr, pw = os.pipe()
|
||||
|
@ -52,6 +49,7 @@ def pswd_pipe(password):
|
|||
fw.write(password)
|
||||
fw.write('\n')
|
||||
fw.write(password)
|
||||
os.set_inheritable(pr, True)
|
||||
|
||||
if not is_windows():
|
||||
return pr
|
||||
|
@ -63,15 +61,16 @@ def pswd_pipe(password):
|
|||
def random_text(path, size):
|
||||
# Generate random text, with 50% probability good-compressible
|
||||
if random.randint(0, 10) < 5:
|
||||
st = ''.join(random.choice(string.ascii_letters + string.digits + " \t\n-,.") for _ in range(size))
|
||||
st = ''.join(random.choice(string.ascii_letters + string.digits + " \t\n-,.")
|
||||
for _ in range(size))
|
||||
else:
|
||||
st = ''.join(random.choice("abcdef0123456789 \t\n-,.") for _ in range(size))
|
||||
with open(path, 'w+') as f:
|
||||
f.write(st)
|
||||
|
||||
def file_text(path):
|
||||
with open(path, 'r') as f:
|
||||
return f.read()
|
||||
with open(path, 'rb') as f:
|
||||
return f.read().decode().replace('\r\r', '\r')
|
||||
|
||||
def find_utility(name, exitifnone = True):
|
||||
path = distutils.spawn.find_executable(name)
|
||||
|
@ -100,17 +99,26 @@ def run_proc_windows(proc, params, stdin=None):
|
|||
|
||||
exe = os.path.basename(proc)
|
||||
# We need to escape empty parameters/ones with spaces with quotes
|
||||
params = map(lambda st: st if (st and not any(x in st for x in [' ','\r','\t'])) else '"%s"' % st, [exe] + params)
|
||||
params = tuple(map(lambda st: st if (st and not any(x in st for x in [' ','\r','\t'])) else '"%s"' % st, [exe] + params))
|
||||
sys.stdout.flush()
|
||||
|
||||
stdin_path = os.path.join(WORKDIR, 'stdin.txt')
|
||||
stdout_path = os.path.join(WORKDIR, 'stdout.txt')
|
||||
stderr_path = os.path.join(WORKDIR, 'stderr.txt')
|
||||
pass_path = os.path.join(WORKDIR, 'pass.txt')
|
||||
passfd = 0
|
||||
passfo = None
|
||||
try:
|
||||
idx = params.index('--pass-fd')
|
||||
if idx < len(params):
|
||||
passfd = int(params[idx+1])
|
||||
passfo = os.fdopen(passfd, 'r', closefd=False)
|
||||
except (ValueError, OSError): pass
|
||||
# We may use pipes here (ensuring we use dup to inherit handles), but those have limited buffer
|
||||
# so we'll need to poll process
|
||||
if stdin:
|
||||
with open(stdin_path, "wb+") as stdinf:
|
||||
stdinf.write(stdin)
|
||||
stdinf.write(stdin.encode() if isinstance(stdin, str) else stdin)
|
||||
stdin_fl = os.open(stdin_path, os.O_RDONLY | os.O_BINARY)
|
||||
stdin_no = sys.stdin.fileno()
|
||||
stdin_cp = os.dup(stdin_no)
|
||||
|
@ -120,6 +128,11 @@ def run_proc_windows(proc, params, stdin=None):
|
|||
stderr_fl = os.open(stderr_path, os.O_CREAT | os.O_RDWR | os.O_BINARY)
|
||||
stderr_no = sys.stderr.fileno()
|
||||
stderr_cp = os.dup(stderr_no)
|
||||
if passfo:
|
||||
with open(pass_path, "w+") as passf:
|
||||
passf.write(passfo.read())
|
||||
pass_fl = os.open(pass_path, os.O_RDONLY | os.O_BINARY)
|
||||
pass_cp = os.dup(passfd)
|
||||
|
||||
try:
|
||||
os.dup2(stdout_fl, stdout_no)
|
||||
|
@ -129,6 +142,9 @@ def run_proc_windows(proc, params, stdin=None):
|
|||
if stdin:
|
||||
os.dup2(stdin_fl, stdin_no)
|
||||
os.close(stdin_fl)
|
||||
if passfo:
|
||||
os.dup2(pass_fl, passfd)
|
||||
os.close(pass_fl)
|
||||
retcode = os.spawnv(os.P_WAIT, proc, params)
|
||||
finally:
|
||||
os.dup2(stdout_cp, stdout_no)
|
||||
|
@ -138,12 +154,18 @@ def run_proc_windows(proc, params, stdin=None):
|
|||
if stdin:
|
||||
os.dup2(stdin_cp, stdin_no)
|
||||
os.close(stdin_cp)
|
||||
if passfo:
|
||||
os.dup2(pass_cp, passfd)
|
||||
os.close(pass_cp)
|
||||
passfo.close()
|
||||
out = file_text(stdout_path).replace('\r\n', '\n')
|
||||
err = file_text(stderr_path).replace('\r\n', '\n')
|
||||
os.unlink(stdout_path)
|
||||
os.unlink(stderr_path)
|
||||
if stdin:
|
||||
os.unlink(stdin_path)
|
||||
if passfo:
|
||||
os.unlink(pass_path)
|
||||
logging.debug(err.strip())
|
||||
logging.debug(out.strip())
|
||||
return (retcode, out, err)
|
||||
|
@ -154,7 +176,8 @@ def run_proc(proc, params, stdin=None):
|
|||
return run_proc_windows(proc, params, stdin)
|
||||
|
||||
logging.debug((proc + ' ' + ' '.join(params)).strip())
|
||||
process = Popen([proc] + params, stdout=PIPE, stderr=PIPE, stdin=PIPE if stdin else None)
|
||||
process = Popen([proc] + params, stdout=PIPE, stderr=PIPE,
|
||||
stdin=PIPE if stdin else None, close_fds=False, universal_newlines=True)
|
||||
output, errout = process.communicate(stdin)
|
||||
retcode = process.poll()
|
||||
logging.debug(errout.strip())
|
||||
|
|
|
@ -55,31 +55,34 @@ def setup(workdir):
|
|||
# Creating working directory and populating it with test files
|
||||
RNPDIR = path.join(WORKDIR, '.rnp')
|
||||
GPGDIR = path.join(WORKDIR, '.gpg')
|
||||
os.mkdir(RNPDIR, 0700)
|
||||
os.mkdir(GPGDIR, 0700)
|
||||
os.mkdir(RNPDIR, 0o700)
|
||||
os.mkdir(GPGDIR, 0o700)
|
||||
|
||||
# Generating key
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
params = ['--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', 'performance@rnp', '--generate-key']
|
||||
params = ['--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', 'performance@rnp',
|
||||
'--generate-key']
|
||||
# Run key generation
|
||||
ret, out, err = run_proc(RNPK, params)
|
||||
os.close(pipe)
|
||||
|
||||
# Importing keys to GnuPG so it can build trustdb and so on
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--passphrase', '', '--homedir', GPGDIR, '--import', path.join(RNPDIR, 'pubring.gpg'), path.join(RNPDIR, 'secring.gpg')])
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--passphrase', '', '--homedir', GPGDIR,
|
||||
'--import', path.join(RNPDIR, 'pubring.gpg'),
|
||||
path.join(RNPDIR, 'secring.gpg')])
|
||||
|
||||
# Generating small file for tests
|
||||
SMALLSIZE = 3312;
|
||||
st = 'lorem ipsum dol ' * (SMALLSIZE/16)
|
||||
SMALLSIZE = 3312
|
||||
st = 'lorem ipsum dol ' * (SMALLSIZE//16+1)
|
||||
with open(path.join(WORKDIR, SMALLFILE), 'w+') as small_file:
|
||||
small_file.write(st)
|
||||
|
||||
# Generating large file for tests
|
||||
print 'Generating large file of size {}'.format(size_to_readable(LARGESIZE))
|
||||
print('Generating large file of size {}'.format(size_to_readable(LARGESIZE)))
|
||||
|
||||
st = '0123456789ABCDEF' * (1024/16)
|
||||
st = '0123456789ABCDEF' * (1024//16)
|
||||
with open(path.join(WORKDIR, LARGEFILE), 'w') as fd:
|
||||
for i in range(0, LARGESIZE / 1024 - 1):
|
||||
for i in range(0, LARGESIZE // 1024):
|
||||
fd.write(st)
|
||||
|
||||
def run_iterated(iterations, func, src, dst, *args):
|
||||
|
@ -96,7 +99,8 @@ def run_iterated(iterations, func, src, dst, *args):
|
|||
return res
|
||||
|
||||
def rnp_symencrypt_file(src, dst, cipher, zlevel = 6, zalgo = 'zip', armor = False):
|
||||
params = ['--homedir', RNPDIR, '--password', PASSWORD, '--cipher', cipher, '-z', str(zlevel), '--' + zalgo, '-c', src, '--output', dst]
|
||||
params = ['--homedir', RNPDIR, '--password', PASSWORD, '--cipher', cipher,
|
||||
'-z', str(zlevel), '--' + zalgo, '-c', src, '--output', dst]
|
||||
if armor:
|
||||
params += ['--armor']
|
||||
ret = run_proc_fast(RNP, params)
|
||||
|
@ -104,12 +108,15 @@ def rnp_symencrypt_file(src, dst, cipher, zlevel = 6, zalgo = 'zip', armor = Fal
|
|||
raise_err('rnp symmetric encryption failed')
|
||||
|
||||
def rnp_decrypt_file(src, dst):
|
||||
ret = run_proc_fast(RNP, ['--homedir', RNPDIR, '--password', PASSWORD, '--decrypt', src, '--output', dst])
|
||||
ret = run_proc_fast(RNP, ['--homedir', RNPDIR, '--password', PASSWORD, '--decrypt', src,
|
||||
'--output', dst])
|
||||
if ret != 0:
|
||||
raise_err('rnp decryption failed')
|
||||
|
||||
def gpg_symencrypt_file(src, dst, cipher = 'AES', zlevel = 6, zalgo = 1, armor = False):
|
||||
params = ['--homedir', GPGDIR, '-c', '-z', str(zlevel), '--s2k-count', '524288', '--compress-algo', str(zalgo), '--batch', '--passphrase', PASSWORD, '--cipher-algo', cipher, '--output', dst, src]
|
||||
params = ['--homedir', GPGDIR, '-c', '-z', str(zlevel), '--s2k-count', '524288',
|
||||
'--compress-algo', str(zalgo), '--batch', '--passphrase', PASSWORD,
|
||||
'--cipher-algo', cipher, '--output', dst, src]
|
||||
if armor:
|
||||
params.insert(2, '--armor')
|
||||
ret = run_proc_fast(GPG, params)
|
||||
|
@ -117,7 +124,9 @@ def gpg_symencrypt_file(src, dst, cipher = 'AES', zlevel = 6, zalgo = 1, armor =
|
|||
raise_err('gpg symmetric encryption failed for cipher ' + cipher)
|
||||
|
||||
def gpg_decrypt_file(src, dst, keypass):
|
||||
ret = run_proc_fast(GPG, ['--homedir', GPGDIR, '--pinentry-mode=loopback', '--batch', '--yes', '--passphrase', keypass, '--trust-model', 'always', '-o', dst, '-d', src])
|
||||
ret = run_proc_fast(GPG, ['--homedir', GPGDIR, '--pinentry-mode=loopback', '--batch',
|
||||
'--yes', '--passphrase', keypass, '--trust-model', 'always',
|
||||
'-o', dst, '-d', src])
|
||||
if ret != 0:
|
||||
raise_err('gpg decryption failed')
|
||||
|
||||
|
@ -132,10 +141,12 @@ def print_test_results(fsize, rnptime, gpgtime, operation):
|
|||
|
||||
if rnpruns >= gpgruns:
|
||||
percents = (rnpruns - gpgruns) / gpgruns * 100
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% FASTER then GnuPG ({})'.format(operation, percents, runstr))
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% FASTER then GnuPG ({})'.format(
|
||||
operation, percents, runstr))
|
||||
else:
|
||||
percents = (gpgruns - rnpruns) / gpgruns * 100
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% SLOWER then GnuPG ({})'.format(operation, percents, runstr))
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% SLOWER then GnuPG ({})'.format(
|
||||
operation, percents, runstr))
|
||||
else:
|
||||
rnpspeed = fsize / 1024.0 / 1024.0 / rnptime
|
||||
gpgspeed = fsize / 1024.0 / 1024.0 / gpgtime
|
||||
|
@ -143,16 +154,20 @@ def print_test_results(fsize, rnptime, gpgtime, operation):
|
|||
|
||||
if rnpspeed >= gpgspeed:
|
||||
percents = (rnpspeed - gpgspeed) / gpgspeed * 100
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% FASTER then GnuPG ({})'.format(operation, percents, spdstr))
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% FASTER then GnuPG ({})'.format(
|
||||
operation, percents, spdstr))
|
||||
else:
|
||||
percents = (gpgspeed - rnpspeed) / gpgspeed * 100
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% SLOWER then GnuPG ({})'.format(operation, percents, spdstr))
|
||||
logging.info('{:<30}: RNP is {:>3.0f}% SLOWER then GnuPG ({})'.format(
|
||||
operation, percents, spdstr))
|
||||
|
||||
def get_file_params(filetype):
|
||||
if filetype == 'small':
|
||||
infile, outfile, iterations, fsize = (SMALLFILE, SMALLFILE + '.gpg', SMALL_ITERATIONS, SMALLSIZE)
|
||||
infile, outfile, iterations, fsize = (SMALLFILE, SMALLFILE + '.gpg',
|
||||
SMALL_ITERATIONS, SMALLSIZE)
|
||||
else:
|
||||
infile, outfile, iterations, fsize = (LARGEFILE, LARGEFILE + '.gpg', LARGE_ITERATIONS, LARGESIZE)
|
||||
infile, outfile, iterations, fsize = (LARGEFILE, LARGEFILE + '.gpg',
|
||||
LARGE_ITERATIONS, LARGESIZE)
|
||||
|
||||
infile = path.join(WORKDIR, infile)
|
||||
rnpout = path.join(WORKDIR, outfile + '.rnp')
|
||||
|
@ -172,8 +187,10 @@ class Benchmark(object):
|
|||
'''
|
||||
infile, rnpout, gpgout, iterations, fsize = get_file_params('small')
|
||||
for armor in [False, True]:
|
||||
tmrnp = run_iterated(iterations, rnp_symencrypt_file, infile, rnpout, 'AES128', 0, 'zip', armor)
|
||||
tmgpg = run_iterated(iterations, gpg_symencrypt_file, infile, gpgout, 'AES128', 0, 1, armor)
|
||||
tmrnp = run_iterated(iterations, rnp_symencrypt_file, infile, rnpout,
|
||||
'AES128', 0, 'zip', armor)
|
||||
tmgpg = run_iterated(iterations, gpg_symencrypt_file, infile, gpgout,
|
||||
'AES128', 0, 1, armor)
|
||||
testname = 'ENCRYPT-SMALL-{}'.format('ARMOR' if armor else 'BINARY')
|
||||
print_test_results(fsize, tmrnp, tmgpg, testname)
|
||||
|
||||
|
@ -183,8 +200,10 @@ class Benchmark(object):
|
|||
'''
|
||||
infile, rnpout, gpgout, iterations, fsize = get_file_params('large')
|
||||
for cipher in ['AES128', 'AES192', 'AES256', 'TWOFISH', 'BLOWFISH', 'CAST5', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256']:
|
||||
tmrnp = run_iterated(iterations, rnp_symencrypt_file, infile, rnpout, cipher, 0, 'zip', False)
|
||||
tmgpg = run_iterated(iterations, gpg_symencrypt_file, infile, gpgout, cipher, 0, 1, False)
|
||||
tmrnp = run_iterated(iterations, rnp_symencrypt_file, infile, rnpout,
|
||||
cipher, 0, 'zip', False)
|
||||
tmgpg = run_iterated(iterations, gpg_symencrypt_file, infile, gpgout,
|
||||
cipher, 0, 1, False)
|
||||
testname = 'ENCRYPT-{}-BINARY'.format(cipher)
|
||||
print_test_results(fsize, tmrnp, tmgpg, testname)
|
||||
|
||||
|
@ -193,7 +212,8 @@ class Benchmark(object):
|
|||
Large file armored encryption
|
||||
'''
|
||||
infile, rnpout, gpgout, iterations, fsize = get_file_params('large')
|
||||
tmrnp = run_iterated(iterations, rnp_symencrypt_file, infile, rnpout, 'AES128', 0, 'zip', True)
|
||||
tmrnp = run_iterated(iterations, rnp_symencrypt_file, infile, rnpout,
|
||||
'AES128', 0, 'zip', True)
|
||||
tmgpg = run_iterated(iterations, gpg_symencrypt_file, infile, gpgout, 'AES128', 0, 1, True)
|
||||
print_test_results(fsize, tmrnp, tmgpg, 'ENCRYPT-LARGE-ARMOR')
|
||||
|
||||
|
@ -217,7 +237,8 @@ class Benchmark(object):
|
|||
'''
|
||||
infile, rnpout, gpgout, iterations, fsize = get_file_params('large')
|
||||
inenc = infile + '.enc'
|
||||
for cipher in ['AES128', 'AES192', 'AES256', 'TWOFISH', 'BLOWFISH', 'CAST5', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256']:
|
||||
for cipher in ['AES128', 'AES192', 'AES256', 'TWOFISH', 'BLOWFISH', 'CAST5',
|
||||
'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256']:
|
||||
gpg_symencrypt_file(infile, inenc, cipher, 0, 1, False)
|
||||
tmrnp = run_iterated(iterations, rnp_decrypt_file, inenc, rnpout)
|
||||
tmgpg = run_iterated(iterations, gpg_decrypt_file, inenc, gpgout, PASSWORD)
|
||||
|
@ -266,11 +287,14 @@ if __name__ == '__main__':
|
|||
help="Name of the comma-separated benchmarks to run", metavar="benchmarks")
|
||||
parser.add_argument("-w", "--workdir", dest="workdir",
|
||||
help="Working directory to use", metavar="workdir")
|
||||
parser.add_argument("-l", "--list", help="Print list of available benchmarks and exit", action="store_true")
|
||||
parser.add_argument("-l", "--list", help="Print list of available benchmarks and exit",
|
||||
action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
# get list of benchamrks to run
|
||||
bench_methods = [ x[0] for x in inspect.getmembers(Benchmark,predicate=inspect.ismethod) if not x[0].startswith("_") ]
|
||||
bench_methods = [ x[0] for x in inspect.getmembers(Benchmark,
|
||||
predicate=lambda x: inspect.ismethod(x) or inspect.isfunction(x))]
|
||||
print(bench_methods)
|
||||
|
||||
if args.list:
|
||||
for name in bench_methods:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python
|
||||
|
||||
import itertools
|
||||
import logging
|
||||
|
@ -124,9 +124,11 @@ r'new key revocations: 1.*$'
|
|||
|
||||
RNP_TO_GPG_ZALGS = { 'zip' : '1', 'zlib' : '2', 'bzip2' : '3' }
|
||||
# These are mostly identical
|
||||
RNP_TO_GPG_CIPHERS = {'AES' : 'aes128', 'AES192' : 'aes192', 'AES256' : 'aes256', 'TWOFISH' : 'twofish',
|
||||
'CAMELLIA128' : 'camellia128', 'CAMELLIA192' : 'camellia192', 'CAMELLIA256' : 'camellia256',
|
||||
'IDEA' : 'idea', '3DES' : '3des', 'CAST5' : 'cast5', 'BLOWFISH' : 'blowfish'}
|
||||
RNP_TO_GPG_CIPHERS = {'AES' : 'aes128', 'AES192' : 'aes192', 'AES256' : 'aes256',
|
||||
'TWOFISH' : 'twofish', 'CAMELLIA128' : 'camellia128',
|
||||
'CAMELLIA192' : 'camellia192', 'CAMELLIA256' : 'camellia256',
|
||||
'IDEA' : 'idea', '3DES' : '3des', 'CAST5' : 'cast5',
|
||||
'BLOWFISH' : 'blowfish'}
|
||||
|
||||
def check_packets(fname, regexp):
|
||||
ret, output, err = run_proc(GPG, ['--list-packets', path_for_gpg(fname)])
|
||||
|
@ -143,7 +145,7 @@ def check_packets(fname, regexp):
|
|||
|
||||
def clear_keyrings():
|
||||
shutil.rmtree(RNPDIR, ignore_errors=True)
|
||||
os.mkdir(RNPDIR, 0700)
|
||||
os.mkdir(RNPDIR, 0o700)
|
||||
|
||||
run_proc(GPGCONF, ['--homedir', GPGHOME, '--kill', 'gpg-agent'])
|
||||
while os.path.isdir(GPGDIR):
|
||||
|
@ -151,7 +153,7 @@ def clear_keyrings():
|
|||
shutil.rmtree(GPGDIR)
|
||||
except:
|
||||
time.sleep(0.1)
|
||||
os.mkdir(GPGDIR, 0700)
|
||||
os.mkdir(GPGDIR, 0o700)
|
||||
|
||||
def compare_files(src, dst, message):
|
||||
if file_text(src) != file_text(dst):
|
||||
|
@ -201,8 +203,8 @@ def clear_workfiles():
|
|||
|
||||
def rnp_genkey_rsa(userid, bits=2048, pswd=PASSWORD):
|
||||
pipe = pswd_pipe(pswd)
|
||||
ret, _, err = run_proc(RNPK, ['--numbits', str(bits), '--homedir',
|
||||
RNPDIR, '--pass-fd', str(pipe), '--userid', userid, '--generate-key'])
|
||||
ret, _, err = run_proc(RNPK, ['--numbits', str(bits), '--homedir', RNPDIR, '--pass-fd',
|
||||
str(pipe), '--userid', userid, '--generate-key'])
|
||||
os.close(pipe)
|
||||
if ret != 0:
|
||||
raise_err('rsa key generation failed', err)
|
||||
|
@ -221,7 +223,8 @@ def rnp_params_insert_aead(params, pos, aead):
|
|||
if len(aead) > 1 and aead[1] != None:
|
||||
params[pos + 1:pos + 1] = ['--aead-chunk-bits=' + str(aead[1])]
|
||||
|
||||
def rnp_encrypt_file_ex(src, dst, recipients=None, passwords=None, aead=None, cipher=None, z=None, armor=False):
|
||||
def rnp_encrypt_file_ex(src, dst, recipients=None, passwords=None, aead=None, cipher=None,
|
||||
z=None, armor=False):
|
||||
params = ['--homedir', RNPDIR, src, '--output', dst]
|
||||
# Recipients. None disables PK encryption, [] to use default key. Otheriwse list of ids.
|
||||
if recipients != None:
|
||||
|
@ -247,7 +250,8 @@ def rnp_encrypt_file_ex(src, dst, recipients=None, passwords=None, aead=None, ci
|
|||
if ret != 0:
|
||||
raise_err('rnp encryption failed', err)
|
||||
|
||||
def rnp_encrypt_and_sign_file(src, dst, recipients, encrpswd, signers, signpswd, aead=None, cipher=None, z=None, armor=False):
|
||||
def rnp_encrypt_and_sign_file(src, dst, recipients, encrpswd, signers, signpswd,
|
||||
aead=None, cipher=None, z=None, armor=False):
|
||||
params = ['--homedir', RNPDIR, '--sign', '--encrypt', src, '--output', dst]
|
||||
pipe = pswd_pipe('\n'.join(encrpswd + signpswd))
|
||||
params[2:2] = ['--pass-fd', str(pipe)]
|
||||
|
@ -374,8 +378,9 @@ def gpg_import_secring(kpath=None, password = PASSWORD):
|
|||
|
||||
|
||||
def gpg_export_secret_key(userid, password, keyfile):
|
||||
ret, _, err = run_proc(GPG, ['--batch', '--homedir', GPGHOME, '--pinentry-mode=loopback', '--yes',
|
||||
'--passphrase', password, '--output', path_for_gpg(keyfile), '--export-secret-key', userid])
|
||||
ret, _, err = run_proc(GPG, ['--batch', '--homedir', GPGHOME, '--pinentry-mode=loopback',
|
||||
'--yes', '--passphrase', password, '--output',
|
||||
path_for_gpg(keyfile), '--export-secret-key', userid])
|
||||
|
||||
if ret != 0:
|
||||
raise_err('gpg secret key export failed', err)
|
||||
|
@ -390,7 +395,8 @@ def gpg_params_insert_z(params, pos, z):
|
|||
def gpg_encrypt_file(src, dst, cipher=None, z=None, armor=False):
|
||||
src = path_for_gpg(src)
|
||||
dst = path_for_gpg(dst)
|
||||
params = ['--homedir', GPGHOME, '-e', '-r', KEY_ENCRYPT, '--batch', '--trust-model', 'always', '--output', dst, src]
|
||||
params = ['--homedir', GPGHOME, '-e', '-r', KEY_ENCRYPT, '--batch',
|
||||
'--trust-model', 'always', '--output', dst, src]
|
||||
if z: gpg_params_insert_z(params, 3, z)
|
||||
if cipher: params[3:3] = ['--cipher-algo', RNP_TO_GPG_CIPHERS[cipher]]
|
||||
if armor: params[2:2] = ['--armor']
|
||||
|
@ -403,7 +409,8 @@ def gpg_encrypt_file(src, dst, cipher=None, z=None, armor=False):
|
|||
def gpg_symencrypt_file(src, dst, cipher=None, z=None, armor=False, aead=None):
|
||||
src = path_for_gpg(src)
|
||||
dst = path_for_gpg(dst)
|
||||
params = ['--homedir', GPGHOME, '-c', '--s2k-count', '65536', '--batch', '--passphrase', PASSWORD, '--output', dst, src]
|
||||
params = ['--homedir', GPGHOME, '-c', '--s2k-count', '65536', '--batch',
|
||||
'--passphrase', PASSWORD, '--output', dst, src]
|
||||
if z: gpg_params_insert_z(params, 3, z)
|
||||
if cipher: params[3:3] = ['--cipher-algo', RNP_TO_GPG_CIPHERS[cipher]]
|
||||
if armor: params[2:2] = ['--armor']
|
||||
|
@ -423,7 +430,8 @@ def gpg_decrypt_file(src, dst, keypass):
|
|||
src = path_for_gpg(src)
|
||||
dst = path_for_gpg(dst)
|
||||
ret, out, err = run_proc(GPG, ['--homedir', GPGHOME, '--pinentry-mode=loopback', '--batch',
|
||||
'--yes', '--passphrase', keypass, '--trust-model', 'always', '-o', dst, '-d', src])
|
||||
'--yes', '--passphrase', keypass, '--trust-model',
|
||||
'always', '-o', dst, '-d', src])
|
||||
if ret != 0:
|
||||
raise_err('gpg decryption failed', err)
|
||||
|
||||
|
@ -446,8 +454,8 @@ def gpg_verify_file(src, dst, signer=None):
|
|||
def gpg_verify_detached(src, sig, signer=None):
|
||||
src = path_for_gpg(src)
|
||||
sig = path_for_gpg(sig)
|
||||
ret, _, err = run_proc(GPG, ['--homedir', GPGHOME, '--batch',
|
||||
'--yes', '--trust-model', 'always', '--verify', sig, src])
|
||||
ret, _, err = run_proc(GPG, ['--homedir', GPGHOME, '--batch', '--yes', '--trust-model',
|
||||
'always', '--verify', sig, src])
|
||||
if ret != 0:
|
||||
raise_err('gpg detached verification failed', err)
|
||||
# Check GPG output
|
||||
|
@ -476,7 +484,8 @@ def gpg_sign_file(src, dst, signer, z=None, armor=False):
|
|||
src = path_for_gpg(src)
|
||||
dst = path_for_gpg(dst)
|
||||
params = ['--homedir', GPGHOME, '--pinentry-mode=loopback', '--batch', '--yes',
|
||||
'--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer, '-o', dst, '-s', src]
|
||||
'--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer, '-o',
|
||||
dst, '-s', src]
|
||||
if z: gpg_params_insert_z(params, 3, z)
|
||||
if armor: params.insert(2, '--armor')
|
||||
ret, _, err = run_proc(GPG, params)
|
||||
|
@ -487,7 +496,8 @@ def gpg_sign_file(src, dst, signer, z=None, armor=False):
|
|||
def gpg_sign_detached(src, signer, armor=False):
|
||||
src = path_for_gpg(src)
|
||||
params = ['--homedir', GPGHOME, '--pinentry-mode=loopback', '--batch', '--yes',
|
||||
'--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer, '--detach-sign', src]
|
||||
'--passphrase', PASSWORD, '--trust-model', 'always', '-u', signer,
|
||||
'--detach-sign', src]
|
||||
if armor: params.insert(2, '--armor')
|
||||
ret, _, err = run_proc(GPG, params)
|
||||
if ret != 0:
|
||||
|
@ -726,13 +736,13 @@ def setup(loglvl):
|
|||
RNPDIR = path.join(WORKDIR, '.rnp')
|
||||
RNP = os.getenv('RNP_TESTS_RNP_PATH') or 'rnp'
|
||||
RNPK = os.getenv('RNP_TESTS_RNPKEYS_PATH') or 'rnpkeys'
|
||||
os.mkdir(RNPDIR, 0700)
|
||||
os.mkdir(RNPDIR, 0o700)
|
||||
|
||||
GPGDIR = path.join(WORKDIR, '.gpg')
|
||||
GPGHOME = path_for_gpg(GPGDIR) if is_windows() else GPGDIR
|
||||
GPGHOME = path_for_gpg(GPGDIR) if is_windows() else GPGDIR
|
||||
GPG = os.getenv('RNP_TESTS_GPG_PATH') or find_utility('gpg')
|
||||
GPGCONF = os.getenv('RNP_TESTS_GPGCONF_PATH') or find_utility('gpgconf')
|
||||
os.mkdir(GPGDIR, 0700)
|
||||
os.mkdir(GPGDIR, 0o700)
|
||||
|
||||
def data_path(subpath):
|
||||
''' Constructs path to the tests data file/dir'''
|
||||
|
@ -740,7 +750,8 @@ def data_path(subpath):
|
|||
|
||||
def key_path(file_base_name, secret):
|
||||
''' Constructs path to the .gpg file'''
|
||||
path=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/cli_EncryptSign', file_base_name)
|
||||
path=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/cli_EncryptSign',
|
||||
file_base_name)
|
||||
return ''.join([path, '-sec' if secret else '', '.gpg'])
|
||||
|
||||
class TestIdMixin(object):
|
||||
|
@ -806,8 +817,8 @@ class Keystore(unittest.TestCase):
|
|||
userid = str(bits) + '@rnptest'
|
||||
# Open pipe for password
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
params = params + ['--homedir', RNPDIR, '--pass-fd',
|
||||
str(pipe), '--userid', userid, '--generate-key']
|
||||
params = params + ['--homedir', RNPDIR, '--pass-fd', str(pipe),
|
||||
'--userid', userid, '--generate-key']
|
||||
# Run key generation
|
||||
ret, out, err = run_proc(RNPK, params)
|
||||
os.close(pipe)
|
||||
|
@ -836,9 +847,10 @@ class Keystore(unittest.TestCase):
|
|||
if not match.group(1) == str(bits):
|
||||
raise_err('wrong key bits in list')
|
||||
# Import key to the gnupg
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--passphrase', PASSWORD, '--homedir', GPGHOME,
|
||||
'--import', path_for_gpg(path.join(RNPDIR, 'pubring.gpg')),
|
||||
path_for_gpg(path.join(RNPDIR, 'secring.gpg'))])
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--passphrase', PASSWORD, '--homedir',
|
||||
GPGHOME, '--import',
|
||||
path_for_gpg(path.join(RNPDIR, 'pubring.gpg')),
|
||||
path_for_gpg(path.join(RNPDIR, 'secring.gpg'))])
|
||||
if ret != 0:
|
||||
raise_err('gpg key import failed', err)
|
||||
# Cleanup and return
|
||||
|
@ -858,7 +870,8 @@ class Keystore(unittest.TestCase):
|
|||
pipe = pswd_pipe(PASSWORD)
|
||||
userid = str(i) + '@rnp-multiple'
|
||||
ret, out, err = run_proc(RNPK, ['--numbits', '2048', '--homedir', RNPDIR,
|
||||
'--pass-fd', str(pipe), '--userid', userid, '--generate-key'])
|
||||
'--pass-fd', str(pipe), '--userid', userid,
|
||||
'--generate-key'])
|
||||
os.close(pipe)
|
||||
if ret != 0:
|
||||
raise_err('key generation failed', err)
|
||||
|
@ -889,8 +902,8 @@ class Keystore(unittest.TestCase):
|
|||
Generate key with GnuPG and import it to rnp
|
||||
'''
|
||||
# Generate key in GnuPG
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--homedir', GPGHOME,
|
||||
'--passphrase', '', '--quick-generate-key', 'rsakey@gpg', 'rsa'])
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--homedir', GPGHOME, '--passphrase',
|
||||
'', '--quick-generate-key', 'rsakey@gpg', 'rsa'])
|
||||
if ret != 0:
|
||||
raise_err('gpg key generation failed, error ' + str(ret) , err)
|
||||
# Getting fingerprint of the generated key
|
||||
|
@ -936,7 +949,8 @@ class Keystore(unittest.TestCase):
|
|||
# Open pipe for password
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
# Run key generation
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', 'rsakey@rnp', '--generate-key'])
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--pass-fd', str(pipe),
|
||||
'--userid', 'rsakey@rnp', '--generate-key'])
|
||||
os.close(pipe)
|
||||
if ret != 0: raise_err('key generation failed', err)
|
||||
# Export key
|
||||
|
@ -946,7 +960,8 @@ class Keystore(unittest.TestCase):
|
|||
with open(pubpath, 'w+') as f:
|
||||
f.write(out)
|
||||
# Import key with GPG
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--homedir', GPGHOME, '--import', path_for_gpg(pubpath)])
|
||||
ret, out, err = run_proc(GPG, ['--batch', '--homedir', GPGHOME, '--import',
|
||||
path_for_gpg(pubpath)])
|
||||
if ret != 0: raise_err('gpg : public key import failed', err)
|
||||
|
||||
def test_generate_to_kbx(self):
|
||||
|
@ -957,8 +972,9 @@ class Keystore(unittest.TestCase):
|
|||
pipe = pswd_pipe(PASSWORD)
|
||||
kbx_userid_tracker = 'kbx_userid_tracker@rnp'
|
||||
# Run key generation
|
||||
ret, out, err = run_proc(RNPK, ['--gen-key', '--keystore-format', 'GPG21', '--userid', kbx_userid_tracker,
|
||||
'--homedir', RNPDIR, '--pass-fd', str(pipe)])
|
||||
ret, out, err = run_proc(RNPK, ['--gen-key', '--keystore-format', 'GPG21',
|
||||
'--userid', kbx_userid_tracker, '--homedir',
|
||||
RNPDIR, '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if ret != 0: raise_err('key generation failed', err)
|
||||
# Read KBX with GPG
|
||||
|
@ -970,12 +986,13 @@ class Keystore(unittest.TestCase):
|
|||
def test_generate_protection_pass_fd(self):
|
||||
'''
|
||||
Generate key with RNP, using the --pass-fd parameter, and make sure key is encrypted
|
||||
'''
|
||||
'''
|
||||
clear_keyrings()
|
||||
# Open pipe for password
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
# Run key generation
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--pass-fd', str(pipe), '--userid', 'enc@rnp', '--generate-key'])
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--pass-fd', str(pipe),
|
||||
'--userid', 'enc@rnp', '--generate-key'])
|
||||
os.close(pipe)
|
||||
if ret != 0:
|
||||
raise_err('key generation failed', err)
|
||||
|
@ -1200,6 +1217,90 @@ class Keystore(unittest.TestCase):
|
|||
raise_err('userids from rnpkeys and gpg don\'t match')
|
||||
clear_keyrings()
|
||||
|
||||
def test_key_revoke(self):
|
||||
clear_keyrings()
|
||||
# Import Alice's public key and be unable to revoke
|
||||
ret, _, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--import', data_path('test_key_validity/alice-pub.asc')])
|
||||
if ret != 0:
|
||||
raise_err('Alice key import failed')
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke-key', 'alice'])
|
||||
if (ret == 0) or (len(out) > 0) or not re.match(r'(?s)^.*Revoker secret key not found.*Failed to revoke a key.*', err):
|
||||
raise_err('Wrong revocation output')
|
||||
# Import Alice's secret key and subkey
|
||||
ret, _, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--import', data_path('test_key_validity/alice-sub-sec.pgp')])
|
||||
if ret != 0:
|
||||
raise_err('Alice secret key import failed')
|
||||
# Attempt to revoke without specifying a key
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if (ret == 0) or (len(out) > 0) or not re.match(r'(?s)^.*You need to specify key or subkey to revoke.*', err):
|
||||
raise_err('Wrong revocation output', err)
|
||||
# Attempt to revoke unknown key
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', 'basil'])
|
||||
if (ret == 0) or (len(out) > 0) or not re.match(r'(?s)^.*Key matching \'basil\' not found.*', err):
|
||||
raise_err('Wrong revocation output', err)
|
||||
# Attempt to revoke with too broad search
|
||||
ret, _, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--import', data_path('test_key_validity/basil-sec.asc')])
|
||||
if ret != 0:
|
||||
raise_err('Basil secret key import failed')
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', 'rnp', '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if not re.match(r'(?s)^.*Ambiguous input: too many keys found for \'rnp\'.*', err):
|
||||
raise_err('Wrong revocation export output', err)
|
||||
# Revoke a primary key
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', '0451409669FFDE3C', '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if (ret != 0):
|
||||
raise_err('Failed to revoke alice key')
|
||||
ret, out, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys'])
|
||||
if (ret != 0) or not re.match(r'(?s)^.*pub.*0451409669ffde3c.*\[REVOKED\].*73edcc9119afc8e2dbbdcde50451409669ffde3c.*', out):
|
||||
raise_err('Wrong revoked key listing', out)
|
||||
# Try again without the '--force' parameter
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', '0451409669FFDE3C', '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if (ret == 0):
|
||||
raise_err('Failed to fail to revoke alice key')
|
||||
if (len(out) > 0) or not re.match(r'(?s)^.*Error: key \'0451409669FFDE3C\' is revoked already. Use --force to generate another revocation signature.*', err):
|
||||
raise_err('Wrong revocation output', err)
|
||||
# Try again with --force parameter
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', '0451409669FFDE3C', '--pass-fd', str(pipe), "--force", "--rev-type", "3", "--rev-reason", "Custom"])
|
||||
os.close(pipe)
|
||||
if (ret != 0):
|
||||
raise_err('Failed to revoke alice key')
|
||||
ret, out, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys'])
|
||||
if (ret != 0) or not re.match(r'(?s)^.*pub.*0451409669ffde3c.*\[REVOKED\].*73edcc9119afc8e2dbbdcde50451409669ffde3c.*', out):
|
||||
raise_err('Wrong revoked key listing', out)
|
||||
# Revoke a subkey
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', 'DD23CEB7FEBEFF17', '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if (ret != 0):
|
||||
raise_err('Failed to revoke alice subkey')
|
||||
ret, out, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys'])
|
||||
if (ret != 0) or not re.match(r'(?s)^.*sub.*dd23ceb7febeff17.*\[REVOKED\].*a4bbb77370217bca2307ad0ddd23ceb7febeff17.*', out):
|
||||
raise_err('Wrong revoked subkey listing', out)
|
||||
# Try again without the '--force' parameter
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', 'DD23CEB7FEBEFF17', '--pass-fd', str(pipe)])
|
||||
os.close(pipe)
|
||||
if (ret == 0):
|
||||
raise_err('Failed to fail to revoke alice subkey')
|
||||
if (len(out) > 0) or not re.match(r'(?s)^.*Error: key \'DD23CEB7FEBEFF17\' is revoked already. Use --force to generate another revocation signature.*', err):
|
||||
raise_err('Wrong revocation output', err)
|
||||
# Try again with --force parameter
|
||||
pipe = pswd_pipe(PASSWORD)
|
||||
ret, out, err = run_proc(RNPK, ['--homedir', RNPDIR, '--revoke', 'DD23CEB7FEBEFF17', '--pass-fd', str(pipe), "--force", "--rev-type", "2", "--rev-reason", "Other"])
|
||||
os.close(pipe)
|
||||
if (ret != 0):
|
||||
raise_err('Failed to revoke alice subkey')
|
||||
ret, out, _ = run_proc(RNPK, ['--homedir', RNPDIR, '--list-keys'])
|
||||
if (ret != 0) or not re.match(r'(?s)^.*sub.*dd23ceb7febeff17.*\[REVOKED\].*a4bbb77370217bca2307ad0ddd23ceb7febeff17.*', out):
|
||||
raise_err('Wrong revoked subkey listing', out)
|
||||
|
||||
class Misc(unittest.TestCase):
|
||||
|
||||
|
@ -1222,7 +1323,9 @@ class Misc(unittest.TestCase):
|
|||
# Generate random file of required size
|
||||
random_text(src, 64000)
|
||||
# Encrypt cleartext file with GPG
|
||||
params = ['--homedir', GPGHOME, '-c', '-z', '0', '--disable-mdc', '--s2k-count', '65536', '--batch', '--passphrase', PASSWORD, '--output', path_for_gpg(dst), path_for_gpg(src)]
|
||||
params = ['--homedir', GPGHOME, '-c', '-z', '0', '--disable-mdc', '--s2k-count',
|
||||
'65536', '--batch', '--passphrase', PASSWORD, '--output',
|
||||
path_for_gpg(dst), path_for_gpg(src)]
|
||||
ret, _, err = run_proc(GPG, params)
|
||||
if ret != 0:
|
||||
raise_err('gpg symmetric encryption failed', err)
|
||||
|
@ -1234,14 +1337,15 @@ class Misc(unittest.TestCase):
|
|||
src, dst, dec = reg_workfiles('cleartext', '.txt', '.gpg', '.rnp')
|
||||
random_text(src, 64000)
|
||||
|
||||
ciphers = ['AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128',
|
||||
'CAMELLIA192', 'CAMELLIA256', 'IDEA', '3DES', 'CAST5', 'BLOWFISH']
|
||||
ciphers = ['AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192',
|
||||
'CAMELLIA256', 'IDEA', '3DES', 'CAST5', 'BLOWFISH']
|
||||
hashes = ['SHA1', 'RIPEMD160', 'SHA256', 'SHA384', 'SHA512', 'SHA224']
|
||||
s2kmodes = [0, 1, 3]
|
||||
|
||||
def rnp_encryption_s2k_gpg(cipher, hash_alg, s2k=None, iterations=None):
|
||||
params = ['--homedir', GPGHOME, '-c', '--s2k-cipher-algo', cipher, '--s2k-digest-algo',
|
||||
hash_alg, '--batch', '--passphrase', PASSWORD, '--output', dst, src]
|
||||
params = ['--homedir', GPGHOME, '-c', '--s2k-cipher-algo', cipher,
|
||||
'--s2k-digest-algo', hash_alg, '--batch', '--passphrase', PASSWORD,
|
||||
'--output', dst, src]
|
||||
|
||||
if s2k is not None:
|
||||
params.insert(7, '--s2k-mode')
|
||||
|
@ -1263,8 +1367,10 @@ class Misc(unittest.TestCase):
|
|||
i % len(hashes)], s2kmodes[i % len(s2kmodes)])
|
||||
|
||||
def test_armor(self):
|
||||
src_beg, dst_beg, dst_mid, dst_fin = reg_workfiles('beg','.src','.dst', '.mid.dst', '.fin.dst')
|
||||
armor_types = [('msg', 'MESSAGE'), ('pubkey', 'PUBLIC KEY BLOCK'), ('seckey', 'PRIVATE KEY BLOCK'), ('sign', 'SIGNATURE')]
|
||||
src_beg, dst_beg, dst_mid, dst_fin = reg_workfiles('beg', '.src', '.dst',
|
||||
'.mid.dst', '.fin.dst')
|
||||
armor_types = [('msg', 'MESSAGE'), ('pubkey', 'PUBLIC KEY BLOCK'),
|
||||
('seckey', 'PRIVATE KEY BLOCK'), ('sign', 'SIGNATURE')]
|
||||
|
||||
for data_type, header in armor_types:
|
||||
random_text(src_beg, 1000)
|
||||
|
@ -1293,7 +1399,8 @@ class Misc(unittest.TestCase):
|
|||
compare_file(path + 'keyring_1_list_sigs', out, 'keyring 1 sig listing failed')
|
||||
_, out, _ = run_proc(RNPK, ['--home', data_path('keyrings/1'), '--list-keys', '--secret'])
|
||||
compare_file(path + 'keyring_1_list_keys_sec', out, 'keyring 1 sec key listing failed')
|
||||
_, out, _ = run_proc(RNPK, ['--home', data_path('keyrings/1'), '--list-keys', '--secret', '--with-sigs'])
|
||||
_, out, _ = run_proc(RNPK, ['--home', data_path('keyrings/1'), '--list-keys',
|
||||
'--secret', '--with-sigs'])
|
||||
compare_file(path + 'keyring_1_list_sigs_sec', out, 'keyring 1 sec sig listing failed')
|
||||
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/2'), '--list-keys'])
|
||||
|
@ -1311,21 +1418,30 @@ class Misc(unittest.TestCase):
|
|||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/5'), '-l', '--with-sigs'])
|
||||
compare_file(path + 'keyring_5_list_sigs', out, 'keyring 5 sig listing failed')
|
||||
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '--list-keys'])
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'),
|
||||
'--list-keys'])
|
||||
compare_file(path + 'test_stream_key_load_keys', out, 'g10 keyring key listing failed')
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '-l', '--with-sigs'])
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'),
|
||||
'-l', '--with-sigs'])
|
||||
compare_file(path + 'test_stream_key_load_sigs', out, 'g10 keyring sig listing failed')
|
||||
# Below are disabled until we have some kind of sorting which doesn't depend on readdir order
|
||||
#_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '-l', '--secret'])
|
||||
#compare_file(path + 'test_stream_key_load_keys_sec', out, 'g10 sec keyring key listing failed')
|
||||
#_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '-l', '--secret', '--with-sigs'])
|
||||
#compare_file(path + 'test_stream_key_load_sigs_sec', out, 'g10 sec keyring sig listing failed')
|
||||
# Below are disabled until we have some kind of sorting which doesn't depend on
|
||||
# readdir order
|
||||
#_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'),
|
||||
# '-l', '--secret'])
|
||||
#compare_file(path + 'test_stream_key_load_keys_sec', out,
|
||||
# 'g10 sec keyring key listing failed')
|
||||
#_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'),
|
||||
# '-l', '--secret', '--with-sigs'])
|
||||
#compare_file(path + 'test_stream_key_load_sigs_sec', out,
|
||||
# 'g10 sec keyring sig listing failed')
|
||||
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '-l', '2fcadf05ffa501bb'])
|
||||
compare_file(path + 'getkey_2fcadf05ffa501bb', out, 'list key 2fcadf05ffa501bb failed')
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '-l', '--with-sigs', '2fcadf05ffa501bb'])
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '-l',
|
||||
'--with-sigs', '2fcadf05ffa501bb'])
|
||||
compare_file(path + 'getkey_2fcadf05ffa501bb_sig', out, 'list sig 2fcadf05ffa501bb failed')
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '-l', '--secret', '2fcadf05ffa501bb'])
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '-l',
|
||||
'--secret', '2fcadf05ffa501bb'])
|
||||
compare_file(path + 'getkey_2fcadf05ffa501bb_sec', out, 'list sec 2fcadf05ffa501bb failed')
|
||||
|
||||
_, out, err = run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '-l', '00000000'])
|
||||
|
@ -1334,10 +1450,13 @@ class Misc(unittest.TestCase):
|
|||
compare_file(path + 'getkey_zzzzzzzz', out, 'list key zzzzzzzz failed')
|
||||
|
||||
def test_rnpkeys_g10_list_order(self):
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '--list-keys'])
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path(
|
||||
'test_stream_key_load/g10'), '--list-keys'])
|
||||
compare_file(data_path('test_cli_rnpkeys/g10_list_keys'), out, 'g10 key listing failed')
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '--secret', '--list-keys'])
|
||||
compare_file(data_path('test_cli_rnpkeys/g10_list_keys_sec'), out, 'g10 secret key listing failed')
|
||||
_, out, _ = run_proc(RNPK, ['--homedir', data_path(
|
||||
'test_stream_key_load/g10'), '--secret', '--list-keys'])
|
||||
compare_file(data_path('test_cli_rnpkeys/g10_list_keys_sec'), out,
|
||||
'g10 secret key listing failed')
|
||||
return
|
||||
|
||||
def test_rnpkeys_g10_def_key(self):
|
||||
|
@ -1352,7 +1471,8 @@ class Misc(unittest.TestCase):
|
|||
src, dst = reg_workfiles('cleartext', '.txt', '.rnp')
|
||||
random_text(src, 1000)
|
||||
# Sign file with rnp using the default g10 key
|
||||
params = ['--homedir', data_path('test_cli_g10_defkey/g10'), '--password', PASSWORD, '--output', dst, '-s', src]
|
||||
params = ['--homedir', data_path('test_cli_g10_defkey/g10'),
|
||||
'--password', PASSWORD, '--output', dst, '-s', src]
|
||||
ret, _, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('rnp signing failed', err)
|
||||
|
@ -1365,7 +1485,7 @@ class Misc(unittest.TestCase):
|
|||
if not match:
|
||||
raise_err('wrong rnp g10 verification output', err)
|
||||
return
|
||||
|
||||
|
||||
def test_large_packet(self):
|
||||
# Verifying large packet file with GnuPG
|
||||
kpath = path_for_gpg(data_path('keyrings/1/pubring.gpg'))
|
||||
|
@ -1398,7 +1518,8 @@ class Misc(unittest.TestCase):
|
|||
mpath = path_for_gpg(data_path('test_partial_length/message.txt.partial-zero-last'))
|
||||
ret, _, err = run_proc(GPG, ['--homedir', GPGHOME, '--keyring', kpath, '--verify', mpath])
|
||||
if ret != 0:
|
||||
raise_err('message in partial packets having 0-size last chunk verification failed', err)
|
||||
raise_err('message in partial packets having 0-size last chunk ' \
|
||||
'verification failed', err)
|
||||
return
|
||||
|
||||
def test_partial_length_largest(self):
|
||||
|
@ -1416,7 +1537,8 @@ class Misc(unittest.TestCase):
|
|||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('packet listing failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_standard.txt'), out, 'standard listing mismatch')
|
||||
compare_file_ex(data_path('test_list_packets/list_standard.txt'), out,
|
||||
'standard listing mismatch')
|
||||
# List packets with mpi values
|
||||
params = ['--mpi', '--list-packets', data_path('test_list_packets/ecc-p256-pub.asc')]
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
|
@ -1428,7 +1550,8 @@ class Misc(unittest.TestCase):
|
|||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('packet listing with grips failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_grips.txt'), out, 'grips listing mismatch')
|
||||
compare_file_ex(data_path('test_list_packets/list_grips.txt'), out,
|
||||
'grips listing mismatch')
|
||||
# List packets with raw packet contents
|
||||
params = ['--list-packets', data_path('test_list_packets/ecc-p256-pub.asc'), '--raw']
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
|
@ -1436,7 +1559,8 @@ class Misc(unittest.TestCase):
|
|||
raise_err('packet listing with raw packets failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_raw.txt'), out, 'raw listing mismatch')
|
||||
# List packets with all options enabled
|
||||
params = ['--list-packets', data_path('test_list_packets/ecc-p256-pub.asc'), '--grips', '--raw', '--mpi']
|
||||
params = ['--list-packets', data_path('test_list_packets/ecc-p256-pub.asc'),
|
||||
'--grips', '--raw', '--mpi']
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('packet listing with all options failed', err)
|
||||
|
@ -1449,36 +1573,45 @@ class Misc(unittest.TestCase):
|
|||
raise_err('json packet listing failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_json.txt'), out, 'json listing mismatch')
|
||||
# List packets with mpi values, JSON output
|
||||
params = ['--json', '--mpi', '--list-packets', data_path('test_list_packets/ecc-p256-pub.asc')]
|
||||
params = ['--json', '--mpi', '--list-packets', data_path(
|
||||
'test_list_packets/ecc-p256-pub.asc')]
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('json mpi packet listing failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_json_mpi.txt'), out, 'json mpi listing mismatch')
|
||||
compare_file_ex(data_path('test_list_packets/list_json_mpi.txt'), out,
|
||||
'json mpi listing mismatch')
|
||||
# List packets with grip/fingerprint values, JSON output
|
||||
params = ['--json', '--grips', '--list-packets', data_path('test_list_packets/ecc-p256-pub.asc')]
|
||||
params = ['--json', '--grips', '--list-packets', data_path(
|
||||
'test_list_packets/ecc-p256-pub.asc')]
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('json grips packet listing failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_json_grips.txt'), out, 'json grips listing mismatch')
|
||||
compare_file_ex(data_path('test_list_packets/list_json_grips.txt'), out,
|
||||
'json grips listing mismatch')
|
||||
# List packets with raw packet values, JSON output
|
||||
params = ['--json', '--raw', '--list-packets', data_path('test_list_packets/ecc-p256-pub.asc')]
|
||||
params = ['--json', '--raw', '--list-packets', data_path(
|
||||
'test_list_packets/ecc-p256-pub.asc')]
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('json raw packet listing failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_json_raw.txt'), out, 'json raw listing mismatch')
|
||||
compare_file_ex(data_path('test_list_packets/list_json_raw.txt'), out,
|
||||
'json raw listing mismatch')
|
||||
# List packets with all values, JSON output
|
||||
params = ['--json', '--raw', '--list-packets', data_path('test_list_packets/ecc-p256-pub.asc'), '--mpi', '--grips']
|
||||
params = ['--json', '--raw', '--list-packets', data_path(
|
||||
'test_list_packets/ecc-p256-pub.asc'), '--mpi', '--grips']
|
||||
ret, out, err = run_proc(RNP, params)
|
||||
if ret != 0:
|
||||
raise_err('json all listing failed', err)
|
||||
compare_file_ex(data_path('test_list_packets/list_json_all.txt'), out, 'json all listing mismatch')
|
||||
compare_file_ex(data_path('test_list_packets/list_json_all.txt'), out,
|
||||
'json all listing mismatch')
|
||||
return
|
||||
|
||||
def test_debug_log(self):
|
||||
run_proc(RNPK, ['--homedir', data_path('keyrings/1'), '--list-keys', '--debug', '--all'])
|
||||
run_proc(RNPK, ['--homedir', data_path('keyrings/2'), '--list-keys', '--debug', '--all'])
|
||||
run_proc(RNPK, ['--homedir', data_path('keyrings/3'), '--list-keys', '--debug', '--all'])
|
||||
run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'), '--list-keys', '--debug', '--all'])
|
||||
run_proc(RNPK, ['--homedir', data_path('test_stream_key_load/g10'),
|
||||
'--list-keys', '--debug', '--all'])
|
||||
return
|
||||
|
||||
def test_pubring_loading(self):
|
||||
|
@ -1513,12 +1646,15 @@ class Encryption(unittest.TestCase):
|
|||
- different hash algorithms where applicable
|
||||
|
||||
TODO:
|
||||
Tests in this test case should be splitted into many algorithm-specific tests (potentially auto generated)
|
||||
Reason being - if you have a problem with BLOWFISH size 1000000, you don't want to wait until everything else gets
|
||||
Tests in this test case should be splitted into many algorithm-specific tests
|
||||
(potentially auto generated)
|
||||
Reason being - if you have a problem with BLOWFISH size 1000000, you don't want
|
||||
to wait until everything else gets
|
||||
tested before your failing BLOWFISH
|
||||
'''
|
||||
# Ciphers list tro try during encryption. None will use default
|
||||
CIPHERS = [None, 'AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256', 'IDEA', '3DES', 'CAST5', 'BLOWFISH']
|
||||
CIPHERS = [None, 'AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192',
|
||||
'CAMELLIA256', 'IDEA', '3DES', 'CAST5', 'BLOWFISH']
|
||||
SIZES = [20, 40, 120, 600, 1000, 5000, 20000, 150000, 1000000]
|
||||
# Compression parameters to try during encryption(s)
|
||||
Z = [[None, 0], ['zip'], ['zlib'], ['bzip2'], [None, 1], [None, 9]]
|
||||
|
@ -1545,7 +1681,8 @@ class Encryption(unittest.TestCase):
|
|||
def tearDown(self):
|
||||
clear_workfiles()
|
||||
|
||||
# Encrypt cleartext file with GPG and decrypt it with RNP, using different ciphers and file sizes
|
||||
# Encrypt cleartext file with GPG and decrypt it with RNP,
|
||||
# using different ciphers and file sizes
|
||||
def test_file_encryption__gpg_to_rnp(self):
|
||||
for size, cipher in zip(Encryption.SIZES_R, Encryption.CIPHERS_R):
|
||||
gpg_to_rnp_encryption(size, cipher)
|
||||
|
@ -1566,14 +1703,17 @@ class Encryption(unittest.TestCase):
|
|||
rnp_sym_encryption_rnp_to_gpg(size, cipher, z)
|
||||
|
||||
def test_sym_encryption__rnp_aead(self):
|
||||
AEAD_C = list_upto(['AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256'], Encryption.RUNS)
|
||||
AEAD_C = list_upto(['AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128',
|
||||
'CAMELLIA192', 'CAMELLIA256'], Encryption.RUNS)
|
||||
AEAD_M = list_upto([None, 'eax', 'ocb'], Encryption.RUNS)
|
||||
AEAD_B = list_upto([None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 24, 30, 40, 50, 56], Encryption.RUNS)
|
||||
AEAD_B = list_upto([None, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18,
|
||||
24, 30, 40, 50, 56], Encryption.RUNS)
|
||||
|
||||
usegpg = gpg_supports_aead()
|
||||
|
||||
# Encrypt and decrypt cleartext using the AEAD
|
||||
for size, cipher, aead, bits, z in zip(Encryption.SIZES_R, AEAD_C, AEAD_M, AEAD_B, Encryption.Z_R):
|
||||
for size, cipher, aead, bits, z in zip(Encryption.SIZES_R, AEAD_C,
|
||||
AEAD_M, AEAD_B, Encryption.Z_R):
|
||||
rnp_sym_encryption_rnp_aead(size, cipher, z, [aead, bits], usegpg)
|
||||
|
||||
def test_encryption_multiple_recipients(self):
|
||||
|
@ -1587,7 +1727,8 @@ class Encryption(unittest.TestCase):
|
|||
gpg_import_pubring()
|
||||
gpg_import_secring()
|
||||
|
||||
KEYPSWD = tuple((t1, t2) for t1 in range(len(USERIDS) + 1) for t2 in range(len(PASSWORDS) + 1))
|
||||
KEYPSWD = tuple((t1, t2) for t1 in range(len(USERIDS) + 1)
|
||||
for t2 in range(len(PASSWORDS) + 1))
|
||||
KEYPSWD = list_upto(KEYPSWD, Encryption.RUNS)
|
||||
if gpg_supports_aead():
|
||||
AEADS = list_upto([None, [None], ['eax'], ['ocb']], Encryption.RUNS)
|
||||
|
@ -1638,7 +1779,8 @@ class Encryption(unittest.TestCase):
|
|||
USERIDS = ['enc-sign1@rnp', 'enc-sign2@rnp', 'enc-sign3@rnp']
|
||||
KEYPASS = ['encsign1pass', 'encsign2pass', 'encsign3pass']
|
||||
PASSWORDS = ['password1', 'password2', 'password3']
|
||||
AEAD_C = list_upto(['AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128', 'CAMELLIA192', 'CAMELLIA256'], Encryption.RUNS)
|
||||
AEAD_C = list_upto(['AES', 'AES192', 'AES256', 'TWOFISH', 'CAMELLIA128',
|
||||
'CAMELLIA192', 'CAMELLIA256'], Encryption.RUNS)
|
||||
# Generate multiple keys and import to GnuPG
|
||||
for uid, pswd in zip(USERIDS, KEYPASS):
|
||||
rnp_genkey_rsa(uid, 1024, pswd)
|
||||
|
@ -1647,7 +1789,8 @@ class Encryption(unittest.TestCase):
|
|||
gpg_import_secring()
|
||||
|
||||
SIGNERS = list_upto(range(1, len(USERIDS) + 1), Encryption.RUNS)
|
||||
KEYPSWD = tuple((t1, t2) for t1 in range(1, len(USERIDS) + 1) for t2 in range(len(PASSWORDS) + 1))
|
||||
KEYPSWD = tuple((t1, t2) for t1 in range(1, len(USERIDS) + 1)
|
||||
for t2 in range(len(PASSWORDS) + 1))
|
||||
KEYPSWD = list_upto(KEYPSWD, Encryption.RUNS)
|
||||
if gpg_supports_aead():
|
||||
AEADS = list_upto([None, [None], ['eax'], ['ocb']], Encryption.RUNS)
|
||||
|
@ -1669,7 +1812,8 @@ class Encryption(unittest.TestCase):
|
|||
z = ZS[i]
|
||||
cipher = AEAD_C[i]
|
||||
|
||||
rnp_encrypt_and_sign_file(src, dst, recipients, passwords, signers, signpswd, aead, cipher, z)
|
||||
rnp_encrypt_and_sign_file(src, dst, recipients, passwords, signers,
|
||||
signpswd, aead, cipher, z)
|
||||
# Decrypt file with each of the keys, we have different password for each key
|
||||
for pswd in KEYPASS[:keynum]:
|
||||
gpg_decrypt_file(dst, dec, pswd)
|
||||
|
@ -1802,7 +1946,8 @@ class SignDefault(unittest.TestCase):
|
|||
class Encrypt(unittest.TestCase, TestIdMixin, KeyLocationChooserMixin):
|
||||
def _encrypt_decrypt(self, e1, e2):
|
||||
key_id = "".join(self.id().split('.')[1:3])
|
||||
keyfile, input, enc_out, dec_out = reg_workfiles(self.test_id, '.gpg', '.in', '.enc', '.dec')
|
||||
keyfile, input, enc_out, dec_out = reg_workfiles(self.test_id, '.gpg',
|
||||
'.in', '.enc', '.dec')
|
||||
random_text(input, 0x1337)
|
||||
|
||||
if not self.operation_key_location and not self.operation_key_gencmd:
|
||||
|
@ -1853,13 +1998,13 @@ class EncryptElgamal(Encrypt):
|
|||
|
||||
def do_test_encrypt(self, sign_key_size, enc_key_size):
|
||||
pfx = EncryptElgamal.key_pfx(sign_key_size, enc_key_size)
|
||||
self.operation_key_location = tuple((key_path(pfx,False), key_path(pfx,True)))
|
||||
self.operation_key_location = tuple((key_path(pfx, False), key_path(pfx, True)))
|
||||
self.rnp.userid = self.gpg.userid = pfx+"@example.com"
|
||||
self._encrypt_decrypt(self.gpg, self.rnp)
|
||||
|
||||
def do_test_decrypt(self, sign_key_size, enc_key_size):
|
||||
pfx = EncryptElgamal.key_pfx(sign_key_size, enc_key_size)
|
||||
self.operation_key_location = tuple((key_path(pfx,False), key_path(pfx,True)))
|
||||
self.operation_key_location = tuple((key_path(pfx, False), key_path(pfx, True)))
|
||||
self.rnp.userid = self.gpg.userid = pfx+"@example.com"
|
||||
self._encrypt_decrypt(self.rnp, self.gpg)
|
||||
|
||||
|
@ -1899,15 +2044,18 @@ class EncryptEcdh(Encrypt):
|
|||
RNP_GENERATE_ECDH_ECDSA_PATTERN = "19\n{0}\n"
|
||||
|
||||
def test_encrypt_nistP256(self):
|
||||
self.operation_key_gencmd = EncryptEcdh.GPG_GENERATE_ECDH_ECDSA_PATTERN.format("nistp256", self.rnp.userid)
|
||||
self.operation_key_gencmd = EncryptEcdh.GPG_GENERATE_ECDH_ECDSA_PATTERN.format(
|
||||
"nistp256", self.rnp.userid)
|
||||
self._encrypt_decrypt(self.gpg, self.rnp)
|
||||
|
||||
def test_encrypt_nistP384(self):
|
||||
self.operation_key_gencmd = EncryptEcdh.GPG_GENERATE_ECDH_ECDSA_PATTERN.format("nistp384", self.rnp.userid)
|
||||
self.operation_key_gencmd = EncryptEcdh.GPG_GENERATE_ECDH_ECDSA_PATTERN.format(
|
||||
"nistp384", self.rnp.userid)
|
||||
self._encrypt_decrypt(self.gpg, self.rnp)
|
||||
|
||||
def test_encrypt_nistP521(self):
|
||||
self.operation_key_gencmd = EncryptEcdh.GPG_GENERATE_ECDH_ECDSA_PATTERN.format("nistp521", self.rnp.userid)
|
||||
self.operation_key_gencmd = EncryptEcdh.GPG_GENERATE_ECDH_ECDSA_PATTERN.format(
|
||||
"nistp521", self.rnp.userid)
|
||||
self._encrypt_decrypt(self.gpg, self.rnp)
|
||||
|
||||
def test_decrypt_nistP256(self):
|
||||
|
@ -2036,17 +2184,17 @@ class SignDSA(Sign):
|
|||
RNP_GENERATE_DSA_PATTERN = "17\n{0}\n"
|
||||
|
||||
@staticmethod
|
||||
def key_pfx(p): return "GnuPG_dsa_elgamal_%d_%d" % (p,p)
|
||||
def key_pfx(p): return "GnuPG_dsa_elgamal_%d_%d" % (p, p)
|
||||
|
||||
def do_test_sign(self, p_size):
|
||||
pfx = SignDSA.key_pfx(p_size)
|
||||
self.operation_key_location = tuple((key_path(pfx,False), key_path(pfx,True)))
|
||||
self.operation_key_location = tuple((key_path(pfx, False), key_path(pfx, True)))
|
||||
self.rnp.userid = self.gpg.userid = pfx+"@example.com"
|
||||
self._sign_verify(self.rnp, self.gpg)
|
||||
|
||||
def do_test_verify(self, p_size):
|
||||
pfx = SignDSA.key_pfx(p_size)
|
||||
self.operation_key_location = tuple((key_path(pfx,False), key_path(pfx,True)))
|
||||
self.operation_key_location = tuple((key_path(pfx, False), key_path(pfx, True)))
|
||||
self.rnp.userid = self.gpg.userid = pfx+"@example.com"
|
||||
self._sign_verify(self.gpg, self.rnp)
|
||||
|
||||
|
@ -2095,18 +2243,18 @@ class EncryptSignRSA(Encrypt, Sign):
|
|||
RNP_GENERATE_RSA_PATTERN = "1\n{0}\n"
|
||||
|
||||
@staticmethod
|
||||
def key_pfx(p): return "GnuPG_rsa_%d_%d" % (p,p)
|
||||
def key_pfx(p): return "GnuPG_rsa_%d_%d" % (p, p)
|
||||
|
||||
def do_encrypt_verify(self, key_size):
|
||||
pfx = EncryptSignRSA.key_pfx(key_size)
|
||||
self.operation_key_location = tuple((key_path(pfx,False), key_path(pfx,True)))
|
||||
self.operation_key_location = tuple((key_path(pfx, False), key_path(pfx, True)))
|
||||
self.rnp.userid = self.gpg.userid = pfx+"@example.com"
|
||||
self._encrypt_decrypt(self.gpg, self.rnp)
|
||||
self._sign_verify(self.gpg, self.rnp)
|
||||
|
||||
def do_rnp_decrypt_sign(self, key_size):
|
||||
pfx = EncryptSignRSA.key_pfx(key_size)
|
||||
self.operation_key_location = tuple((key_path(pfx,False), key_path(pfx,True)))
|
||||
self.operation_key_location = tuple((key_path(pfx, False), key_path(pfx, True)))
|
||||
self.rnp.userid = self.gpg.userid = pfx+"@example.com"
|
||||
self._encrypt_decrypt(self.rnp, self.gpg)
|
||||
self._sign_verify(self.rnp, self.gpg)
|
||||
|
@ -2131,10 +2279,12 @@ def test_suites(tests):
|
|||
|
||||
if __name__ == '__main__':
|
||||
main = unittest.main
|
||||
main.USAGE += ''.join([
|
||||
"\nRNP test client specific flags:\n",
|
||||
" -w,\t\t Don't remove working directory\n",
|
||||
" -d,\t\t Enable debug messages\n"])
|
||||
if not hasattr(main, 'USAGE'):
|
||||
main.USAGE = ''
|
||||
main.USAGE += ''.join([
|
||||
"\nRNP test client specific flags:\n",
|
||||
" -w,\t\t Don't remove working directory\n",
|
||||
" -d,\t\t Enable debug messages\n"])
|
||||
|
||||
LEAVE_WORKING_DIRECTORY = ("-w" in sys.argv)
|
||||
if LEAVE_WORKING_DIRECTORY:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python
|
||||
|
||||
import tempfile
|
||||
import sys
|
||||
|
|
Двоичные данные
third_party/rnp/src/tests/data/test_forged_keys/dsa-eg-pub-forged-key.pgp
поставляемый
Двоичные данные
third_party/rnp/src/tests/data/test_forged_keys/dsa-eg-pub-forged-key.pgp
поставляемый
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_forged_keys/ecc-25519-pub-future-cert-malf-bind.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_forged_keys/ecc-25519-pub-future-cert-malf-bind.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_forged_keys/ecc-p256-pub-no-cert-malf-binding.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_forged_keys/ecc-p256-pub-no-cert-malf-binding.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/alice-sign-sub-pub.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/alice-sign-sub-pub.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/alice-sign-sub-sec.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/alice-sign-sub-sec.pgp
поставляемый
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,3 @@
|
|||
Hello, world!
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA256
|
||||
|
||||
Hello, world!
|
||||
|
||||
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: rnp 0.9.0+git20200420.739.148391d
|
||||
|
||||
wnsEARYIACMWIQRz7cyRGa/I4tu9zeUEUUCWaf/ePAUCXqBD+QUDAAAAAAAKCRAEUUCWaf/ePAA4
|
||||
AQCab1d6mRcCdEmsIuipCsNHdpEI5Pxcz4DtnOx6GQLL3AD+JlsN4VDfzZiOXY5cDCGmkBgcxMYA
|
||||
ERpgLB46Y2iCKgbCewQBEwgAIxYhBM/lsBS+5D2dJPPvOCLzohfA5DnLBQJeoEP5BQMAAAAAAAoJ
|
||||
ECLzohfA5DnLSzAA/A/oRyERJXtKiFiZ6hq4esWMcM7eShnhW2cFaT1Og/NAAQDcU5vOxpu3LNdH
|
||||
wgpXa7eh2M1O04RHfFrsgO1Pvw8UJg==
|
||||
=BeZD
|
||||
-----END PGP SIGNATURE-----
|
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/primary.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/primary.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/pubring.gpg
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/pubring.gpg
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/subkey-no-sig.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/subkey-no-sig.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/subkey.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case8/subkey.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case9/pubring.gpg
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_key_validity/case9/pubring.gpg
поставляемый
Normal file
Двоичный файл не отображается.
|
@ -35,3 +35,13 @@ Case7:
|
|||
Keys Alice [pub, sub]
|
||||
Alice subkey has revocation signature by Alice
|
||||
Result: Alice [valid], Alice sub [invalid]
|
||||
|
||||
Case8:
|
||||
Keys Alice [pub, sub]
|
||||
Userid is stripped from the key, but it still has valid subkey binding
|
||||
Result: Alice [valid], Alice sub[valid]
|
||||
|
||||
Case9:
|
||||
Keys Alice [pub, sub]
|
||||
Alice key has two self-signatures, one which expires key and second without key expiration.
|
||||
Result: Alice [valid], Alice sub[valid]
|
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_1.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_1.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_2.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_2.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_cut1.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_cut1.pgp
поставляемый
Normal file
Двоичный файл не отображается.
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_cut22.pgp
поставляемый
Normal file
Двоичные данные
third_party/rnp/src/tests/data/test_messages/message_mdc_8k_cut22.pgp
поставляемый
Normal file
Двоичный файл не отображается.
|
@ -9,16 +9,16 @@ Wf4zSDhsEabUFJn2HoBdSoObcDX3DbBLP4GV7KzBDqJ0ZYfyL92Q58wOs5Q8ZDVP
|
|||
v41PvEijwVrgNDq02LYxcHgNDAJ++eGOxQdySb3Blo56AorS3xsVtIXFFlzMFB0j
|
||||
X0lUIeGEj5iKs4xpbRr/EE+m0B70fg2Yn/XpslUnOgboaNp/mZ5T4Zpe1kz/jDV4
|
||||
aNZ3p3l2DxxF8AUAEQEAAbQWdGVzdF9zdHJlYW1fc2lnbmF0dXJlc4kB1AQTAQgA
|
||||
PhYhBHpg5nEXn5uSD2R4olhzvXOOV1OYBQJau41QAhsDBQkDwmcABQsJCAcCBhUK
|
||||
CQgLAgQWAgMBAh4BAheAAAoJEFhzvXOOV1OYt5wL/iwz9BqzPpsGzTMtuCxGlUt5
|
||||
A1p0aOwK6hD8oDlW5Tq9fuJwKrf0bSen5MPRTs7tkRQ5loriRiqwrgqggxbf2wJx
|
||||
bFM3p3OF/CO1NMRBeCQCr37hKmtyPv3rmSHRhdeW6IdA5RS5I+UqgUZ18UF9f5va
|
||||
zM49pflxeDLq16388gcep8pnppw8J0XBFzxW4KWEGLxto1LElq5SJzdTTwQiN2cZ
|
||||
XmDChFyyQhesxY3qosV2jtIJktLT9Pl1qmxr/wwJf38J5DKmvJeisAl55SahN9l1
|
||||
owe2ACHQuE9L0HpjxYYxvmFeing0eydDyU10RVgavdI6+ztfVas5f38zy6r3uxX+
|
||||
mSbV/w4LELvT0jmTAxpVM1O9N7pB71xKypTfsMNEOxi1fWx+/bpB6GVy319JF4aE
|
||||
JfJYO8rAMWn3UpvY8FaxuCnsDudmpwEvzgOHhr+EOyWlWMbpfC+vtFXncPjEPn7R
|
||||
lRVy5CkSL+WidtcRmI82iG8hfG3PcpFryea8zMTKCLkBjQRau41QAQwAwB/4Oa2w
|
||||
PgIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBHpg5nEXn5uSD2R4olhzvXOO
|
||||
V1OYBQJekHJ9BQkWoOgtAAoJEFhzvXOOV1OYdCUMALQ5AsHoE+RU66Qs1qWxQK9k
|
||||
R7wd0j3yLs/l9eUElpXFz0W/ZRWR2bZ9aO8fuCEQTXPgNtdGBG06fCB/MrpTCwoE
|
||||
ScUTlz0jGqC8CqbjfV6a92abk+9fXJkYcWyCjFJ0nWzQSSLOlNJ5xesqBB+yBNx7
|
||||
xyWuggnTcg5F1IbiVN4R3yhKboUZu2nvXIBJVl/JYT5f0jQUAeYLsalmF6Ug6mW3
|
||||
yVR2wvIlvA5BGlr3qJrIZH22QRPNOfwKZorhPvzD1yj/CXlV4zDDl2TjlcuAkcsT
|
||||
mqEq+gg/PkLsCpEd1rHIwbplCJiWAxTZLchw49VkGvWAFsiXKCfaWkHZaJpTbTfP
|
||||
vXppxeJ6VCt/+jU7x8KvRXyqWt45OqIbgs+mi9X4VXqLGXORh4auN6vT/V3uLTOU
|
||||
1rftvc6mEvcYoKVGNutKcQwfl+MJwfMcjAtDAsov8V6CNDJYGMBZVI6wjh6gt34O
|
||||
LjlhHM/znBU+FTtPyjSAOvD2SR3oQyVr5gSKVtlPBrkBjQRau41QAQwAwB/4Oa2w
|
||||
4qupz0+KCmmutEezSKZkf7xZ7UFO87X4hYdoyOUfmtnz4jjA6V5KpZ8DMfrEB9bm
|
||||
vfHaQBrCdASxspfXDAXfZCV8UqyP+RBItfqdT/tlPxd1uWVqO8pwd0UvXgDICiXy
|
||||
mCmUOsJ8sajI0X7yN+PjDGoGrUbT8sXpOdGD0aG5ARnaNr9zKa/7RiEaLt8SGdAt
|
||||
|
@ -27,15 +27,15 @@ NYMeTk33YoRDlhWWepLYkKZ4Tkrq9A3E/5WjJcFP5NuG8pSM7i+T9glRsZCUH0gI
|
|||
BhbzTwehQZ3ZM6Rj0aCiFrxBCfzrhjM9PXiJhXwJmV2vCVW2GQZndkF2JwAcAAsF
|
||||
5mzQD/ylkVLvTg4evNfiFTVQog8nLV0ZyKmodTSUWJCBVgzFP1IuHMbObeAWQF8x
|
||||
jO69SGt4iOGQw68JljCPBJ8u6N7GMY81mTY/36tWd5pIxOLnAbpodl1DABEBAAGJ
|
||||
AbwEGAEIACYWIQR6YOZxF5+bkg9keKJYc71zjldTmAUCWruNUAIbDAUJA8JnAAAK
|
||||
CRBYc71zjldTmBliDACYyguYp9V80mApoM9cdswJCSJu5TpAv+fP+hcekLE0I7wq
|
||||
qs7+zd0vasrReemgMMA9gx2IbSUZxWPUSoZloJsxcoBfEjlfoNNRXn2X9Hq7NUhu
|
||||
19gMdwUxtnyd4dOIleYqk93QkydTeqciI+xZ0s2lmiOps0FDgKLWAbNdC/kWOp5x
|
||||
GHx+Dy9D+cM+4YxjfBnxplG3qreY5Vmu2tlYTXG41LjJHpXL0LOQXdVf6ZdcVdQ5
|
||||
CCynd583xL9fjxGtAoNYV5LK/1qAZuqFVSk/R9eEy2664W/Fj4I5LlH/UQIfcTdl
|
||||
ItY+/5mFa0CK7/7uucy7zfIwILx3M9nAvzbFaTdDP7ZBOO6xkeQE22WOMYrcGGkr
|
||||
lPueHq/gbu/4fl1XHyl4oHJZdqTaI9a9vwO/342ct+y9agtpkooSpljDavVSPiO+
|
||||
wWd45g52HsY/bF/A7qv1e7ucH11elQgUXW6Q8kGvTy/FYMWjk5tV+mokI/k6rupt
|
||||
SEvTyvqqYIWvhPXmkI0=
|
||||
=C3aD
|
||||
AbwEGAEIACYCGwwWIQR6YOZxF5+bkg9keKJYc71zjldTmAUCXpBymQUJFqDoSQAK
|
||||
CRBYc71zjldTmOHODACQHml5YT4hsNN4OLP6xNdEKCCjLfY7V1EKYZZU671vYTQn
|
||||
qIRTGhNB18FATHJwONMjMegsu/8K67V3acnW7cszUbZDC1OMC7Mo0qFHvysfbxbq
|
||||
4Pb10QYtqvmla8nerbKGKqxm32CRYZf2qZ4pXG/7MvE5aAQPXR+cBgByU9EHOB5K
|
||||
t9NwYm7MEZyOSNvcRaJIN1aeS8cur5veRoLLEWYhBF/FrOusCLvkupQ/rqnsqr/D
|
||||
IHaxjHFpSwxAHan8VxkeHsxZNTYb9eejmXTBUrqePARGyuHiqCK7w0fv/RW+mXbn
|
||||
UDJl+NIg2F0oMcsoqj2F74IWkcn7X7FMP2XQv99PuAgVd9q1XhxDXSBUyXCT+E41
|
||||
hmR4rtdQRg8JiJ4RZKE8arDjRVXZdaiNMW9J5vjWrlyvqLiVyNmyyHw63LXNO0cN
|
||||
Qv4qz+S5gir8JAHYzZFnjvisll1Ur9JSQWyg97OB6dsIN7Im6sJOcjpkpHgA5v+9
|
||||
hMHj3/yuwMXx6aMHF1A=
|
||||
=zbzp
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
|
|
@ -8,38 +8,38 @@ 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
|
||||
|
@ -48,36 +48,36 @@ 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
|
||||
=vuN6
|
||||
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
|
||||
=Nabv
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
|
|
|
@ -802,10 +802,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_pair)
|
|||
rnp_key_handle_t primary = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -816,10 +816,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_pair)
|
|||
rnp_key_handle_t sub = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -880,10 +880,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_pair_dsa_elg)
|
|||
rnp_key_handle_t primary = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -894,10 +894,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_pair_dsa_elg)
|
|||
rnp_key_handle_t sub = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -960,10 +960,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_primary)
|
|||
rnp_key_handle_t primary = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -1023,10 +1023,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_sub)
|
|||
char * primary_grip = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
primary_grip = strdup(json_object_get_string(jsogrip));
|
||||
assert_non_null(primary_grip);
|
||||
|
@ -1081,10 +1081,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_sub)
|
|||
rnp_key_handle_t sub = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -2485,10 +2485,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_sub_pass_required)
|
|||
char * primary_grip = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "primary", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
primary_grip = strdup(json_object_get_string(jsogrip));
|
||||
assert_non_null(primary_grip);
|
||||
|
@ -2559,10 +2559,10 @@ TEST_F(rnp_tests, test_ffi_keygen_json_sub_pass_required)
|
|||
rnp_key_handle_t sub = NULL;
|
||||
{
|
||||
json_object *jsokey = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_int_equal(true, json_object_object_get_ex(parsed_results, "sub", &jsokey));
|
||||
assert_non_null(jsokey);
|
||||
json_object *jsogrip = NULL;
|
||||
assert_int_equal(TRUE, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_int_equal(true, json_object_object_get_ex(jsokey, "grip", &jsogrip));
|
||||
assert_non_null(jsogrip);
|
||||
const char *grip = json_object_get_string(jsogrip);
|
||||
assert_non_null(grip);
|
||||
|
@ -3823,7 +3823,7 @@ TEST_F(rnp_tests, test_ffi_key_to_json)
|
|||
assert_int_equal(rnp_strcasecmp(json_object_get_string(get_json_obj(jso, "grip")),
|
||||
"20A48B3C61525DCDF8B3B9D82C6BBCF4D8BFB5E5"),
|
||||
0);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "revoked")), FALSE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "revoked")), false);
|
||||
assert_int_equal(json_object_get_int64(get_json_obj(jso, "creation time")), 1511313500);
|
||||
assert_int_equal(json_object_get_int64(get_json_obj(jso, "expiration")), 0);
|
||||
// usage
|
||||
|
@ -3845,7 +3845,7 @@ TEST_F(rnp_tests, test_ffi_key_to_json)
|
|||
"FFFA72FC225214DC712D0127172EE13E88AF93B4"),
|
||||
0);
|
||||
// public key
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "public key.present")), TRUE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "public key.present")), true);
|
||||
assert_int_equal(
|
||||
rnp_strcasecmp(json_object_get_string(get_json_obj(jso, "public key.mpis.point")),
|
||||
"04B0C6F2F585C1EEDF805C4492CB683839D5EAE6246420780F063D558"
|
||||
|
@ -3853,14 +3853,14 @@ TEST_F(rnp_tests, test_ffi_key_to_json)
|
|||
"793CEBAE8600BEEF"),
|
||||
0);
|
||||
// secret key
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.present")), TRUE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.present")), true);
|
||||
assert_int_equal(
|
||||
rnp_strcasecmp(json_object_get_string(get_json_obj(jso, "secret key.mpis.x")),
|
||||
"46DE93CA439735F36B9CF228F10D8586DA824D88BBF4E24566D5312D061802C8"),
|
||||
0);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.locked")), FALSE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.locked")), false);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.protected")),
|
||||
FALSE);
|
||||
false);
|
||||
// userids
|
||||
assert_int_equal(json_object_array_length(get_json_obj(jso, "userids")), 1);
|
||||
assert_int_equal(rnp_strcasecmp(json_object_get_string(json_object_array_get_idx(
|
||||
|
@ -3909,7 +3909,7 @@ TEST_F(rnp_tests, test_ffi_key_to_json)
|
|||
assert_int_equal(rnp_strcasecmp(json_object_get_string(get_json_obj(jso, "grip")),
|
||||
"FFFA72FC225214DC712D0127172EE13E88AF93B4"),
|
||||
0);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "revoked")), FALSE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "revoked")), false);
|
||||
assert_int_equal(json_object_get_int64(get_json_obj(jso, "creation time")), 1511313500);
|
||||
assert_int_equal(json_object_get_int64(get_json_obj(jso, "expiration")), 0);
|
||||
// usage
|
||||
|
@ -3926,21 +3926,21 @@ TEST_F(rnp_tests, test_ffi_key_to_json)
|
|||
// subkey grips
|
||||
assert_null(get_json_obj(jso, "subkey grips"));
|
||||
// public key
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "public key.present")), TRUE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "public key.present")), true);
|
||||
assert_int_equal(
|
||||
rnp_strcasecmp(json_object_get_string(get_json_obj(jso, "public key.mpis.point")),
|
||||
"04E2746BA4D180011B17A6909EABDBF2F3733674FBE00B20A3B857C2597233651544150B"
|
||||
"896BCE7DCDF47C49FC1E12D5AD86384D26336A48A18845940A3F65F502"),
|
||||
0);
|
||||
// secret key
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.present")), TRUE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.present")), true);
|
||||
assert_int_equal(
|
||||
rnp_strcasecmp(json_object_get_string(get_json_obj(jso, "secret key.mpis.x")),
|
||||
"DF8BEB7272117AD7AFE2B7E882453113059787FBC785C82F78624EE7EF2117FB"),
|
||||
0);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.locked")), FALSE);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.locked")), false);
|
||||
assert_int_equal(json_object_get_boolean(get_json_obj(jso, "secret key.protected")),
|
||||
FALSE);
|
||||
false);
|
||||
// userids
|
||||
assert_null(get_json_obj(jso, "userids"));
|
||||
// signatures
|
||||
|
@ -5502,6 +5502,116 @@ TEST_F(rnp_tests, test_ffi_keys_import)
|
|||
rnp_ffi_destroy(ffi);
|
||||
}
|
||||
|
||||
TEST_F(rnp_tests, test_ffi_stripped_keys_import)
|
||||
{
|
||||
rnp_ffi_t ffi = NULL;
|
||||
rnp_input_t input = NULL;
|
||||
|
||||
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
|
||||
/* load stripped key as keyring */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/pubring.gpg"));
|
||||
assert_rnp_success(rnp_load_keys(ffi, "GPG", input, RNP_LOAD_SAVE_PUBLIC_KEYS));
|
||||
rnp_input_destroy(input);
|
||||
/* validate signatures - must succeed */
|
||||
rnp_op_verify_t verify = NULL;
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/message.txt.asc"));
|
||||
rnp_output_t output = NULL;
|
||||
assert_rnp_success(rnp_output_to_null(&output));
|
||||
assert_rnp_success(rnp_ffi_set_pass_provider(ffi, getpasscb, (void *) "password"));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_success(rnp_op_verify_execute(verify));
|
||||
rnp_input_destroy(input);
|
||||
rnp_output_destroy(output);
|
||||
rnp_op_verify_signature_t sig;
|
||||
/* signature 1 - by primary key */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
/* signature 2 - by subkey */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 1, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
rnp_op_verify_destroy(verify);
|
||||
|
||||
/* load stripped key by parts via import */
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/primary.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
rnp_input_destroy(input);
|
||||
assert_rnp_success(rnp_input_from_path(&input, "data/test_key_validity/case8/subkey.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
rnp_input_destroy(input);
|
||||
/* validate signatures - must be valid */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/message.txt.asc"));
|
||||
assert_rnp_success(rnp_output_to_null(&output));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_success(rnp_op_verify_execute(verify));
|
||||
rnp_input_destroy(input);
|
||||
rnp_output_destroy(output);
|
||||
/* signature 1 - by primary key */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
/* signature 2 - by subkey */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 1, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
rnp_op_verify_destroy(verify);
|
||||
|
||||
/* load stripped key with subkey first */
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC));
|
||||
assert_rnp_success(rnp_input_from_path(&input, "data/test_key_validity/case8/subkey.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
rnp_input_destroy(input);
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/primary.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
rnp_input_destroy(input);
|
||||
/* validate signatures - must be valid */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/message.txt.asc"));
|
||||
assert_rnp_success(rnp_output_to_null(&output));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_success(rnp_op_verify_execute(verify));
|
||||
rnp_input_destroy(input);
|
||||
rnp_output_destroy(output);
|
||||
/* signature 1 - by primary key */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
/* signature 2 - by subkey */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 1, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
rnp_op_verify_destroy(verify);
|
||||
|
||||
/* load stripped key without subkey binding */
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/primary.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
rnp_input_destroy(input);
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/subkey-no-sig.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
rnp_input_destroy(input);
|
||||
/* validate signatures - must be invalid */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case8/message.txt.asc"));
|
||||
assert_rnp_success(rnp_output_to_null(&output));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_int_equal(rnp_op_verify_execute(verify), RNP_ERROR_SIGNATURE_INVALID);
|
||||
rnp_input_destroy(input);
|
||||
rnp_output_destroy(output);
|
||||
/* signature 1 - by primary key */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
|
||||
assert_int_equal(rnp_op_verify_signature_get_status(sig), RNP_ERROR_SIGNATURE_INVALID);
|
||||
/* signature 2 - by subkey */
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 1, &sig));
|
||||
assert_int_equal(rnp_op_verify_signature_get_status(sig), RNP_ERROR_SIGNATURE_INVALID);
|
||||
rnp_op_verify_destroy(verify);
|
||||
|
||||
rnp_ffi_destroy(ffi);
|
||||
}
|
||||
|
||||
static std::vector<uint8_t>
|
||||
read_file_to_vector(const char *valid_key_path)
|
||||
{
|
||||
|
@ -6925,10 +7035,27 @@ TEST_F(rnp_tests, test_ffi_secret_sig_import)
|
|||
assert_rnp_success(rnp_input_from_path(&input, "data/test_key_validity/alice-rev.pgp"));
|
||||
assert_rnp_success(rnp_import_signatures(ffi, input, 0, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
/* make sure that key is still unlocked */
|
||||
assert_rnp_success(rnp_key_is_locked(key_handle, &locked));
|
||||
assert_false(locked);
|
||||
/* import subkey */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sub-sec.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
/* make sure that primary key is still unlocked */
|
||||
assert_rnp_success(rnp_key_is_locked(key_handle, &locked));
|
||||
assert_false(locked);
|
||||
/* unlock subkey and make sure it is unlocked after revocation */
|
||||
rnp_key_handle_t sub_handle = NULL;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub_handle));
|
||||
assert_rnp_success(rnp_key_unlock(sub_handle, "password"));
|
||||
assert_rnp_success(rnp_key_is_locked(sub_handle, &locked));
|
||||
assert_false(locked);
|
||||
assert_rnp_success(rnp_key_revoke(sub_handle, 0, "SHA256", "retired", "Custom reason"));
|
||||
assert_rnp_success(rnp_key_is_locked(sub_handle, &locked));
|
||||
assert_false(locked);
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub_handle));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key_handle));
|
||||
assert_rnp_success(rnp_ffi_destroy(ffi));
|
||||
}
|
||||
|
@ -7014,3 +7141,358 @@ TEST_F(rnp_tests, test_ffi_rnp_request_password)
|
|||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_ffi_destroy(ffi));
|
||||
}
|
||||
|
||||
TEST_F(rnp_tests, test_ffi_key_revoke)
|
||||
{
|
||||
rnp_ffi_t ffi = NULL;
|
||||
rnp_input_t input = NULL;
|
||||
|
||||
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sub-pub.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
rnp_key_handle_t key_handle = NULL;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key_handle));
|
||||
/* check for failure with wrong parameters */
|
||||
assert_rnp_failure(rnp_key_revoke(NULL, 0, "SHA256", "superseded", "test key revocation"));
|
||||
assert_rnp_failure(rnp_key_revoke(key_handle, 0, "SHA256", NULL, NULL));
|
||||
assert_rnp_failure(rnp_key_revoke(key_handle, 0x17, "SHA256", NULL, NULL));
|
||||
assert_rnp_failure(rnp_key_revoke(key_handle, 0, "Wrong hash", NULL, NULL));
|
||||
assert_rnp_failure(rnp_key_revoke(key_handle, 0, "SHA256", "Wrong reason code", NULL));
|
||||
/* attempt to revoke key without the secret */
|
||||
assert_rnp_failure(rnp_key_revoke(key_handle, 0, "SHA256", "retired", "Custom reason"));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key_handle));
|
||||
/* attempt to revoke subkey without the secret */
|
||||
rnp_key_handle_t sub_handle = NULL;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub_handle));
|
||||
assert_rnp_failure(rnp_key_revoke(sub_handle, 0, "SHA256", "retired", "Custom reason"));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub_handle));
|
||||
/* load secret key */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sub-sec.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key_handle));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub_handle));
|
||||
/* wrong password - must fail */
|
||||
assert_rnp_success(rnp_ffi_set_pass_provider(ffi, getpasscb, (void *) "wrong"));
|
||||
assert_rnp_failure(rnp_key_revoke(key_handle, 0, "SHA256", "superseded", NULL));
|
||||
assert_rnp_failure(rnp_key_revoke(sub_handle, 0, "SHA256", "superseded", NULL));
|
||||
/* unlocked key - must succeed */
|
||||
bool revoked = false;
|
||||
assert_rnp_success(rnp_key_is_revoked(key_handle, &revoked));
|
||||
assert_false(revoked);
|
||||
assert_rnp_success(rnp_key_unlock(key_handle, "password"));
|
||||
assert_rnp_success(rnp_key_revoke(key_handle, 0, "SHA256", NULL, NULL));
|
||||
assert_rnp_success(rnp_key_is_revoked(key_handle, &revoked));
|
||||
assert_true(revoked);
|
||||
/* subkey */
|
||||
assert_rnp_success(rnp_key_is_revoked(sub_handle, &revoked));
|
||||
assert_false(revoked);
|
||||
bool locked = true;
|
||||
assert_rnp_success(rnp_key_is_locked(key_handle, &locked));
|
||||
assert_false(locked);
|
||||
assert_rnp_success(rnp_key_revoke(sub_handle, 0, "SHA256", NULL, "subkey revoked"));
|
||||
assert_rnp_success(rnp_key_is_revoked(sub_handle, &revoked));
|
||||
assert_true(revoked);
|
||||
assert_rnp_success(rnp_key_lock(key_handle));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key_handle));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub_handle));
|
||||
/* correct password provider - must succeed */
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_SECRET | RNP_KEY_UNLOAD_PUBLIC));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sub-sec.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key_handle));
|
||||
assert_rnp_success(rnp_ffi_set_pass_provider(ffi, getpasscb, (void *) "password"));
|
||||
assert_rnp_success(rnp_key_is_revoked(key_handle, &revoked));
|
||||
assert_false(revoked);
|
||||
assert_rnp_success(
|
||||
rnp_key_revoke(key_handle, 0, "SHA256", "superseded", "test key revocation"));
|
||||
assert_rnp_success(rnp_key_is_revoked(key_handle, &revoked));
|
||||
assert_true(revoked);
|
||||
/* make sure FFI locks key back */
|
||||
assert_rnp_success(rnp_key_is_locked(key_handle, &locked));
|
||||
assert_true(locked);
|
||||
assert_rnp_success(rnp_key_handle_destroy(key_handle));
|
||||
/* repeat for subkey */
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub_handle));
|
||||
assert_rnp_success(rnp_key_is_revoked(sub_handle, &revoked));
|
||||
assert_false(revoked);
|
||||
assert_rnp_success(rnp_key_revoke(sub_handle, 0, "SHA256", "no", "test sub revocation"));
|
||||
assert_rnp_success(rnp_key_is_revoked(sub_handle, &revoked));
|
||||
assert_true(revoked);
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub_handle));
|
||||
assert_rnp_success(rnp_ffi_destroy(ffi));
|
||||
}
|
||||
|
||||
TEST_F(rnp_tests, test_ffi_key_set_expiry)
|
||||
{
|
||||
rnp_ffi_t ffi = NULL;
|
||||
rnp_input_t input = NULL;
|
||||
|
||||
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sub-pub.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
/* check edge cases */
|
||||
assert_rnp_failure(rnp_key_set_expiration(NULL, 0));
|
||||
rnp_key_handle_t key = NULL;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
/* cannot set key expiration with public key only */
|
||||
assert_rnp_failure(rnp_key_set_expiration(key, 1000));
|
||||
rnp_key_handle_t sub = NULL;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub));
|
||||
assert_rnp_failure(rnp_key_set_expiration(sub, 1000));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
|
||||
/* load secret key */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sub-sec.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
uint32_t expiry = 0;
|
||||
const uint32_t new_expiry = 10 * 365 * 24 * 60 * 60;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_key_set_expiration(key, 0));
|
||||
/* will fail on locked key */
|
||||
assert_rnp_failure(rnp_key_set_expiration(key, new_expiry));
|
||||
assert_rnp_success(rnp_key_unlock(key, "password"));
|
||||
assert_rnp_success(rnp_key_set_expiration(key, new_expiry));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, new_expiry);
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub));
|
||||
/* will succeed on locked subkey since it is not signing one */
|
||||
assert_rnp_success(rnp_key_set_expiration(sub, 0));
|
||||
assert_rnp_success(rnp_key_set_expiration(sub, new_expiry * 2));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, new_expiry * 2);
|
||||
/* make sure new expiration times are properly saved */
|
||||
rnp_output_t keymem = NULL;
|
||||
rnp_output_t seckeymem = NULL;
|
||||
assert_rnp_success(rnp_output_to_memory(&keymem, 0));
|
||||
assert_rnp_success(
|
||||
rnp_key_export(key, keymem, RNP_KEY_EXPORT_PUBLIC | RNP_KEY_EXPORT_SUBKEYS));
|
||||
assert_rnp_success(rnp_output_to_memory(&seckeymem, 0));
|
||||
assert_rnp_success(
|
||||
rnp_key_export(key, seckeymem, RNP_KEY_EXPORT_SECRET | RNP_KEY_EXPORT_SUBKEYS));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
|
||||
uint8_t *keybuf = NULL;
|
||||
size_t keylen = 0;
|
||||
assert_rnp_success(rnp_output_memory_get_buf(keymem, &keybuf, &keylen, false));
|
||||
assert_rnp_success(rnp_input_from_memory(&input, keybuf, keylen, false));
|
||||
/* load public key */
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, new_expiry);
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, new_expiry * 2);
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
|
||||
/* now load exported secret key */
|
||||
assert_rnp_success(rnp_output_memory_get_buf(seckeymem, &keybuf, &keylen, false));
|
||||
assert_rnp_success(rnp_input_from_memory(&input, keybuf, keylen, false));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_output_destroy(seckeymem));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, new_expiry);
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, new_expiry * 2);
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
/* now unset expiration time back, first loading the public key back */
|
||||
assert_rnp_success(rnp_output_memory_get_buf(keymem, &keybuf, &keylen, false));
|
||||
assert_rnp_success(rnp_input_from_memory(&input, keybuf, keylen, false));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_output_destroy(keymem));
|
||||
/* set primary key expiration */
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_key_unlock(key, "password"));
|
||||
assert_rnp_success(rnp_key_set_expiration(key, 0));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub));
|
||||
assert_rnp_success(rnp_key_set_expiration(sub, 0));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
/* let's export them and reload */
|
||||
assert_rnp_success(rnp_output_to_memory(&keymem, 0));
|
||||
assert_rnp_success(
|
||||
rnp_key_export(key, keymem, RNP_KEY_EXPORT_PUBLIC | RNP_KEY_EXPORT_SUBKEYS));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
|
||||
assert_rnp_success(rnp_output_memory_get_buf(keymem, &keybuf, &keylen, false));
|
||||
assert_rnp_success(rnp_input_from_memory(&input, keybuf, keylen, false));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_output_destroy(keymem));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "DD23CEB7FEBEFF17", &sub));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
|
||||
/* now try the sign-able subkey */
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sign-sub-pub.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sign-sub-sec.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "22F3A217C0E439CB", &sub));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_failure(rnp_key_set_expiration(sub, new_expiry));
|
||||
/* now unlock only primary key - should fail */
|
||||
assert_rnp_success(rnp_key_unlock(key, "password"));
|
||||
assert_rnp_failure(rnp_key_set_expiration(sub, new_expiry));
|
||||
/* unlock subkey */
|
||||
assert_rnp_success(rnp_key_unlock(sub, "password"));
|
||||
assert_rnp_success(rnp_key_set_expiration(sub, new_expiry));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, new_expiry);
|
||||
assert_rnp_success(rnp_output_to_memory(&keymem, 0));
|
||||
assert_rnp_success(
|
||||
rnp_key_export(key, keymem, RNP_KEY_EXPORT_PUBLIC | RNP_KEY_EXPORT_SUBKEYS));
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
|
||||
assert_rnp_success(rnp_output_memory_get_buf(keymem, &keybuf, &keylen, false));
|
||||
assert_rnp_success(rnp_input_from_memory(&input, keybuf, keylen, false));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_output_destroy(keymem));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "22F3A217C0E439CB", &sub));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, new_expiry);
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
|
||||
/* check whether we can change expiration for already expired key */
|
||||
assert_rnp_success(rnp_unload_keys(ffi, RNP_KEY_UNLOAD_PUBLIC | RNP_KEY_UNLOAD_SECRET));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sign-sub-pub.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/alice-sign-sub-sec.pgp"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_SECRET_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
assert_rnp_success(rnp_locate_key(ffi, "keyid", "22F3A217C0E439CB", &sub));
|
||||
assert_rnp_success(rnp_key_unlock(key, "password"));
|
||||
assert_rnp_success(rnp_key_unlock(sub, "password"));
|
||||
assert_rnp_success(rnp_key_set_expiration(key, 1));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, 1);
|
||||
assert_rnp_success(rnp_key_set_expiration(sub, 1));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, 1);
|
||||
assert_rnp_success(rnp_key_set_expiration(key, 0));
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_key_set_expiration(sub, 0));
|
||||
assert_rnp_success(rnp_key_get_expiration(sub, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_key_handle_destroy(sub));
|
||||
|
||||
// TODO: check expiration date in direct-key signature, check without
|
||||
// self-signature/binding signature.
|
||||
|
||||
assert_rnp_success(rnp_ffi_destroy(ffi));
|
||||
}
|
||||
|
||||
TEST_F(rnp_tests, test_ffi_mdc_8k_boundary)
|
||||
{
|
||||
rnp_ffi_t ffi = NULL;
|
||||
rnp_input_t input = NULL;
|
||||
|
||||
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
|
||||
assert_rnp_success(rnp_ffi_set_pass_provider(ffi, getpasscb, (void *) "password"));
|
||||
assert_rnp_success(rnp_input_from_path(&input, "data/keyrings/1/pubring.gpg"));
|
||||
assert_rnp_success(rnp_load_keys(ffi, "GPG", input, RNP_LOAD_SAVE_PUBLIC_KEYS));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
assert_rnp_success(rnp_input_from_path(&input, "data/keyrings/1/secring.gpg"));
|
||||
assert_rnp_success(rnp_load_keys(ffi, "GPG", input, RNP_LOAD_SAVE_SECRET_KEYS));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
/* correctly process two messages */
|
||||
assert_rnp_success(rnp_input_from_path(&input, "data/test_messages/message_mdc_8k_1.pgp"));
|
||||
rnp_output_t output = NULL;
|
||||
assert_rnp_success(rnp_output_to_null(&output));
|
||||
rnp_op_verify_t verify;
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_success(rnp_op_verify_execute(verify));
|
||||
/* check signature */
|
||||
size_t sig_count = 0;
|
||||
assert_rnp_success(rnp_op_verify_get_signature_count(verify, &sig_count));
|
||||
assert_int_equal(sig_count, 1);
|
||||
rnp_op_verify_signature_t sig = NULL;
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
/* cleanup */
|
||||
assert_rnp_success(rnp_op_verify_destroy(verify));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
assert_rnp_success(rnp_input_from_path(&input, "data/test_messages/message_mdc_8k_2.pgp"));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_success(rnp_op_verify_execute(verify));
|
||||
/* check signature */
|
||||
sig_count = 0;
|
||||
assert_rnp_success(rnp_op_verify_get_signature_count(verify, &sig_count));
|
||||
assert_int_equal(sig_count, 1);
|
||||
assert_rnp_success(rnp_op_verify_get_signature_at(verify, 0, &sig));
|
||||
assert_rnp_success(rnp_op_verify_signature_get_status(sig));
|
||||
/* cleanup */
|
||||
assert_rnp_success(rnp_op_verify_destroy(verify));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
/* let it gracefully fail on message 1 with the last byte cut */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_messages/message_mdc_8k_cut1.pgp"));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_failure(rnp_op_verify_execute(verify));
|
||||
/* cleanup */
|
||||
assert_rnp_success(rnp_op_verify_destroy(verify));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
/* let it gracefully fail on message 1 with the last 22 bytes (MDC size) cut */
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_messages/message_mdc_8k_cut22.pgp"));
|
||||
assert_rnp_success(rnp_op_verify_create(&verify, ffi, input, output));
|
||||
assert_rnp_failure(rnp_op_verify_execute(verify));
|
||||
/* cleanup */
|
||||
assert_rnp_success(rnp_op_verify_destroy(verify));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
|
||||
assert_rnp_success(rnp_output_destroy(output));
|
||||
assert_rnp_success(rnp_ffi_destroy(ffi));
|
||||
}
|
||||
|
|
|
@ -915,8 +915,8 @@ TEST_F(rnp_tests, test_generated_key_sigs)
|
|||
|
||||
// primary
|
||||
{
|
||||
pgp_key_t pub = {0};
|
||||
pgp_key_t sec = {0};
|
||||
pgp_key_t pub = {};
|
||||
pgp_key_t sec = {};
|
||||
rnp_keygen_primary_desc_t desc;
|
||||
pgp_fingerprint_t fp = {};
|
||||
pgp_sig_subpkt_t * subpkt = NULL;
|
||||
|
@ -940,6 +940,10 @@ TEST_F(rnp_tests, test_generated_key_sigs)
|
|||
primary_sec = rnp_key_store_get_key_by_grip(secring, pgp_key_get_grip(&pub));
|
||||
assert_non_null(primary_pub);
|
||||
assert_non_null(primary_sec);
|
||||
assert_true(primary_pub->valid);
|
||||
assert_true(primary_pub->validated);
|
||||
assert_true(primary_sec->valid);
|
||||
assert_true(primary_sec->validated);
|
||||
|
||||
// check packet and subsig counts
|
||||
assert_int_equal(3, pgp_key_get_rawpacket_count(&pub));
|
||||
|
@ -1009,34 +1013,48 @@ TEST_F(rnp_tests, test_generated_key_sigs)
|
|||
|
||||
// validate via an alternative method
|
||||
// primary_pub + pubring
|
||||
assert_rnp_success(pgp_key_validate(primary_pub, pubring));
|
||||
primary_pub->valid = false;
|
||||
primary_pub->validated = false;
|
||||
pgp_key_validate(primary_pub, pubring);
|
||||
assert_true(primary_pub->valid);
|
||||
assert_true(primary_pub->validated);
|
||||
// primary_sec + pubring
|
||||
assert_rnp_success(pgp_key_validate(primary_sec, pubring));
|
||||
primary_sec->valid = false;
|
||||
primary_sec->validated = false;
|
||||
pgp_key_validate(primary_sec, pubring);
|
||||
assert_true(primary_sec->valid);
|
||||
assert_true(primary_sec->validated);
|
||||
// primary_pub + secring
|
||||
assert_rnp_success(pgp_key_validate(primary_pub, secring));
|
||||
primary_pub->valid = primary_pub->validated = false;
|
||||
pgp_key_validate(primary_pub, secring);
|
||||
assert_true(primary_pub->valid);
|
||||
assert_true(primary_pub->validated);
|
||||
// primary_sec + secring
|
||||
assert_rnp_success(pgp_key_validate(primary_sec, secring));
|
||||
primary_sec->valid = primary_sec->validated = false;
|
||||
pgp_key_validate(primary_sec, secring);
|
||||
assert_true(primary_sec->valid);
|
||||
assert_true(primary_sec->validated);
|
||||
// modify a hashed portion of the sig packet, offset may change in future
|
||||
pgp_subsig_t *sig = pgp_key_get_subsig(primary_pub, 0);
|
||||
assert_non_null(sig);
|
||||
sig->sig.hashed_data[10] ^= 0xff;
|
||||
sig->validated = false;
|
||||
// ensure validation fails
|
||||
assert_rnp_success(pgp_key_validate(primary_pub, pubring));
|
||||
pgp_key_validate(primary_pub, pubring);
|
||||
assert_false(primary_pub->valid);
|
||||
assert_true(primary_pub->validated);
|
||||
// restore the original data
|
||||
sig->sig.hashed_data[10] ^= 0xff;
|
||||
assert_rnp_success(pgp_key_validate(primary_pub, pubring));
|
||||
sig->validated = false;
|
||||
pgp_key_validate(primary_pub, pubring);
|
||||
assert_true(primary_pub->valid);
|
||||
assert_true(primary_pub->validated);
|
||||
}
|
||||
|
||||
// sub
|
||||
{
|
||||
pgp_key_t pub = {0};
|
||||
pgp_key_t sec = {0};
|
||||
pgp_key_t pub = {};
|
||||
pgp_key_t sec = {};
|
||||
rnp_keygen_subkey_desc_t desc;
|
||||
pgp_fingerprint_t fp = {};
|
||||
pgp_sig_subpkt_t * subpkt = NULL;
|
||||
|
@ -1051,6 +1069,10 @@ TEST_F(rnp_tests, test_generated_key_sigs)
|
|||
// generate
|
||||
assert_true(pgp_generate_subkey(
|
||||
&desc, true, primary_sec, primary_pub, &sec, &pub, NULL, PGP_KEY_STORE_GPG));
|
||||
assert_true(pub.valid);
|
||||
assert_true(pub.validated);
|
||||
assert_true(sec.valid);
|
||||
assert_true(sec.validated);
|
||||
|
||||
// check packet and subsig counts
|
||||
assert_int_equal(2, pgp_key_get_rawpacket_count(&pub));
|
||||
|
@ -1109,12 +1131,22 @@ TEST_F(rnp_tests, test_generated_key_sigs)
|
|||
sub_sec = rnp_key_store_get_key_by_grip(secring, pgp_key_get_grip(&pub));
|
||||
assert_non_null(sub_pub);
|
||||
assert_non_null(sub_sec);
|
||||
assert_true(sub_pub->valid);
|
||||
assert_true(sub_pub->validated);
|
||||
assert_true(sub_sec->valid);
|
||||
assert_true(sub_sec->validated);
|
||||
|
||||
// validate via an alternative method
|
||||
assert_rnp_success(pgp_key_validate(sub_pub, pubring));
|
||||
sub_pub->valid = false;
|
||||
sub_pub->validated = false;
|
||||
pgp_key_validate(sub_pub, pubring);
|
||||
assert_true(sub_pub->valid);
|
||||
assert_rnp_success(pgp_key_validate(sub_sec, pubring));
|
||||
assert_true(sub_pub->validated);
|
||||
sub_sec->valid = false;
|
||||
sub_sec->validated = false;
|
||||
pgp_key_validate(sub_sec, pubring);
|
||||
assert_true(sub_sec->valid);
|
||||
assert_true(sub_sec->validated);
|
||||
}
|
||||
|
||||
rnp_key_store_free(pubring);
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2020 [Ribose Inc](https://www.ribose.com).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../rnp_tests.h"
|
||||
#include "../support.h"
|
||||
|
||||
TEST_F(rnp_tests, test_issue_1115)
|
||||
{
|
||||
rnp_ffi_t ffi = NULL;
|
||||
rnp_input_t input = NULL;
|
||||
|
||||
assert_rnp_success(rnp_ffi_create(&ffi, "GPG", "GPG"));
|
||||
assert_rnp_success(
|
||||
rnp_input_from_path(&input, "data/test_key_validity/case9/pubring.gpg"));
|
||||
assert_rnp_success(rnp_import_keys(ffi, input, RNP_LOAD_SAVE_PUBLIC_KEYS, NULL));
|
||||
assert_rnp_success(rnp_input_destroy(input));
|
||||
rnp_key_handle_t key = NULL;
|
||||
assert_rnp_success(rnp_locate_key(ffi, "userid", "Alice <alice@rnp>", &key));
|
||||
uint32_t expiry = 0;
|
||||
assert_rnp_success(rnp_key_get_expiration(key, &expiry));
|
||||
assert_int_equal(expiry, 0);
|
||||
assert_rnp_success(rnp_key_handle_destroy(key));
|
||||
assert_rnp_success(rnp_ffi_destroy(ffi));
|
||||
}
|
|
@ -68,8 +68,7 @@ TEST_F(rnp_tests, test_key_add_userid)
|
|||
|
||||
// add a userid
|
||||
|
||||
rnp_selfsig_cert_info_t selfsig;
|
||||
memset(&selfsig, 0, sizeof(selfsig));
|
||||
rnp_selfsig_cert_info_t selfsig = {};
|
||||
strcpy((char *) selfsig.userid, "added1");
|
||||
selfsig.key_flags = 0xAB;
|
||||
selfsig.key_expiration = 123456789;
|
||||
|
@ -79,17 +78,18 @@ TEST_F(rnp_tests, test_key_add_userid)
|
|||
|
||||
// make sure this userid has been marked as primary
|
||||
assert_int_equal(pgp_key_get_userid_count(key) - 1, key->uid0);
|
||||
// make sure key expiration and flags are set
|
||||
assert_int_equal(123456789, pgp_key_get_expiration(key));
|
||||
assert_int_equal(0xAB, pgp_key_get_flags(key));
|
||||
|
||||
// try to add the same userid (should fail)
|
||||
rnp_selfsig_cert_info_t dup_selfsig;
|
||||
memset(&dup_selfsig, 0, sizeof(dup_selfsig));
|
||||
rnp_selfsig_cert_info_t dup_selfsig = {};
|
||||
strcpy((char *) dup_selfsig.userid, "added1");
|
||||
assert_false(
|
||||
pgp_key_add_userid_certified(key, pgp_key_get_pkt(key), PGP_HASH_SHA1, &dup_selfsig));
|
||||
|
||||
// try to add another primary userid (should fail)
|
||||
rnp_selfsig_cert_info_t selfsig2;
|
||||
memset(&selfsig2, 0, sizeof(selfsig2));
|
||||
rnp_selfsig_cert_info_t selfsig2 = {};
|
||||
strcpy((char *) selfsig2.userid, "added2");
|
||||
selfsig2.primary = 1;
|
||||
assert_false(
|
||||
|
@ -107,12 +107,14 @@ TEST_F(rnp_tests, test_key_add_userid)
|
|||
assert_int_equal(pgp_key_get_userid_count(key), uidc + 2);
|
||||
assert_int_equal(pgp_key_get_subsig_count(key), subsigc + 2);
|
||||
|
||||
// make sure key expiration and flags are now updated
|
||||
assert_int_equal(0, pgp_key_get_expiration(key));
|
||||
assert_int_equal(0xCD, pgp_key_get_flags(key));
|
||||
// check the userids array
|
||||
// added1
|
||||
assert_int_equal(0, strcmp(pgp_key_get_userid(key, uidc)->str, "added1"));
|
||||
assert_int_equal(uidc, pgp_key_get_subsig(key, subsigc)->uid);
|
||||
assert_int_equal(0xAB, pgp_key_get_subsig(key, subsigc)->key_flags);
|
||||
assert_int_equal(123456789, pgp_key_get_expiration(key));
|
||||
// added2
|
||||
assert_int_equal(0, strcmp(pgp_key_get_userid(key, uidc + 1)->str, "added2"));
|
||||
assert_int_equal(uidc + 1, pgp_key_get_subsig(key, subsigc + 1)->uid);
|
||||
|
@ -142,12 +144,15 @@ TEST_F(rnp_tests, test_key_add_userid)
|
|||
assert_int_equal(pgp_key_get_userid_count(key), uidc + 2);
|
||||
assert_int_equal(pgp_key_get_subsig_count(key), subsigc + 2);
|
||||
|
||||
// make sure correct key expiration and flags are set
|
||||
assert_int_equal(0, pgp_key_get_expiration(key));
|
||||
assert_int_equal(0xCD, pgp_key_get_flags(key));
|
||||
|
||||
// check the userids array
|
||||
// added1
|
||||
assert_int_equal(0, strcmp(pgp_key_get_userid(key, uidc)->str, "added1"));
|
||||
assert_int_equal(uidc, pgp_key_get_subsig(key, subsigc)->uid);
|
||||
assert_int_equal(0xAB, pgp_key_get_subsig(key, subsigc)->key_flags);
|
||||
assert_int_equal(123456789, pgp_key_get_expiration(key));
|
||||
// added2
|
||||
assert_int_equal(0, strcmp(pgp_key_get_userid(key, uidc + 1)->str, "added2"));
|
||||
assert_int_equal(uidc + 1, pgp_key_get_subsig(key, subsigc + 1)->uid);
|
||||
|
|
|
@ -75,13 +75,11 @@ TEST_F(rnp_tests, test_key_protect_load_pgp)
|
|||
|
||||
pgp_key_t *tmp = NULL;
|
||||
assert_non_null(tmp = rnp_tests_get_key_by_id(ks, keyids[0], NULL));
|
||||
assert_non_null(tmp);
|
||||
|
||||
// steal this key from the store
|
||||
key = (pgp_key_t *) calloc(1, sizeof(*key));
|
||||
key = new pgp_key_t();
|
||||
assert_non_null(key);
|
||||
memcpy(key, tmp, sizeof(*key));
|
||||
assert_true(rnp_key_store_remove_key(ks, tmp));
|
||||
pgp_key_copy(key, tmp, false);
|
||||
rnp_key_store_free(ks);
|
||||
}
|
||||
|
||||
|
@ -250,5 +248,5 @@ TEST_F(rnp_tests, test_key_protect_load_pgp)
|
|||
assert_true(mpi_equal(&pgp_key_get_material(key)->rsa.u, &u));
|
||||
|
||||
// cleanup
|
||||
pgp_key_free(key);
|
||||
delete key;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ TEST_F(rnp_tests, test_key_store_search)
|
|||
// add our fake test keys
|
||||
for (size_t i = 0; i < ARRAY_SIZE(testdata); i++) {
|
||||
for (size_t n = 0; n < testdata[i].count; n++) {
|
||||
pgp_key_t key = {0};
|
||||
pgp_key_t key = {};
|
||||
|
||||
key.pkt.tag = PGP_PKT_PUBLIC_KEY;
|
||||
key.pkt.version = PGP_V4;
|
||||
|
|
|
@ -142,6 +142,13 @@ key_store_add(rnp_key_store_t *keyring, const char *keypath)
|
|||
src_close(&keysrc);
|
||||
}
|
||||
|
||||
static bool
|
||||
key_check(const rnp_key_store_t *keyring, const std::string &keyid, bool valid)
|
||||
{
|
||||
pgp_key_t *key = rnp_tests_get_key_by_id(keyring, keyid, NULL);
|
||||
return key && (key->validated) && (key->valid == valid);
|
||||
}
|
||||
|
||||
TEST_F(rnp_tests, test_forged_key_validate)
|
||||
{
|
||||
rnp_key_store_t *pubring;
|
||||
|
@ -152,19 +159,14 @@ TEST_F(rnp_tests, test_forged_key_validate)
|
|||
|
||||
/* load valid dsa-eg key */
|
||||
key_store_add(pubring, DATA_PATH "dsa-eg-pub.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "C8A10A7D78273E10", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "C8A10A7D78273E10", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load dsa-eg key with forged self-signature. Subkey will not be valid as well. */
|
||||
/* load dsa-eg key with forged self-signature and binding. Subkey will not be valid as
|
||||
* well. */
|
||||
key_store_add(pubring, DATA_PATH "dsa-eg-pub-forged-key.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "C8A10A7D78273E10", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "02A5715C3537717E", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "C8A10A7D78273E10", false));
|
||||
assert_true(key_check(pubring, "02A5715C3537717E", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load dsa-eg key with forged key material */
|
||||
|
@ -178,26 +180,18 @@ TEST_F(rnp_tests, test_forged_key_validate)
|
|||
|
||||
/* load dsa-eg keypair with forged subkey binding signature */
|
||||
key_store_add(pubring, DATA_PATH "dsa-eg-pub-forged-subkey.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "02A5715C3537717E", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "C8A10A7D78273E10", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "02A5715C3537717E", false));
|
||||
assert_true(key_check(pubring, "C8A10A7D78273E10", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load valid eddsa key */
|
||||
key_store_add(pubring, DATA_PATH "ecc-25519-pub.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "CC786278981B0728", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "CC786278981B0728", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load eddsa key with forged self-signature */
|
||||
key_store_add(pubring, DATA_PATH "ecc-25519-pub-forged-key.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "CC786278981B0728", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "CC786278981B0728", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load eddsa key with forged key material */
|
||||
|
@ -209,22 +203,15 @@ TEST_F(rnp_tests, test_forged_key_validate)
|
|||
|
||||
/* load valid ecdsa/ecdh p-256 keypair */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "23674F21B2441527", true));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh key with forged self-signature. Subkey is not valid as well. */
|
||||
/* load ecdsa/ecdh key with forged self-signature. Both valid since there is valid binding.
|
||||
*/
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-forged-key.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "23674F21B2441527", true));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh key with forged key material. Subkey is not valid as well. */
|
||||
|
@ -234,59 +221,43 @@ TEST_F(rnp_tests, test_forged_key_validate)
|
|||
key = rnp_tests_key_search(pubring, "ecc-p256");
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh keypair with forged subkey binding signature */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-forged-subkey.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", false));
|
||||
assert_true(key_check(pubring, "23674F21B2441527", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh keypair without certification */
|
||||
/* load ecdsa/ecdh keypair without certification: valid since have binding */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-no-certification.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "23674F21B2441527", true));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh keypair without certification and invalid binding */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-no-cert-malf-binding.pgp");
|
||||
assert_true(key_check(pubring, "23674F21B2441527", false));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh keypair without subkey binding */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-no-binding.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "23674F21B2441527", true));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load valid rsa/rsa keypair */
|
||||
key_store_add(pubring, DATA_PATH "rsa-rsa-pub.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "2FB9179118898E8B", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "6E2F73008F8B8D6E", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "2FB9179118898E8B", true));
|
||||
assert_true(key_check(pubring, "6E2F73008F8B8D6E", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load rsa/rsa key with forged self-signature. Subkey is not valid as well. */
|
||||
/* load rsa/rsa key with forged self-signature. Valid because of valid binding. */
|
||||
key_store_add(pubring, DATA_PATH "rsa-rsa-pub-forged-key.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "2FB9179118898E8B", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "6E2F73008F8B8D6E", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "2FB9179118898E8B", true));
|
||||
assert_true(key_check(pubring, "6E2F73008F8B8D6E", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load rsa/rsa key with forged key material. Subkey is not valid as well. */
|
||||
|
@ -296,59 +267,45 @@ TEST_F(rnp_tests, test_forged_key_validate)
|
|||
key = rnp_tests_key_search(pubring, "rsa-rsa");
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "6E2F73008F8B8D6E", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "6E2F73008F8B8D6E", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load rsa/rsa keypair with forged subkey binding signature */
|
||||
key_store_add(pubring, DATA_PATH "rsa-rsa-pub-forged-subkey.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "6E2F73008F8B8D6E", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "2FB9179118898E8B", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
assert_true(key_check(pubring, "2FB9179118898E8B", true));
|
||||
assert_true(key_check(pubring, "6E2F73008F8B8D6E", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load rsa/rsa keypair with future creation date */
|
||||
key_store_add(pubring, DATA_PATH "rsa-rsa-pub-future-key.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "3D032D00EE1EC3F5", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "021085B640CE8DCE", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "3D032D00EE1EC3F5", false));
|
||||
assert_true(key_check(pubring, "021085B640CE8DCE", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load eddsa/rsa keypair with certification with future creation date */
|
||||
/* load eddsa/rsa keypair with certification with future creation date - valid because of
|
||||
* binding. */
|
||||
key_store_add(pubring, DATA_PATH "ecc-25519-pub-future-cert.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "D3B746FA852C2BE8", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "EB8C21ACDC15CA14", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "D3B746FA852C2BE8", true));
|
||||
assert_true(key_check(pubring, "EB8C21ACDC15CA14", true));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load eddsa/rsa keypair with certification with future creation date - invalid because of
|
||||
* invalid binding. */
|
||||
key_store_add(pubring, DATA_PATH "ecc-25519-pub-future-cert-malf-bind.pgp");
|
||||
assert_true(key_check(pubring, "D3B746FA852C2BE8", false));
|
||||
assert_true(key_check(pubring, "EB8C21ACDC15CA14", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/rsa keypair with expired subkey */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-expired-subkey.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_true(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "23674F21B2441527", true));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
/* load ecdsa/ecdh keypair with expired key */
|
||||
key_store_add(pubring, DATA_PATH "ecc-p256-pub-expired-key.pgp");
|
||||
key = rnp_tests_get_key_by_id(pubring, "23674F21B2441527", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
key = rnp_tests_get_key_by_id(pubring, "37E285E9E9851491", NULL);
|
||||
assert_non_null(key);
|
||||
assert_false(key->valid);
|
||||
assert_true(key_check(pubring, "23674F21B2441527", false));
|
||||
assert_true(key_check(pubring, "37E285E9E9851491", false));
|
||||
rnp_key_store_clear(pubring);
|
||||
|
||||
rnp_key_store_free(pubring);
|
||||
|
@ -465,4 +422,35 @@ TEST_F(rnp_tests, test_key_validity)
|
|||
assert_non_null(subkey = pgp_key_get_subkey(key, pubring, 0));
|
||||
assert_false(subkey->valid);
|
||||
rnp_key_store_free(pubring);
|
||||
|
||||
/* Case8:
|
||||
* Keys Alice [pub, sub]
|
||||
* Userid is stripped from the key, but it still has valid subkey binding
|
||||
* Result: Alice [valid], Alice sub[valid]
|
||||
*/
|
||||
pubring = rnp_key_store_new(PGP_KEY_STORE_GPG, KEYSIG_PATH "case8/pubring.gpg");
|
||||
assert_non_null(pubring);
|
||||
assert_true(rnp_key_store_load_from_path(pubring, NULL));
|
||||
assert_non_null(key = rnp_tests_get_key_by_id(pubring, "0451409669FFDE3C", NULL));
|
||||
assert_true(key->valid);
|
||||
assert_int_equal(pgp_key_get_subkey_count(key), 1);
|
||||
assert_non_null(subkey = pgp_key_get_subkey(key, pubring, 0));
|
||||
assert_true(subkey->valid);
|
||||
rnp_key_store_free(pubring);
|
||||
|
||||
/* Case9:
|
||||
* Keys Alice [pub, sub]
|
||||
* Alice key has two self-signatures, one which expires key and second without key
|
||||
* expiration.
|
||||
* Result: Alice [valid], Alice sub[valid]
|
||||
*/
|
||||
pubring = rnp_key_store_new(PGP_KEY_STORE_GPG, KEYSIG_PATH "case9/pubring.gpg");
|
||||
assert_non_null(pubring);
|
||||
assert_true(rnp_key_store_load_from_path(pubring, NULL));
|
||||
assert_non_null(key = rnp_tests_get_key_by_id(pubring, "0451409669FFDE3C", NULL));
|
||||
assert_true(key->valid);
|
||||
assert_int_equal(pgp_key_get_subkey_count(key), 1);
|
||||
assert_non_null(subkey = pgp_key_get_subkey(key, pubring, 0));
|
||||
assert_true(subkey->valid);
|
||||
rnp_key_store_free(pubring);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,9 @@ TEST_F(rnp_tests, test_load_v3_keyring_pgp)
|
|||
assert_int_equal(pgp_key_get_flags(key),
|
||||
PGP_KF_ENCRYPT | PGP_KF_SIGN | PGP_KF_CERTIFY | PGP_KF_AUTH);
|
||||
|
||||
// confirm that key expiration is correct
|
||||
assert_int_equal(pgp_key_get_expiration(key), 0);
|
||||
|
||||
// cleanup
|
||||
rnp_key_store_free(key_store);
|
||||
|
||||
|
@ -84,8 +87,8 @@ TEST_F(rnp_tests, test_load_v3_keyring_pgp)
|
|||
assert_true(pgp_key_is_locked(key));
|
||||
|
||||
// decrypt the key
|
||||
pgp_rawpacket_t *pkt = pgp_key_get_rawpacket(key, 0);
|
||||
pgp_key_pkt_t * seckey =
|
||||
const pgp_rawpacket_t *pkt = pgp_key_get_rawpacket(key, 0);
|
||||
pgp_key_pkt_t * seckey =
|
||||
pgp_decrypt_seckey_pgp(pkt->raw, pkt->length, pgp_key_get_pkt(key), "password");
|
||||
assert_non_null(seckey);
|
||||
|
||||
|
@ -713,7 +716,7 @@ TEST_F(rnp_tests, test_load_merge)
|
|||
|
||||
TEST_F(rnp_tests, test_load_public_from_secret)
|
||||
{
|
||||
pgp_key_t * key, *skey1, *skey2, keycp;
|
||||
pgp_key_t * key, *skey1, *skey2, keycp = {};
|
||||
uint8_t keyid[PGP_KEY_ID_SIZE];
|
||||
uint8_t sub1id[PGP_KEY_ID_SIZE];
|
||||
uint8_t sub2id[PGP_KEY_ID_SIZE];
|
||||
|
@ -741,7 +744,6 @@ TEST_F(rnp_tests, test_load_public_from_secret)
|
|||
memcmp(pgp_key_get_subkey_grip(&keycp, 1), pgp_key_get_grip(skey2), PGP_KEY_GRIP_SIZE));
|
||||
assert_false(memcmp(pgp_key_get_grip(&keycp), pgp_key_get_grip(key), PGP_KEY_GRIP_SIZE));
|
||||
assert_int_equal(pgp_key_get_rawpacket(&keycp, 0)->tag, PGP_PKT_SECRET_KEY);
|
||||
pgp_key_free_data(&keycp);
|
||||
|
||||
/* copy the public part */
|
||||
assert_rnp_success(pgp_key_copy(&keycp, key, true));
|
||||
|
|
|
@ -245,6 +245,8 @@ void test_ffi_key_signatures(void **state);
|
|||
|
||||
void test_ffi_keys_import(void **state);
|
||||
|
||||
void test_ffi_stripped_keys_import(void **state);
|
||||
|
||||
void test_ffi_import_keys_check_pktlen(void **state);
|
||||
|
||||
void test_ffi_calculate_iterations(void **state);
|
||||
|
@ -279,6 +281,12 @@ void test_ffi_secret_sig_import(void **state);
|
|||
|
||||
void test_ffi_rnp_request_password(void **state);
|
||||
|
||||
void test_ffi_key_revoke(void **state);
|
||||
|
||||
void test_ffi_set_key_expiry(void **state);
|
||||
|
||||
void test_ffi_mdc_8k_boundary(void **state);
|
||||
|
||||
void test_dsa_roundtrip(void **state);
|
||||
|
||||
void test_dsa_verify_negative(void **state);
|
||||
|
@ -351,6 +359,8 @@ void test_partial_length_first_packet_length(void **state);
|
|||
|
||||
void test_kbx_nsigs(void **state);
|
||||
|
||||
void test_issue_1115(void **state);
|
||||
|
||||
#define assert_true(a) EXPECT_TRUE((a))
|
||||
#define assert_false(a) EXPECT_FALSE((a))
|
||||
#define assert_string_equal(a, b) EXPECT_STREQ((a), (b))
|
||||
|
|
|
@ -1162,7 +1162,7 @@ validate_key_sigs(const char *path)
|
|||
for (size_t i = 0; i < rnp_key_store_get_key_count(pubring); i++) {
|
||||
pgp_key_t *pkey = rnp_key_store_get_key(pubring, i);
|
||||
assert_non_null(pkey);
|
||||
assert_rnp_success(pgp_key_validate(pkey, pubring));
|
||||
pgp_key_validate(pkey, pubring);
|
||||
assert_true(pkey->valid);
|
||||
}
|
||||
rnp_key_store_free(pubring);
|
||||
|
@ -1179,7 +1179,7 @@ TEST_F(rnp_tests, test_stream_key_signature_validate)
|
|||
assert_true(rnp_key_store_load_from_path(pubring, NULL));
|
||||
assert_int_equal(rnp_key_store_get_key_count(pubring), 1);
|
||||
assert_non_null(pkey = rnp_key_store_get_key(pubring, 0));
|
||||
assert_rnp_success(pgp_key_validate(pkey, pubring));
|
||||
pgp_key_validate(pkey, pubring);
|
||||
assert_true(pkey->valid);
|
||||
rnp_key_store_free(pubring);
|
||||
|
||||
|
@ -1190,7 +1190,7 @@ TEST_F(rnp_tests, test_stream_key_signature_validate)
|
|||
assert_true(rnp_key_store_get_key_count(pubring) > 0);
|
||||
for (size_t i = 0; i < rnp_key_store_get_key_count(pubring); i++) {
|
||||
pkey = rnp_key_store_get_key(pubring, i);
|
||||
assert_rnp_success(pgp_key_validate(pkey, pubring));
|
||||
pgp_key_validate(pkey, pubring);
|
||||
// subkey #2 is expired
|
||||
if (i == 2) {
|
||||
assert_false(pkey->valid);
|
||||
|
|
|
@ -46,7 +46,7 @@ find_subsig(const pgp_key_t *key, const char *userid)
|
|||
}
|
||||
// find the subsig index
|
||||
for (size_t i = 0; i < pgp_key_get_subsig_count(key); i++) {
|
||||
pgp_subsig_t *subsig = pgp_key_get_subsig(key, i);
|
||||
const pgp_subsig_t *subsig = pgp_key_get_subsig(key, i);
|
||||
if ((int) subsig->uid == uididx) {
|
||||
return subsig;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче