1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-02-01 16:33:02 +01:00

* 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.
This commit is contained in:
David Shaw 2005-12-19 19:39:32 +00:00
parent aebd3a04f3
commit 5432755319
5 changed files with 165 additions and 47 deletions

View File

@ -1,3 +1,11 @@
2005-12-19 David Shaw <dshaw@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@jabberwocky.com> 2005-12-07 David Shaw <dshaw@jabberwocky.com>
* gpgkeys_finger.c (get_key), gpgkeys_curl.c (get_key): Better * gpgkeys_finger.c (get_key), gpgkeys_curl.c (get_key): Better

View File

@ -74,13 +74,18 @@ get_key(char *getkey)
res,errorbuffer); res,errorbuffer);
fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res)); fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
} }
else if(!ctx.done) else
{
curl_writer_finalize(&ctx);
if(!ctx.flags.done)
{ {
fprintf(console,"gpgkeys: no key data found for %s\n",request); fprintf(console,"gpgkeys: no key data found for %s\n",request);
fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,KEYSERVER_KEY_NOT_FOUND); fprintf(output,"\nKEY 0x%s FAILED %d\n",
getkey,KEYSERVER_KEY_NOT_FOUND);
} }
else else
fprintf(output,"\nKEY 0x%s END\n",getkey); fprintf(output,"\nKEY 0x%s END\n",getkey);
}
return curl_err_to_gpg_err(res); return curl_err_to_gpg_err(res);
} }

View File

@ -263,21 +263,22 @@ get_key(char *getkey)
curl_easy_setopt(curl,CURLOPT_FILE,&ctx); curl_easy_setopt(curl,CURLOPT_FILE,&ctx);
res=curl_easy_perform(curl); res=curl_easy_perform(curl);
if(res!=0) if(res!=CURLE_OK)
{ {
fprintf(console,"gpgkeys: HTTP fetch error %d: %s\n",res,errorbuffer); 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)); fprintf(output,"\nKEY 0x%s FAILED %d\n",getkey,curl_err_to_gpg_err(res));
} }
else else
{ {
if(ctx.done) curl_writer_finalize(&ctx);
fprintf(output,"\nKEY 0x%s END\n",getkey); if(!ctx.flags.done)
else
{ {
fprintf(console,"gpgkeys: key %s not found on keyserver\n",getkey); 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); getkey,KEYSERVER_KEY_NOT_FOUND);
} }
else
fprintf(output,"\nKEY 0x%s END\n",getkey);
} }
return KEYSERVER_OK; return KEYSERVER_OK;

View File

@ -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 size_t
curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx) curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
{ {
@ -378,27 +419,42 @@ curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
const char *buf=ptr; const char *buf=ptr;
size_t i; size_t i;
if(!ctx->initialized) if(!ctx->flags.initialized)
{ {
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->marker=BEGIN;
ctx->initialized=1;
ctx->flags.initialized=1;
} }
if(ctx->flags.armor)
curl_armor_writer(ptr,size*nmemb,cw_ctx);
else
{
/* scan the incoming data for our marker */ /* scan the incoming data for our marker */
for(i=0;!ctx->done && i<(size*nmemb);i++) for(i=0;!ctx->flags.done && i<(size*nmemb);i++)
{ {
if(buf[i]==ctx->marker[ctx->markeridx]) if(buf[i]==ctx->marker[ctx->markeridx])
{ {
ctx->markeridx++; ctx->markeridx++;
if(ctx->marker[ctx->markeridx]=='\0') if(ctx->marker[ctx->markeridx]=='\0')
{ {
if(ctx->begun) if(ctx->flags.begun)
ctx->done=1; ctx->flags.done=1;
else else
{ {
/* We've found the BEGIN marker, so now we're looking /* We've found the BEGIN marker, so now we're
for the END marker. */ looking for the END marker. */
ctx->begun=1; ctx->flags.begun=1;
ctx->marker=END; ctx->marker=END;
ctx->markeridx=0; ctx->markeridx=0;
fprintf(ctx->stream,BEGIN); fprintf(ctx->stream,BEGIN);
@ -409,21 +465,57 @@ curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx)
else else
ctx->markeridx=0; ctx->markeridx=0;
if(ctx->begun) if(ctx->flags.begun)
{ {
/* Canonicalize CRLF to just LF by stripping CRs. This /* Canonicalize CRLF to just LF by stripping CRs. This
actually makes sense, since on Unix-like machines LF is actually makes sense, since on Unix-like machines LF
correct, and on win32-like machines, our output buffer is is correct, and on win32-like machines, our output
opened in textmode and will re-canonicalize line endings buffer is opened in textmode and will re-canonicalize
back to CRLF. Since we only need to handle armored keys, line endings back to CRLF. Since this code is just
we don't have to worry about odd cases like CRCRCR and for handling armored keys, we don't have to worry
the like. */ about odd cases like CRCRCR and the like. */
if(buf[i]!='\r') if(buf[i]!='\r')
fputc(buf[i],ctx->stream); fputc(buf[i],ctx->stream);
} }
} }
}
return size*nmemb; 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 #endif

View File

@ -111,12 +111,24 @@ int curl_err_to_gpg_err(CURLcode error);
struct curl_writer_ctx 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; const char *marker;
FILE *stream; FILE *stream;
}; };
size_t curl_writer(const void *ptr,size_t size,size_t nmemb,void *cw_ctx); 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
#endif /* !_KSUTIL_H_ */ #endif /* !_KSUTIL_H_ */