aboutsummaryrefslogtreecommitdiffstats
path: root/g10/build-packet.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/build-packet.c132
1 files changed, 73 insertions, 59 deletions
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 83d6c7a73..1cdf9616c 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -1,6 +1,6 @@
/* build-packet.c - assemble packets and write them
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- * 2006, 2010 Free Software Foundation, Inc.
+ * 2006, 2010, 2011 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -157,32 +157,41 @@ build_packet( IOBUF out, PACKET *pkt )
/*
* Write the mpi A to OUT.
*/
-static int
-mpi_write (iobuf_t out, gcry_mpi_t a)
+gpg_error_t
+gpg_mpi_write (iobuf_t out, gcry_mpi_t a)
{
- char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
- size_t nbytes;
int rc;
- nbytes = DIM(buffer);
- rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
- if( !rc )
- rc = iobuf_write( out, buffer, nbytes );
- else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
+ if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
{
- log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
- /* The buffer was too small. We better tell the user about the MPI. */
- rc = gpg_error (GPG_ERR_TOO_LARGE);
+ size_t nbits;
+ const void *p;
+
+ p = gcry_mpi_get_opaque (a, &nbits);
+ rc = iobuf_write (out, p, (nbits+7)/8);
+ }
+ else
+ {
+ char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */
+ size_t nbytes;
+
+ nbytes = DIM(buffer);
+ rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
+ if( !rc )
+ rc = iobuf_write( out, buffer, nbytes );
+ else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT )
+ {
+ log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a));
+ /* The buffer was too small. We better tell the user about the MPI. */
+ rc = gpg_error (GPG_ERR_TOO_LARGE);
+ }
}
return rc;
}
-
-/****************
- * calculate the length of a packet described by PKT
- */
+/* Calculate the length of a packet described by PKT. */
u32
calc_packet_length( PACKET *pkt )
{
@@ -216,19 +225,20 @@ calc_packet_length( PACKET *pkt )
return n;
}
-static void
+
+static gpg_error_t
write_fake_data (IOBUF out, gcry_mpi_t a)
{
- if (a)
- {
- unsigned int n;
- void *p;
-
- p = gcry_mpi_get_opaque ( a, &n );
- iobuf_write (out, p, (n+7)/8 );
- }
+ unsigned int n;
+ void *p;
+
+ if (!a)
+ return 0;
+ p = gcry_mpi_get_opaque ( a, &n);
+ return iobuf_write (out, p, (n+7)/8 );
}
+
static int
do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
{
@@ -272,36 +282,39 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
ndays = 0;
write_16(a, ndays);
}
-
+
iobuf_put (a, pk->pubkey_algo );
-
+
/* Get number of secret and public parameters. They are held in one
array first the public ones, then the secret ones. */
nskey = pubkey_get_nskey (pk->pubkey_algo);
npkey = pubkey_get_npkey (pk->pubkey_algo);
-
+
/* If we don't have any public parameters - which is the case if we
don't know the algorithm used - the parameters are stored as one
blob in a faked (opaque) MPI. */
- if (!npkey)
+ if (!npkey)
{
write_fake_data (a, pk->pkey[0]);
goto leave;
}
assert (npkey < nskey);
- /* Writing the public parameters is easy. */
for (i=0; i < npkey; i++ )
- if ((err = mpi_write (a, pk->pkey[i])))
- goto leave;
-
+ {
+ err = gpg_mpi_write (a, pk->pkey[i]);
+ if (err)
+ goto leave;
+ }
+
+
if (pk->seckey_info)
{
/* This is a secret key packet. */
struct seckey_info *ski = pk->seckey_info;
/* Build the header for protected (encrypted) secret parameters. */
- if (ski->is_protected)
+ if (ski->is_protected)
{
if ( is_RSA (pk->pubkey_algo) && pk->version < 4 && !ski->s2k.mode )
{
@@ -321,12 +334,12 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
viewed as a private/experimental extension (this
is not specified in rfc2440 but the same scheme
is used for all other algorithm identifiers). */
- iobuf_put (a, 101);
+ iobuf_put (a, 101);
iobuf_put (a, ski->s2k.hash_algo);
iobuf_write (a, "GNU", 3 );
iobuf_put (a, ski->s2k.mode - 1000);
}
- else
+ else
{
iobuf_put (a, ski->s2k.mode);
iobuf_put (a, ski->s2k.hash_algo);
@@ -336,7 +349,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
iobuf_write (a, ski->s2k.salt, 8);
if (ski->s2k.mode == 3)
- iobuf_put (a, ski->s2k.count);
+ iobuf_put (a, ski->s2k.count);
/* For our special modes 1001, 1002 we do not need an IV. */
if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
@@ -347,10 +360,10 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
iobuf_put (a, 0 );
if (ski->s2k.mode == 1001)
- ; /* GnuPG extension - don't write a secret key at all. */
+ ; /* GnuPG extension - don't write a secret key at all. */
else if (ski->s2k.mode == 1002)
- {
- /* GnuPG extension - divert to OpenPGP smartcard. */
+ {
+ /* GnuPG extension - divert to OpenPGP smartcard. */
/* Length of the serial number or 0 for no serial number. */
iobuf_put (a, ski->ivlen );
/* The serial number gets stored in the IV field. */
@@ -361,19 +374,19 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
/* The secret key is protected - write it out as it is. */
byte *p;
unsigned int ndatabits;
-
+
assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
iobuf_write (a, p, (ndatabits+7)/8 );
}
- else if (ski->is_protected)
+ else if (ski->is_protected)
{
/* The secret key is protected the old v4 way. */
- for ( ; i < nskey; i++ )
+ for ( ; i < nskey; i++ )
{
byte *p;
unsigned int ndatabits;
-
+
assert (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE));
p = gcry_mpi_get_opaque (pk->pkey[i], &ndatabits);
iobuf_write (a, p, (ndatabits+7)/8);
@@ -384,7 +397,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
{
/* Non-protected key. */
for ( ; i < nskey; i++ )
- if ( (err = mpi_write (a, pk->pkey[i])))
+ if ( (err = gpg_mpi_write (a, pk->pkey[i])))
goto leave;
write_16 (a, ski->csum );
}
@@ -442,9 +455,9 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
int rc = 0;
int n, i;
IOBUF a = iobuf_temp();
-
+
write_version( a, ctb );
- if ( enc->throw_keyid )
+ if ( enc->throw_keyid )
{
write_32(a, 0 ); /* Don't tell Eve who can decrypt the message. */
write_32(a, 0 );
@@ -458,13 +471,14 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
n = pubkey_get_nenc( enc->pubkey_algo );
if ( !n )
write_fake_data( a, enc->data[0] );
+
for (i=0; i < n && !rc ; i++ )
- rc = mpi_write(a, enc->data[i] );
+ rc = gpg_mpi_write (a, enc->data[i]);
if (!rc)
{
- write_header(out, ctb, iobuf_get_temp_length(a) );
- rc = iobuf_write_temp( out, a );
+ write_header (out, ctb, iobuf_get_temp_length(a) );
+ rc = iobuf_write_temp (out, a);
}
iobuf_close(a);
return rc;
@@ -498,7 +512,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
for(i=0; i < pt->namelen; i++ )
iobuf_put(out, pt->name[i] );
rc = write_32(out, pt->timestamp );
- if (rc)
+ if (rc)
return rc;
n = 0;
@@ -614,7 +628,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
}
if( buflen < n )
break;
-
+
type = *buffer & 0x7f;
if( type == reqtype ) {
buffer++;
@@ -648,7 +662,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype )
* Note: All pointers into sig->[un]hashed (e.g. returned by
* parse_sig_subpkt) are not valid after a call to this function. The
* data to put into the subpaket should be in a buffer with a length
- * of buflen.
+ * of buflen.
*/
void
build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
@@ -751,7 +765,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
case SIGSUBPKT_SIGNATURE:
hashed = 0;
break;
- default:
+ default:
hashed = 1;
break;
}
@@ -802,7 +816,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
memcpy (p, buffer, buflen);
}
- if (hashed)
+ if (hashed)
sig->hashed = newarea;
else
sig->unhashed = newarea;
@@ -1088,7 +1102,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
if ( sig->version < 4 )
iobuf_put (a, 5 ); /* Constant */
iobuf_put (a, sig->sig_class );
- if ( sig->version < 4 )
+ if ( sig->version < 4 )
{
write_32(a, sig->timestamp );
write_32(a, sig->keyid[0] );
@@ -1096,7 +1110,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
}
iobuf_put(a, sig->pubkey_algo );
iobuf_put(a, sig->digest_algo );
- if ( sig->version >= 4 )
+ if ( sig->version >= 4 )
{
size_t nn;
/* Timestamp and keyid must have been packed into the subpackets
@@ -1117,7 +1131,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
if ( !n )
write_fake_data( a, sig->data[0] );
for (i=0; i < n && !rc ; i++ )
- rc = mpi_write(a, sig->data[i] );
+ rc = gpg_mpi_write (a, sig->data[i] );
if (!rc)
{