See ChangeLog: Wed Sep 15 16:22:17 CEST 1999 Werner Koch
[gnupg.git] / g10 / free-packet.c
index fb5949a..0a61e22 100644 (file)
@@ -1,14 +1,14 @@
 /* free-packet.c - cleanup stuff for packets
- *     Copyright (c) 1997 by Werner Koch (dd9jn)
+ *     Copyright (C) 1998 Free Software Foundation, Inc.
  *
- * This file is part of G10.
+ * This file is part of GnuPG.
  *
- * G10 is free software; you can redistribute it and/or modify
+ * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * G10 is distributed in the hope that it will be useful,
+ * GnuPG is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
 #include "util.h"
 #include "cipher.h"
 #include "memory.h"
+#include "options.h"
 
+void
+free_symkey_enc( PKT_symkey_enc *enc )
+{
+    m_free(enc);
+}
 
 void
 free_pubkey_enc( PKT_pubkey_enc *enc )
 {
-    if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       mpi_free( enc->d.elg.a );
-       mpi_free( enc->d.elg.b );
-    }
-    else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
-       mpi_free( enc->d.rsa.rsa_integer );
+    int n, i;
+    n = pubkey_get_nenc( enc->pubkey_algo );
+    if( !n )
+       mpi_free(enc->data[0]);
+    for(i=0; i < n; i++ )
+       mpi_free( enc->data[i] );
     m_free(enc);
 }
 
 void
-free_seckey_enc( PKT_signature *enc )
+free_seckey_enc( PKT_signature *sig )
 {
-    if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       mpi_free( enc->d.elg.a );
-       mpi_free( enc->d.elg.b );
-    }
-    else if( enc->pubkey_algo == PUBKEY_ALGO_RSA )
-       mpi_free( enc->d.rsa.rsa_integer );
-    m_free(enc);
+    int n, i;
+    n = pubkey_get_nsig( sig->pubkey_algo );
+    if( !n )
+       mpi_free(sig->data[0]);
+    for(i=0; i < n; i++ )
+       mpi_free( sig->data[i] );
+    m_free(sig->hashed_data);
+    m_free(sig->unhashed_data);
+    m_free(sig);
 }
 
+
+
 void
-free_public_cert( PKT_public_cert *cert )
+release_public_key_parts( PKT_public_key *pk )
 {
-    if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       mpi_free( cert->d.elg.p );
-       mpi_free( cert->d.elg.g );
-       mpi_free( cert->d.elg.y );
+    int n, i;
+    n = pubkey_get_npkey( pk->pubkey_algo );
+    if( !n )
+       mpi_free(pk->pkey[0]);
+    for(i=0; i < n; i++ ) {
+       mpi_free( pk->pkey[i] );
+       pk->pkey[i] = NULL;
     }
-    else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
-       mpi_free( cert->d.rsa.rsa_n );
-       mpi_free( cert->d.rsa.rsa_e );
+    if( pk->namehash ) {
+       m_free(pk->namehash);
+       pk->namehash = NULL;
     }
-    md_close( cert->mfx.md );
-    m_free(cert);
 }
 
-PKT_public_cert *
-copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
+
+void
+free_public_key( PKT_public_key *pk )
+{
+    release_public_key_parts( pk );
+    m_free(pk);
+}
+
+
+static void *
+cp_data_block( byte *s )
+{
+    byte *d;
+    u16 len;
+
+    if( !s )
+       return NULL;
+    len = (s[0] << 8) | s[1];
+    d = m_alloc( len+2 );
+    memcpy(d, s, len+2);
+    return d;
+}
+
+
+PKT_public_key *
+copy_public_key_new_namehash( PKT_public_key *d, PKT_public_key *s,
+                             const byte *namehash )
 {
+    int n, i;
+
     if( !d )
        d = m_alloc(sizeof *d);
     memcpy( d, s, sizeof *d );
-    if( s->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       d->d.elg.p = mpi_copy( s->d.elg.p );
-       d->d.elg.g = mpi_copy( s->d.elg.g );
-       d->d.elg.y = mpi_copy( s->d.elg.y );
+    if( namehash ) {
+       d->namehash = m_alloc( 20 );
+       memcpy(d->namehash, namehash, 20 );
+    }
+    else if( s->namehash ) {
+       d->namehash = m_alloc( 20 );
+       memcpy(d->namehash, s->namehash, 20 );
     }
-    else if( s->pubkey_algo == PUBKEY_ALGO_RSA ) {
-       d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
-       d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
+    n = pubkey_get_npkey( s->pubkey_algo );
+    if( !n )
+       d->pkey[0] = mpi_copy(s->pkey[0]);
+    else {
+       for(i=0; i < n; i++ )
+           d->pkey[i] = mpi_copy( s->pkey[i] );
     }
-    d->mfx.md = NULL;
     return d;
 }
 
-void
-free_secret_cert( PKT_secret_cert *cert )
+PKT_public_key *
+copy_public_key( PKT_public_key *d, PKT_public_key *s )
 {
-    if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       mpi_free( cert->d.elg.p );
-       mpi_free( cert->d.elg.g );
-       mpi_free( cert->d.elg.y );
-       mpi_free( cert->d.elg.x );
+   return copy_public_key_new_namehash( d, s, NULL );
+}
+
+PKT_signature *
+copy_signature( PKT_signature *d, PKT_signature *s )
+{
+    int n, i;
+
+    if( !d )
+       d = m_alloc(sizeof *d);
+    memcpy( d, s, sizeof *d );
+    n = pubkey_get_nsig( s->pubkey_algo );
+    if( !n )
+       d->data[0] = mpi_copy(s->data[0]);
+    else {
+       for(i=0; i < n; i++ )
+           d->data[i] = mpi_copy( s->data[i] );
     }
-    else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
-       mpi_free( cert->d.rsa.rsa_n );
-       mpi_free( cert->d.rsa.rsa_e );
-       mpi_free( cert->d.rsa.rsa_d );
-       mpi_free( cert->d.rsa.rsa_p );
-       mpi_free( cert->d.rsa.rsa_q );
-       mpi_free( cert->d.rsa.rsa_u );
+    d->hashed_data = cp_data_block(s->hashed_data);
+    d->unhashed_data = cp_data_block(s->unhashed_data);
+    return d;
+}
+
+
+PKT_user_id *
+copy_user_id( PKT_user_id *d, PKT_user_id *s )
+{
+    if( !d )
+       d = m_alloc(sizeof *d + s->len - 1 );
+    memcpy( d, s, sizeof *d + s->len - 1 );
+    return d;
+}
+
+
+
+void
+release_secret_key_parts( PKT_secret_key *sk )
+{
+    int n, i;
+
+    n = pubkey_get_nskey( sk->pubkey_algo );
+    if( !n )
+       mpi_free(sk->skey[0]);
+    for(i=0; i < n; i++ ) {
+       mpi_free( sk->skey[i] );
+       sk->skey[i] = NULL;
     }
-    m_free(cert);
 }
 
-PKT_secret_cert *
-copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s )
+void
+free_secret_key( PKT_secret_key *sk )
 {
+    release_secret_key_parts( sk );
+    m_free(sk);
+}
+
+PKT_secret_key *
+copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
+{
+    int n, i;
+
     if( !d )
        d = m_alloc(sizeof *d);
     memcpy( d, s, sizeof *d );
-    if( s->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       d->d.elg.p = mpi_copy( s->d.elg.p );
-       d->d.elg.g = mpi_copy( s->d.elg.g );
-       d->d.elg.y = mpi_copy( s->d.elg.y );
-       d->d.elg.x = mpi_copy( s->d.elg.x );
-    }
-    else if( s->pubkey_algo == PUBKEY_ALGO_RSA ) {
-       d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
-       d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
-       d->d.rsa.rsa_d = mpi_copy( s->d.rsa.rsa_d );
-       d->d.rsa.rsa_p = mpi_copy( s->d.rsa.rsa_p );
-       d->d.rsa.rsa_q = mpi_copy( s->d.rsa.rsa_q );
-       d->d.rsa.rsa_u = mpi_copy( s->d.rsa.rsa_u );
+    n = pubkey_get_nskey( s->pubkey_algo );
+    if( !n )
+       d->skey[0] = mpi_copy(s->skey[0]);
+    else {
+       for(i=0; i < n; i++ )
+           d->skey[i] = mpi_copy( s->skey[i] );
     }
     return d;
 }
@@ -150,9 +227,9 @@ void
 free_compressed( PKT_compressed *zd )
 {
     if( zd->buf ) { /* have to skip some bytes */
-       /* don't have any informations about the length, so
+       /* don't have any information about the length, so
         * we assume this is the last packet */
-       while( iobuf_get(zd->buf) != -1 )
+       while( iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
            ;
     }
     m_free(zd);
@@ -163,13 +240,17 @@ free_encrypted( PKT_encrypted *ed )
 {
     if( ed->buf ) { /* have to skip some bytes */
        if( iobuf_in_block_mode(ed->buf) ) {
-           while( iobuf_get(ed->buf) != -1 )
+           while( iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
                ;
-           iobuf_set_block_mode(ed->buf, 0);
        }
        else {
-           for( ; ed->len; ed->len-- ) /* skip the packet */
-               iobuf_get(ed->buf);
+          while( ed->len ) { /* skip the packet */
+              int n = iobuf_read( ed->buf, NULL, ed->len );
+              if( n == -1 )
+                  ed->len = 0;
+              else
+                  ed->len -= n;
+          }
        }
     }
     m_free(ed);
@@ -181,13 +262,17 @@ free_plaintext( PKT_plaintext *pt )
 {
     if( pt->buf ) { /* have to skip some bytes */
        if( iobuf_in_block_mode(pt->buf) ) {
-           while( iobuf_get(pt->buf) != -1 )
+           while( iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
                ;
-           iobuf_set_block_mode(pt->buf, 0);
        }
        else {
-           for( ; pt->len; pt->len-- ) /* skip the packet */
-               iobuf_get(pt->buf);
+          while( pt->len ) { /* skip the packet */
+              int n = iobuf_read( pt->buf, NULL, pt->len );
+              if( n == -1 )
+                  pt->len = 0;
+              else
+                  pt->len -= n;
+          }
        }
     }
     m_free(pt);
@@ -212,11 +297,16 @@ free_packet( PACKET *pkt )
       case PKT_PUBKEY_ENC:
        free_pubkey_enc( pkt->pkt.pubkey_enc );
        break;
-      case PKT_PUBLIC_CERT:
-       free_public_cert( pkt->pkt.public_cert );
+      case PKT_SYMKEY_ENC:
+       free_symkey_enc( pkt->pkt.symkey_enc );
        break;
-      case PKT_SECRET_CERT:
-       free_secret_cert( pkt->pkt.secret_cert );
+      case PKT_PUBLIC_KEY:
+      case PKT_PUBLIC_SUBKEY:
+       free_public_key( pkt->pkt.public_key );
+       break;
+      case PKT_SECRET_KEY:
+      case PKT_SECRET_SUBKEY:
+       free_secret_key( pkt->pkt.secret_key );
        break;
       case PKT_COMMENT:
        free_comment( pkt->pkt.comment );
@@ -240,4 +330,122 @@ free_packet( PACKET *pkt )
     pkt->pkt.generic = NULL;
 }
 
+/****************
+ * returns 0 if they match.
+ */
+int
+cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
+{
+    int n, i;
+
+    if( a->timestamp != b->timestamp )
+       return -1;
+    if( a->version < 4 && a->expiredate != b->expiredate )
+       return -1;
+    if( a->pubkey_algo != b->pubkey_algo )
+       return -1;
+
+    n = pubkey_get_npkey( b->pubkey_algo );
+    if( !n )
+       return -1; /* can't compare due to unknown algorithm */
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( a->pkey[i], b->pkey[i] ) )
+           return -1;
+    }
+
+    return 0;
+}
+
+/****************
+ * Returns 0 if they match.
+ * We only compare the public parts.
+ */
+int
+cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
+{
+    int n, i;
+
+    if( a->timestamp != b->timestamp )
+       return -1;
+    if( a->version < 4 && a->expiredate != b->expiredate )
+       return -1;
+    if( a->pubkey_algo != b->pubkey_algo )
+       return -1;
+
+    n = pubkey_get_npkey( b->pubkey_algo );
+    if( !n )
+       return -1; /* can't compare due to unknown algorithm */
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( a->skey[i], b->skey[i] ) )
+           return -1;
+    }
+
+    return 0;
+}
+
+/****************
+ * Returns 0 if they match.
+ */
+int
+cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
+{
+    int n, i;
+
+    if( pk->timestamp != sk->timestamp )
+       return -1;
+    if( pk->version < 4 && pk->expiredate != sk->expiredate )
+       return -1;
+    if( pk->pubkey_algo != sk->pubkey_algo )
+       return -1;
+
+    n = pubkey_get_npkey( pk->pubkey_algo );
+    if( !n )
+       return -1; /* can't compare due to unknown algorithm */
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
+           return -1;
+    }
+    return 0;
+}
+
+
+
+int
+cmp_signatures( PKT_signature *a, PKT_signature *b )
+{
+    int n, i;
+
+    if( a->keyid[0] != b->keyid[0] )
+       return -1;
+    if( a->keyid[1] != b->keyid[1] )
+       return -1;
+    if( a->pubkey_algo != b->pubkey_algo )
+       return -1;
+
+    n = pubkey_get_nsig( a->pubkey_algo );
+    if( !n )
+       return -1; /* can't compare due to unknown algorithm */
+    for(i=0; i < n; i++ ) {
+       if( mpi_cmp( a->data[i] , b->data[i] ) )
+           return -1;
+    }
+    return 0;
+}
+
+
+
+/****************
+ * Returns: true if the user ids do not match
+ */
+int
+cmp_user_ids( PKT_user_id *a, PKT_user_id *b )
+{
+    int res;
+
+    res = a->len - b->len;
+    if( !res )
+       res = memcmp( a->name, b->name, a->len );
+    return res;
+}
+