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)
{
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 else
fprintf(output,"\nKEY 0x%s END\n",getkey); {
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);
}
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,52 +419,103 @@ 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)
{ {
ctx->marker=BEGIN; if(size*nmemb==0)
ctx->initialized=1; return 0;
}
/* scan the incoming data for our marker */ /* The object we're fetching is in binary form */
for(i=0;!ctx->done && i<(size*nmemb);i++) if(*buf&0x80)
{
if(buf[i]==ctx->marker[ctx->markeridx])
{ {
ctx->markeridx++; ctx->flags.armor=1;
if(ctx->marker[ctx->markeridx]=='\0') fprintf(ctx->stream,BEGIN"\n\n");
{
if(ctx->begun)
ctx->done=1;
else
{
/* 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;
}
}
} }
else else
ctx->markeridx=0; ctx->marker=BEGIN;
if(ctx->begun) ctx->flags.initialized=1;
}
if(ctx->flags.armor)
curl_armor_writer(ptr,size*nmemb,cw_ctx);
else
{
/* scan the incoming data for our marker */
for(i=0;!ctx->flags.done && i<(size*nmemb);i++)
{ {
/* Canonicalize CRLF to just LF by stripping CRs. This if(buf[i]==ctx->marker[ctx->markeridx])
actually makes sense, since on Unix-like machines LF is {
correct, and on win32-like machines, our output buffer is ctx->markeridx++;
opened in textmode and will re-canonicalize line endings if(ctx->marker[ctx->markeridx]=='\0')
back to CRLF. Since we only need to handle armored keys, {
we don't have to worry about odd cases like CRCRCR and if(ctx->flags.begun)
the like. */ 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;
if(buf[i]!='\r') if(ctx->flags.begun)
fputc(buf[i],ctx->stream); {
/* 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; 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_ */