pgp_encrypt_buf now accepts multiple recipients and raw openPGP message as input

master
Edouard Tisserant 8 years ago
parent 1e8d2a8003
commit 8423fdb58e

@ -932,7 +932,7 @@ encode_m_buf(const uint8_t *M, size_t mLen, const pgp_pubkey_t * pubkey,
\note Currently hard-coded to use RSA
*/
pgp_pk_sesskey_t *
pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername, pgp_pk_sesskey_t *initial_sesskey)
{
/*
* Creates a random session key and encrypts it for the given key
@ -1022,7 +1022,14 @@ pgp_create_pk_sesskey(const pgp_key_t *key, const char *ciphername)
sesskey->alg = pubkey->alg;
sesskey->symm_alg = cipher;
pgp_random(sesskey->key, cipherinfo.keysize);
if(initial_sesskey){
if(initial_sesskey->symm_alg != cipher){
return NULL;
}
memcpy(sesskey->key, initial_sesskey->key, cipherinfo.keysize);
}else{
pgp_random(sesskey->key, cipherinfo.keysize);
}
if (pgp_get_debug_level(__FILE__)) {
hexdump(stderr, "sesskey created", sesskey->key,

@ -91,7 +91,7 @@ unsigned pgp_write_litdata(pgp_output_t *,
const uint8_t *,
const int,
const pgp_litdata_enum);
pgp_pk_sesskey_t *pgp_create_pk_sesskey(const pgp_key_t *, const char *);
pgp_pk_sesskey_t *pgp_create_pk_sesskey(const pgp_key_t *, const char *, pgp_pk_sesskey_t *);
unsigned pgp_write_pk_sesskey(pgp_output_t *, pgp_pk_sesskey_t *);
unsigned pgp_write_xfer_pubkey(pgp_output_t *,
const pgp_key_t *, const unsigned);

@ -361,6 +361,7 @@ pgp_encrypt_file(pgp_io_t *io,
{
pgp_output_t *output;
pgp_memory_t *inmem;
pgp_keyring_t *rcpts;
int fd_out;
__PGP_USED(io);
@ -379,11 +380,23 @@ pgp_encrypt_file(pgp_io_t *io,
pgp_writer_push_armor_msg(output);
}
if ((rcpts = calloc(1, sizeof(*rcpts))) == NULL) {
(void) fprintf(io->errs,
"netpgp_encrypt_buf: out of memory to create recipients list\n");
return 0;
}
pgp_keyring_add(rcpts, key);
if(rcpts->keys == NULL){
(void) fprintf(io->errs,
"netpgp_encrypt_buf: out of memory to add recipient\n");
return 0;
}
/* Push the encrypted writer */
if (!pgp_push_enc_se_ip(output, key, cipher)) {
if (!pgp_push_enc_se_ip(output, rcpts, cipher, 0)) {
pgp_memory_free(inmem);
return 0;
}
pgp_keyring_free(rcpts);
/* This does the writing */
pgp_write(output, pgp_mem_data(inmem), (unsigned)pgp_mem_len(inmem));
@ -400,9 +413,10 @@ pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *io,
const void *input,
const size_t insize,
const pgp_key_t *pubkey,
const pgp_keyring_t *pubkeys,
const unsigned use_armour,
const char *cipher)
const char *cipher,
unsigned raw)
{
pgp_output_t *output;
pgp_memory_t *outmem;
@ -422,7 +436,7 @@ pgp_encrypt_buf(pgp_io_t *io,
}
/* Push the encrypted writer */
pgp_push_enc_se_ip(output, pubkey, cipher);
pgp_push_enc_se_ip(output, pubkeys, cipher, raw);
/* This does the writing */
pgp_write(output, input, (unsigned)insize);

@ -190,8 +190,8 @@ unsigned pgp_decrypt_file(pgp_io_t *,
pgp_memory_t *
pgp_encrypt_buf(pgp_io_t *, const void *, const size_t,
const pgp_key_t *,
const unsigned, const char *);
const pgp_keyring_t *,
const unsigned, const char *, unsigned);
pgp_memory_t *
pgp_decrypt_buf(pgp_io_t *,
const void *,

@ -1068,6 +1068,18 @@ pgp_export_key(pgp_io_t *io, const pgp_key_t *keydata, uint8_t *passphrase)
return cp;
}
/* lowlevel add to keyring */
int
pgp_keyring_add(pgp_keyring_t *dst, const pgp_key_t *src)
{
pgp_key_t *key;
EXPAND_ARRAY(dst, key);
key = &dst->keys[dst->keyc++];
memcpy(key, src, sizeof(*key));
return 1;
}
/* add a key to a public keyring */
int
pgp_add_to_pubring(pgp_keyring_t *keyring, const pgp_pubkey_t *pubkey, pgp_content_enum tag)

@ -144,6 +144,7 @@ int pgp_list_packets(pgp_io_t *,
char *pgp_export_key(pgp_io_t *, const pgp_key_t *, uint8_t *);
int pgp_keyring_add(pgp_keyring_t *, const pgp_key_t *);
int pgp_add_to_pubring(pgp_keyring_t *, const pgp_pubkey_t *, pgp_content_enum tag);
int pgp_add_to_secring(pgp_keyring_t *, const pgp_seckey_t *);

@ -1599,6 +1599,7 @@ netpgp_encrypt_memory(netpgp_t *netpgp,
int armored)
{
const pgp_key_t *keypair;
pgp_keyring_t *rcpts;
pgp_memory_t *enc;
pgp_io_t *io;
size_t m;
@ -1622,8 +1623,22 @@ netpgp_encrypt_memory(netpgp_t *netpgp,
"netpgp_encrypt_buf: input size is larger than output size\n");
return 0;
}
enc = pgp_encrypt_buf(io, in, insize, keypair, (unsigned)armored,
netpgp_getvar(netpgp, "cipher"));
if ((rcpts = calloc(1, sizeof(*rcpts))) == NULL) {
(void) fprintf(io->errs,
"netpgp_encrypt_buf: out of memory to create recipients list\n");
return 0;
}
pgp_keyring_add(rcpts, keypair);
if(rcpts->keys == NULL){
(void) fprintf(io->errs,
"netpgp_encrypt_buf: out of memory to add recipient\n");
return 0;
}
enc = pgp_encrypt_buf(io, in, insize, rcpts, (unsigned)armored,
netpgp_getvar(netpgp, "cipher"),0);
pgp_keyring_free(rcpts);
m = MIN(pgp_mem_len(enc), outsize);
(void) memcpy(out, pgp_mem_data(enc), m);
pgp_memory_free(enc);

@ -75,7 +75,7 @@ unsigned pgp_write_se_ip_pktset(pgp_output_t *, const uint8_t *,
const unsigned,
pgp_crypt_t *);
void pgp_push_enc_crypt(pgp_output_t *, pgp_crypt_t *);
int pgp_push_enc_se_ip(pgp_output_t *, const pgp_key_t *, const char *);
int pgp_push_enc_se_ip(pgp_output_t *, const pgp_keyring_t *, const char *, unsigned);
/* Secret Key checksum */
void pgp_push_checksum_writer(pgp_output_t *, pgp_seckey_t *);

@ -1011,6 +1011,7 @@ pgp_push_enc_crypt(pgp_output_t *output, pgp_crypt_t *pgp_crypt)
typedef struct {
pgp_crypt_t *crypt;
unsigned raw;
} encrypt_se_ip_t;
static unsigned encrypt_se_ip_writer(const uint8_t *,
@ -1026,24 +1027,39 @@ static void encrypt_se_ip_destroyer(pgp_writer_t *);
\brief Push Encrypted SE IP Writer onto stack
*/
int
pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *cipher)
pgp_push_enc_se_ip(pgp_output_t *output, const pgp_keyring_t *pubkeys, const char *cipher, unsigned raw)
{
pgp_pk_sesskey_t *initial_sesskey = NULL;
pgp_pk_sesskey_t *encrypted_pk_sesskey;
encrypt_se_ip_t *se_ip;
pgp_crypt_t *encrypted;
uint8_t *iv;
unsigned n;
if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
return 0;
}
/* Create and write encrypted PK session key */
if ((encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher)) == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
return 0;
}
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
for (n = 0; n < pubkeys->keyc; ++n) {
/* Create and write encrypted PK session key */
if ((encrypted_pk_sesskey =
pgp_create_pk_sesskey(&pubkeys->keys[n],
cipher, initial_sesskey)) == NULL) {
(void) fprintf(stderr, "pgp_push_enc_se_ip: null pk sesskey\n");
return 0;
}
if (initial_sesskey == NULL) {
initial_sesskey = encrypted_pk_sesskey;
}
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
if(encrypted_pk_sesskey != initial_sesskey){
free(encrypted_pk_sesskey);
}
}
/* Setup the se_ip */
if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) {
@ -1051,7 +1067,7 @@ pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *ci
(void) fprintf(stderr, "pgp_push_enc_se_ip: bad alloc\n");
return 0;
}
pgp_crypt_any(encrypted, encrypted_pk_sesskey->symm_alg);
pgp_crypt_any(encrypted, initial_sesskey->symm_alg);
if ((iv = calloc(1, encrypted->blocksize)) == NULL) {
free(se_ip);
free(encrypted);
@ -1059,16 +1075,17 @@ pgp_push_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const char *ci
return 0;
}
encrypted->set_iv(encrypted, iv);
encrypted->set_crypt_key(encrypted, &encrypted_pk_sesskey->key[0]);
encrypted->set_crypt_key(encrypted, &initial_sesskey->key[0]);
pgp_encrypt_init(encrypted);
se_ip->crypt = encrypted;
se_ip->raw = raw;
/* And push writer on stack */
pgp_writer_push(output, encrypt_se_ip_writer, NULL,
encrypt_se_ip_destroyer, se_ip);
/* tidy up */
free(encrypted_pk_sesskey);
free(initial_sesskey);
free(iv);
return 1;
}
@ -1089,19 +1106,29 @@ encrypt_se_ip_writer(const uint8_t *src,
pgp_memory_t *localmem;
unsigned ret = 1;
const uint8_t *zsrc;
unsigned zsrclen;
pgp_setup_memory_write(&litoutput, &litmem, bufsz);
pgp_setup_memory_write(&zoutput, &zmem, bufsz);
pgp_setup_memory_write(&output, &localmem, bufsz);
/* create literal data packet from source data */
pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
if (pgp_mem_len(litmem) <= len) {
(void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
return 0;
}
if (!se_ip->raw) {
/* create literal data packet from source data */
pgp_write_litdata(litoutput, src, (const int)len, PGP_LDT_BINARY);
if (pgp_mem_len(litmem) <= len) {
(void) fprintf(stderr, "encrypt_se_ip_writer: bad len\n");
return 0;
}
zsrc = pgp_mem_data(litmem);
zsrclen = (unsigned)pgp_mem_len(litmem);
}else{
zsrc = src;
zsrclen = len;
}
/* create compressed packet from literal data packet */
pgp_writez(zoutput, pgp_mem_data(litmem), (unsigned)pgp_mem_len(litmem));
pgp_writez(zoutput, zsrc, zsrclen);
/* create SE IP packet set from this compressed literal data */
pgp_write_se_ip_pktset(output, pgp_mem_data(zmem),
@ -1425,7 +1452,7 @@ pgp_push_stream_enc_se_ip(pgp_output_t *output, const pgp_key_t *pubkey, const c
"pgp_push_stream_enc_se_ip: bad alloc\n");
return;
}
encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher);
encrypted_pk_sesskey = pgp_create_pk_sesskey(pubkey, cipher, NULL);
pgp_write_pk_sesskey(output, encrypted_pk_sesskey);
/* Setup the se_ip */

Loading…
Cancel
Save