[svn] GnuPG - r3969 - trunk/keyserver

svn author dshaw cvs at cvs.gnupg.org
Mon Dec 19 20:39:35 CET 2005


Author: dshaw
Date: 2005-12-19 20:39:32 +0100 (Mon, 19 Dec 2005)
New Revision: 3969

Modified:
   trunk/keyserver/ChangeLog
   trunk/keyserver/gpgkeys_curl.c
   trunk/keyserver/gpgkeys_hkp.c
   trunk/keyserver/ksutil.c
   trunk/keyserver/ksutil.h
Log:
* ksutil.h, ksutil.c (curl_armor_writer, curl_writer,
curl_writer_finalize): New functionality to handle binary format keys by
armoring them for input to GPG.

* gpgkeys_curl.c (get_key), gpgkeys_hkp.c (get_key): Call it here.


Modified: trunk/keyserver/ChangeLog
===================================================================
--- trunk/keyserver/ChangeLog	2005-12-19 01:51:31 UTC (rev 3968)
+++ trunk/keyserver/ChangeLog	2005-12-19 19:39:32 UTC (rev 3969)
@@ -1,3 +1,11 @@
+2005-12-19  David Shaw  <dshaw at jabberwocky.com>
+
+	* ksutil.h, ksutil.c (curl_armor_writer, curl_writer,
+	curl_writer_finalize): New functionality to handle binary format
+	keys by armoring them for input to GPG.
+
+	* gpgkeys_curl.c (get_key), gpgkeys_hkp.c (get_key): Call it here.
+
 2005-12-07  David Shaw  <dshaw at jabberwocky.com>
 
 	* gpgkeys_finger.c (get_key), gpgkeys_curl.c (get_key): Better

Modified: trunk/keyserver/gpgkeys_curl.c
===================================================================
--- trunk/keyserver/gpgkeys_curl.c	2005-12-19 01:51:31 UTC (rev 3968)
+++ trunk/keyserver/gpgkeys_curl.c	2005-12-19 19:39:32 UTC (rev 3969)
@@ -74,13 +74,18 @@
 	      res,errorbuffer);
       fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
     }
-  else if(!ctx.done)
+  else
     {
-      fprintf(console,"gpgkeys: no key data found for %s\n",request);
-      fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND);
+      curl_writer_finalize(&ctx);
+      if(!ctx.flags.done)
+	{
+	  fprintf(console,"gpgkeys: no key data found for %s\n",request);
+	  fprintf(output,"\nKEY 0x%s FAILED %d\n",
+		  getkey,KEYSERVER_KEY_NOT_FOUND);
+	}
+      else
+	fprintf(output,"\nKEY 0x%s END\n",getkey);
     }
-  else
-    fprintf(output,"\nKEY 0x%s END\n",getkey);
 
   return curl_err_to_gpg_err(res);
 }

Modified: trunk/keyserver/gpgkeys_hkp.c
===================================================================
--- trunk/keyserver/gpgkeys_hkp.c	2005-12-19 01:51:31 UTC (rev 3968)
+++ trunk/keyserver/gpgkeys_hkp.c	2005-12-19 19:39:32 UTC (rev 3969)
@@ -263,21 +263,22 @@
   curl_easy_setopt(curl,CURLOPT_FILE,&ctx);
 
   res=curl_easy_perform(curl);
-  if(res!=0)
+  if(res!=CURLE_OK)
     {
       fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer);
       fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
     }
   else
     {
-      if(ctx.done)
-	fprintf(output,"\nKEY 0x%s END\n",getkey);
-      else
+      curl_writer_finalize(&ctx);
+      if(!ctx.flags.done)
 	{
 	  fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey);
-	  fprintf(output,"KEY 0x%s FAILED %d\n",
+	  fprintf(output,"\nKEY 0x%s FAILED %d\n",
 		  getkey,KEYSERVER_KEY_NOT_FOUND);
 	}
+      else
+	fprintf(output,"\nKEY 0x%s END\n",getkey);
     }
 
   return KEYSERVER_OK;

Modified: trunk/keyserver/ksutil.c
===================================================================
--- trunk/keyserver/ksutil.c	2005-12-19 01:51:31 UTC (rev 3968)
+++ trunk/keyserver/ksutil.c	2005-12-19 19:39:32 UTC (rev 3969)
@@ -371,6 +371,47 @@
     }
 }
 
+#define B64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+
+static void
+curl_armor_writer(const unsigned char *buf,size_t size,void *cw_ctx)
+{
+  struct curl_writer_ctx *ctx=cw_ctx;
+  size_t idx=0;
+
+  while(idx<size)
+    {
+      for(;ctx->armor_remaining<3 && idx<size;ctx->armor_remaining++,idx++)
+	ctx->armor_ctx[ctx->armor_remaining]=buf[idx];
+
+      if(ctx->armor_remaining==3)
+	{
+	  /* Top 6 bytes of ctx->armor_ctx[0] */
+	  fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
+	  /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of
+	     ctx->armor_ctx[1] */
+	  fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30)
+		     |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream);
+	  /* Bottom 4 bytes of ctx->armor_ctx[1] and top 2 bytes of
+	     ctx->armor_ctx[2] */
+	  fputc(B64[(((ctx->armor_ctx[1]<<2)&0x3C)
+		     |((ctx->armor_ctx[2]>>6)&0x03))&0x3F],ctx->stream);
+	  /* Bottom 6 bytes of ctx->armor_ctx[2] */
+	  fputc(B64[(ctx->armor_ctx[2]&0x3F)],ctx->stream);
+
+	  ctx->linelen+=4;
+	  if(ctx->linelen>=70)
+	    {
+	      fputc('\n',ctx->stream);
+	      ctx->linelen=0;
+	    }
+
+	  ctx->armor_remaining=0;
+	}
+    }
+
+}
+
 size_t
 curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
 {
@@ -378,52 +419,103 @@
   const char *buf=ptr;
   size_t i;
 
-  if(!ctx->initialized)
+  if(!ctx->flags.initialized)
     {
-      ctx->marker=BEGIN;
-      ctx->initialized=1;
+      if(size*nmemb==0)
+	return 0;
+
+      /* The object we're fetching is in binary form */
+      if(*buf&0x80)
+	{
+	  ctx->flags.armor=1;
+	  fprintf(ctx->stream,BEGIN"\n\n");
+	}
+      else
+	ctx->marker=BEGIN;
+
+      ctx->flags.initialized=1;
     }
 
-  /* scan the incoming data for our marker */
-  for(i=0;!ctx->done && i<(size*nmemb);i++)
+  if(ctx->flags.armor)
+    curl_armor_writer(ptr,size*nmemb,cw_ctx);
+  else
     {
-      if(buf[i]==ctx->marker[ctx->markeridx])
+      /* scan the incoming data for our marker */
+      for(i=0;!ctx->flags.done && i<(size*nmemb);i++)
 	{
-	  ctx->markeridx++;
-	  if(ctx->marker[ctx->markeridx]=='\0')
+	  if(buf[i]==ctx->marker[ctx->markeridx])
 	    {
-	      if(ctx->begun)
-		ctx->done=1;
-	      else
+	      ctx->markeridx++;
+	      if(ctx->marker[ctx->markeridx]=='\0')
 		{
-		  /* We've found the BEGIN marker, so now we're looking
-		     for the END marker. */
-		  ctx->begun=1;
-		  ctx->marker=END;
-		  ctx->markeridx=0;
-		  fprintf(ctx->stream,BEGIN);
-		  continue;
+		  if(ctx->flags.begun)
+		    ctx->flags.done=1;
+		  else
+		    {
+		      /* We've found the BEGIN marker, so now we're
+			 looking for the END marker. */
+		      ctx->flags.begun=1;
+		      ctx->marker=END;
+		      ctx->markeridx=0;
+		      fprintf(ctx->stream,BEGIN);
+		      continue;
+		    }
 		}
 	    }
-	}
-      else
-	ctx->markeridx=0;
+	  else
+	    ctx->markeridx=0;
 
-      if(ctx->begun)
-	{
-	  /* Canonicalize CRLF to just LF by stripping CRs.  This
-	     actually makes sense, since on Unix-like machines LF is
-	     correct, and on win32-like machines, our output buffer is
-	     opened in textmode and will re-canonicalize line endings
-	     back to CRLF.  Since we only need to handle armored keys,
-	     we don't have to worry about odd cases like CRCRCR and
-	     the like. */
+	  if(ctx->flags.begun)
+	    {
+	      /* Canonicalize CRLF to just LF by stripping CRs.  This
+		 actually makes sense, since on Unix-like machines LF
+		 is correct, and on win32-like machines, our output
+		 buffer is opened in textmode and will re-canonicalize
+		 line endings back to CRLF.  Since this code is just
+		 for handling armored keys, we don't have to worry
+		 about odd cases like CRCRCR and the like. */
 
-	  if(buf[i]!='\r')
-	    fputc(buf[i],ctx->stream);
+	      if(buf[i]!='\r')
+		fputc(buf[i],ctx->stream);
+	    }
 	}
     }
 
   return size*nmemb;
 }
+
+void
+curl_writer_finalize(struct curl_writer_ctx *ctx)
+{
+  if(ctx->flags.armor)
+    {
+      if(ctx->armor_remaining==2)
+	{
+	  /* Top 6 bytes of ctx->armorctx[0] */
+	  fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
+	  /* Bottom 2 bytes of ctx->armor_ctx[0] and top 4 bytes of
+	     ctx->armor_ctx[1] */
+	  fputc(B64[(((ctx->armor_ctx[0]<<4)&0x30)
+		     |((ctx->armor_ctx[1]>>4)&0x0F))&0x3F],ctx->stream);
+	  /* Bottom 4 bytes of ctx->armor_ctx[1] */
+	  fputc(B64[((ctx->armor_ctx[1]<<2)&0x3C)],ctx->stream);
+	  /* Pad */
+	  fputc('=',ctx->stream);
+	}
+      else if(ctx->armor_remaining==1)
+	{
+	  /* Top 6 bytes of ctx->armor_ctx[0] */
+	  fputc(B64[(ctx->armor_ctx[0]>>2)&0x3F],ctx->stream);
+	  /* Bottom 2 bytes of ctx->armor_ctx[0] */
+	  fputc(B64[((ctx->armor_ctx[0]<<4)&0x30)],ctx->stream);
+	  /* Pad */
+	  fputc('=',ctx->stream);
+	  /* Pad */
+	  fputc('=',ctx->stream);
+	}
+
+      fprintf(ctx->stream,"\n"END);
+      ctx->flags.done=1;
+    }
+}
 #endif

Modified: trunk/keyserver/ksutil.h
===================================================================
--- trunk/keyserver/ksutil.h	2005-12-19 01:51:31 UTC (rev 3968)
+++ trunk/keyserver/ksutil.h	2005-12-19 19:39:32 UTC (rev 3969)
@@ -111,12 +111,24 @@
 
 struct curl_writer_ctx
 {
-  int initialized,markeridx,begun,done;
+  struct
+  {
+    unsigned int initialized:1;
+    unsigned int begun:1;
+    unsigned int done:1;
+    unsigned int armor:1;
+  } flags;
+
+  int armor_remaining;
+  unsigned char armor_ctx[3];
+  int markeridx,linelen;
   const char *marker;
   FILE *stream;
 };
 
 size_t curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx);
+void curl_writer_finalize(struct curl_writer_ctx *ctx);
+
 #endif
 
 #endif /* !_KSUTIL_H_ */




More information about the Gnupg-commits mailing list