1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

Photo ID support (actually generic "attribute packet" support, but there

is only one attribute packet defined thus far, and it's a picture)
This commit is contained in:
David Shaw 2001-12-21 23:06:02 +00:00
parent ca058399b0
commit d560bdac18
16 changed files with 522 additions and 350 deletions

View file

@ -61,7 +61,7 @@ static int parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
byte *hdr, int hdrlen, PACKET *packet );
static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static int parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen,
static int parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
@ -438,9 +438,9 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
case PKT_USER_ID:
rc = parse_user_id(inp, pkttype, pktlen, pkt );
break;
case PKT_PHOTO_ID:
case PKT_ATTRIBUTE:
pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */
rc = parse_photo_id(inp, pkttype, pktlen, pkt);
rc = parse_attribute(inp, pkttype, pktlen, pkt);
break;
case PKT_OLD_COMMENT:
case PKT_COMMENT:
@ -1657,6 +1657,98 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
return rc;
}
/* Attribute subpackets have the same format as v4 signature
subpackets. This is not part of OpenPGP, but is done in several
versions of PGP nevertheless. */
int
parse_attribute_subpkts(PKT_user_id *uid)
{
size_t n;
int count=0;
struct user_attribute *attribs=NULL;
const byte *buffer=uid->attrib_data;
int buflen=uid->attrib_len;
byte type;
m_free(uid->attribs);
while(buflen)
{
n = *buffer++; buflen--;
if( n == 255 ) { /* 4 byte length header */
if( buflen < 4 )
goto too_short;
n = (buffer[0] << 24) | (buffer[1] << 16)
| (buffer[2] << 8) | buffer[3];
buffer += 4;
buflen -= 4;
}
else if( n >= 192 ) { /* 2 byte special encoded length header */
if( buflen < 2 )
goto too_short;
n = (( n - 192 ) << 8) + *buffer + 192;
buffer++;
buflen--;
}
if( buflen < n )
goto too_short;
attribs=m_realloc(attribs,(count+1)*sizeof(struct user_attribute));
memset(&attribs[count],0,sizeof(struct user_attribute));
type=*buffer;
buffer++;
buflen--;
n--;
/* In order: is it an image, is it large enough to carry the
image header, is it version 1, and is it a JPEG? */
if(type==1 && n>=16 && buffer[2]==1 && buffer[3]==1)
{
/* For historical reasons (i.e. "oops!"), headerlen is
little endian. */
u16 headerlen=(buffer[1]<<8) | buffer[0];
attribs[count].type=ATTRIB_JPEG;
buffer+=headerlen;
buflen-=headerlen;
n-=headerlen;
}
else
attribs[count].type=ATTRIB_UNKNOWN;
attribs[count].data=buffer;
attribs[count].len=n;
buffer+=n;
buflen-=n;
count++;
}
uid->attribs=attribs;
uid->numattribs=count;
return count;
too_short:
log_error("buffer shorter than attribute subpacket\n");
uid->attribs=attribs;
uid->numattribs=count;
return count;
}
static void setup_user_id(PACKET *packet)
{
packet->pkt.user_id->ref = 1;
packet->pkt.user_id->attribs = NULL;
packet->pkt.user_id->attrib_data = NULL;
packet->pkt.user_id->attrib_len = 0;
packet->pkt.user_id->is_primary = 0;
packet->pkt.user_id->is_revoked = 0;
packet->pkt.user_id->created = 0;
packet->pkt.user_id->help_key_usage = 0;
packet->pkt.user_id->help_key_expire = 0;
packet->pkt.user_id->prefs = NULL;
}
static int
parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
@ -1664,16 +1756,9 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
byte *p;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + pktlen);
packet->pkt.user_id->ref = 1;
packet->pkt.user_id->len = pktlen;
packet->pkt.user_id->photo = NULL;
packet->pkt.user_id->photolen = 0;
packet->pkt.user_id->is_primary = 0;
packet->pkt.user_id->is_revoked = 0;
packet->pkt.user_id->created = 0;
packet->pkt.user_id->help_key_usage = 0;
packet->pkt.user_id->help_key_expire = 0;
packet->pkt.user_id->prefs = NULL;
setup_user_id(packet);
p = packet->pkt.user_id->name;
for( ; pktlen; pktlen--, p++ )
@ -1695,35 +1780,45 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
return 0;
}
void
make_attribute_uidname(PKT_user_id *uid)
{
/* List the first attribute as the "user id" */
if(uid->attribs)
sprintf( uid->name, "[%s of size %lu]",
uid->attribs->type==ATTRIB_JPEG?"image":"unknown attribute",
uid->attribs->len);
else
sprintf( uid->name, "[bad attribute of size %lu]",
uid->attrib_len );
uid->len = strlen(uid->name);
}
/****************
* PGP generates a packet of type 17. We assume this is a photo ID and
* simply store it here as a comment packet.
*/
static int
parse_photo_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
byte *p;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 30);
packet->pkt.user_id->ref = 1;
sprintf( packet->pkt.user_id->name, "[image of size %lu]", pktlen );
packet->pkt.user_id->len = strlen(packet->pkt.user_id->name);
packet->pkt.user_id->is_primary = 0;
packet->pkt.user_id->is_revoked = 0;
packet->pkt.user_id->created = 0;
packet->pkt.user_id->help_key_usage = 0;
packet->pkt.user_id->help_key_expire = 0;
packet->pkt.user_id->prefs = NULL;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 50);
packet->pkt.user_id->photo = m_alloc(sizeof *packet->pkt.user_id + pktlen);
packet->pkt.user_id->photolen = pktlen;
p = packet->pkt.user_id->photo;
setup_user_id(packet);
packet->pkt.user_id->attrib_data = m_alloc(pktlen);
packet->pkt.user_id->attrib_len = pktlen;
p = packet->pkt.user_id->attrib_data;
for( ; pktlen; pktlen--, p++ )
*p = iobuf_get_noeof(inp);
/* Now parse out the individual attribute subpackets. This is
somewhat pointless since there is only one currently defined
attribute type (jpeg), but it is correct by the spec. */
parse_attribute_subpkts(packet->pkt.user_id);
make_attribute_uidname(packet->pkt.user_id);
if( list_mode ) {
printf(":photo_id packet: %s\n", packet->pkt.user_id->name );
printf(":attribute packet: %s\n", packet->pkt.user_id->name );
}
return 0;
}