mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-11 22:01:08 +02: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,
|
_keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
|
||||||
unsigned char *sha1_digest)
|
unsigned char *sha1_digest)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int i, rc = 0;
|
||||||
KEYBOXBLOB blob;
|
KEYBOXBLOB blob;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
unsigned char **names = NULL;
|
||||||
|
size_t max_names;
|
||||||
|
|
||||||
*r_blob = NULL;
|
*r_blob = NULL;
|
||||||
blob = xtrycalloc (1, sizeof *blob);
|
blob = xtrycalloc (1, sizeof *blob);
|
||||||
@ -790,10 +792,43 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
|
|||||||
blob->seriallen = n;
|
blob->seriallen = n;
|
||||||
blob->serial = p;
|
blob->serial = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
blob->nkeys = 1;
|
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->nsigs = 1;
|
||||||
|
|
||||||
blob->keys = xtrycalloc (blob->nkeys, sizeof *blob->keys );
|
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].off_kid = 0; /* We don't have keyids */
|
||||||
blob->keys[0].flags = 0;
|
blob->keys[0].flags = 0;
|
||||||
|
|
||||||
/* issuer */
|
/* issuer and subject names */
|
||||||
p = ksba_cert_get_issuer (cert);
|
for (i=0; i < blob->nuids; i++)
|
||||||
blob->uids[0].name = p;
|
{
|
||||||
blob->uids[0].len = p? (strlen(p)+1):0;
|
blob->uids[i].name = names[i];
|
||||||
blob->uids[0].flags = 0;
|
blob->uids[i].len = strlen(names[i]);
|
||||||
blob->uids[0].validity = 0;
|
names[i] = NULL;
|
||||||
|
blob->uids[i].flags = 0;
|
||||||
/* subject */
|
blob->uids[i].validity = 0;
|
||||||
p = ksba_cert_get_subject (cert);
|
}
|
||||||
blob->uids[1].name = p;
|
xfree (names);
|
||||||
blob->uids[1].len = p? (strlen(p)+1):0;
|
names = NULL;
|
||||||
blob->uids[1].flags = 0;
|
|
||||||
blob->uids[1].validity = 0;
|
|
||||||
|
|
||||||
/* fixme: add alternate names */
|
|
||||||
|
|
||||||
/* signatures */
|
/* signatures */
|
||||||
blob->sigs[0] = 0; /* not yet checked */
|
blob->sigs[0] = 0; /* not yet checked */
|
||||||
@ -849,6 +880,12 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert,
|
|||||||
leave:
|
leave:
|
||||||
release_kid_list (blob->temp_kids);
|
release_kid_list (blob->temp_kids);
|
||||||
blob->temp_kids = NULL;
|
blob->temp_kids = NULL;
|
||||||
|
if (blob && names)
|
||||||
|
{
|
||||||
|
for (i=0; i < blob->nuids; i++)
|
||||||
|
xfree (names[i]);
|
||||||
|
}
|
||||||
|
xfree (names);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
_keybox_release_blob (blob);
|
_keybox_release_blob (blob);
|
||||||
|
@ -38,6 +38,7 @@ keybox_strerror (KeyboxError err)
|
|||||||
case KEYBOX_File_Close_Error: s="file close error"; break;
|
case KEYBOX_File_Close_Error: s="file close error"; break;
|
||||||
case KEYBOX_Nothing_Found: s="nothing found"; break;
|
case KEYBOX_Nothing_Found: s="nothing found"; break;
|
||||||
case KEYBOX_Wrong_Blob_Type: s="wrong blob type"; 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;
|
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);
|
return nserial == snlen && !memcmp (buffer+off, sn, snlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
blob_cmp_name (KEYBOXBLOB blob, int idx, const char *name, size_t namelen)
|
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)
|
if (pos + uidinfolen*nuids > length)
|
||||||
return 0; /* out of bounds */
|
return 0; /* out of bounds */
|
||||||
|
|
||||||
if (idx > nuids)
|
if (idx < 0)
|
||||||
return 0; /* no user ID with that idx */
|
{ /* compare all names starting with that (negated) index */
|
||||||
pos += idx*uidinfolen;
|
idx = -idx;
|
||||||
off = get32 (buffer+pos);
|
|
||||||
len = get32 (buffer+pos+4);
|
for ( ;idx < nuids; idx++)
|
||||||
if (off+len > length)
|
{
|
||||||
|
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 */
|
return 0; /* out of bounds */
|
||||||
if (len < 2)
|
|
||||||
return 0; /* empty name or 0 not stored */
|
/*serial*/
|
||||||
len--;
|
nserial = get16 (buffer+pos);
|
||||||
|
pos += 2 + nserial;
|
||||||
return len == namelen && !memcmp (buffer+off, name, len);
|
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);
|
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
|
static void
|
||||||
release_sn_array (unsigned char **array, size_t size)
|
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 ();
|
never_reached ();
|
||||||
break;
|
break;
|
||||||
case KEYDB_SEARCH_MODE_EXACT:
|
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:
|
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_MAILSUB:
|
||||||
case KEYDB_SEARCH_MODE_MAILEND:
|
case KEYDB_SEARCH_MODE_MAILEND:
|
||||||
case KEYDB_SEARCH_MODE_WORDS:
|
case KEYDB_SEARCH_MODE_WORDS:
|
||||||
|
@ -60,6 +60,7 @@ typedef enum {
|
|||||||
KEYBOX_File_Close_Error = 13,
|
KEYBOX_File_Close_Error = 13,
|
||||||
KEYBOX_Nothing_Found = 14,
|
KEYBOX_Nothing_Found = 14,
|
||||||
KEYBOX_Wrong_Blob_Type = 15,
|
KEYBOX_Wrong_Blob_Type = 15,
|
||||||
|
KEYBOX_Missing_Value = 16,
|
||||||
} KeyboxError;
|
} KeyboxError;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user