See ChangeLog: Mon Jul 26 09:34:46 CEST 1999 Werner Koch
[gnupg.git] / g10 / export.c
index 2c824d2..911a715 100644 (file)
@@ -1,14 +1,14 @@
 /* export.c
  *     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.
 #include "memory.h"
 #include "util.h"
 #include "main.h"
+#include "i18n.h"
 
-static int do_export( STRLIST users, int secret );
+static int do_export( STRLIST users, int secret, int onlyrfc );
+static int do_export_stream( IOBUF out, STRLIST users,
+                            int secret, int onlyrfc, int *any );
 
 /****************
  * Export the public keys (to standard out or --output).
  * Depending on opt.armor the output is armored.
+ * If onlyrfc is True only RFC24404 compatible keys are exported.
  * If USERS is NULL, the complete ring will be exported.
  */
 int
-export_pubkeys( STRLIST users )
+export_pubkeys( STRLIST users, int onlyrfc )
 {
-    return do_export( users, 0 );
+    return do_export( users, 0, onlyrfc );
+}
+
+/****************
+ * Export to an already opened stream; return -1 if no keys have
+ * been exported
+ */
+int
+export_pubkeys_stream( IOBUF out, STRLIST users, int onlyrfc )
+{
+    int any, rc;
+
+    rc = do_export_stream( out, users, 0, onlyrfc, &any );
+    if( !rc && !any )
+       rc = -1;
+    return rc;
 }
 
 int
 export_seckeys( STRLIST users )
 {
-    return do_export( users, 1 );
+    return do_export( users, 1, 0 );
 }
 
 static int
-do_export( STRLIST users, int secret )
+do_export( STRLIST users, int secret, int onlyrfc )
 {
-    int rc = 0;
+    IOBUF out = NULL;
+    int any, rc;
     armor_filter_context_t afx;
+
+    memset( &afx, 0, sizeof afx);
+
+    rc = open_outfile( NULL, 0, &out );
+    if( rc )
+       return rc;
+
+    if( opt.armor ) {
+       afx.what = secret?5:1;
+       iobuf_push_filter( out, armor_filter, &afx );
+    }
+    rc = do_export_stream( out, users, secret, onlyrfc, &any );
+
+    if( rc || !any )
+       iobuf_cancel(out);
+    else
+       iobuf_close(out);
+    return rc;
+}
+
+
+static int
+do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
+{
+    int rc = 0;
     compress_filter_context_t zfx;
-    IOBUF out = NULL;
     PACKET pkt;
     KBNODE keyblock = NULL;
     KBNODE kbctx, node;
     KBPOS kbpos;
     STRLIST sl;
     int all = !users;
-    int any=0;
 
-    memset( &afx, 0, sizeof afx);
+    *any = 0;
     memset( &zfx, 0, sizeof zfx);
     init_packet( &pkt );
 
-    if( !(out = open_outfile( NULL, 0 )) ) {
-       rc = G10ERR_CREATE_FILE;
-       goto leave;
-    }
-
-    if( opt.armor ) {
-       afx.what = secret?5:1;
-       iobuf_push_filter( out, armor_filter, &afx );
-    }
     if( opt.compress_keys && opt.compress )
        iobuf_push_filter( out, compress_filter, &zfx );
 
@@ -110,7 +144,7 @@ do_export( STRLIST users, int secret )
            rc = secret? find_secret_keyblock_byname( &kbpos, sl->d )
                       : find_keyblock_byname( &kbpos, sl->d );
            if( rc ) {
-               log_error("%s: user not found: %s\n", sl->d, g10_errstr(rc) );
+               log_error(_("%s: user not found: %s\n"), sl->d, g10_errstr(rc));
                rc = 0;
                continue;
            }
@@ -119,30 +153,36 @@ do_export( STRLIST users, int secret )
        }
 
        if( rc ) {
-           log_error("certificate read problem: %s\n", g10_errstr(rc));
+           log_error(_("certificate read problem: %s\n"), g10_errstr(rc));
            goto leave;
        }
 
+
+       /* do not export keys which are incompatible with rfc2440 */
+       if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
+           PKT_public_key *pk = node->pkt->pkt.public_key;
+           if( pk->version == 3 && pk->pubkey_algo > 3 ) {
+               log_info(_("key %08lX: not a rfc2440 key - skipped\n"),
+                             (ulong)keyid_from_pk( pk, NULL) );
+               continue;
+           }
+       }
+
        /* and write it */
        for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
-           if( opt.do_not_export_rsa ) {
-               int algo;
-               switch( node->pkt->pkttype ) {
-                 /* note: we canĀ“ do this for subkeys here */
-                 case PKT_PUBLIC_KEY:
-                   algo = node->pkt->pkt.public_key->pubkey_algo;
-                   break;
-                 case PKT_SECRET_KEY:
-                   algo = node->pkt->pkt.secret_key->pubkey_algo;
-                   break;
-                 case PKT_SIGNATURE:
-                   algo = node->pkt->pkt.signature->pubkey_algo;
-                   break;
-                 default: algo = 0;
-               }
-               if( is_RSA(algo) )
-                   continue;
+           /* don't export any comment packets but those in the
+            * secret keyring */
+           if( !secret && node->pkt->pkttype == PKT_COMMENT )
+               continue;
+           /* do not export packets which are marked as not exportable */
+           if( node->pkt->pkttype == PKT_SIGNATURE ) {
+               const char *p;
+               p = parse_sig_subpkt2( node->pkt->pkt.signature,
+                                      SIGSUBPKT_EXPORTABLE, NULL );
+               if( p && !*p )
+                   continue; /* not exportable */
            }
+
            if( (rc = build_packet( out, node->pkt )) ) {
                log_error("build_packet(%d) failed: %s\n",
                            node->pkt->pkttype, g10_errstr(rc) );
@@ -150,7 +190,7 @@ do_export( STRLIST users, int secret )
                goto leave;
            }
        }
-       any++;
+       ++*any;
     }
     if( rc == -1 )
        rc = 0;
@@ -159,13 +199,8 @@ do_export( STRLIST users, int secret )
     if( all == 2 )
        enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
     release_kbnode( keyblock );
-    if( rc || !any )
-       iobuf_cancel(out);
-    else
-       iobuf_close(out);
-    if( !any )
-       log_info("warning: nothing exported\n");
+    if( !*any )
+       log_info(_("WARNING: nothing exported\n"));
     return rc;
 }
 
-