* build-packet.c (build_sig_subpkt): Comments.
[gnupg.git] / g10 / build-packet.c
index e7bc3f6..3fec9a8 100644 (file)
@@ -1,5 +1,6 @@
 /* build-packet.c - assemble packets and write them
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -44,7 +45,6 @@ static u32 calc_plaintext( PKT_plaintext *pt );
 static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
 static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
 static int do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed );
-static int do_mdc( IOBUF out, PKT_mdc *mdc );
 static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
 static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
 static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
@@ -122,9 +122,6 @@ build_packet( IOBUF out, PACKET *pkt )
       case PKT_ENCRYPTED_MDC:
        rc = do_encrypted_mdc( out, ctb, pkt->pkt.encrypted );
        break;
-      case PKT_MDC:
-       rc = do_mdc( out, pkt->pkt.mdc );
-       break;
       case PKT_COMPRESSED:
        rc = do_compressed( out, ctb, pkt->pkt.compressed );
        break;
@@ -136,6 +133,7 @@ build_packet( IOBUF out, PACKET *pkt )
        break;
       case PKT_RING_TRUST:
        break; /* ignore it (keyring.c does write it directly)*/
+      case PKT_MDC: /* we write it directly, so we should never see it here. */
       default:
        log_bug("invalid packet type in build_packet()\n");
        break;
@@ -393,7 +391,7 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
            iobuf_put(a, sk->protect.algo );
            if( sk->protect.s2k.mode >= 1000 ) {
                 /* These modes are not possible in OpenPGP, we use them
-                   to implement our extesnsions, 101 can ve views as a
+                   to implement our extensions, 101 can be seen as a
                    private/experimental extension (this is not
                    specified in rfc2440 but the same scheme is used
                    for all other algorithm identifiers) */
@@ -429,8 +427,20 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
        p = mpi_get_opaque( sk->skey[npkey], &i );
        iobuf_write(a, p, i );
     }
+    else if( sk->is_protected ) {
+        /* The secret key is protected te old v4 way. */
+       for(   ; i < nskey; i++ ) {
+            byte *p;
+            int ndata;
+
+            assert (mpi_is_opaque (sk->skey[i]));
+            p = mpi_get_opaque (sk->skey[i], &ndata);
+            iobuf_write (a, p, ndata);
+        }
+       write_16(a, sk->csum );
+    }
     else {
-        /* v3 way - same code for protected and non- protected key */
+        /* non-protected key */
        for(   ; i < nskey; i++ )
            mpi_write(a, sk->skey[i] );
        write_16(a, sk->csum );
@@ -530,6 +540,12 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
     byte buf[1000]; /* this buffer has the plaintext! */
     int nbytes;
 
+    /* Truncate namelen to the maximum 255 characters.  This does mean
+       that a function that calls build_packet with an illegal literal
+       packet will get it back legalized. */
+    if(pt->namelen>255)
+      pt->namelen=255;
+
     write_header(out, ctb, calc_plaintext( pt ) );
     iobuf_put(out, pt->mode );
     iobuf_put(out, pt->namelen );
@@ -546,7 +562,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt )
        }
        n += nbytes;
     }
-    memset(buf,0,1000); /* at least burn the buffer */
+    wipememory(buf,1000); /* burn the buffer */
     if( !pt->len )
        iobuf_set_block_mode(out, 0 ); /* write end marker */
     else if( n != pt->len )
@@ -580,7 +596,8 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
 
     assert( ed->mdc_method );
 
-    n = ed->len ? (ed->len + ed->extralen) : 0;
+    /* Take version number and the following MDC packet in account. */
+    n = ed->len ? (ed->len + ed->extralen + 1 + 22) : 0;
     write_header(out, ctb, n );
     iobuf_put(out, 1 );  /* version */
 
@@ -591,22 +608,15 @@ do_encrypted_mdc( IOBUF out, int ctb, PKT_encrypted *ed )
 
 
 static int
-do_mdc( IOBUF out, PKT_mdc *mdc )
-{
-    /* This packet requires a fixed header encoding */
-    iobuf_put( out, 0xd3 ); /* packet ID and 1 byte length */
-    iobuf_put( out, 0x14 ); /* length = 20 */
-    if( iobuf_write( out, mdc->hash, sizeof(mdc->hash) ) )
-       return G10ERR_WRITE_FILE;
-    return 0;
-}
-
-static int
 do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
 {
     int rc = 0;
 
-    /* we must use the old convention and don't use blockmode */
+    /* We must use the old convention and don't use blockmode for tyhe
+       sake of PGP 2 compatibility.  However if the new_ctb flag was
+       set, CTB is already formatted as new style and write_header2
+       does create a partial length encoding using new the new
+       style. */
     write_header2(out, ctb, 0, 0, 0 );
     iobuf_put(out, cd->algorithm );
 
@@ -751,6 +761,24 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
          sig->flags.revocable=0;
        break;
 
+      case SIGSUBPKT_TRUST:
+       sig->trust_depth=buffer[0];
+       sig->trust_value=buffer[1];
+       break;
+
+      case SIGSUBPKT_REGEXP:
+       sig->trust_regexp=buffer;
+       break;
+
+       /* This should never happen since we don't currently allow
+          creating such a subpacket, but just in case... */
+      case SIGSUBPKT_SIG_EXPIRE:
+       if(buffer_to_u32(buffer)+sig->timestamp<=make_timestamp())
+         sig->flags.expired=1;
+       else
+         sig->flags.expired=0;
+       break;
+
       default:
        break;
       }
@@ -766,6 +794,10 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
       case SIGSUBPKT_PRIV_VERIFY_CACHE: /*(obsolete)*/
        BUG();
        break;
+       /* The issuer being unhashed is a historical oddity.  It
+          should work equally as well hashed.  Of course, if even an
+          unhashed issuer is tampered with, it makes it awfully hard
+          to verify the sig... */
       case SIGSUBPKT_ISSUER:
         hashed = 0;
         break;
@@ -857,7 +889,11 @@ build_sig_subpkt_from_sig( PKT_signature *sig )
 
     if(sig->expiredate)
       {
-       u = sig->expiredate-sig->timestamp;
+       if(sig->expiredate>sig->timestamp)
+         u=sig->expiredate-sig->timestamp;
+       else
+         u=0;
+
        buf[0] = (u >> 24) & 0xff;
        buf[1] = (u >> 16) & 0xff;
        buf[2] = (u >>  8) & 0xff;
@@ -1161,4 +1197,3 @@ write_version( IOBUF out, int ctb )
        return -1;
     return 0;
 }
-