diff --git a/kbx/ChangeLog b/kbx/ChangeLog index e1a2bb734..f35742829 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog @@ -1,3 +1,14 @@ +2001-12-18 Werner Koch + + * keybox-blob.c (_keybox_create_x509_blob): Use + gcry_sexp_canon_len to get the length of the serial number. + (_keybox_release_blob): Need to use a new serialbuf to free the memory. + +2001-12-17 Werner Koch + + * keybox-search.c: Changed the way the serial number is + represented. + 2001-12-15 Werner Koch * keybox-search.c (blob_cmp_name): There is no terminating 0 stored diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 44d53d3d0..f3bc859b3 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -172,7 +172,8 @@ struct keyboxblob { size_t bloblen; /* stuff used only by keybox_create_blob */ - unsigned char *serial; + unsigned char *serialbuf; + const unsigned char *serial; size_t seriallen; int nkeys; struct keyboxblob_key *keys; @@ -820,7 +821,14 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, KsbaCert cert, p = ksba_cert_get_serial (cert); if (p) { - size_t n = (p[0] << 24) | (p[1] << 16) | (p[2] <<8) | p[3]; + size_t n; + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + return KEYBOX_General_Error; + blob->serialbuf = p; + for (; n && *p != ':'; n--, p++) + ; + p++; blob->seriallen = n; blob->serial = p; } @@ -960,7 +968,7 @@ _keybox_release_blob (KEYBOXBLOB blob) return; /* hmmm: release membuf here?*/ xfree (blob->keys ); - xfree (blob->serial); + xfree (blob->serialbuf); for (i=0; i < blob->nuids; i++) xfree (blob->uids[i].name); xfree (blob->uids ); diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h index 84be20f18..4be59c27d 100644 --- a/kbx/keybox-search-desc.h +++ b/kbx/keybox-search-desc.h @@ -53,7 +53,7 @@ struct keydb_search_desc { int (*skipfnc)(void *,void*); /* used to be: void*, u32* */ void *skipfncvalue; const unsigned char *sn; - int sn_is_string; /* very ugly */ + int snlen; /* -1 := sn is a hex string */ union { const char *name; unsigned char fpr[24]; diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 41fb83233..1c78caedd 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -30,6 +30,12 @@ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +struct sn_array_s { + int snlen; + unsigned char *sn; +}; + + static ulong get32 (const byte *buffer) @@ -68,18 +74,14 @@ blob_get_type (KEYBOXBLOB blob) static int -blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn) +blob_cmp_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) { - size_t snlen; const unsigned char *buffer; size_t length; size_t pos, off; size_t nkeys, keyinfolen; size_t nserial; - snlen = (sn[0] << 24) | (sn[1] << 16) | (sn[2] << 8) | sn[3]; - sn += 4; - buffer = _keybox_get_blob_image (blob, &length); if (length < 40) return 0; /* blob too short */ @@ -284,7 +286,8 @@ has_issuer (KEYBOXBLOB blob, const char *name) } static int -has_issuer_sn (KEYBOXBLOB blob, const char *name, const unsigned char *sn) +has_issuer_sn (KEYBOXBLOB blob, const char *name, + const unsigned char *sn, int snlen) { size_t namelen; @@ -296,18 +299,18 @@ has_issuer_sn (KEYBOXBLOB blob, const char *name, const unsigned char *sn) namelen = strlen (name); - return (blob_cmp_sn (blob, sn) + return (blob_cmp_sn (blob, sn, snlen) && blob_cmp_name (blob, 0 /* issuer */, name, namelen)); } static int -has_sn (KEYBOXBLOB blob, const unsigned char *sn) +has_sn (KEYBOXBLOB blob, const unsigned char *sn, int snlen) { return_val_if_fail (sn, 0); if (blob_get_type (blob) != BLOBTYPE_X509) return 0; - return blob_cmp_sn (blob, sn); + return blob_cmp_sn (blob, sn, snlen); } static int @@ -357,12 +360,12 @@ has_mail (KEYBOXBLOB blob, const char *name) static void -release_sn_array (unsigned char **array, size_t size) +release_sn_array (struct sn_array_s *array, size_t size) { size_t n; for (n=0; n < size; n++) - xfree (array[n]); + xfree (array[n].sn); xfree (array); } @@ -402,7 +405,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) size_t n; int need_words, any_skip; KEYBOXBLOB blob = NULL; - unsigned char **sn_array = NULL; + struct sn_array_s *sn_array = NULL; if (!hd) return KEYBOX_Invalid_Value; @@ -437,7 +440,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) } if (desc[n].skipfnc) any_skip = 1; - if (desc[n].sn_is_string && !sn_array) + if (desc[n].snlen == -1 && !sn_array) { sn_array = xtrycalloc (ndesc, sizeof *sn_array); if (!sn_array) @@ -469,7 +472,7 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) { if (!desc[n].sn) ; - else if (desc[n].sn_is_string) + else if (desc[n].snlen == -1) { unsigned char *sn; @@ -478,13 +481,14 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) ; odd = (i & 1); snlen = (i+1)/2; - sn_array[n] = xtrymalloc (4+snlen); - if (!sn_array[n]) + sn_array[n].sn = xtrymalloc (snlen); + if (!sn_array[n].sn) { release_sn_array (sn_array, n); return (hd->error = KEYBOX_Out_Of_Core); } - sn = sn_array[n] + 4; + sn_array[n].snlen = snlen; + sn = sn_array[n].sn; s = desc[n].sn; if (odd) { @@ -493,26 +497,21 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) } for (; *s && *s != '/'; s += 2) *sn++ = xtoi_2 (s); - assert (sn - sn_array[n] == 4+snlen); - sn = sn_array[n]; - sn[0] = snlen >> 24; - sn[1] = snlen >> 16; - sn[2] = snlen >> 8; - sn[3] = snlen; } else { const unsigned char *sn; sn = desc[n].sn; - snlen = (sn[0] << 24) | (sn[1] << 16) | (sn[2] << 8) | sn[3]; - sn_array[n] = xtrymalloc (4+snlen); - if (!sn_array[n]) + snlen = desc[n].snlen; + sn_array[n].sn = xtrymalloc (snlen); + if (!sn_array[n].sn) { release_sn_array (sn_array, n); return (hd->error = KEYBOX_Out_Of_Core); } - memcpy (sn_array[n], sn, 4+snlen); + sn_array[n].snlen = snlen; + memcpy (sn_array[n].sn, sn, snlen); } } } @@ -552,11 +551,13 @@ keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc) break; case KEYDB_SEARCH_MODE_ISSUER_SN: if (has_issuer_sn (blob, desc[n].u.name, - sn_array? sn_array[n] : desc[n].sn)) + 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] : desc[n].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: diff --git a/sm/ChangeLog b/sm/ChangeLog index b25a87fb1..654b4e93c 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,5 +1,38 @@ +2001-12-18 Werner Koch + + * verify.c (print_integer_sexp): Renamed from print_integer and + print the serial number according to the S-Exp rules. + * decrypt.c (print_integer_sexp): Ditto. + +2001-12-17 Werner Koch + + * keylist.c (list_cert_colon): Changed for new return value of + get_serial. + * keydb.c (keydb_search_issuer_sn): Ditto. + * certcheck.c (gpgsm_check_cert_sig): Likewise for other S-Exp + returingin functions. + * fingerprint.c (gpgsm_get_keygrip): Ditto. + * encrypt.c (encrypt_dek): Ditto + * certcheck.c (gpgsm_check_cms_signature): Ditto + * decrypt.c (prepare_decryption): Ditto. + * call-agent.c (gpgsm_agent_pkdecrypt): Removed arg ciphertextlen, + use KsbaSexp type and calculate the length. + + * certdump.c (print_sexp): Remaned from print_integer, changed caller. + + * Makefile.am: Use the LIBGCRYPT and LIBKSBA variables. + + * fingerprint.c (gpgsm_get_keygrip): Use the new + gcry_pk_get_keygrip to calculate the grip - note the algorithm and + therefore the grip values changed. + 2001-12-15 Werner Koch + * certcheck.c (gpgsm_check_cms_signature): Removed the faked-key + kludge. + (gpgsm_create_cms_signature): Removed the commented fake key + code. This makes the function pretty simple. + * gpgsm.c (main): Renamed the default key database to "keyring.kbx". * decrypt.c (gpgsm_decrypt): Write STATUS_DECRYPTION_*. diff --git a/sm/Makefile.am b/sm/Makefile.am index 52b78bc0b..1c21a91dc 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -20,9 +20,9 @@ bin_PROGRAMS = gpgsm -INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/intl +INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/intl \ + $(LIBGCRYPT_CFLAGS) $(LIBKSBA_CFLAGS) LDFLAGS = @LDFLAGS@ -#$(LIBGCRYPT_LIBS) gpgsm_SOURCES = \ gpgsm.c gpgsm.h \ @@ -45,8 +45,6 @@ gpgsm_SOURCES = \ gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a ../kbx/libkeybox.a \ - ../common/libcommon.a \ - ../../libksba/src/.libs/libksba.a \ - ../../libgcrypt/src/.libs/libgcrypt.so.1 + ../common/libcommon.a $(LIBGCRYPT_LIBS) $(LIBKSBA_LIBS) diff --git a/sm/call-agent.c b/sm/call-agent.c index 5facd6990..6952e22f7 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -273,7 +273,7 @@ inq_ciphertext_cb (void *opaque, const char *keyword) the hex string KEYGRIP. */ int gpgsm_agent_pkdecrypt (const char *keygrip, - const char *ciphertext, size_t ciphertextlen, + KsbaConstSexp ciphertext, char **r_buf, size_t *r_buflen ) { int rc; @@ -282,11 +282,16 @@ gpgsm_agent_pkdecrypt (const char *keygrip, struct cipher_parm_s cipher_parm; size_t n, len; char *buf, *endp; + size_t ciphertextlen; if (!keygrip || strlen(keygrip) != 40 || !ciphertext || !r_buf || !r_buflen) return GNUPG_Invalid_Value; *r_buf = NULL; + ciphertextlen = gcry_sexp_canon_len (ciphertext, 0, NULL, NULL); + if (!ciphertextlen) + return GNUPG_Invalid_Value; + rc = start_agent (); if (rc) return rc; diff --git a/sm/certcheck.c b/sm/certcheck.c index f56359e43..9108eb8e9 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -107,7 +107,8 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert) GCRY_MD_HD md; int rc, algo; GCRY_MPI frame; - char *p; + KsbaSexp p; + size_t n; GCRY_SEXP s_sig, s_hash, s_pkey; algo = gcry_md_map_name ( (algoid=ksba_cert_get_digest_algo (cert))); @@ -132,11 +133,14 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert) } gcry_md_final (md); - p = ksba_cert_get_sig_val (cert); /* fixme: check p*/ - if (DBG_X509) - log_debug ("signature: %s\n", p); - - rc = gcry_sexp_sscan ( &s_sig, NULL, p, strlen(p)); + p = ksba_cert_get_sig_val (cert); + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + return GNUPG_Bug; + } + rc = gcry_sexp_sscan ( &s_sig, NULL, p, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); @@ -144,10 +148,13 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert) } p = ksba_cert_get_public_key (issuer_cert); - if (DBG_X509) - log_debug ("issuer public key: %s\n", p); - - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, strlen(p)); + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + return GNUPG_Bug; + } + rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); @@ -174,46 +181,38 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert) int -gpgsm_check_cms_signature (KsbaCert cert, const char *sigval, +gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval, GCRY_MD_HD md, int algo) { int rc; - char *p; + KsbaSexp p; GCRY_MPI frame; GCRY_SEXP s_sig, s_hash, s_pkey; + size_t n; - rc = gcry_sexp_sscan (&s_sig, NULL, sigval, strlen(sigval)); + n = gcry_sexp_canon_len (sigval, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + return GNUPG_Bug; + } + rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); return map_gcry_err (rc); } - if (getenv ("GPGSM_FAKE_KEY")) - { - const char n[] = "#8732A669BB7C5057AD070EFA54E035C86DF474F7A7EBE2435" - "3DADEB86FFE74C32AEEF9E5C6BD7584CB572520167B3E8C89A1FA75C74FF9E938" - "2710F3B270B638EB96E7486491D81C53CA8A50B4E840B1C7458A4A1E52EC18D681" - "8A2805C9165827F77EF90D55014E4B2AF9386AE8F6462F46A547CB593ABD509311" - "4D3D16375F#"; - const char e[] = "#11#"; - char *tmp; - - log_debug ("Using HARDWIRED public key\n"); - asprintf (&tmp, "(public-key(rsa(n %s)(e %s)))", n, e); - /* asprintf does not use our allocation fucntions, so we can't - use our free */ - p = xstrdup (tmp); - free (tmp); - } - else - { - p = ksba_cert_get_public_key (cert); - } - + p = ksba_cert_get_public_key (cert); if (DBG_X509) log_debug ("public key: %s\n", p); - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, strlen(p)); + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + return GNUPG_Bug; + } + rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); @@ -244,78 +243,6 @@ int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, char **r_sigval) { -#if 0 - - /* our sample key */ - const char n[] = "#8732A669BB7C5057AD070EFA54E035C86DF474F7A7EBE2435" - "3DADEB86FFE74C32AEEF9E5C6BD7584CB572520167B3E8C89A1FA75C74FF9E938" - "2710F3B270B638EB96E7486491D81C53CA8A50B4E840B1C7458A4A1E52EC18D681" - "8A2805C9165827F77EF90D55014E4B2AF9386AE8F6462F46A547CB593ABD509311" - "4D3D16375F#"; - const char e[] = "#11#"; - const char d[] = "#07F3EBABDDDA22D7FB1E8869140D30571586D9B4370DE02213F" - "DD0DDAC3C24FC6BEFF0950BB0CAAD755F7AA788DA12BCF90987341AC8781CC7115" - "B59A115B05D9D99B3D7AF77854DC2EE6A36154512CC0EAD832601038A88E837112" - "AB2A39FD9FBE05E30D6FFA6F43D71C59F423CA43BC91C254A8C89673AB61F326B0" - "762FBC9#"; - const char p[] = "#B2ABAD4328E66303E206C53CFBED17F18F712B1C47C966EE13DD" - "AA9AD3616A610ADF513F8376FA48BAE12FED64CECC1E73091A77B45119AF0FC1286A" - "85BD9BBD#"; - const char q[] = "#C1B648B294BB9AEE7FEEB77C4F64E9333E4EA9A7C54D521356FB" - "BBB7558A0E7D6331EC7B42E3F0CD7BBBA9B7A013422F615F10DCC1E8462828BF8FC7" - "39C5E34B#"; - const char u[] = "#A9B5EFF9C80A4A356B9A95EB63E381B262071E5CE9C1F32FF03" - "83AD8289BED8BC690555E54411FA2FDB9B49638A21B2046C325F5633B4B1ECABEBFD" - "1B3519072#"; - - GCRY_SEXP s_skey, s_hash, s_sig; - GCRY_MPI frame; - int rc; - char *buf; - size_t len; - - /* create a secret key as an sexp */ - log_debug ("Using HARDWIRED secret key\n"); - asprintf (&buf, "(private-key(oid.1.2.840.113549.1.1.1" - "(n %s)(e %s)(d %s)(p %s)(q %s)(u %s)))", - n, e, d, p, q, u); - /* asprintf does not use our allocation fucntions, so we can't - use our free */ - rc = gcry_sexp_sscan (&s_skey, NULL, buf, strlen(buf)); - free (buf); - if (rc) - { - log_error ("failed to build S-Exp: %s\n", gcry_strerror (rc)); - return map_gcry_err (rc); - } - - /* put the hash into a sexp */ - rc = do_encode_md (md, mdalgo, gcry_pk_get_nbits (s_skey), &frame); - if (rc) - { - /* fixme: clean up some things */ - return rc; - } - if ( gcry_sexp_build (&s_hash, NULL, "%m", frame) ) - BUG (); - - - /* sign */ - rc = gcry_pk_sign (&s_sig, s_hash, s_skey); - if (rc) - { - log_error ("signing failed: %s\n", gcry_strerror (rc)); - return map_gcry_err (rc); - } - - len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xmalloc (len); - len = gcry_sexp_sprint (s_sig, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - - *r_sigval = buf; -#else int rc; char *grip; size_t siglen; @@ -330,10 +257,8 @@ gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, xfree (grip); /* FIXME: we should check that the returnes S-Exp is valid fits int siglen. It ould probaly be a good idea to scan and print it - again to make this sure and be sure that we have canocical + again to make this sure and be sure that we have canoncical encoding */ - -#endif return rc; } diff --git a/sm/certdump.c b/sm/certdump.c index 10af4beae..733fcea4f 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -34,20 +34,29 @@ #include "keydb.h" static void -print_integer (unsigned char *p) +print_sexp (KsbaConstSexp p) { - unsigned long len; + unsigned long n; + KsbaConstSexp endp; if (!p) log_printf ("none"); else { - len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - for (p+=4; len; len--, p++) - log_printf ("%02X", *p); + n = strtoul (p, (char**)&endp, 10); + p = endp; + if (*p!=':') + log_printf ("ERROR - invalid value"); + else + { + for (p++; n; n--, p++) + log_printf ("%02X", *p); + } } } + + static void print_time (time_t t) { @@ -81,6 +90,7 @@ print_dn (char *p) void gpgsm_dump_cert (const char *text, KsbaCert cert) { + KsbaSexp sexp; unsigned char *p; char *dn; time_t t; @@ -88,10 +98,10 @@ gpgsm_dump_cert (const char *text, KsbaCert cert) log_debug ("BEGIN Certificate `%s':\n", text? text:""); if (cert) { - p = ksba_cert_get_serial (cert); + sexp = ksba_cert_get_serial (cert); log_debug (" serial: "); - print_integer (p); - ksba_free (p); + print_sexp (sexp); + ksba_free (sexp); log_printf ("\n"); t = ksba_cert_get_validity (cert, 0); diff --git a/sm/decrypt.c b/sm/decrypt.c index 4038f8d27..7237fef7c 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -51,7 +51,7 @@ struct decrypt_filter_parm_s { static void -print_integer (unsigned char *p) +print_integer_sexp (unsigned char *p) { unsigned long len; @@ -59,23 +59,30 @@ print_integer (unsigned char *p) log_printf ("none"); else { - len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - for (p+=4; len; len--, p++) - log_printf ("%02X", *p); + len = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!len) + log_printf ("invalid encoding"); + else + { + for (; len && *p != ':'; len--, p++) + ; + for (p++; len; len--, p++) + log_printf ("%02X", *p); + } } } /* decrypt the session key and fill in the parm structure. The algo and the IV is expected to be already in PARM. */ static int -prepare_decryption (const char *hexkeygrip, const char *enc_val, +prepare_decryption (const char *hexkeygrip, KsbaConstSexp enc_val, struct decrypt_filter_parm_s *parm) { char *seskey = NULL; size_t n, seskeylen; int rc; - rc = gpgsm_agent_pkdecrypt (hexkeygrip, enc_val, strlen (enc_val), + rc = gpgsm_agent_pkdecrypt (hexkeygrip, enc_val, &seskey, &seskeylen); if (rc) { @@ -348,8 +355,8 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp) for (recp=0; recp < 1; recp++) { char *issuer; - unsigned char *serial; - char *enc_val; + KsbaSexp serial; + KsbaSexp enc_val; char *hexkeygrip = NULL; err = ksba_cms_get_issuer_serial (cms, recp, &issuer, &serial); @@ -363,7 +370,7 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp) log_debug ("recp %d - issuer: `%s'\n", recp, issuer? issuer:"[NONE]"); log_debug ("recp %d - serial: ", recp); - print_integer (serial); + print_integer_sexp (serial); log_printf ("\n"); keydb_search_reset (kh); @@ -395,8 +402,6 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp) recp); else { - log_debug ("recp %d - enc-val: `%s'\n", - recp, enc_val); rc = prepare_decryption (hexkeygrip, enc_val, &dfparm); xfree (enc_val); diff --git a/sm/encrypt.c b/sm/encrypt.c index b8981508a..be2a346ae 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -247,7 +247,7 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval) { GCRY_SEXP s_ciph, s_data, s_pkey; int rc; - char *buf; + KsbaSexp buf; size_t len; *encval = NULL; @@ -259,7 +259,13 @@ encrypt_dek (const DEK dek, KsbaCert cert, char **encval) log_error ("no public key for recipient\n"); return GNUPG_No_Public_Key; } - rc = gcry_sexp_sscan (&s_pkey, NULL, buf, strlen(buf)); + len = gcry_sexp_canon_len (buf, 0, NULL, NULL); + if (!len) + { + log_error ("libksba did not return a proper S-Exp\n"); + return GNUPG_Bug; + } + rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len); xfree (buf); buf = NULL; if (rc) { diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 005f10f1f..22ed0149d 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -125,7 +125,7 @@ gpgsm_get_fingerprint_hexstring (KsbaCert cert, int algo) } -/* Return the sop called KEYGRIP which is the SHA-1 hash of the public +/* Return the so called KEYGRIP which is the SHA-1 hash of the public key parameters expressed as an canoncial encoded S-Exp. array must be 20 bytes long. returns the array or a newly allocated one if the passed one was NULL */ @@ -133,8 +133,9 @@ char * gpgsm_get_keygrip (KsbaCert cert, char *array) { GCRY_SEXP s_pkey; - int rc, len; - char *buf, *p; + int rc; + KsbaSexp p; + size_t n; p = ksba_cert_get_public_key (cert); if (!p) @@ -142,25 +143,27 @@ gpgsm_get_keygrip (KsbaCert cert, char *array) if (DBG_X509) log_debug ("get_keygrip for public key: %s\n", p); - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, strlen(p)); + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + return NULL; + } + rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + xfree (p); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc)); return NULL; } - /* and now convert it into canoncial form - fixme: we should modify - libksba to return it in this form */ - len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, NULL, 0); - assert (len); - buf = xmalloc (len); - len = gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, buf, len); - assert (len); - + array = gcry_pk_get_keygrip (s_pkey, array); + gcry_sexp_release (s_pkey); if (!array) - array = xmalloc (20); - - gcry_md_hash_buffer (GCRY_MD_SHA1, array, buf, len); - xfree (buf); + { + rc = seterr (General_Error); + log_error ("can't calculate keygrip\n"); + return NULL; + } if (DBG_X509) log_printhex ("keygrip=", array, 20); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index c43938c5d..44f6b3fb8 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -141,7 +141,7 @@ void gpgsm_dump_cert (const char *text, KsbaCert cert); /*-- certcheck.c --*/ int gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert); -int gpgsm_check_cms_signature (KsbaCert cert, const char *sigval, +int gpgsm_check_cms_signature (KsbaCert cert, KsbaConstSexp sigval, GCRY_MD_HD md, int hash_algo); /* fixme: move create functions to another file */ int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, @@ -180,7 +180,7 @@ int gpgsm_agent_pksign (const char *keygrip, int digestalgo, char **r_buf, size_t *r_buflen); int gpgsm_agent_pkdecrypt (const char *keygrip, - const char *ciphertext, size_t ciphertextlen, + KsbaConstSexp ciphertext, char **r_buf, size_t *r_buflen); diff --git a/sm/keydb.c b/sm/keydb.c index d8d0ad7e3..b80f42642 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -834,14 +834,19 @@ keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer) int keydb_search_issuer_sn (KEYDB_HANDLE hd, - const char *issuer, const unsigned char *serial) + const char *issuer, KsbaConstSexp serial) { KEYDB_SEARCH_DESC desc; int rc; + const unsigned char *s; memset (&desc, 0, sizeof desc); desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN; - desc.sn = serial; + for (s=serial,desc.snlen = 0; digitp (s); s++) + desc.snlen = 10*desc.snlen + atoi_1 (s); + if (*s !=':') + return GNUPG_Invalid_Value; + desc.sn = s+1; desc.u.name = issuer; rc = keydb_search (hd, &desc, 1); return rc; @@ -975,7 +980,7 @@ classify_user_id (const char *name, return 0; /* invalid digit in serial number*/ } desc->sn = s; - desc->sn_is_string = 1; + desc->snlen = -1; if (!*si) mode = KEYDB_SEARCH_MODE_SN; else diff --git a/sm/keylist.c b/sm/keylist.c index bae95a6e0..07844fed1 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -116,7 +116,8 @@ static void list_cert_colon (KsbaCert cert, FILE *fp) { int idx, trustletter = 0; - unsigned char *p; + char *p; + KsbaSexp sexp; fputs ("crt:", fp); trustletter = 0; @@ -144,12 +145,17 @@ list_cert_colon (KsbaCert cert, FILE *fp) print_time ( ksba_cert_get_validity (cert, 1), fp); putc (':', fp); putc (':', fp); - if ((p = ksba_cert_get_serial (cert))) + if ((sexp = ksba_cert_get_serial (cert))) { - int i, len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - for (i=0; i < len; i++) - fprintf (fp,"%02X", p[4+i]); - xfree (p); + int len; + const unsigned char *s = sexp; + + for (len=0; *s && *s != ':' && digitp (s); s++) + len = len*10 + atoi_1 (s); + if (*s == ':') + for (s++; len; len--, s++) + fprintf (fp,"%02X", *s); + xfree (sexp); } putc (':', fp); putc (':', fp); diff --git a/sm/verify.c b/sm/verify.c index 8a999da14..cb57682f1 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -85,7 +85,7 @@ store_cert (KsbaCert cert) static void -print_integer (unsigned char *p) +print_integer_sexp (unsigned char *p) { unsigned long len; @@ -93,9 +93,16 @@ print_integer (unsigned char *p) log_printf ("none"); else { - len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - for (p+=4; len; len--, p++) - log_printf ("%02X", *p); + len = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!len) + log_printf ("invalid encoding"); + else + { + for (; len && *p != ':'; len--, p++) + ; + for (p++; len; len--, p++) + log_printf ("%02X", *p); + } } } @@ -289,9 +296,9 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd) for (signer=0; signer < 1; signer++) { char *issuer = NULL; - char *sigval = NULL; + KsbaSexp sigval = NULL; time_t sigtime; - unsigned char *serial; + KsbaSexp serial; char *msgdigest = NULL; size_t msgdigestlen; @@ -300,7 +307,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd) break; log_debug ("signer %d - issuer: `%s'\n", signer, issuer? issuer:"[NONE]"); log_debug ("signer %d - serial: ", signer); - print_integer (serial); + print_integer_sexp (serial); log_printf ("\n"); err = ksba_cms_get_signing_time (cms, signer, &sigtime);