summaryrefslogtreecommitdiffstats
path: root/keyserver/ksutil.c
diff options
context:
space:
mode:
authorDavid Shaw <dshaw@jabberwocky.com>2005-12-19 20:39:32 +0100
committerDavid Shaw <dshaw@jabberwocky.com>2005-12-19 20:39:32 +0100
commit5432755319f34010f587dae19ae325020bf9454c (patch)
treee6743212622a6479a23893c1ad045d25c081985c /keyserver/ksutil.c
parent* gpg.c (main): Restore convert-sk-to-pk as programs rely on it. (diff)
downloadgnupg2-5432755319f34010f587dae19ae325020bf9454c.tar.xz
gnupg2-5432755319f34010f587dae19ae325020bf9454c.zip
* 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.
Diffstat (limited to 'keyserver/ksutil.c')
-rw-r--r--keyserver/ksutil.c158
1 files changed, 125 insertions, 33 deletions
diff --git a/keyserver/ksutil.c b/keyserver/ksutil.c
index e858bd410..8ea2a1ab4 100644
--- a/keyserver/ksutil.c
+++ b/keyserver/ksutil.c
@@ -371,6 +371,47 @@ curl_err_to_gpg_err(CURLcode error)
}
}
+#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 @@ curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
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(buf[i]!='\r')
- fputc(buf[i],ctx->stream);
+ 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);
+ }
}
}
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