mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-05 12:31:50 +01:00
gpg: Refactor function encrypt_seskey.
* g10/encrypt.c (encrypt_seskey): Allocate the buffer for the encrypted key and returns that buffer and its length. (encrypt_simple): Adjust for above change. (write_symkey_enc): Ditto. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
7356d6ec50
commit
0131d4369a
154
g10/encrypt.c
154
g10/encrypt.c
@ -67,45 +67,75 @@ encrypt_store (const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *SESKEY contains the unencrypted session key ((*SESKEY)->KEY) and
|
/* Encrypt a session key using DEK and store a pointer to the result
|
||||||
the algorithm that will be used to encrypt the contents of the SED
|
* at R_ENCKEY and its length at R_ENCKEYLEN.
|
||||||
packet ((*SESKEY)->ALGO). If *SESKEY is NULL, then a random
|
*
|
||||||
session key that is appropriate for DEK->ALGO is generated and
|
* R_SESKEY points to the unencrypted session key (.KEY, >KEYLEN) and
|
||||||
stored there.
|
* the algorithm that will be used to encrypt the contents of the
|
||||||
|
* SKESK packet (.ALGO). If R_SESKEY points to NULL, then a random
|
||||||
Encrypt that session key using DEK and store the result in ENCKEY,
|
* session key that is appropriate for DEK->ALGO is generated and
|
||||||
which must be large enough to hold (*SESKEY)->KEYLEN + 1 bytes. */
|
* stored at R_SESKEY.
|
||||||
void
|
*/
|
||||||
encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey)
|
gpg_error_t
|
||||||
|
encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen)
|
||||||
{
|
{
|
||||||
gcry_cipher_hd_t hd;
|
gpg_error_t err;
|
||||||
byte buf[33];
|
gcry_cipher_hd_t hd = NULL;
|
||||||
|
byte *buf = NULL;
|
||||||
|
DEK *seskey;
|
||||||
|
|
||||||
log_assert ( dek->keylen <= 32 );
|
*r_enckey = NULL;
|
||||||
if (!*seskey)
|
*r_enckeylen = 0;
|
||||||
|
|
||||||
|
if (*r_seskey)
|
||||||
|
seskey = *r_seskey;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*seskey=xmalloc_clear(sizeof(DEK));
|
seskey = xtrycalloc (1, sizeof(DEK));
|
||||||
(*seskey)->algo=dek->algo;
|
if (!seskey)
|
||||||
make_session_key(*seskey);
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
seskey->algo = dek->algo;
|
||||||
|
make_session_key (seskey);
|
||||||
/*log_hexdump( "thekey", c->key, c->keylen );*/
|
/*log_hexdump( "thekey", c->key, c->keylen );*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = xtrymalloc_secure (1 + seskey->keylen);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
/* The encrypted session key is prefixed with a one-octet algorithm id. */
|
/* The encrypted session key is prefixed with a one-octet algorithm id. */
|
||||||
buf[0] = (*seskey)->algo;
|
buf[0] = seskey->algo;
|
||||||
memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen );
|
memcpy (buf + 1, seskey->key, seskey->keylen);
|
||||||
|
|
||||||
/* We only pass already checked values to the following function,
|
err = openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1);
|
||||||
thus we consider any failure as fatal. */
|
if (!err)
|
||||||
if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
|
err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
|
||||||
BUG ();
|
if (!err)
|
||||||
if (gcry_cipher_setkey (hd, dek->key, dek->keylen))
|
err = gcry_cipher_setiv (hd, NULL, 0);
|
||||||
BUG ();
|
if (!err)
|
||||||
gcry_cipher_setiv (hd, NULL, 0);
|
err = gcry_cipher_encrypt (hd, buf, seskey->keylen + 1, NULL, 0);
|
||||||
gcry_cipher_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
*r_enckey = buf;
|
||||||
|
buf = NULL;
|
||||||
|
*r_enckeylen = seskey->keylen + 1;
|
||||||
|
/* Return the session key in case we allocated it. */
|
||||||
|
*r_seskey = seskey;
|
||||||
|
seskey = NULL;
|
||||||
|
|
||||||
|
leave:
|
||||||
gcry_cipher_close (hd);
|
gcry_cipher_close (hd);
|
||||||
|
if (seskey != *r_seskey)
|
||||||
memcpy( enckey, buf, (*seskey)->keylen + 1 );
|
xfree (seskey);
|
||||||
wipememory( buf, sizeof buf ); /* burn key */
|
xfree (buf);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -218,9 +248,9 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
|||||||
PACKET pkt;
|
PACKET pkt;
|
||||||
PKT_plaintext *pt = NULL;
|
PKT_plaintext *pt = NULL;
|
||||||
STRING2KEY *s2k = NULL;
|
STRING2KEY *s2k = NULL;
|
||||||
byte enckey[33];
|
void *enckey = NULL;
|
||||||
|
size_t enckeylen = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int seskeylen = 0;
|
|
||||||
u32 filesize;
|
u32 filesize;
|
||||||
cipher_filter_context_t cfx;
|
cipher_filter_context_t cfx;
|
||||||
armor_filter_context_t *afx = NULL;
|
armor_filter_context_t *afx = NULL;
|
||||||
@ -273,6 +303,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
|||||||
if ( mode )
|
if ( mode )
|
||||||
{
|
{
|
||||||
int canceled;
|
int canceled;
|
||||||
|
aead_algo_t aead_algo;
|
||||||
|
|
||||||
s2k = xmalloc_clear( sizeof *s2k );
|
s2k = xmalloc_clear( sizeof *s2k );
|
||||||
s2k->mode = opt.s2k_mode;
|
s2k->mode = opt.s2k_mode;
|
||||||
@ -296,21 +327,33 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
|||||||
"due to the S2K mode\n"));
|
"due to the S2K mode\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See whether we want to use AEAD. */
|
||||||
|
aead_algo = use_aead (NULL, cfx.dek->algo)? default_aead_algo () : 0;
|
||||||
|
|
||||||
if ( use_seskey )
|
if ( use_seskey )
|
||||||
{
|
{
|
||||||
DEK *dek = NULL;
|
DEK *dek = NULL;
|
||||||
|
|
||||||
seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
|
rc = encrypt_seskey (cfx.dek, &dek, &enckey, &enckeylen);
|
||||||
encrypt_seskey( cfx.dek, &dek, enckey );
|
if (rc)
|
||||||
xfree( cfx.dek ); cfx.dek = dek;
|
{
|
||||||
|
xfree (cfx.dek);
|
||||||
|
xfree (s2k);
|
||||||
|
iobuf_close (inp);
|
||||||
|
release_progress_context (pfx);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/* Replace key in DEK. */
|
||||||
|
xfree (cfx.dek);
|
||||||
|
cfx.dek = dek;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
log_info(_("using cipher %s\n"),
|
log_info(_("using cipher %s\n"),
|
||||||
openpgp_cipher_algo_name (cfx.dek->algo));
|
openpgp_cipher_algo_name (cfx.dek->algo));
|
||||||
|
|
||||||
if (use_aead (NULL, cfx.dek->algo))
|
if (aead_algo)
|
||||||
cfx.dek->use_aead = default_aead_algo ();
|
cfx.dek->use_aead = aead_algo;
|
||||||
else
|
else
|
||||||
cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);
|
cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);
|
||||||
}
|
}
|
||||||
@ -342,20 +385,23 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
|||||||
|
|
||||||
if ( s2k )
|
if ( s2k )
|
||||||
{
|
{
|
||||||
PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
|
/* Fixme: This is quite similar to write_symkey_enc. */
|
||||||
|
PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen);
|
||||||
enc->version = 4;
|
enc->version = 4;
|
||||||
enc->cipher_algo = cfx.dek->algo;
|
enc->cipher_algo = cfx.dek->algo;
|
||||||
enc->s2k = *s2k;
|
enc->s2k = *s2k;
|
||||||
if ( use_seskey && seskeylen )
|
if (enckeylen)
|
||||||
{
|
{
|
||||||
enc->seskeylen = seskeylen + 1; /* algo id */
|
enc->seskeylen = enckeylen;
|
||||||
memcpy (enc->seskey, enckey, seskeylen + 1 );
|
memcpy (enc->seskey, enckey, enckeylen);
|
||||||
}
|
}
|
||||||
pkt.pkttype = PKT_SYMKEY_ENC;
|
pkt.pkttype = PKT_SYMKEY_ENC;
|
||||||
pkt.pkt.symkey_enc = enc;
|
pkt.pkt.symkey_enc = enc;
|
||||||
if ((rc = build_packet( out, &pkt )))
|
if ((rc = build_packet( out, &pkt )))
|
||||||
log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
|
log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
|
||||||
xfree (enc);
|
xfree (enc);
|
||||||
|
xfree (enckey);
|
||||||
|
enckey = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opt.no_literal)
|
if (!opt.no_literal)
|
||||||
@ -459,6 +505,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
|
|||||||
if (pt)
|
if (pt)
|
||||||
pt->buf = NULL;
|
pt->buf = NULL;
|
||||||
free_packet (&pkt, NULL);
|
free_packet (&pkt, NULL);
|
||||||
|
xfree (enckey);
|
||||||
xfree (cfx.dek);
|
xfree (cfx.dek);
|
||||||
xfree (s2k);
|
xfree (s2k);
|
||||||
release_armor_context (afx);
|
release_armor_context (afx);
|
||||||
@ -493,20 +540,29 @@ static int
|
|||||||
write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
||||||
iobuf_t out)
|
iobuf_t out)
|
||||||
{
|
{
|
||||||
int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
|
int rc;
|
||||||
|
void *enckey;
|
||||||
|
size_t enckeylen;
|
||||||
PKT_symkey_enc *enc;
|
PKT_symkey_enc *enc;
|
||||||
byte enckey[33];
|
|
||||||
PACKET pkt;
|
PACKET pkt;
|
||||||
|
|
||||||
enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
|
rc = encrypt_seskey (symkey_dek, &dek, &enckey, &enckeylen);
|
||||||
encrypt_seskey(symkey_dek,&dek,enckey);
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
enc = xtrycalloc (1, sizeof (PKT_symkey_enc) + enckeylen);
|
||||||
|
if (!enc)
|
||||||
|
{
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
xfree (enckey);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
enc->version = 4;
|
enc->version = 4;
|
||||||
enc->cipher_algo = opt.s2k_cipher_algo;
|
enc->cipher_algo = opt.s2k_cipher_algo;
|
||||||
enc->s2k = *symkey_s2k;
|
enc->s2k = *symkey_s2k;
|
||||||
enc->seskeylen = seskeylen + 1; /* algo id */
|
enc->seskeylen = enckeylen;
|
||||||
memcpy( enc->seskey, enckey, seskeylen + 1 );
|
memcpy (enc->seskey, enckey, enckeylen);
|
||||||
|
xfree (enckey);
|
||||||
|
|
||||||
pkt.pkttype = PKT_SYMKEY_ENC;
|
pkt.pkttype = PKT_SYMKEY_ENC;
|
||||||
pkt.pkt.symkey_enc = enc;
|
pkt.pkt.symkey_enc = enc;
|
||||||
@ -514,7 +570,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
|
|||||||
if ((rc=build_packet(out,&pkt)))
|
if ((rc=build_packet(out,&pkt)))
|
||||||
log_error("build symkey_enc packet failed: %s\n",gpg_strerror (rc));
|
log_error("build symkey_enc packet failed: %s\n",gpg_strerror (rc));
|
||||||
|
|
||||||
xfree(enc);
|
xfree (enc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2283,9 +2283,11 @@ sk_esk (const char *option, int argc, char *argv[], void *cookie)
|
|||||||
DEK *sesdekp = &sesdek;
|
DEK *sesdekp = &sesdek;
|
||||||
|
|
||||||
/* Now encrypt the session key (or rather, the algorithm used to
|
/* Now encrypt the session key (or rather, the algorithm used to
|
||||||
encrypt the SED plus the session key) using ENCKEY. */
|
encrypt the SKESK plus the session key) using ENCKEY. */
|
||||||
ske->seskeylen = 1 + sesdek.keylen;
|
err = encrypt_seskey (&s2kdek, &sesdekp,
|
||||||
encrypt_seskey (&s2kdek, &sesdekp, ske->seskey);
|
(void**)&ske->seskey, (size_t *)&ske->seskeylen);
|
||||||
|
if (err)
|
||||||
|
log_fatal ("encrypt_seskey failed: %s\n", gpg_strerror (err));
|
||||||
|
|
||||||
/* Save the session key for later. */
|
/* Save the session key for later. */
|
||||||
session_key = sesdek;
|
session_key = sesdek;
|
||||||
|
@ -232,7 +232,8 @@ void display_online_help( const char *keyword );
|
|||||||
|
|
||||||
/*-- encode.c --*/
|
/*-- encode.c --*/
|
||||||
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
|
||||||
void encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey);
|
gpg_error_t encrypt_seskey (DEK *dek, DEK **r_seskey,
|
||||||
|
void **r_enckey, size_t *r_enckeylen);
|
||||||
int use_aead (pk_list_t pk_list, int algo);
|
int use_aead (pk_list_t pk_list, int algo);
|
||||||
int use_mdc (pk_list_t pk_list,int algo);
|
int use_mdc (pk_list_t pk_list,int algo);
|
||||||
int encrypt_symmetric (const char *filename );
|
int encrypt_symmetric (const char *filename );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user