static void collect_data (char *hexdata, const char *address, unsigned int lineno) { size_t length; int is_bi; char *s; unsigned int value; is_bi = (*address && address[1] == 'i'); if (databuffer.is_bi != is_bi || strcmp (databuffer.address, address)) flush_data (); databuffer.is_bi = is_bi; if (strlen (address) >= sizeof databuffer.address) die ("address field too long"); strcpy (databuffer.address, address); length = databuffer.count; for (s=hexdata; *s; s++ ) { if (ascii_isspace (*s)) continue; if (!hexdigitp (*s)) { err ("invalid hex digit in line %u - line skipped", lineno); break; } value = xtoi_1 (*s) * 16; s++; if (!hexdigitp (*s)) { err ("invalid hex digit in line %u - line skipped", lineno); break; } value += xtoi_1 (*s); if (length >= sizeof (databuffer.data)) { err ("too much data at line %u - can handle only up to % bytes", lineno, sizeof (databuffer.data)); break; } databuffer.data[length++] = value; } databuffer.count = length; }
/* Create a simple S-expression from the hex string at LINE. Returns a newly allocated buffer with that canonical encoded S-expression or NULL in case of an error. On return the number of characters scanned in LINE will be stored at NSCANNED. This fucntions stops converting at the first character not representing a hexdigit. Odd numbers of hex digits are allowed; a leading zero is then assumed. If no characters have been found, NULL is returned.*/ unsigned char * make_simple_sexp_from_hexstr (const char *line, size_t *nscanned) { size_t n, len; const char *s; unsigned char *buf; unsigned char *p; char numbuf[50], *numbufp; size_t numbuflen; for (n=0, s=line; hexdigitp (s); s++, n++) ; if (nscanned) *nscanned = n; if (!n) return NULL; len = ((n+1) & ~0x01)/2; numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen); buf = xtrymalloc (1 + numbuflen + len + 1 + 1); if (!buf) return NULL; buf[0] = '('; p = (unsigned char *)stpcpy ((char *)buf+1, numbufp); s = line; if ((n&1)) { *p++ = xtoi_1 (s); s++; n--; } for (; n > 1; n -=2, s += 2) *p++ = xtoi_2 (s); *p++ = ')'; *p = 0; /* (Not really neaded.) */ return buf; }
static void parse_line_sniffusb (char *line, unsigned int lineno) { char *p; if (debug) printf ("line[%u] ='%s'\n", lineno, line); p = strtok (line, " \t"); if (!p) return; p = strtok (NULL, " \t"); if (!p) return; p = strtok (NULL, " \t"); if (!p) return; if (hexdigitp (p[0]) && hexdigitp (p[1]) && hexdigitp (p[2]) && hexdigitp (p[3]) && p[4] == ':' && !p[5]) { size_t length; unsigned int value; length = databuffer.count; while ((p=strtok (NULL, " \t"))) { if (!hexdigitp (p[0]) || !hexdigitp (p[1])) { err ("invalid hex digit in line %u (%s)", lineno,p); break; } value = xtoi_1 (p[0]) * 16 + xtoi_1 (p[1]); if (length >= sizeof (databuffer.data)) { err ("too much data at line %u - can handle only up to % bytes", lineno, sizeof (databuffer.data)); break; } databuffer.data[length++] = value; } databuffer.count = length; } else if (!strcmp (p, "TransferFlags")) { flush_data (); *databuffer.address = 0; while ((p=strtok (NULL, " \t(,)"))) { if (!strcmp (p, "USBD_TRANSFER_DIRECTION_IN")) { databuffer.is_bi = 1; break; } else if (!strcmp (p, "USBD_TRANSFER_DIRECTION_OUT")) { databuffer.is_bi = 0; break; } } } }
/* Note: When in ephemeral mode the search function does visit all blobs but in standard mode, blobs flagged as ephemeral are ignored. */ int keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) { int rc; size_t n; int need_words, any_skip; KEYBOXBLOB blob = NULL; struct sn_array_s *sn_array = NULL; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); /* clear last found result */ if (hd->found.blob) { _keybox_release_blob (hd->found.blob); hd->found.blob = NULL; } if (hd->error) return hd->error; /* still in error state */ if (hd->eof) return -1; /* still EOF */ /* figure out what information we need */ need_words = any_skip = 0; for (n=0; n < ndesc; n++) { switch (desc[n].mode) { case KEYDB_SEARCH_MODE_WORDS: need_words = 1; break; case KEYDB_SEARCH_MODE_FIRST: /* always restart the search in this mode */ keybox_search_reset (hd); break; default: break; } if (desc[n].skipfnc) any_skip = 1; if (desc[n].snlen == -1 && !sn_array) { sn_array = xtrycalloc (ndesc, sizeof *sn_array); if (!sn_array) return (hd->error = gpg_error_from_syserror ()); } } (void)need_words; /* Not yet implemented. */ if (!hd->fp) { hd->fp = fopen (hd->kb->fname, "rb"); if (!hd->fp) { hd->error = gpg_error_from_syserror (); xfree (sn_array); return hd->error; } } /* Kludge: We need to convert an SN given as hexstring to its binary representation - in some cases we are not able to store it in the search descriptor, because due to the way we use it, it is not possible to free allocated memory. */ if (sn_array) { const unsigned char *s; int i, odd; size_t snlen; for (n=0; n < ndesc; n++) { if (!desc[n].sn) ; else if (desc[n].snlen == -1) { unsigned char *sn; s = desc[n].sn; for (i=0; *s && *s != '/'; s++, i++) ; odd = (i & 1); snlen = (i+1)/2; sn_array[n].sn = xtrymalloc (snlen); if (!sn_array[n].sn) { hd->error = gpg_error_from_syserror (); release_sn_array (sn_array, n); return hd->error; } sn_array[n].snlen = snlen; sn = sn_array[n].sn; s = desc[n].sn; if (odd) { *sn++ = xtoi_1 (s); s++; } for (; *s && *s != '/'; s += 2) *sn++ = xtoi_2 (s); } else { const unsigned char *sn; sn = desc[n].sn; snlen = desc[n].snlen; sn_array[n].sn = xtrymalloc (snlen); if (!sn_array[n].sn) { hd->error = gpg_error_from_syserror (); release_sn_array (sn_array, n); return hd->error; } sn_array[n].snlen = snlen; memcpy (sn_array[n].sn, sn, snlen); } } } for (;;) { unsigned int blobflags; _keybox_release_blob (blob); blob = NULL; rc = _keybox_read_blob (&blob, hd->fp); if (rc) break; if (blob_get_type (blob) == BLOBTYPE_HEADER) continue; blobflags = blob_get_blob_flags (blob); if (!hd->ephemeral && (blobflags & 2)) continue; /* Not in ephemeral mode but blob is flagged ephemeral. */ for (n=0; n < ndesc; n++) { switch (desc[n].mode) { case KEYDB_SEARCH_MODE_NONE: never_reached (); break; case KEYDB_SEARCH_MODE_EXACT: if (has_subject_or_alt (blob, desc[n].u.name, 0)) goto found; break; case KEYDB_SEARCH_MODE_MAIL: if (has_mail (blob, desc[n].u.name, 0)) goto found; break; case KEYDB_SEARCH_MODE_MAILSUB: if (has_mail (blob, desc[n].u.name, 1)) goto found; break; case KEYDB_SEARCH_MODE_SUBSTR: if (has_subject_or_alt (blob, desc[n].u.name, 1)) goto found; break; case KEYDB_SEARCH_MODE_MAILEND: case KEYDB_SEARCH_MODE_WORDS: never_reached (); /* not yet implemented */ break; case KEYDB_SEARCH_MODE_ISSUER: if (has_issuer (blob, desc[n].u.name)) goto found; break; case KEYDB_SEARCH_MODE_ISSUER_SN: if (has_issuer_sn (blob, desc[n].u.name, sn_array? sn_array[n].sn : desc[n].sn, sn_array? sn_array[n].snlen : desc[n].snlen)) goto found; break; case KEYDB_SEARCH_MODE_SN: if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn, sn_array? sn_array[n].snlen : desc[n].snlen)) goto found; break; case KEYDB_SEARCH_MODE_SUBJECT: if (has_subject (blob, desc[n].u.name)) goto found; break; case KEYDB_SEARCH_MODE_SHORT_KID: if (has_short_kid (blob, desc[n].u.kid[1])) goto found; break; case KEYDB_SEARCH_MODE_LONG_KID: if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1])) goto found; break; case KEYDB_SEARCH_MODE_FPR: case KEYDB_SEARCH_MODE_FPR20: if (has_fingerprint (blob, desc[n].u.fpr)) goto found; break; case KEYDB_SEARCH_MODE_KEYGRIP: if (has_keygrip (blob, desc[n].u.grip)) goto found; break; case KEYDB_SEARCH_MODE_FIRST: goto found; break; case KEYDB_SEARCH_MODE_NEXT: goto found; break; default: rc = gpg_error (GPG_ERR_INV_VALUE); goto found; } } continue; found: for (n=any_skip?0:ndesc; n < ndesc; n++) { /* if (desc[n].skipfnc */ /* && desc[n].skipfnc (desc[n].skipfncvalue, aki, NULL)) */ /* break; */ } if (n == ndesc) break; /* got it */ } if (!rc) { hd->found.blob = blob; } else if (rc == -1) { _keybox_release_blob (blob); hd->eof = 1; } else { _keybox_release_blob (blob); hd->error = rc; } if (sn_array) release_sn_array (sn_array, ndesc); return rc; }