Primary certify-only key?

David Shaw dshaw at jabberwocky.com
Wed Aug 3 21:48:39 CEST 2005


On Wed, Aug 03, 2005 at 07:26:38PM +0200, Thomas Kuehne wrote:
> Is there a way to generate the following key collection with GnuPG?
> 
> pub  4096R  usage: C
> sub  4096R  usage: S
> 
> The problem is that I cant create the first key with only "C" the
> capability.
> 
> Using the --expert option and disabling "E", "S" and "A" results in "CSEA".

Try the attached patch (to 1.4.2).

David
-------------- next part --------------
Index: keyid.c
===================================================================
--- keyid.c	(revision 3847)
+++ keyid.c	(working copy)
@@ -547,10 +547,13 @@
   if ( use & PUBKEY_USAGE_SIG )
     {
       if (pk->is_primary)
-        buffer[i++] = 'C';
+        use|=PUBKEY_USAGE_CERT;
       buffer[i++] = 'S';
     }
 
+  if ( use & PUBKEY_USAGE_CERT )
+    buffer[i++] = 'C';
+
   if ( use & PUBKEY_USAGE_ENC )
     buffer[i++] = 'E';
 
Index: keygen.c
===================================================================
--- keygen.c	(revision 3847)
+++ keygen.c	(working copy)
@@ -190,9 +190,6 @@
 {
     byte buf[1];
 
-    if (!use) 
-        return;
-
     buf[0] = 0;
 
     /* The spec says that all primary keys MUST be able to certify. */
@@ -205,6 +202,10 @@
         buf[0] |= 0x04 | 0x08;
     if (use & PUBKEY_USAGE_AUTH)
         buf[0] |= 0x20;
+
+    if (!buf[0]) 
+        return;
+
     build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1);
 }
 
@@ -1238,6 +1239,9 @@
   if(flags&PUBKEY_USAGE_SIG)
     tty_printf("%s ",_("Sign"));
 
+  if(flags&PUBKEY_USAGE_CERT)
+    tty_printf("%s ",_("Certify"));
+
   if(flags&PUBKEY_USAGE_ENC)
     tty_printf("%s ",_("Encrypt"));
 
@@ -1248,7 +1252,7 @@
 
 /* Returns the key flags */
 static unsigned int
-ask_key_flags(int algo)
+ask_key_flags(int algo,int subkey)
 {
   const char *togglers=_("SsEeAaQq");
   char *answer=NULL;
@@ -1258,6 +1262,10 @@
   if(strlen(togglers)!=8)
     BUG();
 
+  /* Only primary keys may certify. */
+  if(subkey)
+    possible&=~PUBKEY_USAGE_CERT;
+
   /* Preload the current set with the possible set, minus
      authentication, since nobody really uses auth yet. */
   current=possible&~PUBKEY_USAGE_AUTH;
@@ -1291,7 +1299,7 @@
       cpr_kill_prompt();
 
       if(strlen(answer)>1)
-	continue;
+	tty_printf(_("Invalid selection.\n"));
       else if(*answer=='\0' || *answer==togglers[6] || *answer==togglers[7])
 	break;
       else if((*answer==togglers[0] || *answer==togglers[1])
@@ -1318,6 +1326,8 @@
 	  else
 	    current|=PUBKEY_USAGE_AUTH;
 	}
+      else
+	tty_printf(_("Invalid selection.\n"));
     }
 
   xfree(answer);
@@ -1362,7 +1372,7 @@
 	}
 	else if( algo == 7 && opt.expert ) {
 	    algo = PUBKEY_ALGO_RSA;
-	    *r_usage=ask_key_flags(algo);
+	    *r_usage=ask_key_flags(algo,addmode);
 	    break;
 	}
 	else if( algo == 6 && addmode ) {
@@ -1382,7 +1392,7 @@
 	}
 	else if( algo == 3 && opt.expert ) {
 	    algo = PUBKEY_ALGO_DSA;
-	    *r_usage=ask_key_flags(algo);
+	    *r_usage=ask_key_flags(algo,addmode);
 	    break;
 	}
 	else if( algo == 2 ) {
Index: getkey.c
===================================================================
--- getkey.c	(revision 3847)
+++ getkey.c	(working copy)
@@ -1291,16 +1291,24 @@
       /* first octet of the keyflags */
       flags=*p;
 
-      if(flags & 3)
+      if(flags & 1)
 	{
+	  key_usage |= PUBKEY_USAGE_CERT;
+	  flags&=~1;
+	}
+
+      if(flags & 2)
+	{
 	  key_usage |= PUBKEY_USAGE_SIG;
-	  flags&=~3;
+	  flags&=~2;
 	}
 
-      if(flags & 12)
+      /* We do not distinguish between encrypting communications and
+	 encrypting storage. */
+      if(flags & (0x04|0x08))
 	{
 	  key_usage |= PUBKEY_USAGE_ENC;
-	  flags&=~12;
+	  flags&=~(0x04|0x08);
 	}
 
       if(flags & 0x20)
Index: misc.c
===================================================================
--- misc.c	(revision 3847)
+++ misc.c	(working copy)
@@ -407,19 +407,19 @@
     /* they are hardwired in gpg 1.0 */
     switch ( algo ) {    
       case PUBKEY_ALGO_RSA:
-          use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
+          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
           break;
       case PUBKEY_ALGO_RSA_E:
           use = PUBKEY_USAGE_ENC;
           break;
       case PUBKEY_ALGO_RSA_S:
-          use = PUBKEY_USAGE_SIG;
+          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
           break;
       case PUBKEY_ALGO_ELGAMAL_E:
           use = PUBKEY_USAGE_ENC;
           break;
       case PUBKEY_ALGO_DSA:  
-          use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
+          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
           break;
       default:
           break;


More information about the Gnupg-users mailing list