* keybox-search.c (blob_cmp_name): Kludge to allow searching for

more than one name.
(has_subject_or_alt): New.
(blob_cmp_mail): New.
(has_mail): New.
(keybox_search): Implemented exact search and exact mail search.

* kbx/keybox-blob.c (_keybox_create_x509_blob): Insert alternate
names.
This commit is contained in:
Werner Koch 2001-12-13 13:10:58 +00:00
parent c3567c42b7
commit e4f9871d91
5 changed files with 215 additions and 30 deletions

23
kbx/ChangeLog Normal file
View File

@ -0,0 +1,23 @@
2001-12-13 Werner Koch <wk@gnupg.org>
* keybox-search.c (blob_cmp_name): Kludge to allow searching for
more than one name.
(has_subject_or_alt): New.
(blob_cmp_mail): New.
(has_mail): New.
(keybox_search): Implemented exact search and exact mail search.
* kbx/keybox-blob.c (_keybox_create_x509_blob): Insert alternate
names.
Copyright 2001 g10 Code GmbH
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
modifications, as long as this notice is preserved.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -774,9 +774,11 @@ int
_keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
unsigned char *sha1_digest)
{
int rc = 0;
int i, rc = 0;
KEYBOXBLOB blob;
unsigned char *p;
unsigned char **names = NULL;
size_t max_names;
*r_blob = NULL;
blob = xtrycalloc (1, sizeof *blob);
@ -790,10 +792,43 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
blob->seriallen = n;
blob->serial = p;
}
blob->nkeys = 1;
blob->nuids = 2; /* issuer and subject - fixme: count alternate names */
/* create list of names */
blob->nuids = 0;
max_names = 100;
names = xtrymalloc (max_names * sizeof *names);
if (!names)
{
rc = KEYBOX_Out_Of_Core;
goto leave;
}
p = ksba_cert_get_issuer (cert, 0);
if (!p)
{
rc = KEYBOX_Missing_Value;
goto leave;
}
names[blob->nuids++] = p;
for (i=0; (p = ksba_cert_get_subject (cert, i)); i++)
{
if (blob->nuids >= max_names)
{
unsigned char **tmp;
max_names += 100;
tmp = xtryrealloc (names, max_names * sizeof *names);
if (!tmp)
{
rc = KEYBOX_Out_Of_Core;
goto leave;
}
}
names[blob->nuids++] = p;
}
/* space for signature information */
blob->nsigs = 1;
blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
@ -809,21 +844,17 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
blob->keys[0].off_kid = 0; /* We don't have keyids */
blob->keys[0].flags = 0;
/* issuer */
p = ksba_cert_get_issuer (cert);
blob->uids[0].name = p;
blob->uids[0].len = p? (strlen(p)+1):0;
blob->uids[0].flags = 0;
blob->uids[0].validity = 0;
/* subject */
p = ksba_cert_get_subject (cert);
blob->uids[1].name = p;
blob->uids[1].len = p? (strlen(p)+1):0;
blob->uids[1].flags = 0;
blob->uids[1].validity = 0;
/* fixme: add alternate names */
/* issuer and subject names */
for (i=0; i < blob->nuids; i++)
{
blob->uids[i].name = names[i];
blob->uids[i].len = strlen(names[i]);
names[i] = NULL;
blob->uids[i].flags = 0;
blob->uids[i].validity = 0;
}
xfree (names);
names = NULL;
/* signatures */
blob->sigs[0] = 0; /* not yet checked */
@ -849,6 +880,12 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
leave:
release_kid_list (blob->temp_kids);
blob->temp_kids = NULL;
if (blob && names)
{
for (i=0; i < blob->nuids; i++)
xfree (names[i]);
}
xfree (names);
if (rc)
{
_keybox_release_blob (blob);

View File

@ -38,6 +38,7 @@ keybox_strerror (KeyboxError err)
case KEYBOX_File_Close_Error: s="file close error"; break;
case KEYBOX_Nothing_Found: s="nothing found"; break;
case KEYBOX_Wrong_Blob_Type: s="wrong blob type"; break;
case KEYBOX_Missing_Value: s="missing value"; break;
default: sprintf (buf, "ec=%d", err ); s=buf; break;
}

View File

@ -102,6 +102,7 @@ blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn)
return nserial == snlen && !memcmp (buffer+off, sn, snlen);
}
static int
blob_cmp_name (KEYBOXBLOB blob, int idx, const char *name, size_t namelen)
{
@ -139,18 +140,105 @@ blob_cmp_name (KEYBOXBLOB blob, int idx, const char *name, size_t namelen)
if (pos + uidinfolen*nuids > length)
return 0; /* out of bounds */
if (idx > nuids)
return 0; /* no user ID with that idx */
pos += idx*uidinfolen;
off = get32 (buffer+pos);
len = get32 (buffer+pos+4);
if (off+len > length)
if (idx < 0)
{ /* compare all names starting with that (negated) index */
idx = -idx;
for ( ;idx < nuids; idx++)
{
size_t mypos = pos;
mypos += idx*uidinfolen;
off = get32 (buffer+mypos);
len = get32 (buffer+mypos+4);
if (off+len > length)
return 0; /* error: better stop here out of bounds */
if (len < 2)
continue; /* empty name or 0 not stored */
len--;
if (len == namelen && !memcmp (buffer+off, name, len))
return 1; /* found */
}
return 0; /* not found */
}
else
{
if (idx > nuids)
return 0; /* no user ID with that idx */
pos += idx*uidinfolen;
off = get32 (buffer+pos);
len = get32 (buffer+pos+4);
if (off+len > length)
return 0; /* out of bounds */
if (len < 2)
return 0; /* empty name or 0 not stored */
len--;
return len == namelen && !memcmp (buffer+off, name, len);
}
}
/* compare all email addresses of the subject */
static int
blob_cmp_mail (KEYBOXBLOB blob, const char *name, size_t namelen)
{
const unsigned char *buffer;
size_t length;
size_t pos, off, len;
size_t nkeys, keyinfolen;
size_t nuids, uidinfolen;
size_t nserial;
int idx;
/* fixme: this code is common to blob_cmp_mail */
buffer = _keybox_get_blob_image (blob, &length);
if (length < 40)
return 0; /* blob too short */
/*keys*/
nkeys = get16 (buffer + 16);
keyinfolen = get16 (buffer + 18 );
if (keyinfolen < 28)
return 0; /* invalid blob */
pos = 20 + keyinfolen*nkeys;
if (pos+2 > length)
return 0; /* out of bounds */
if (len < 2)
return 0; /* empty name or 0 not stored */
len--;
return len == namelen && !memcmp (buffer+off, name, len);
/*serial*/
nserial = get16 (buffer+pos);
pos += 2 + nserial;
if (pos+4 > length)
return 0; /* out of bounds */
/* user ids*/
nuids = get16 (buffer + pos); pos += 2;
uidinfolen = get16 (buffer + pos); pos += 2;
if (uidinfolen < 12 /* should add a: || nuidinfolen > MAX_UIDINFOLEN */)
return 0; /* invalid blob */
if (pos + uidinfolen*nuids > length)
return 0; /* out of bounds */
for (idx=1 ;idx < nuids; idx++)
{
size_t mypos = pos;
mypos += idx*uidinfolen;
off = get32 (buffer+mypos);
len = get32 (buffer+mypos+4);
if (off+len > length)
return 0; /* error: better stop here out of bounds */
if (len < 2 || buffer[off] != '<')
continue; /* empty name or trailing 0 not stored */
len--; /* remove the null */
if ( len < 3 || buffer[off+len-1] != '>')
continue; /* not a prober email address */
off++; len--; /* skip the leading angle bracket */
len--; /* don't compare the trailing one */
if (len == namelen && !memcmp (buffer+off, name, len))
return 1; /* found */
}
return 0; /* not found */
}
@ -235,6 +323,35 @@ has_subject (KEYBOXBLOB blob, const char *name)
return blob_cmp_name (blob, 1 /* subject */, name, namelen);
}
static int
has_subject_or_alt (KEYBOXBLOB blob, const char *name)
{
size_t namelen;
return_val_if_fail (name, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
return blob_cmp_name (blob, -1 /* all subject names*/, name, namelen);
}
static int
has_mail (KEYBOXBLOB blob, const char *name)
{
size_t namelen;
return_val_if_fail (name, 0);
if (blob_get_type (blob) != BLOBTYPE_X509)
return 0;
namelen = strlen (name);
return blob_cmp_mail (blob, name, namelen);
}
static void
release_sn_array (unsigned char **array, size_t size)
@ -413,8 +530,14 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
never_reached ();
break;
case KEYDB_SEARCH_MODE_EXACT:
case KEYDB_SEARCH_MODE_SUBSTR:
if (has_subject_or_alt (blob, desc[n].u.name))
goto found;
break;
case KEYDB_SEARCH_MODE_MAIL:
if (has_mail (blob, desc[n].u.name))
goto found;
break;
case KEYDB_SEARCH_MODE_SUBSTR:
case KEYDB_SEARCH_MODE_MAILSUB:
case KEYDB_SEARCH_MODE_MAILEND:
case KEYDB_SEARCH_MODE_WORDS:

View File

@ -60,6 +60,7 @@ typedef enum {
KEYBOX_File_Close_Error = 13,
KEYBOX_Nothing_Found = 14,
KEYBOX_Wrong_Blob_Type = 15,
KEYBOX_Missing_Value = 16,
} KeyboxError;