summaryrefslogtreecommitdiffstats
path: root/kbx
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2001-12-13 14:10:58 +0100
committerWerner Koch <wk@gnupg.org>2001-12-13 14:10:58 +0100
commite4f9871d91017a5d929f8ab7c0ae29f7bbe31265 (patch)
tree7a66472be56ccc14851b4203b3d036dbce64713a /kbx
parentNow that the DN encoding works more correct, we have to update the (diff)
downloadgnupg2-e4f9871d91017a5d929f8ab7c0ae29f7bbe31265.tar.xz
gnupg2-e4f9871d91017a5d929f8ab7c0ae29f7bbe31265.zip
* 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.
Diffstat (limited to 'kbx')
-rw-r--r--kbx/ChangeLog23
-rw-r--r--kbx/keybox-blob.c73
-rw-r--r--kbx/keybox-errors.c1
-rw-r--r--kbx/keybox-search.c147
-rw-r--r--kbx/keybox.h1
5 files changed, 215 insertions, 30 deletions
diff --git a/kbx/ChangeLog b/kbx/ChangeLog
new file mode 100644
index 000000000..8451dd250
--- /dev/null
+++ b/kbx/ChangeLog
@@ -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.
+ \ No newline at end of file
diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c
index 84ebc904c..18503a576 100644
--- a/kbx/keybox-blob.c
+++ b/kbx/keybox-blob.c
@@ -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);
diff --git a/kbx/keybox-errors.c b/kbx/keybox-errors.c
index e75373c0b..e11efc10b 100644
--- a/kbx/keybox-errors.c
+++ b/kbx/keybox-errors.c
@@ -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;
}
diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c
index 23543ec66..e168d2b97 100644
--- a/kbx/keybox-search.c
+++ b/kbx/keybox-search.c
@@ -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:
diff --git a/kbx/keybox.h b/kbx/keybox.h
index 645f1e715..fcacc49d3 100644
--- a/kbx/keybox.h
+++ b/kbx/keybox.h
@@ -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;