mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-17 14:07:03 +01:00
* 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:
parent
c3567c42b7
commit
e4f9871d91
23
kbx/ChangeLog
Normal file
23
kbx/ChangeLog
Normal 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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user