See ChangeLog: Thu Jul 15 10:15:35 CEST 1999 Werner Koch
[libgcrypt.git] / cipher / pubkey.c
index f59996c..548d2e8 100644 (file)
@@ -1,14 +1,14 @@
 /* pubkey.c  - pubkey dispatcher
  *     Copyright (C) 1998 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * This file is part of GnuPG.
  *
- * GNUPG 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.
  *
- * GNUPG 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.
@@ -42,7 +42,7 @@ struct pubkey_table_s {
     int nskey;
     int nenc;
     int nsig;
-    int usage;
+    int use;
     int (*generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
     int (*check_secret_key)( int algo, MPI *skey );
     int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
@@ -54,7 +54,7 @@ struct pubkey_table_s {
 };
 
 static struct pubkey_table_s pubkey_table[TABLE_SIZE];
-
+static int disabled_algos[TABLE_SIZE];
 
 
 static int
@@ -89,9 +89,11 @@ dummy_get_nbits( int algo, MPI *pkey )
 
 /****************
  * Put the static entries into the table.
+ * This is out constructor function which fill the table
+ * of algorithms with the one we have statically linked.
  */
 static void
-setup_pubkey_table()
+setup_pubkey_table(void)
 {
     int i;
 
@@ -102,7 +104,7 @@ setup_pubkey_table()
                                         &pubkey_table[i].nskey,
                                         &pubkey_table[i].nenc,
                                         &pubkey_table[i].nsig,
-                                        &pubkey_table[i].usage );
+                                        &pubkey_table[i].use );
     pubkey_table[i].generate        = elg_generate;
     pubkey_table[i].check_secret_key = elg_check_secret_key;
     pubkey_table[i].encrypt         = elg_encrypt;
@@ -119,7 +121,7 @@ setup_pubkey_table()
                                         &pubkey_table[i].nskey,
                                         &pubkey_table[i].nenc,
                                         &pubkey_table[i].nsig,
-                                        &pubkey_table[i].usage );
+                                        &pubkey_table[i].use );
     pubkey_table[i].generate        = elg_generate;
     pubkey_table[i].check_secret_key = elg_check_secret_key;
     pubkey_table[i].encrypt         = elg_encrypt;
@@ -136,7 +138,7 @@ setup_pubkey_table()
                                         &pubkey_table[i].nskey,
                                         &pubkey_table[i].nenc,
                                         &pubkey_table[i].nsig,
-                                        &pubkey_table[i].usage );
+                                        &pubkey_table[i].use );
     pubkey_table[i].generate        = dsa_generate;
     pubkey_table[i].check_secret_key = dsa_check_secret_key;
     pubkey_table[i].encrypt         = dummy_encrypt;
@@ -157,7 +159,7 @@ setup_pubkey_table()
  * Try to load all modules and return true if new modules are available
  */
 static int
-load_pubkey_modules()
+load_pubkey_modules(void)
 {
     static int initialized = 0;
     static int done = 0;
@@ -170,6 +172,7 @@ load_pubkey_modules()
 
 
     if( !initialized ) {
+       cipher_modules_constructor();
        setup_pubkey_table();
        initialized = 1;
        return 1;
@@ -186,7 +189,7 @@ load_pubkey_modules()
     /* now load all extensions */
     while( (name = enum_gnupgext_pubkeys( &context, &ct->algo,
                                &ct->npkey, &ct->nskey, &ct->nenc,
-                               &ct->nsig,  &ct->usage,
+                               &ct->nsig,  &ct->use,
                                &ct->generate,
                                &ct->check_secret_key,
                                &ct->encrypt,
@@ -264,6 +267,20 @@ pubkey_algo_to_string( int algo )
 }
 
 
+void
+disable_pubkey_algo( int algo )
+{
+    int i;
+
+    for(i=0; i < DIM(disabled_algos); i++ ) {
+       if( !disabled_algos[i] || disabled_algos[i] == algo ) {
+           disabled_algos[i] = algo;
+           return;
+       }
+    }
+    log_fatal("can't disable pubkey algo %d: table full\n");
+}
+
 
 int
 check_pubkey_algo( int algo )
@@ -272,20 +289,27 @@ check_pubkey_algo( int algo )
 }
 
 /****************
- * a usage of 0 means: don't care
+ * a use of 0 means: don't care
  */
 int
-check_pubkey_algo2( int algo, unsigned usage )
+check_pubkey_algo2( int algo, unsigned use )
 {
     int i;
 
     do {
        for(i=0; pubkey_table[i].name; i++ )
            if( pubkey_table[i].algo == algo ) {
-               if( (usage & 1) && !(pubkey_table[i].usage & 1) )
+               if( (use & PUBKEY_USAGE_SIG)
+                   && !(pubkey_table[i].use & PUBKEY_USAGE_SIG) )
                    return G10ERR_WR_PUBKEY_ALGO;
-               if( (usage & 2) && !(pubkey_table[i].usage & 2) )
+               if( (use & PUBKEY_USAGE_ENC)
+                   && !(pubkey_table[i].use & PUBKEY_USAGE_ENC) )
                    return G10ERR_WR_PUBKEY_ALGO;
+
+               for(i=0; i < DIM(disabled_algos); i++ ) {
+                   if( disabled_algos[i] == algo )
+                       return G10ERR_PUBKEY_ALGO;
+               }
                return 0; /* okay */
            }
     } while( load_pubkey_modules() );
@@ -307,6 +331,8 @@ pubkey_get_npkey( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].npkey;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 2;         /* see the RSA keyids */
     return 0;
 }
 
@@ -322,6 +348,8 @@ pubkey_get_nskey( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].nskey;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 6;         /* see the RSA keyids */
     return 0;
 }
 
@@ -337,6 +365,8 @@ pubkey_get_nsig( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].nsig;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 1;         /* see the RSA keyids */
     return 0;
 }
 
@@ -352,6 +382,8 @@ pubkey_get_nenc( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].nenc;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 1;         /* see the RSA keyids */
     return 0;
 }
 
@@ -368,6 +400,8 @@ pubkey_nbits( int algo, MPI *pkey )
            if( pubkey_table[i].algo == algo )
                return (*pubkey_table[i].get_nbits)( algo, pkey );
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) ) /* we always wanna see the length of a key :-) */
+       return mpi_get_nbits( pkey[0] );
     return 0;
 }
 
@@ -412,8 +446,6 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
 {
     int i, rc;
 
-    /* FIXME: check that data fits into the key (in xxx_encrypt)*/
-
     if( DBG_CIPHER ) {
        log_debug("pubkey_encrypt: algo=%d\n", algo );
        for(i=0; i < pubkey_get_npkey(algo); i++ )
@@ -478,7 +510,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
 
 /****************
  * This is the interface to the public key signing.
- * Sign hash with skey and put the result into resarr which
+ * Sign data with skey and put the result into resarr which
  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
  * algorithm allows this - check with pubkey_get_nsig() )
  */