From cvs at cvs.gnupg.org Mon Jan 5 20:46:28 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 05 Jan 2009 20:46:28 +0100 Subject: [svn] GnuPG - r4908 - trunk/po Message-ID: Author: wk Date: 2009-01-05 20:46:24 +0100 (Mon, 05 Jan 2009) New Revision: 4908 Modified: trunk/po/ChangeLog trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po Log: Updated tr anz zh_TW. Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2008-12-21 16:57:33 UTC (rev 4907) +++ trunk/po/ChangeLog 2009-01-05 19:46:24 UTC (rev 4908) @@ -1,3 +1,11 @@ +2009-01-05 Nilg?n Belma Bug?ner (wk) + + * tr.po: Update. + +2009-01-05 Jedi (wk) + + * zh_TW.po: Update. + 2008-12-08 Werner Koch * de.po: Typo fixes. Reported by Daniel Leidert. @@ -227,7 +235,7 @@ * de.po: New. - Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004, 2005, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Mon Jan 5 20:56:52 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 05 Jan 2009 20:56:52 +0100 Subject: [svn] GnuPG - r4909 - trunk/scd Message-ID: Author: wk Date: 2009-01-05 20:56:52 +0100 (Mon, 05 Jan 2009) New Revision: 4909 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c Log: Fix card change detection. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-01-05 19:46:24 UTC (rev 4908) +++ trunk/scd/ChangeLog 2009-01-05 19:56:52 UTC (rev 4909) @@ -1,3 +1,7 @@ +2009-01-05 Werner Koch + + * apdu.c (apdu_get_status): Save the last status. + 2008-12-18 Werner Koch * ccid-driver.c (abort_cmd): New. Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-01-05 19:46:24 UTC (rev 4908) +++ trunk/scd/apdu.c 2009-01-05 19:56:52 UTC (rev 4909) @@ -2735,11 +2735,12 @@ || !reader_table[slot].any_status ) { reader_table[slot].change_counter++; - /* Make sure that the ATR is invalid so that a reset will be by - activate. */ + /* Make sure that the ATR is invalid so that a reset will be + triggered by activate. */ reader_table[slot].atrlen = 0; } reader_table[slot].any_status = 1; + reader_table[slot].last_status = s; if (status) *status = s; From cvs at cvs.gnupg.org Thu Jan 8 16:48:52 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 08 Jan 2009 16:48:52 +0100 Subject: [svn] GnuPG - r4910 - in trunk: . g10 jnlib po scripts Message-ID: Author: wk Date: 2009-01-08 16:48:51 +0100 (Thu, 08 Jan 2009) New Revision: 4910 Modified: trunk/NEWS trunk/g10/ChangeLog trunk/g10/cpr.c trunk/g10/keygen.c trunk/g10/misc.c trunk/jnlib/argparse.c trunk/po/ChangeLog trunk/po/es.po trunk/scripts/mail-to-translators Log: Update spanish translation. Cleanups. Allow utf-8 in email addresses. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/g10/ChangeLog 2009-01-08 15:48:51 UTC (rev 4910) @@ -1,3 +1,9 @@ +2009-01-08 Werner Koch + + * misc.c (has_invalid_email_chars): Let non-ascii pass through. + + * cpr.c [USE_SHM_COPROCESSING]: Remove this code. + 2008-12-12 Werner Koch * passphrase.c (passphrase_get): Write a STATUS_ERROR. Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/po/ChangeLog 2009-01-08 15:48:51 UTC (rev 4910) @@ -1,3 +1,7 @@ +2009-01-07 Jaime Su?rez (wk) + + * es.po: Update. + 2009-01-05 Nilg?n Belma Bug?ner (wk) * tr.po: Update. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/NEWS 2009-01-08 15:48:51 UTC (rev 4910) @@ -649,7 +649,7 @@ Copyright 2002, 2003, 2004, 2005, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/g10/cpr.c =================================================================== --- trunk/g10/cpr.c 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/g10/cpr.c 2009-01-08 15:48:51 UTC (rev 4910) @@ -357,10 +357,6 @@ { if( opt.command_fd != -1 ) return 1; -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return 1; -#endif return 0; } @@ -371,10 +367,6 @@ if( opt.command_fd != -1 ) return do_get_from_fd ( keyword, 0, 0 ); -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return do_shm_get( keyword, 0, 0 ); -#endif for(;;) { p = tty_get( prompt ); return p; @@ -388,10 +380,6 @@ if( opt.command_fd != -1 ) return do_get_from_fd ( keyword, 0, 0 ); -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return do_shm_get( keyword, 0, 0 ); -#endif for(;;) { p = tty_get( prompt ); if( *p=='?' && !p[1] && !(keyword && !*keyword)) { @@ -424,10 +412,6 @@ if( opt.command_fd != -1 ) return do_get_from_fd ( keyword, 1, 0 ); -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return do_shm_get( keyword, 1, 0 ); -#endif for(;;) { p = tty_get_hidden( prompt ); if( *p == '?' && !p[1] ) { @@ -444,10 +428,6 @@ { if( opt.command_fd != -1 ) return; -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return; -#endif tty_kill_prompt(); return; } @@ -460,10 +440,6 @@ if( opt.command_fd != -1 ) return !!do_get_from_fd ( keyword, 0, 1 ); -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return !!do_shm_get( keyword, 0, 1 ); -#endif for(;;) { p = tty_get( prompt ); trim_spaces(p); /* it is okay to do this here */ @@ -488,10 +464,6 @@ if( opt.command_fd != -1 ) return !!do_get_from_fd ( keyword, 0, 1 ); -#ifdef USE_SHM_COPROCESSING - if( opt.shm_coprocess ) - return !!do_shm_get( keyword, 0, 1 ); -#endif for(;;) { p = tty_get( prompt ); trim_spaces(p); /* it is okay to do this here */ @@ -520,10 +492,6 @@ if( opt.command_fd != -1 ) answer = do_get_from_fd ( keyword, 0, 0 ); -#ifdef USE_SHM_COPROCESSING - else if( opt.shm_coprocess ) - answer = do_shm_get( keyword, 0, 0 ); -#endif if (answer) { Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/g10/keygen.c 2009-01-08 15:48:51 UTC (rev 4910) @@ -1958,6 +1958,11 @@ if ( !mode ) { + /* TRANSLATORS: This is the new string telling the user what + gpg is now going to do (i.e. ask for the parts of the user + ID). Note that if you do not tyranslated this string, a + different string will be used used, which might still have + a correct transaltion. */ const char *s1 = N_("\n" "GnuPG needs to construct a user ID to identify your key.\n" @@ -1970,6 +1975,10 @@ the old info text. gettext has no way to tell whether a translation is actually available, thus we need to to compare again. */ + /* TRANSLATORS: This string is in general not anymore used + but you should keep your existing translation. In case + the new string is not translated this old string will + be used. */ const char *s3 = N_("\n" "You need a user ID to identify your key; " "the software constructs the user ID\n" Modified: trunk/g10/misc.c =================================================================== --- trunk/g10/misc.c 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/g10/misc.c 2009-01-08 15:48:51 UTC (rev 4910) @@ -1248,6 +1248,17 @@ } +/* Check whether the string has characters not valid in an RFC822 + address. To cope with OpenPGP we ignore allow non-ascii characters + so that for example umlauts are legal in an email address. An + OpenPGP user ID must be utf-8 encoded and tehre is no strict + requirement for RFC-822. Thus to avoid IDNA encoding we put the + address verbatim as utf-8 into the user ID under the assumtiopn + that mail programs etc handle IDNA at a lower level and take + OpenPGP user IDS as utf-8. Note that we can't do an utf-8 encoding + checking here becuase in keygen.c this function is called with the + native encoding and native to utf-8 encoding is done only after + checking. */ int has_invalid_email_chars (const char *s) { @@ -1257,8 +1268,8 @@ for ( ; *s; s++ ) { - if ( *s & 0x80 ) - return 1; + if ( (*s & 0x80) ) + continue; /* We only care about ASCII. */ if ( *s == '@' ) at_seen=1; else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) ) Modified: trunk/jnlib/argparse.c =================================================================== --- trunk/jnlib/argparse.c 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/jnlib/argparse.c 2009-01-08 15:48:51 UTC (rev 4910) @@ -1107,7 +1107,7 @@ break; case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2008 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2009 Free Software Foundation, Inc."; break; case 15: p = "This is free software: you are free to change and redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n"; Modified: trunk/po/es.po [not shown] Modified: trunk/scripts/mail-to-translators =================================================================== --- trunk/scripts/mail-to-translators 2009-01-05 19:56:52 UTC (rev 4909) +++ trunk/scripts/mail-to-translators 2009-01-08 15:48:51 UTC (rev 4910) @@ -5,6 +5,9 @@ # remove the colon to armor this script. SENDMAIL=": /usr/sbin/sendmail" +LC_ALL=C +LC_CTYPE=C + for file in *.po; do addr=$(head -100 $file | awk '/^# ?Designated-Translator:/ { printf "%s", $0; exit 0}' | sed 's/.*\(<.*>\).*/\1/') if [ -z "$addr" ]; then From cvs at cvs.gnupg.org Thu Jan 8 20:52:00 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 08 Jan 2009 20:52:00 +0100 Subject: [svn] GnuPG - r4911 - trunk/sm Message-ID: Author: wk Date: 2009-01-08 20:51:59 +0100 (Thu, 08 Jan 2009) New Revision: 4911 Modified: trunk/sm/ChangeLog trunk/sm/fingerprint.c Log: Fix error detection Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-01-08 15:48:51 UTC (rev 4910) +++ trunk/sm/ChangeLog 2009-01-08 19:51:59 UTC (rev 4911) @@ -1,3 +1,7 @@ +2009-01-08 Werner Koch + + * fingerprint.c (gpgsm_get_keygrip_hexstring): Add error detection. + 2008-12-10 Werner Koch * gpgsm.c (our_cipher_test_algo): Use the GCRY constants as we now Modified: trunk/sm/fingerprint.c =================================================================== --- trunk/sm/fingerprint.c 2009-01-08 15:48:51 UTC (rev 4910) +++ trunk/sm/fingerprint.c 2009-01-08 19:51:59 UTC (rev 4911) @@ -152,9 +152,9 @@ /* 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 */ + key parameters expressed as an canoncial encoded S-Exp. ARRAY must + be 20 bytes long. Returns ARRAY or a newly allocated buffer if ARRAY was + given as NULL. May return NULL on error. */ unsigned char * gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array) { @@ -204,9 +204,11 @@ unsigned char grip[20]; char *buf; - gpgsm_get_keygrip (cert, grip); - buf = xmalloc (20*2+1); - bin2hex (grip, 20, buf); + if (!gpgsm_get_keygrip (cert, grip)) + return NULL; + buf = xtrymalloc (20*2+1); + if (buf) + bin2hex (grip, 20, buf); return buf; } From cvs at cvs.gnupg.org Thu Jan 8 20:52:54 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 08 Jan 2009 20:52:54 +0100 Subject: [svn] ksba - r298 - trunk/src Message-ID: Author: wk Date: 2009-01-08 20:52:54 +0100 (Thu, 08 Jan 2009) New Revision: 298 Modified: trunk/src/ChangeLog trunk/src/keyinfo.c Log: Fix segv for certain DSA certificates. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-11-12 18:25:52 UTC (rev 297) +++ trunk/src/ChangeLog 2009-01-08 19:52:54 UTC (rev 298) @@ -1,3 +1,13 @@ +2009-01-08 Werner Koch + + * keyinfo.c (get_algorithm): Initialize R_PARM_POS, R_PARM_LEN and + R_PARM_TYPE. + +2009-01-06 Werner Koch + + * keyinfo.c (sig_algo_table): Fix TeleTrust dsaWithRIPEMD160 + encoding. Add TeleTrust sigS_ISO9796-2rndWithrsa_ripemd160. + 2008-10-30 Werner Koch * ber-dump.c (one_file): Mark unused arg. Modified: trunk/src/keyinfo.c =================================================================== --- trunk/src/keyinfo.c 2008-11-12 18:25:52 UTC (rev 297) +++ trunk/src/keyinfo.c 2009-01-08 19:52:54 UTC (rev 298) @@ -115,7 +115,7 @@ 1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "sha1" }, { /* Teletrust signature algorithm. */ "1.3.36.8.5.1.2.2", /* dsaWithRIPEMD160 */ - "\x06\x07\x2B\x24\x08\x05\x01\x02\x02", 9, + "\x2b\x24\x08\x05\x01\x02\x02", 7, 1, PKALGO_DSA, "dsa", "-rs", "\x30\x02\x02", NULL, NULL, "rmd160" }, { /* NIST Algorithm */ "2.16.840.1.101.3.4.3.1", /* dsaWithSha224 */ @@ -192,6 +192,13 @@ "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0d", 9, 1, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "sha512" }, + { /* TeleTrust signature scheme with RSA signature and DSI according + to ISO/IEC 9796-2 with random number and RIPEMD-160. I am not + sure for what this is good; thus disabled. */ + "1.3.36.3.4.3.2.2", /* sigS_ISO9796-2rndWithrsa_ripemd160 */ + "\x2B\x24\x03\x04\x03\x02\x02", 7, + 0, PKALGO_RSA, "rsa", "s", "\x82", NULL, NULL, "rmd160" }, + {NULL} }; @@ -336,6 +343,12 @@ unsigned long seqlen, len; *r_bitstr = 0; + if (r_parm_pos) + *r_parm_pos = 0; + if (r_parm_len) + *r_parm_len = 0; + if (r_parm_type) + *r_parm_type = 0; /* get the inner sequence */ if (!derlen) return gpg_error (GPG_ERR_INV_KEYINFO); From cvs at cvs.gnupg.org Thu Jan 8 20:56:30 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 08 Jan 2009 20:56:30 +0100 Subject: [svn] GnuPG - r4912 - in trunk: g10 scd Message-ID: Author: wk Date: 2009-01-08 20:56:30 +0100 (Thu, 08 Jan 2009) New Revision: 4912 Modified: trunk/g10/misc.c trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/app-nks.c trunk/scd/command.c trunk/scd/iso7816.c trunk/scd/iso7816.h Log: Add limited support for NetKey 3.0 cards. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/scd/ChangeLog 2009-01-08 19:56:30 UTC (rev 4912) @@ -1,3 +1,18 @@ +2009-01-08 Werner Koch + + * iso7816.c (iso7816_read_record, iso7816_read_binary): Pass 0 for + L_e because the problem with the CCID driver has gone. + (iso7816_apdu_direct): New. + + * app-nks.c (filelist): Add NKS_VER field. Add NKS 3 specific + entries. + (app_local_s, do_deinit): New. + (get_nks_version): New. + (app_select_nks): Setup local data. + (keygripstr_from_pk_file): Replace SLOT by APP and take care of + NKS version > 2. + (do_learn_status): Take care of NKS version. + 2009-01-05 Werner Koch * apdu.c (apdu_get_status): Save the last status. Modified: trunk/g10/misc.c =================================================================== --- trunk/g10/misc.c 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/g10/misc.c 2009-01-08 19:56:30 UTC (rev 4912) @@ -1248,17 +1248,16 @@ } -/* Check whether the string has characters not valid in an RFC822 +/* Check whether the string has characters not valid in an RFC-822 address. To cope with OpenPGP we ignore allow non-ascii characters so that for example umlauts are legal in an email address. An - OpenPGP user ID must be utf-8 encoded and tehre is no strict + OpenPGP user ID must be utf-8 encoded but there is no strict requirement for RFC-822. Thus to avoid IDNA encoding we put the - address verbatim as utf-8 into the user ID under the assumtiopn - that mail programs etc handle IDNA at a lower level and take - OpenPGP user IDS as utf-8. Note that we can't do an utf-8 encoding - checking here becuase in keygen.c this function is called with the - native encoding and native to utf-8 encoding is done only after - checking. */ + address verbatim as utf-8 into the user ID under the assumption + that mail programs handle IDNA at a lower level and take OpenPGP + user IDs as utf-8. Note that we can't do an utf-8 encoding + checking here because in keygen.c this function is called with the + native encoding and native to utf-8 encoding is only done later. */ int has_invalid_email_chars (const char *s) { Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/scd/apdu.c 2009-01-08 19:56:30 UTC (rev 4912) @@ -2793,9 +2793,9 @@ related operations if not NULL. If EXTENDED_MODE is not NULL command chaining or extended length will be used according to these values: - n < 0 := Use command chaining without the data part limited to -n + n < 0 := Use command chaining with the data part limited to -n in each chunk. If -1 is used a default value is used. - n == 1 := Use extended length for input and output with out a + n == 1 := Use extended length for input and output without a length limit. n > 1 := Use extended length with up to N bytes. */ @@ -3107,7 +3107,7 @@ /* This is a more generic version of the apdu sending routine. It takes an already formatted APDU in APDUDATA or length APDUDATALEN - and returns the with an APDU including the status word. With + and returns with an APDU including the status word. With HANDLE_MORE set to true this function will handle the MORE DATA status and return all APDUs concatenated with one status word at the end. The function does not return a regular status word but 0 @@ -3237,7 +3237,7 @@ } } else - log_info ("apdu_send_sdirect(%d) " + log_info ("apdu_send_direct(%d) " "got unexpected status %04X from get response\n", slot, sw); } @@ -3268,8 +3268,8 @@ unlock_slot (slot); - /* Append the status word - we reseved the two extra bytes while - allocating the buffer. */ + /* Append the status word. Note that we reserved the two extra + bytes while allocating the buffer. */ if (retbuf) { (*retbuf)[(*retbuflen)++] = (sw >> 8); Modified: trunk/scd/app-nks.c =================================================================== --- trunk/scd/app-nks.c 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/scd/app-nks.c 2009-01-08 19:56:30 UTC (rev 4912) @@ -1,5 +1,5 @@ -/* app-nks.c - The Telesec NKS 2.0 card application. - * Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. +/* app-nks.c - The Telesec NKS card application. + * Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -34,29 +34,55 @@ static struct { int fid; /* File ID. */ + int nks_ver; /* 0 for NKS version 2, 3 for version 3. */ int certtype; /* Type of certificate or 0 if it is not a certificate. */ int iskeypair; /* If true has the FID of the correspoding certificate. */ int issignkey; /* True if file is a key usable for signing. */ int isenckey; /* True if file is a key usable for decryption. */ } filelist[] = { - { 0x4531, 0, 0xC000, 1, 0 }, - { 0xC000, 101 }, - { 0x4331, 100 }, - { 0x4332, 100 }, - { 0xB000, 110 }, - { 0x45B1, 0, 0xC200, 0, 1 }, - { 0xC200, 101 }, - { 0x43B1, 100 }, - { 0x43B2, 100 }, - { 0, 0 } + { 0x4531, 0, 0, 0xC000, 1, 0 }, /* EF_PK.NKS.SIG */ + { 0xC000, 0, 101 }, /* EF_C.NKS.SIG */ + { 0x4331, 0, 100 }, + { 0x4332, 0, 100 }, + { 0xB000, 0, 110 }, /* EF_PK.RCA.NKS */ + { 0x45B1, 0, 0, 0xC200, 0, 1 }, /* EF_PK.NKS.ENC */ + { 0xC200, 0, 101 }, /* EF_C.NKS.ENC */ + { 0x43B1, 0, 100 }, + { 0x43B2, 0, 100 }, + { 0x4571, 3, 0, 0xc500, 0, 0 }, /* EF_PK.NKS.AUT */ + { 0xC500, 3, 101 }, /* EF_C.NKS.AUT */ + { 0x45B2, 3, 0, 0xC201, 0, 1 }, /* EF_PK.NKS.ENC1024 */ + { 0xC201, 3, 101 }, /* EF_C.NKS.ENC1024 */ + { 0 } }; +/* Object with application (i.e. NKS) specific data. */ +struct app_local_s { + int nks_version; /* NKS version. */ + +}; + + + + +/* Release local data. */ +static void +do_deinit (app_t app) +{ + if (app && app->app_local) + { + xfree (app->app_local); + app->app_local = NULL; + } +} + + /* Read the file with FID, assume it contains a public key and return its keygrip in the caller provided 41 byte buffer R_GRIPSTR. */ static gpg_error_t -keygripstr_from_pk_file (int slot, int fid, char *r_gripstr) +keygripstr_from_pk_file (app_t app, int fid, char *r_gripstr) { gpg_error_t err; unsigned char grip[20]; @@ -65,29 +91,34 @@ gcry_sexp_t sexp; int i; - err = iso7816_select_file (slot, fid, 0, NULL, NULL); + err = iso7816_select_file (app->slot, fid, 0, NULL, NULL); if (err) return err; - err = iso7816_read_record (slot, 1, 1, 0, &buffer[0], &buflen[0]); + err = iso7816_read_record (app->slot, 1, 1, 0, &buffer[0], &buflen[0]); if (err) return err; - err = iso7816_read_record (slot, 2, 1, 0, &buffer[1], &buflen[1]); + err = iso7816_read_record (app->slot, 2, 1, 0, &buffer[1], &buflen[1]); if (err) { xfree (buffer[0]); return err; } - for (i=0; i < 2; i++) + if (app->app_local->nks_version < 3) { - /* Check that the value appears like an integer encoded as - Simple-TLV. We don't check the tag because the tests cards I - have use 1 for both, the modulus and the exponent - the - example in the documentation gives 2 for the exponent. */ - if (buflen[i] < 3) - err = gpg_error (GPG_ERR_TOO_SHORT); - else if (buffer[i][1] != buflen[i]-2 ) - err = gpg_error (GPG_ERR_INV_OBJ); + /* Old versions of NKS store the values in a TLV encoded format. + We need to do some checks. */ + for (i=0; i < 2; i++) + { + /* Check that the value appears like an integer encoded as + Simple-TLV. We don't check the tag because the tests cards I + have use 1 for both, the modulus and the exponent - the + example in the documentation gives 2 for the exponent. */ + if (buflen[i] < 3) + err = gpg_error (GPG_ERR_TOO_SHORT); + else if (buffer[i][1] != buflen[i]-2 ) + err = gpg_error (GPG_ERR_INV_OBJ); + } } if (!err) @@ -126,6 +157,9 @@ /* Output information about all useful objects. */ for (i=0; filelist[i].fid; i++) { + if (filelist[i].nks_ver > app->app_local->nks_version) + continue; + if (filelist[i].certtype) { size_t len; @@ -149,7 +183,7 @@ { char gripstr[40+1]; - err = keygripstr_from_pk_file (app->slot, filelist[i].fid, gripstr); + err = keygripstr_from_pk_file (app, filelist[i].fid, gripstr); if (err) log_error ("can't get keygrip from FID 0x%04X: %s\n", filelist[i].fid, gpg_strerror (err)); @@ -580,7 +614,40 @@ } -/* Select the NKS 2.0 application. */ +/* Return the version of the NKS application. */ +static int +get_nks_version (int slot) +{ + unsigned char *result = NULL; + size_t resultlen; + int type; + + if (iso7816_apdu_direct (slot, "\x80\xaa\x06\x00\x00", 5, 0, + &result, &resultlen)) + return 2; /* NKS 2 does not support this command. */ + + /* Example value: 04 11 19 22 21 6A 20 80 03 03 01 01 01 00 00 00 + vv tt ccccccccccccccccc aa bb cc vvvvvvvvvvv xx + vendor (Philips) -+ | | | | | | | + chip type -----------+ | | | | | | + chip id ----------------+ | | | | | + card type (3 - tcos 3) -------------------+ | | | | + OS version of card type ---------------------+ | | | + OS release of card type ------------------------+ | | + OS vendor internal version ------------------------+ | + RFU -----------------------------------------------------------+ + */ + if (resultlen < 16) + type = 0; /* Invalid data returned. */ + else + type = result[8]; + xfree (result); + + return type; +} + + +/* Select the NKS application. */ gpg_error_t app_select_nks (app_t app) { @@ -593,6 +660,18 @@ { app->apptype = "NKS"; + app->app_local = xtrycalloc (1, sizeof *app->app_local); + if (!app->app_local) + { + rc = gpg_error (gpg_err_code_from_errno (errno)); + goto leave; + } + + app->app_local->nks_version = get_nks_version (slot); + if (opt.verbose) + log_info ("Detected NKS version: %d\n", app->app_local->nks_version); + + app->fnc.deinit = do_deinit; app->fnc.learn_status = do_learn_status; app->fnc.readcert = do_readcert; app->fnc.getattr = NULL; @@ -605,6 +684,9 @@ app->fnc.check_pin = do_check_pin; } + leave: + if (rc) + do_deinit (app); return rc; } Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/scd/command.c 2009-01-08 19:56:30 UTC (rev 4912) @@ -559,7 +559,7 @@ 100 := Regular X.509 cert 101 := Trusted X.509 cert 102 := Useful X.509 cert - 110 := Root CA cert (DINSIG) + 110 := Root CA cert (e.g. DINSIG) For certain cards, more information will be returned: Modified: trunk/scd/iso7816.c =================================================================== --- trunk/scd/iso7816.c 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/scd/iso7816.c 2009-01-08 19:56:30 UTC (rev 4912) @@ -1,5 +1,5 @@ /* iso7816.c - ISO 7816 commands - * Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -226,6 +226,48 @@ } +/* This funcion sends an already formatted APDU to the card. With + HANDLE_MORE set to true a MORE DATA status will be handled + internally. The return value is a gpg error code (i.e. a mapped + status word). This is basically the same as apdu_send_direct but + it maps the status word and does not return it in the result + buffer. */ +gpg_error_t +iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen, + int handle_more, + unsigned char **result, size_t *resultlen) +{ + int sw; + + if (!result || !resultlen) + return gpg_error (GPG_ERR_INV_VALUE); + *result = NULL; + *resultlen = 0; + + sw = apdu_send_direct (slot, apdudata, apdudatalen, handle_more, + result, resultlen); + if (!sw) + { + if (*resultlen < 2) + sw = SW_HOST_GENERAL_ERROR; + else + { + sw = ((*result)[*resultlen-2] << 8) | (*result)[*resultlen-1]; + (*resultlen)--; + (*resultlen)--; + } + } + if (sw != SW_SUCCESS) + { + /* Make sure that pending buffers are released. */ + xfree (*result); + *result = NULL; + *resultlen = 0; + } + return map_sw (sw); +} + + /* Check whether the reader supports the ISO command code COMMAND on the keypad. Returns 0 on success. */ gpg_error_t @@ -668,14 +710,7 @@ { buffer = NULL; bufferlen = 0; - /* Note, that we to set N to 254 due to problems either with the - ccid driver or some TCOS cards. It actually should be 0 - which is the official ISO value to read a variable length - object. */ - if (read_all || nmax > 254) - n = 254; - else - n = nmax; + n = read_all? 0 : nmax; sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY, ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL, n, &buffer, &bufferlen); @@ -769,13 +804,11 @@ buffer = NULL; bufferlen = 0; - /* Fixme: Either the ccid driver or the TCOS cards have problems - with an Le of 0. */ sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD, recno, short_ef? short_ef : 0x04, -1, NULL, - 254, &buffer, &bufferlen); + 0, &buffer, &bufferlen); if (sw != SW_SUCCESS && sw != SW_EOF_REACHED) { Modified: trunk/scd/iso7816.h =================================================================== --- trunk/scd/iso7816.h 2009-01-08 19:51:59 UTC (rev 4911) +++ trunk/scd/iso7816.h 2009-01-08 19:56:30 UTC (rev 4912) @@ -57,6 +57,10 @@ unsigned char **result, size_t *resultlen); gpg_error_t iso7816_list_directory (int slot, int list_dirs, unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_apdu_direct (int slot, + const void *apdudata, size_t apdudatalen, + int handle_more, + unsigned char **result, size_t *resultlen); gpg_error_t iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo); gpg_error_t iso7816_verify (int slot, From cvs at cvs.gnupg.org Fri Jan 9 13:17:26 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 09 Jan 2009 13:17:26 +0100 Subject: [svn] ksba - r299 - trunk Message-ID: Author: wk Date: 2009-01-09 13:17:26 +0100 (Fri, 09 Jan 2009) New Revision: 299 Modified: trunk/ChangeLog trunk/NEWS trunk/README trunk/configure.ac Log: Preparing a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-08 19:52:54 UTC (rev 298) +++ trunk/ChangeLog 2009-01-09 12:17:26 UTC (rev 299) @@ -1,3 +1,9 @@ +2009-01-09 Werner Koch + + Release 1.0.5. + + * configure.ac: Bump LT version to C17/A9/R5. + 2008-10-30 Werner Koch * configure.ac: Use more strict warnings with newer gcc versions. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-08 19:52:54 UTC (rev 298) +++ trunk/NEWS 2009-01-09 12:17:26 UTC (rev 299) @@ -1,7 +1,9 @@ -Noteworthy changes in version 1.0.5 +Noteworthy changes in version 1.0.5 (2009-01-09) ------------------------------------------------ + * Minor big fixes. + Noteworthy changes in version 1.0.4 (2008-09-22) ------------------------------------------------ Modified: trunk/README =================================================================== --- trunk/README 2009-01-08 19:52:54 UTC (rev 298) +++ trunk/README 2009-01-09 12:17:26 UTC (rev 299) @@ -1,7 +1,7 @@ LIBKSBA --------- - Copyright 2001, 2006, 2007, 2008 g10 Code GmbH + Copyright 2001, 2006, 2007, 2008, 2009 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 Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-08 19:52:54 UTC (rev 298) +++ trunk/configure.ac 2009-01-09 12:17:26 UTC (rev 299) @@ -25,7 +25,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [1.0.5]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -40,7 +40,7 @@ # Please remember to document interface changes in the NEWS file. LIBKSBA_LT_CURRENT=17 LIBKSBA_LT_AGE=9 -LIBKSBA_LT_REVISION=4 +LIBKSBA_LT_REVISION=5 #------------------- # If the API is changed in an incompatible way: increment the next counter. KSBA_CONFIG_API_VERSION=1 From cvs at cvs.gnupg.org Fri Jan 9 13:41:50 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 09 Jan 2009 13:41:50 +0100 Subject: [svn] ksba - r300 - tags Message-ID: Author: wk Date: 2009-01-09 13:41:50 +0100 (Fri, 09 Jan 2009) New Revision: 300 Added: tags/libksba-1.0.5/ Log: Release tag. From cvs at cvs.gnupg.org Mon Jan 12 10:18:32 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 12 Jan 2009 10:18:32 +0100 Subject: [svn] GnuPG - r4913 - in trunk: . doc g10 po Message-ID: Author: wk Date: 2009-01-12 10:18:27 +0100 (Mon, 12 Jan 2009) New Revision: 4913 Modified: trunk/ChangeLog trunk/NEWS trunk/README trunk/configure.ac trunk/doc/ChangeLog trunk/doc/faq.raw trunk/g10/ChangeLog trunk/g10/getkey.c trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po Log: preparing a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/ChangeLog 2009-01-12 09:18:27 UTC (rev 4913) @@ -1,3 +1,7 @@ +2009-01-12 Werner Koch + + Release 2.0.10. + 2008-12-09 Werner Koch Release 2.0.10rc1. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/doc/ChangeLog 2009-01-12 09:18:27 UTC (rev 4913) @@ -1,3 +1,7 @@ +2009-01-12 Werner Koch + + * faq.raw: Fix bug reorting address. + 2008-12-12 Werner Koch * gpgsm.texi (General GPGSM Commands): Fix --help, --version and Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/g10/ChangeLog 2009-01-12 09:18:27 UTC (rev 4913) @@ -1,3 +1,8 @@ +2009-01-12 Werner Koch + + * getkey.c (finish_lookup): Take care of keys with a zero + timestamp. Reported by Peter Gutmann. + 2009-01-08 Werner Koch * misc.c (has_invalid_email_chars): Let non-ascii pass through. @@ -10420,7 +10425,7 @@ Copyright 1998,1999,2000,2001,2002,2003,2004,2005, - 2006,2007,2008 Free Software Foundation, Inc. + 2006,2007,2008,2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/NEWS 2009-01-12 09:18:27 UTC (rev 4913) @@ -1,4 +1,4 @@ -Noteworthy changes in version 2.0.10 (unreleased) +Noteworthy changes in version 2.0.10 (2009-01-12) ------------------------------------------------- * [gpg] New keyserver helper gpg2keys_kdns as generic DNS CERT Modified: trunk/README =================================================================== --- trunk/README 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/README 2009-01-12 09:18:27 UTC (rev 4913) @@ -3,7 +3,7 @@ Version 2.0 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009 Free Software Foundation, Inc. INTRODUCTION Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/configure.ac 2009-01-12 09:18:27 UTC (rev 4913) @@ -25,7 +25,8 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [2.0.10]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) + m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) AC_INIT([gnupg], Modified: trunk/doc/faq.raw =================================================================== --- trunk/doc/faq.raw 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/doc/faq.raw 2009-01-12 09:18:27 UTC (rev 4913) @@ -1028,8 +1028,8 @@ lists? Did you have a look at the bug list (you'll find a link to the list of reported bugs on the documentation page). If you're not sure about it being a bug, you can send mail to the gnupg-devel - list. Otherwise, use the GUUG bug tracking system - [H a href=http://bugs.guug.de/Reporting.html][H /a]. + list. Otherwise, use the bug tracking system + [H a href=http://bugs.gnupg.org][H /a]. Why doesn't GnuPG support X.509 certificates? Modified: trunk/g10/getkey.c =================================================================== --- trunk/g10/getkey.c 2009-01-08 19:56:30 UTC (rev 4912) +++ trunk/g10/getkey.c 2009-01-12 09:18:27 UTC (rev 4913) @@ -2696,8 +2696,13 @@ } if (DBG_CACHE) - log_debug( "\tsubkey looks fine\n"); - if ( pk->timestamp > latest_date ) { + log_debug( "\tsubkey might be fine\n"); + /* In case a key has a timestamp of 0 set, we make sure + that it is used. A better change would be to compare + ">=" but that might also change the selected keys and + is as such a more intrusive change. */ + if ( pk->timestamp > latest_date + || (!pk->timestamp && !latest_date)) { latest_date = pk->timestamp; latest_key = k; } Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Mon Jan 12 11:08:55 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 12 Jan 2009 11:08:55 +0100 Subject: [svn] GnuPG - r4914 - in trunk: scd sm Message-ID: Author: wk Date: 2009-01-12 11:08:55 +0100 (Mon, 12 Jan 2009) New Revision: 4914 Modified: trunk/scd/ChangeLog trunk/scd/command.c trunk/sm/ChangeLog trunk/sm/keylist.c Log: Minor fixes Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-01-12 09:18:27 UTC (rev 4913) +++ trunk/scd/ChangeLog 2009-01-12 10:08:55 UTC (rev 4914) @@ -1,3 +1,8 @@ +2009-01-12 Werner Koch + + * command.c (send_client_notifications) [HAVE_W32_SYSTEM]: Fix + brackets. + 2009-01-08 Werner Koch * iso7816.c (iso7816_read_record, iso7816_read_binary): Pass 0 for Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-01-12 09:18:27 UTC (rev 4913) +++ trunk/sm/ChangeLog 2009-01-12 10:08:55 UTC (rev 4914) @@ -1,3 +1,7 @@ +2009-01-12 Werner Koch + + * keylist.c (print_utf8_extn_raw): Cast printf precision argument. + 2009-01-08 Werner Koch * fingerprint.c (gpgsm_get_keygrip_hexstring): Add error detection. Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-01-12 09:18:27 UTC (rev 4913) +++ trunk/scd/command.c 2009-01-12 10:08:55 UTC (rev 4914) @@ -2034,8 +2034,8 @@ killidx++; } } + } #endif /*!HAVE_W32_SYSTEM*/ - } } } } Modified: trunk/sm/keylist.c =================================================================== --- trunk/sm/keylist.c 2009-01-12 09:18:27 UTC (rev 4913) +++ trunk/sm/keylist.c 2009-01-12 10:08:55 UTC (rev 4914) @@ -597,7 +597,7 @@ es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err)); return; } - es_fprintf (fp, "%*s(%.*s)\n", indent, "", objlen, der); + es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der); } From cvs at cvs.gnupg.org Mon Jan 12 11:19:51 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 12 Jan 2009 11:19:51 +0100 Subject: [svn] GnuPG - r4915 - trunk/po Message-ID: Author: wk Date: 2009-01-12 11:19:51 +0100 (Mon, 12 Jan 2009) New Revision: 4915 Modified: trunk/po/ChangeLog trunk/po/ru.po Log: The Russion translation arrived just in time. Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2009-01-12 10:08:55 UTC (rev 4914) +++ trunk/po/ChangeLog 2009-01-12 10:19:51 UTC (rev 4915) @@ -1,3 +1,7 @@ +2009-01-12 Maxim Britov (wk) + + * ru.po: Update. + 2009-01-07 Jaime Su?rez (wk) * es.po: Update. Modified: trunk/po/ru.po [not shown] From cvs at cvs.gnupg.org Mon Jan 12 11:37:13 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 12 Jan 2009 11:37:13 +0100 Subject: [svn] GnuPG - r4916 - tags Message-ID: Author: wk Date: 2009-01-12 11:37:12 +0100 (Mon, 12 Jan 2009) New Revision: 4916 Added: tags/gnupg-2.0.10/ Log: Release tag. From cvs at cvs.gnupg.org Mon Jan 12 11:56:52 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 12 Jan 2009 11:56:52 +0100 Subject: [svn] GnuPG - r4917 - trunk Message-ID: Author: wk Date: 2009-01-12 11:56:52 +0100 (Mon, 12 Jan 2009) New Revision: 4917 Modified: trunk/NEWS trunk/configure.ac Log: Post release updates Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-12 10:37:12 UTC (rev 4916) +++ trunk/NEWS 2009-01-12 10:56:52 UTC (rev 4917) @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.0.11 (unreleased) +------------------------------------------------- + + Noteworthy changes in version 2.0.10 (2009-01-12) ------------------------------------------------- @@ -40,7 +44,7 @@ * [w32] The gnupg2.nls directory is not anymore used. The standard locale directory is now used. - * [w32] Fixed a race condition bteween gpg and gpgsm in the use of + * [w32] Fixed a race condition between gpg and gpgsm in the use of temporary file names. * The gpg-preset-passphrase mechanism works again. An arbitrary Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-12 10:37:12 UTC (rev 4916) +++ trunk/configure.ac 2009-01-12 10:56:52 UTC (rev 4917) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.0.10]) -m4_define([my_issvn], [no]) +m4_define([my_version], [2.0.11]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) From cvs at cvs.gnupg.org Tue Jan 13 15:01:56 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 13 Jan 2009 15:01:56 +0100 Subject: [svn] GnuPG - r4918 - in trunk: g10 scd tests/openpgp tests/openpgp/samplekeys Message-ID: Author: wk Date: 2009-01-13 15:01:56 +0100 (Tue, 13 Jan 2009) New Revision: 4918 Added: trunk/tests/openpgp/samplekeys/ trunk/tests/openpgp/samplekeys/README trunk/tests/openpgp/samplekeys/no-creation-time.gpg Modified: trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/call-agent.h trunk/g10/card-util.c trunk/scd/command.c Log: Add a sample key. Detect and show the card type. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-01-12 10:56:52 UTC (rev 4917) +++ trunk/g10/ChangeLog 2009-01-13 14:01:56 UTC (rev 4918) @@ -1,3 +1,10 @@ +2009-01-13 Werner Koch + + * call-agent.c (dummy_data_cb): New. + (agent_learn): Use it. + * card-util.c (card_status): Print type of non-OpenPGP card. + * call-agent.h (agent_card_info_s): Add field APPTYPE. + 2009-01-12 Werner Koch * getkey.c (finish_lookup): Take care of keys with a zero Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2009-01-12 10:56:52 UTC (rev 4917) +++ trunk/g10/call-agent.c 2009-01-13 14:01:56 UTC (rev 4918) @@ -208,6 +208,17 @@ +/* This is a dummy data line callback. */ +static int +dummy_data_cb (void *opaque, const void *buffer, size_t length) +{ + (void)opaque; + (void)buffer; + (void)length; + return 0; +} + + /* This is the default inquiry callback. It mainly handles the Pinentry notifications. */ static int @@ -239,6 +250,7 @@ return; xfree (info->serialno); info->serialno = NULL; + xfree (info->apptype); info->apptype = NULL; xfree (info->disp_name); info->disp_name = NULL; xfree (info->disp_lang); info->disp_lang = NULL; xfree (info->pubkey_url); info->pubkey_url = NULL; @@ -267,6 +279,11 @@ parm->is_v2 = (strlen (parm->serialno) >= 16 && xtoi_2 (parm->serialno+12) >= 2 ); } + else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen)) + { + xfree (parm->apptype); + parm->apptype = unescape_status_string (line); + } else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen)) { xfree (parm->disp_name); @@ -372,7 +389,7 @@ memset (info, 0, sizeof *info); rc = assuan_transact (agent_ctx, "LEARN --send", - NULL, NULL, default_inq_cb, NULL, + dummy_data_cb, NULL, default_inq_cb, NULL, learn_status_cb, info); return rc; Modified: trunk/g10/call-agent.h =================================================================== --- trunk/g10/call-agent.h 2009-01-12 10:56:52 UTC (rev 4917) +++ trunk/g10/call-agent.h 2009-01-13 14:01:56 UTC (rev 4918) @@ -23,6 +23,7 @@ struct agent_card_info_s { int error; /* private. */ + char *apptype; /* Malloced application type string. */ char *serialno; /* malloced hex string. */ char *disp_name; /* malloced. */ char *disp_lang; /* malloced. */ Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2009-01-12 10:56:52 UTC (rev 4917) +++ trunk/g10/card-util.c 2009-01-13 14:01:56 UTC (rev 4918) @@ -369,8 +369,29 @@ if (!info.serialno || strncmp (info.serialno, "D27600012401", 12) || strlen (info.serialno) != 32 ) { - if (opt.with_colons) - fputs ("unknown:\n", fp); + if (info.apptype && !strcmp (info.apptype, "NKS")) + { + if (opt.with_colons) + fputs ("netkey-card:\n", fp); + log_info ("this is a NetKey card\n"); + } + else if (info.apptype && !strcmp (info.apptype, "DINSIG")) + { + if (opt.with_colons) + fputs ("dinsig-card:\n", fp); + log_info ("this is a DINSIG compliant card\n"); + } + else if (info.apptype && !strcmp (info.apptype, "P15")) + { + if (opt.with_colons) + fputs ("pkcs15-card:\n", fp); + log_info ("this is a PKCS#15 compliant card\n"); + } + else + { + if (opt.with_colons) + fputs ("unknown:\n", fp); + } log_info ("not an OpenPGP card\n"); agent_release_card_info (&info); xfree (pk); Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-01-12 10:56:52 UTC (rev 4917) +++ trunk/scd/command.c 2009-01-13 14:01:56 UTC (rev 4918) @@ -543,7 +543,8 @@ P15 = PKCS-15 structure used DINSIG = DIN SIG OPENPGP = OpenPGP card - + NKS = NetKey card + are implemented. These strings are aliases for the AID S KEYPAIRINFO Added: trunk/tests/openpgp/samplekeys/README =================================================================== --- trunk/tests/openpgp/samplekeys/README (rev 0) +++ trunk/tests/openpgp/samplekeys/README 2009-01-13 14:01:56 UTC (rev 4918) @@ -0,0 +1,4 @@ + +no-creation-time.gpg A key with a zero creation time. + + Added: trunk/tests/openpgp/samplekeys/no-creation-time.gpg =================================================================== (Binary files differ) Property changes on: trunk/tests/openpgp/samplekeys/no-creation-time.gpg ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From cvs at cvs.gnupg.org Wed Jan 14 13:55:37 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 14 Jan 2009 13:55:37 +0100 Subject: [svn] ksba - r301 - in trunk: . src Message-ID: Author: wk Date: 2009-01-14 13:55:36 +0100 (Wed, 14 Jan 2009) New Revision: 301 Modified: trunk/NEWS trunk/configure.ac trunk/src/ChangeLog trunk/src/cms-parser.c trunk/src/cms.c trunk/src/ocsp.c trunk/src/visibility.c Log: Remove return statements in void fucntions. Mark some more unused args. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/src/ChangeLog 2009-01-14 12:55:36 UTC (rev 301) @@ -1,3 +1,19 @@ +2009-01-14 Werner Koch + + * ocsp.c (ksba_ocsp_set_requestor, ksba_ocsp_hash_request) + (ksba_ocsp_set_sig_val, ksba_ocsp_add_cert): Mark unused args. + * cms-parser.c (_ksba_cms_parse_enveloped_data_part_2): Ditto. + * cms.c (ct_parse_data, ct_parse_digested_data) + (ct_parse_encrypted_data, ct_build_data, ct_build_digested_data) + (ct_build_encrypted_data): Ditto. + + * visibility.c (ksba_cms_release, ksba_cms_set_hash_function) + (ksba_crl_release, ksba_crl_set_hash_function, ksba_ocsp_release) + (ksba_certreq_release, ksba_certreq_set_hash_function) + (ksba_reader_release, ksba_writer_release, ksba_asn_tree_release) + (ksba_asn_tree_dump, ksba_name_ref, ksba_name_release): No return + vor a void fucntion. Reported by Nelson H. F. Beebe. + 2009-01-08 Werner Koch * keyinfo.c (get_algorithm): Initialize R_PARM_POS, R_PARM_LEN and @@ -1036,7 +1052,7 @@ (ksba_cert_get_subject): Ditto. - Copyright 2001, 2002, 2003, 2004, 2005, 2008 g10 Code GmbH + Copyright 2001, 2002, 2003, 2004, 2005, 2008, 2009 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 Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/NEWS 2009-01-14 12:55:36 UTC (rev 301) @@ -1,7 +1,11 @@ +Noteworthy changes in version 1.0.6 +------------------------------------------------ + + Noteworthy changes in version 1.0.5 (2009-01-09) ------------------------------------------------ - * Minor big fixes. + * Minor bug fixes. Noteworthy changes in version 1.0.4 (2008-09-22) Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/configure.ac 2009-01-14 12:55:36 UTC (rev 301) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.0.5]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.0.6]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) Modified: trunk/src/cms-parser.c =================================================================== --- trunk/src/cms-parser.c 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/src/cms-parser.c 2009-01-14 12:55:36 UTC (rev 301) @@ -904,6 +904,7 @@ gpg_error_t _ksba_cms_parse_enveloped_data_part_2 (ksba_cms_t cms) { + (void)cms; /* FIXME */ return 0; } Modified: trunk/src/cms.c =================================================================== --- trunk/src/cms.c 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/src/cms.c 2009-01-14 12:55:36 UTC (rev 301) @@ -1878,6 +1878,7 @@ static gpg_error_t ct_parse_data (ksba_cms_t cms) { + (void)cms; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -2033,6 +2034,7 @@ static gpg_error_t ct_parse_digested_data (ksba_cms_t cms) { + (void)cms; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -2040,6 +2042,7 @@ static gpg_error_t ct_parse_encrypted_data (ksba_cms_t cms) { + (void)cms; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -2052,6 +2055,7 @@ static gpg_error_t ct_build_data (ksba_cms_t cms) { + (void)cms; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -3263,6 +3267,7 @@ static gpg_error_t ct_build_digested_data (ksba_cms_t cms) { + (void)cms; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -3270,6 +3275,7 @@ static gpg_error_t ct_build_encrypted_data (ksba_cms_t cms) { + (void)cms; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } Modified: trunk/src/ocsp.c =================================================================== --- trunk/src/ocsp.c 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/src/ocsp.c 2009-01-14 12:55:36 UTC (rev 301) @@ -335,6 +335,8 @@ gpg_error_t ksba_ocsp_set_requestor (ksba_ocsp_t ocsp, ksba_cert_t cert) { + (void)ocsp; + (void)cert; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -773,6 +775,9 @@ size_t length), void *hasher_arg) { + (void)ocsp; + (void)hasher; + (void)hasher_arg; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -781,6 +786,8 @@ ksba_ocsp_set_sig_val (ksba_ocsp_t ocsp, ksba_const_sexp_t sigval) { + (void)ocsp; + (void)sigval; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } @@ -788,6 +795,8 @@ gpg_error_t ksba_ocsp_add_cert (ksba_ocsp_t ocsp, ksba_cert_t cert) { + (void)ocsp; + (void)cert; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } Modified: trunk/src/visibility.c =================================================================== --- trunk/src/visibility.c 2009-01-09 12:41:50 UTC (rev 300) +++ trunk/src/visibility.c 2009-01-14 12:55:36 UTC (rev 301) @@ -319,7 +319,7 @@ void ksba_cms_release (ksba_cms_t cms) { - return _ksba_cms_release (cms); + _ksba_cms_release (cms); } @@ -441,7 +441,7 @@ void (*hash_fnc)(void *, const void *, size_t), void *hash_fnc_arg) { - return _ksba_cms_set_hash_function (cms, hash_fnc, hash_fnc_arg); + _ksba_cms_set_hash_function (cms, hash_fnc, hash_fnc_arg); } @@ -555,7 +555,7 @@ void ksba_crl_release (ksba_crl_t crl) { - return _ksba_crl_release (crl); + _ksba_crl_release (crl); } @@ -572,7 +572,7 @@ const void *, size_t), void *hash_fnc_arg) { - return _ksba_crl_set_hash_function (crl, hash_fnc, hash_fnc_arg); + _ksba_crl_set_hash_function (crl, hash_fnc, hash_fnc_arg); } @@ -662,7 +662,7 @@ void ksba_ocsp_release (ksba_ocsp_t ocsp) { - return _ksba_ocsp_release (ocsp); + _ksba_ocsp_release (ocsp); } @@ -829,7 +829,7 @@ void ksba_certreq_release (ksba_certreq_t cr) { - return _ksba_certreq_release (cr); + _ksba_certreq_release (cr); } @@ -845,7 +845,7 @@ void (*hash_fnc)(void *, const void *, size_t), void *hash_fnc_arg) { - return _ksba_certreq_set_hash_function (cr, hash_fnc, hash_fnc_arg); + _ksba_certreq_set_hash_function (cr, hash_fnc, hash_fnc_arg); } @@ -903,7 +903,7 @@ void ksba_reader_release (ksba_reader_t r) { - return _ksba_reader_release (r); + _ksba_reader_release (r); } @@ -989,7 +989,7 @@ void ksba_writer_release (ksba_writer_t w) { - return _ksba_writer_release (w); + _ksba_writer_release (w); } @@ -1092,7 +1092,7 @@ void ksba_asn_tree_release (ksba_asn_tree_t tree) { - return _ksba_asn_tree_release (tree); + _ksba_asn_tree_release (tree); } @@ -1100,7 +1100,7 @@ void ksba_asn_tree_dump (ksba_asn_tree_t tree, const char *name, FILE *fp) { - return _ksba_asn_tree_dump (tree, name, fp); + _ksba_asn_tree_dump (tree, name, fp); } @@ -1176,14 +1176,14 @@ void ksba_name_ref (ksba_name_t name) { - return _ksba_name_ref (name); + _ksba_name_ref (name); } void ksba_name_release (ksba_name_t name) { - return _ksba_name_release (name); + _ksba_name_release (name); } From cvs at cvs.gnupg.org Fri Jan 16 18:50:09 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 16 Jan 2009 18:50:09 +0100 Subject: [svn] GpgOL - r292 - in trunk: . src Message-ID: Author: wk Date: 2009-01-16 18:50:09 +0100 (Fri, 16 Jan 2009) New Revision: 292 Modified: trunk/AUTHORS trunk/NEWS trunk/README trunk/src/ChangeLog trunk/src/engine-assuan.c trunk/src/mapihelp.cpp trunk/src/olflange-dlgs.cpp trunk/src/versioninfo.rc.in Log: * engine-assuan.c (attach_thread_input_wndw_proc) (attach_thread_input): Enable code. (async_worker_thread): Replace WFMO by MsgWaitForMultipleObjects and add message dispatcher loops. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/src/ChangeLog 2009-01-16 17:50:09 UTC (rev 292) @@ -1,3 +1,14 @@ +2009-01-16 Werner Koch + + * engine-assuan.c (attach_thread_input_wndw_proc) + (attach_thread_input): Enable code. + (async_worker_thread): Replace WFMO by MsgWaitForMultipleObjects + and add message dispatcher loops. + +2008-11-27 Werner Koch + + * mapihelp.cpp (mapi_get_sender): Extract the CN name if available. + 2008-11-26 Werner Koch * ext-commands.cpp (InstallCommands): Don't show status icon for Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/AUTHORS 2009-01-16 17:50:09 UTC (rev 292) @@ -17,3 +17,4 @@ Some files may still contain code from the orginal plugin: Copyright (C) 2001 G Data Software AG, http://www.gdata.de + Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/NEWS 2009-01-16 17:50:09 UTC (rev 292) @@ -1,3 +1,7 @@ +Noteworthy changes for version 0.10.18 (unreleased) +=================================================== + + Noteworthy changes for version 0.10.17 (2008-11-14) =================================================== Modified: trunk/README =================================================================== --- trunk/README 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/README 2009-01-16 17:50:09 UTC (rev 292) @@ -1,6 +1,11 @@ + GpgOL Version 0.10.x + ======================= + Copyright (C) 2004, 2005, 2007, 2008, 2009 g10 Code GmbH + + GpgOL is a GnuPG plugin for MS Outlook. -WARNING: This version requires the latest Kleopatra software. +WARNING: This version requires the latest Kleopatra or GPA software. . Top directory with build scripts and information files. Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/src/engine-assuan.c 2009-01-16 17:50:09 UTC (rev 292) @@ -1,5 +1,5 @@ /* engine-assuan.c - Crypto engine using an Assuan server - * Copyright (C) 2007, 2008 g10 Code GmbH + * Copyright (C) 2007, 2008, 2009 g10 Code GmbH * * This file is part of GpgOL. * @@ -613,7 +613,7 @@ return 0; } -#if 0 /* Not used. */ + /* Dummy window procedure. */ static LRESULT CALLBACK attach_thread_input_wndw_proc (HWND hwnd, UINT msg, @@ -657,10 +657,8 @@ log_debug ("%s:%s: attached thread %lu to %lu", SRCNAME, __func__, GetCurrentThreadId (), other_tid); } -#endif /* not used. */ - /* Helper to write to the callback. */ static void @@ -875,7 +873,7 @@ HANDLE hdarray[MAXIMUM_WAIT_OBJECTS]; int count, addit, any_ready, hdarraylen; -/* attach_thread_input ( (DWORD)dummy ); */ + attach_thread_input ( (DWORD)dummy ); (void)dummy; for (;;) @@ -975,19 +973,19 @@ after the wait because we will only get to here if there is actual ui-server work to be done but some messages might still be in the queue. */ -/* { */ -/* MSG msg; */ + { + MSG msg; -/* while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) */ -/* { */ -/* TranslateMessage (&msg); */ -/* DispatchMessage (&msg); */ -/* } */ -/* } */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } - n = WaitForMultipleObjects (hdarraylen, hdarray, FALSE, INFINITE); -/* n = MsgWaitForMultipleObjects (hdarraylen, hdarray, FALSE, */ -/* INFINITE, QS_ALLEVENTS); */ +/* n = WaitForMultipleObjects (hdarraylen, hdarray, FALSE, INFINITE); */ + n = MsgWaitForMultipleObjects (hdarraylen, hdarray, FALSE, + INFINITE, QS_ALLEVENTS); if (n == WAIT_FAILED) { /* The WFMO failed. This is an error; to help debugging @@ -1030,15 +1028,15 @@ /* [Currently not used] Try to process the message queue. */ -/* { */ -/* MSG msg; */ + { + MSG msg; -/* while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) */ -/* { */ -/* TranslateMessage (&msg); */ -/* DispatchMessage (&msg); */ -/* } */ -/* } */ + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + } } /* Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/src/mapihelp.cpp 2009-01-16 17:50:09 UTC (rev 292) @@ -1404,6 +1404,18 @@ for (p0=buf, p++; *p && *p != '\x01';) *p0++ = *p++; *p0 = 0; + + /* When using an Exchange account this is an X.509 address and not + an SMTP address. We try to detect this here and extract only the + CN RDN. Note that there are two CNs. This is just a simple + approach and not a real parser. A better way to do this would be + to ask MAPI to resolve the X.500 name to an SMTP name. */ + if (strstr (buf, "/o=") && strstr (buf, "/ou=") && + (p = strstr (buf, "/cn=Recipients")) && (p = strstr (p+1, "/cn="))) + { + log_debug ("%s:%s: orig address is `%s'\n", SRCNAME, __func__, buf); + memmove (buf, p+4, strlen (p+4)+1); + } log_debug ("%s:%s: address is `%s'\n", SRCNAME, __func__, buf); return buf; } Modified: trunk/src/olflange-dlgs.cpp =================================================================== --- trunk/src/olflange-dlgs.cpp 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/src/olflange-dlgs.cpp 2009-01-16 17:50:09 UTC (rev 292) @@ -248,7 +248,7 @@ case PSN_HELP: { - const char cpynotice[] = "Copyright (C) 2008 g10 Code GmbH"; + const char cpynotice[] = "Copyright (C) 2009 g10 Code GmbH"; const char en_notice[] = "GpgOL is a plugin for Outlook to allow encryption and\n" "signing of messages using the OpenPGP and S/MIME standard.\n" Modified: trunk/src/versioninfo.rc.in =================================================================== --- trunk/src/versioninfo.rc.in 2008-12-02 18:22:54 UTC (rev 291) +++ trunk/src/versioninfo.rc.in 2009-01-16 17:50:09 UTC (rev 292) @@ -39,7 +39,7 @@ VALUE "FileDescription", "GpgOL - GnuPG plugin for Outlook\0" VALUE "FileVersion", "@VERSION@\0" VALUE "InternalName", "gpgol\0" - VALUE "LegalCopyright", "Copyright ? 2005 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright ? 2009 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gpgol.dll\0" VALUE "PrivateBuild", "\0" From cvs at cvs.gnupg.org Mon Jan 19 15:44:14 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 19 Jan 2009 15:44:14 +0100 Subject: [svn] gpgme - r1352 - trunk/src Message-ID: Author: wk Date: 2009-01-19 15:44:13 +0100 (Mon, 19 Jan 2009) New Revision: 1352 Added: trunk/src/engine-gpg.c Removed: trunk/src/rungpg.c Modified: trunk/src/ChangeLog trunk/src/Makefile.am Log: Renamed rungpg.c to engine-gpg.c for conistency. [The diff below has been truncated] Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-12-08 19:28:36 UTC (rev 1351) +++ trunk/src/ChangeLog 2009-01-19 14:44:13 UTC (rev 1352) @@ -1,3 +1,8 @@ +2009-01-19 Werner Koch + + * rungpg.c: Rename to engine-gpg.c + * Makefile.am (main_sources): Ditto. + 2008-12-03 Marcus Brinkmann * Makefile.am (status-table.h): Use $(builddir) to find gpgme.h. @@ -5893,7 +5898,7 @@ * data.c (gpgme_data_rewind): Allow to rewind data_type_none. - Copyright 2001,2002,2003,2004,2005,2006,2007 g10 Code GmbH + Copyright 2001,2002,2003,2004,2005,2006,2007,2008,2009 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 Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2008-12-08 19:28:36 UTC (rev 1351) +++ trunk/src/Makefile.am 2009-01-19 14:44:13 UTC (rev 1352) @@ -105,7 +105,7 @@ sign.c passphrase.c progress.c \ key.c keylist.c trust-item.c trustlist.c \ import.c export.c genkey.c delete.c edit.c getauditlog.c \ - engine.h engine-backend.h engine.c rungpg.c status-table.h \ + engine.h engine-backend.h engine.c engine-gpg.c status-table.h \ $(gpgsm_components) $(gpgconf_components) gpgconf.c \ sema.h priv-io.h $(system_components) \ debug.c debug.h gpgme.c version.c error.c Copied: trunk/src/engine-gpg.c (from rev 1351, trunk/src/rungpg.c) =================================================================== --- trunk/src/engine-gpg.c (rev 0) +++ trunk/src/engine-gpg.c 2009-01-19 14:44:13 UTC (rev 1352) @@ -0,0 +1,2192 @@ +/* engine-gpg.c - Gpg Engine. + Copyright (C) 2000 Werner Koch (dd9jn) + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, + 2009 g10 Code GmbH + + This file is part of GPGME. + + GPGME is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + GPGME is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see . +*/ + +#if HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "gpgme.h" +#include "util.h" +#include "ops.h" +#include "wait.h" +#include "context.h" /*temp hack until we have GpmeData methods to do I/O */ +#include "priv-io.h" +#include "sema.h" +#include "debug.h" + +#include "status-table.h" +#include "engine-backend.h" + + +/* This type is used to build a list of gpg arguments and data + sources/sinks. */ +struct arg_and_data_s +{ + struct arg_and_data_s *next; + gpgme_data_t data; /* If this is not NULL, use arg below. */ + int inbound; /* True if this is used for reading from gpg. */ + int dup_to; + int print_fd; /* Print the fd number and not the special form of it. */ + int *arg_locp; /* Write back the argv idx of this argument when + building command line to this location. */ + char arg[1]; /* Used if data above is not used. */ +}; + + +struct fd_data_map_s +{ + gpgme_data_t data; + int inbound; /* true if this is used for reading from gpg */ + int dup_to; + int fd; /* the fd to use */ + int peer_fd; /* the other side of the pipe */ + int arg_loc; /* The index into the argv for translation purposes. */ + void *tag; +}; + + +typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline); + +struct engine_gpg +{ + char *file_name; + + char *lc_messages; + char *lc_ctype; + + struct arg_and_data_s *arglist; + struct arg_and_data_s **argtail; + + struct + { + int fd[2]; + int arg_loc; + size_t bufsize; + char *buffer; + size_t readpos; + int eof; + engine_status_handler_t fnc; + void *fnc_value; + void *tag; + } status; + + /* This is a kludge - see the comment at colon_line_handler. */ + struct + { + int fd[2]; + int arg_loc; + size_t bufsize; + char *buffer; + size_t readpos; + int eof; + engine_colon_line_handler_t fnc; /* this indicate use of this structrue */ + void *fnc_value; + void *tag; + colon_preprocessor_t preprocess_fnc; + } colon; + + char **argv; + struct fd_data_map_s *fd_data_map; + + /* stuff needed for interactive (command) mode */ + struct + { + int used; + int fd; + void *cb_data; + int idx; /* Index in fd_data_map */ + gpgme_status_code_t code; /* last code */ + char *keyword; /* what has been requested (malloced) */ + engine_command_handler_t fnc; + void *fnc_value; + /* The kludges never end. This is used to couple command handlers + with output data in edit key mode. */ + gpgme_data_t linked_data; + int linked_idx; + } cmd; + + struct gpgme_io_cbs io_cbs; +}; + +typedef struct engine_gpg *engine_gpg_t; + + +static void +gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data) +{ + engine_gpg_t gpg = engine; + + TRACE3 (DEBUG_ENGINE, "gpgme:gpg_io_event", gpg, + "event %p, type %d, type_data %p", + gpg->io_cbs.event, type, type_data); + if (gpg->io_cbs.event) + (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data); +} + + +static void +close_notify_handler (int fd, void *opaque) +{ + engine_gpg_t gpg = opaque; + assert (fd != -1); + + if (gpg->status.fd[0] == fd) + { + if (gpg->status.tag) + (*gpg->io_cbs.remove) (gpg->status.tag); + gpg->status.fd[0] = -1; + } + else if (gpg->status.fd[1] == fd) + gpg->status.fd[1] = -1; + else if (gpg->colon.fd[0] == fd) + { + if (gpg->colon.tag) + (*gpg->io_cbs.remove) (gpg->colon.tag); + gpg->colon.fd[0] = -1; + } + else if (gpg->colon.fd[1] == fd) + gpg->colon.fd[1] = -1; + else if (gpg->fd_data_map) + { + int i; + + for (i = 0; gpg->fd_data_map[i].data; i++) + { + if (gpg->fd_data_map[i].fd == fd) + { + if (gpg->fd_data_map[i].tag) + (*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag); + gpg->fd_data_map[i].fd = -1; + break; + } + if (gpg->fd_data_map[i].peer_fd == fd) + { + gpg->fd_data_map[i].peer_fd = -1; + break; + } + } + } +} + +/* If FRONT is true, push at the front of the list. Use this for + options added late in the process. */ +static gpgme_error_t +_add_arg (engine_gpg_t gpg, const char *arg, int front, int *arg_locp) +{ + struct arg_and_data_s *a; + + assert (gpg); + assert (arg); + + a = malloc (sizeof *a + strlen (arg)); + if (!a) + return gpg_error_from_errno (errno); + + a->data = NULL; + a->dup_to = -1; + a->arg_locp = arg_locp; + + strcpy (a->arg, arg); + if (front) + { + a->next = gpg->arglist; + if (!gpg->arglist) + { + /* If this is the first argument, we need to update the tail + pointer. */ + gpg->argtail = &a->next; + } + gpg->arglist = a; + } + else + { + a->next = NULL; + *gpg->argtail = a; + gpg->argtail = &a->next; + } + + return 0; +} + +static gpgme_error_t +add_arg_ext (engine_gpg_t gpg, const char *arg, int front) +{ + return _add_arg (gpg, arg, front, NULL); +} + + +static gpgme_error_t +add_arg_with_locp (engine_gpg_t gpg, const char *arg, int *locp) +{ + return _add_arg (gpg, arg, 0, locp); +} + + +static gpgme_error_t +add_arg (engine_gpg_t gpg, const char *arg) +{ + return add_arg_ext (gpg, arg, 0); +} + + +static gpgme_error_t +add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound) +{ + struct arg_and_data_s *a; + + assert (gpg); + assert (data); + + a = malloc (sizeof *a - 1); + if (!a) + return gpg_error_from_errno (errno); + a->next = NULL; + a->data = data; + a->inbound = inbound; + a->arg_locp = NULL; + + if (dup_to == -2) + { + a->print_fd = 1; + a->dup_to = -1; + } + else + { + a->print_fd = 0; + a->dup_to = dup_to; + } + *gpg->argtail = a; + gpg->argtail = &a->next; + return 0; +} + + +static char * +gpg_get_version (const char *file_name) +{ + return _gpgme_get_program_version (file_name ? file_name + : _gpgme_get_gpg_path ()); +} + + +static const char * +gpg_get_req_version (void) +{ + return NEED_GPG_VERSION; +} + + +static void +free_argv (char **argv) +{ + int i; + + for (i = 0; argv[i]; i++) + free (argv[i]); + free (argv); +} + + +static void +free_fd_data_map (struct fd_data_map_s *fd_data_map) +{ + int i; + + if (!fd_data_map) + return; + + for (i = 0; fd_data_map[i].data; i++) + { + if (fd_data_map[i].fd != -1) + _gpgme_io_close (fd_data_map[i].fd); + if (fd_data_map[i].peer_fd != -1) + _gpgme_io_close (fd_data_map[i].peer_fd); + /* Don't release data because this is only a reference. */ + } + free (fd_data_map); +} + + +static gpgme_error_t +gpg_cancel (void *engine) +{ + engine_gpg_t gpg = engine; + + if (!gpg) + return gpg_error (GPG_ERR_INV_VALUE); + + /* If gpg may be waiting for a cmd, close the cmd fd first. On + Windows, close operations block on the reader/writer thread. */ + if (gpg->cmd.used) + { + if (gpg->cmd.fd != -1) + _gpgme_io_close (gpg->cmd.fd); + else if (gpg->fd_data_map + && gpg->fd_data_map[gpg->cmd.idx].fd != -1) + _gpgme_io_close (gpg->fd_data_map[gpg->cmd.idx].fd); + } + + if (gpg->status.fd[0] != -1) + _gpgme_io_close (gpg->status.fd[0]); + if (gpg->status.fd[1] != -1) + _gpgme_io_close (gpg->status.fd[1]); + if (gpg->colon.fd[0] != -1) + _gpgme_io_close (gpg->colon.fd[0]); + if (gpg->colon.fd[1] != -1) + _gpgme_io_close (gpg->colon.fd[1]); + if (gpg->fd_data_map) + { + free_fd_data_map (gpg->fd_data_map); + gpg->fd_data_map = NULL; + } + + return 0; +} + +static void +gpg_release (void *engine) +{ + engine_gpg_t gpg = engine; + + if (!gpg) + return; + + gpg_cancel (engine); + + if (gpg->file_name) + free (gpg->file_name); + + if (gpg->lc_messages) + free (gpg->lc_messages); + if (gpg->lc_ctype) + free (gpg->lc_ctype); + + while (gpg->arglist) + { + struct arg_and_data_s *next = gpg->arglist->next; + + if (gpg->arglist) + free (gpg->arglist); + gpg->arglist = next; + } + + if (gpg->status.buffer) + free (gpg->status.buffer); + if (gpg->colon.buffer) + free (gpg->colon.buffer); + if (gpg->argv) + free_argv (gpg->argv); + if (gpg->cmd.keyword) + free (gpg->cmd.keyword); + + free (gpg); +} + + +static gpgme_error_t +gpg_new (void **engine, const char *file_name, const char *home_dir) +{ + engine_gpg_t gpg; + gpgme_error_t rc = 0; + char *dft_display = NULL; + char dft_ttyname[64]; + char *dft_ttytype = NULL; + + gpg = calloc (1, sizeof *gpg); + if (!gpg) + return gpg_error_from_errno (errno); + + if (file_name) + { + gpg->file_name = strdup (file_name); + if (!gpg->file_name) + { + rc = gpg_error_from_errno (errno); + goto leave; + } + } + + gpg->argtail = &gpg->arglist; + gpg->status.fd[0] = -1; + gpg->status.fd[1] = -1; + gpg->colon.fd[0] = -1; + gpg->colon.fd[1] = -1; + gpg->cmd.fd = -1; + gpg->cmd.idx = -1; + gpg->cmd.linked_data = NULL; + gpg->cmd.linked_idx = -1; + + /* Allocate the read buffer for the status pipe. */ + gpg->status.bufsize = 1024; + gpg->status.readpos = 0; + gpg->status.buffer = malloc (gpg->status.bufsize); + if (!gpg->status.buffer) + { + rc = gpg_error_from_errno (errno); + goto leave; + } + /* In any case we need a status pipe - create it right here and + don't handle it with our generic gpgme_data_t mechanism. */ + if (_gpgme_io_pipe (gpg->status.fd, 1) == -1) + { + rc = gpg_error_from_errno (errno); + goto leave; + } + if (_gpgme_io_set_close_notify (gpg->status.fd[0], + close_notify_handler, gpg) + || _gpgme_io_set_close_notify (gpg->status.fd[1], + close_notify_handler, gpg)) + { + rc = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + gpg->status.eof = 0; + + if (home_dir) + { + rc = add_arg (gpg, "--homedir"); + if (!rc) + rc = add_arg (gpg, home_dir); + if (rc) + goto leave; + } + + rc = add_arg (gpg, "--status-fd"); + if (rc) + goto leave; + + { + char buf[25]; + _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]); + rc = add_arg_with_locp (gpg, buf, &gpg->status.arg_loc); + if (rc) + goto leave; + } + + rc = add_arg (gpg, "--no-tty"); + if (!rc) + rc = add_arg (gpg, "--charset"); + if (!rc) + rc = add_arg (gpg, "utf8"); + if (!rc) + rc = add_arg (gpg, "--enable-progress-filter"); + if (rc) + goto leave; + + rc = _gpgme_getenv ("DISPLAY", &dft_display); + if (rc) + goto leave; + if (dft_display) + { + rc = add_arg (gpg, "--display"); + if (!rc) + rc = add_arg (gpg, dft_display); + + free (dft_display); + } + + if (isatty (1)) + { + int err; + + err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); + if (err) + rc = gpg_error_from_errno (err); + else + { + if (*dft_ttyname) + { + rc = add_arg (gpg, "--ttyname"); + if (!rc) + rc = add_arg (gpg, dft_ttyname); + } + else + rc = 0; + if (!rc) + { + rc = _gpgme_getenv ("TERM", &dft_ttytype); + if (rc) + goto leave; + + if (dft_ttytype) + { + rc = add_arg (gpg, "--ttytype"); + if (!rc) + rc = add_arg (gpg, dft_ttytype); + } + + free (dft_ttytype); + } + } + if (rc) + goto leave; + } + + leave: + if (rc) + gpg_release (gpg); + else + *engine = gpg; + return rc; +} + + +static gpgme_error_t +gpg_set_locale (void *engine, int category, const char *value) +{ + engine_gpg_t gpg = engine; + + if (category == LC_CTYPE) + { + if (gpg->lc_ctype) + { + free (gpg->lc_ctype); + gpg->lc_ctype = NULL; + } + if (value) + { + gpg->lc_ctype = strdup (value); + if (!gpg->lc_ctype) + return gpg_error_from_syserror (); + } + } +#ifdef LC_MESSAGES + else if (category == LC_MESSAGES) + { + if (gpg->lc_messages) + { + free (gpg->lc_messages); + gpg->lc_messages = NULL; + } + if (value) + { + gpg->lc_messages = strdup (value); + if (!gpg->lc_messages) + return gpg_error_from_syserror (); + } + } +#endif /* LC_MESSAGES */ + else + return gpg_error (GPG_ERR_INV_VALUE); + + return 0; +} + + +/* Note, that the status_handler is allowed to modifiy the args + value. */ +static void +gpg_set_status_handler (void *engine, engine_status_handler_t fnc, + void *fnc_value) +{ + engine_gpg_t gpg = engine; + + gpg->status.fnc = fnc; + gpg->status.fnc_value = fnc_value; +} + +/* Kludge to process --with-colon output. */ +static gpgme_error_t +gpg_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc, + void *fnc_value) +{ + engine_gpg_t gpg = engine; + + gpg->colon.bufsize = 1024; + gpg->colon.readpos = 0; + gpg->colon.buffer = malloc (gpg->colon.bufsize); + if (!gpg->colon.buffer) + return gpg_error_from_errno (errno); + + if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1) + { + int saved_errno = errno; + free (gpg->colon.buffer); + gpg->colon.buffer = NULL; + return gpg_error_from_errno (saved_errno); + } + if (_gpgme_io_set_close_notify (gpg->colon.fd[0], close_notify_handler, gpg) + || _gpgme_io_set_close_notify (gpg->colon.fd[1], + close_notify_handler, gpg)) + return gpg_error (GPG_ERR_GENERAL); + gpg->colon.eof = 0; + gpg->colon.fnc = fnc; + gpg->colon.fnc_value = fnc_value; + return 0; +} + + +static gpgme_error_t +command_handler (void *opaque, int fd) +{ + gpgme_error_t err; + engine_gpg_t gpg = (engine_gpg_t) opaque; + int processed = 0; + + assert (gpg->cmd.used); + assert (gpg->cmd.code); + assert (gpg->cmd.fnc); + + err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd, + &processed); + + gpg->cmd.code = 0; + /* And sleep again until read_status will wake us up again. */ + /* XXX We must check if there are any more fds active after removing + this one. */ + (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag); + gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd; + gpg->fd_data_map[gpg->cmd.idx].fd = -1; + + if (err) + return err; + + /* We always need to send at least a newline character. */ + if (!processed) + _gpgme_io_write (fd, "\n", 1); + + return 0; +} + + + +/* The Fnc will be called to get a value for one of the commands with + a key KEY. If the Code pssed to FNC is 0, the function may release + resources associated with the returned value from another call. To + match such a second call to a first call, the returned value from + the first call is passed as keyword. */ +static gpgme_error_t +gpg_set_command_handler (void *engine, engine_command_handler_t fnc, + void *fnc_value, gpgme_data_t linked_data) +{ + engine_gpg_t gpg = engine; + gpgme_error_t rc; + + rc = add_arg (gpg, "--command-fd"); + if (rc) + return rc; + + /* This is a hack. We don't have a real data object. The only + thing that matters is that we use something unique, so we use the + address of the cmd structure in the gpg object. */ + rc = add_data (gpg, (void *) &gpg->cmd, -2, 0); + if (rc) + return rc; + + gpg->cmd.fnc = fnc; + gpg->cmd.cb_data = (void *) &gpg->cmd; + gpg->cmd.fnc_value = fnc_value; + gpg->cmd.linked_data = linked_data; + gpg->cmd.used = 1; + return 0; +} + + +static gpgme_error_t +build_argv (engine_gpg_t gpg) +{ + gpgme_error_t err; + struct arg_and_data_s *a; + struct fd_data_map_s *fd_data_map; + size_t datac=0, argc=0; + char **argv; + int need_special = 0; + int use_agent = 0; + char *p; + + /* We don't want to use the agent with a malformed environment + variable. This is only a very basic test but sufficient to make + our life in the regression tests easier. */ + err = _gpgme_getenv ("GPG_AGENT_INFO", &p); + if (err) + return err; + use_agent = (p && strchr (p, ':')); + if (p) + free (p); + + if (gpg->argv) + { + free_argv (gpg->argv); + gpg->argv = NULL; + } + if (gpg->fd_data_map) + { + free_fd_data_map (gpg->fd_data_map); + gpg->fd_data_map = NULL; + } + + argc++; /* For argv[0]. */ + for (a = gpg->arglist; a; a = a->next) + { + argc++; + if (a->data) + { + /*fprintf (stderr, "build_argv: data\n" );*/ + datac++; + if (a->dup_to == -1 && !a->print_fd) + need_special = 1; + } + else + { + /* fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/ + } + } + if (need_special) + argc++; + if (use_agent) + argc++; + if (!gpg->cmd.used) + argc++; /* --batch */ + argc += 1; /* --no-sk-comment */ + + argv = calloc (argc + 1, sizeof *argv); + if (!argv) + return gpg_error_from_errno (errno); + fd_data_map = calloc (datac + 1, sizeof *fd_data_map); + if (!fd_data_map) + { + int saved_errno = errno; + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + + argc = datac = 0; + argv[argc] = strdup ("gpg"); /* argv[0] */ + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + argc++; + if (need_special) + { + argv[argc] = strdup ("--enable-special-filenames"); + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + argc++; + } + if (use_agent) + { + argv[argc] = strdup ("--use-agent"); + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + argc++; + } + if (!gpg->cmd.used) + { + argv[argc] = strdup ("--batch"); + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + argc++; + } + argv[argc] = strdup ("--no-sk-comment"); + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + argc++; + for (a = gpg->arglist; a; a = a->next) + { + if (a->arg_locp) + *(a->arg_locp) = argc; + + if (a->data) + { + /* Create a pipe to pass it down to gpg. */ + fd_data_map[datac].inbound = a->inbound; + + /* Create a pipe. */ + { + int fds[2]; + + if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0) + == -1) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error (saved_errno); + } + if (_gpgme_io_set_close_notify (fds[0], + close_notify_handler, gpg) + || _gpgme_io_set_close_notify (fds[1], + close_notify_handler, + gpg)) + { + return gpg_error (GPG_ERR_GENERAL); + } + /* If the data_type is FD, we have to do a dup2 here. */ + if (fd_data_map[datac].inbound) + { + fd_data_map[datac].fd = fds[0]; + fd_data_map[datac].peer_fd = fds[1]; + } + else + { + fd_data_map[datac].fd = fds[1]; + fd_data_map[datac].peer_fd = fds[0]; + } + } + + /* Hack to get hands on the fd later. */ + if (gpg->cmd.used) + { + if (gpg->cmd.cb_data == a->data) + { + assert (gpg->cmd.idx == -1); + gpg->cmd.idx = datac; + } + else if (gpg->cmd.linked_data == a->data) + { + assert (gpg->cmd.linked_idx == -1); + gpg->cmd.linked_idx = datac; + } + } + + fd_data_map[datac].data = a->data; + fd_data_map[datac].dup_to = a->dup_to; + + if (a->dup_to == -1) + { + char *ptr; + int buflen = 25; + + argv[argc] = malloc (buflen); + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + + ptr = argv[argc]; + if (!a->print_fd) + { + *(ptr++) = '-'; + *(ptr++) = '&'; + buflen -= 2; + } + + _gpgme_io_fd2str (ptr, buflen, fd_data_map[datac].peer_fd); + fd_data_map[datac].arg_loc = argc; + argc++; + } + datac++; + } + else + { + argv[argc] = strdup (a->arg); + if (!argv[argc]) + { + int saved_errno = errno; + free (fd_data_map); + free_argv (argv); + return gpg_error_from_errno (saved_errno); + } + argc++; + } + } + + gpg->argv = argv; + gpg->fd_data_map = fd_data_map; + return 0; +} + + +static gpgme_error_t +add_io_cb (engine_gpg_t gpg, int fd, int dir, gpgme_io_cb_t handler, void *data, + void **tag) +{ + gpgme_error_t err; + + err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag); + if (err) + return err; + if (!dir) + /* FIXME Kludge around poll() problem. */ + err = _gpgme_io_set_nonblocking (fd); + return err; +} + + +static int +status_cmp (const void *ap, const void *bp) +{ + const struct status_table_s *a = ap; + const struct status_table_s *b = bp; + + return strcmp (a->name, b->name); +} + + +/* Handle the status output of GnuPG. This function does read entire + lines and passes them as C strings to the callback function (we can + use C Strings because the status output is always UTF-8 encoded). + Of course we have to buffer the lines to cope with long lines + e.g. with a large user ID. Note: We can optimize this to only cope + with status line code we know about and skip all other stuff + without buffering (i.e. without extending the buffer). */ +static gpgme_error_t +read_status (engine_gpg_t gpg) +{ + char *p; + int nread; + size_t bufsize = gpg->status.bufsize; + char *buffer = gpg->status.buffer; + size_t readpos = gpg->status.readpos; + + assert (buffer); + if (bufsize - readpos < 256) + { + /* Need more room for the read. */ + bufsize += 1024; + buffer = realloc (buffer, bufsize); + if (!buffer) + return gpg_error_from_errno (errno); + } + + nread = _gpgme_io_read (gpg->status.fd[0], + buffer + readpos, bufsize-readpos); + if (nread == -1) + return gpg_error_from_errno (errno); + + if (!nread) + { + gpg->status.eof = 1; + if (gpg->status.fnc) + { + gpgme_error_t err; + err = gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, ""); + if (err) + return err; + } + return 0; + } + + while (nread > 0) + { + for (p = buffer + readpos; nread; nread--, p++) + { + if (*p == '\n') + { + /* (we require that the last line is terminated by a LF) */ + if (p > buffer && p[-1] == '\r') + p[-1] = 0; + *p = 0; + if (!strncmp (buffer, "[GNUPG:] ", 9) + && buffer[9] >= 'A' && buffer[9] <= 'Z') + { + struct status_table_s t, *r; + char *rest; + + rest = strchr (buffer + 9, ' '); + if (!rest) + rest = p; /* Set to an empty string. */ + else + *rest++ = 0; + + t.name = buffer+9; + /* (the status table has one extra element) */ + r = bsearch (&t, status_table, DIM(status_table) - 1, + sizeof t, status_cmp); + if (r) + { + if (gpg->cmd.used + && (r->code == GPGME_STATUS_GET_BOOL + || r->code == GPGME_STATUS_GET_LINE + || r->code == GPGME_STATUS_GET_HIDDEN)) + { + gpg->cmd.code = r->code; + if (gpg->cmd.keyword) + free (gpg->cmd.keyword); + gpg->cmd.keyword = strdup (rest); + if (!gpg->cmd.keyword) + return gpg_error_from_errno (errno); + /* This should be the last thing we have + received and the next thing will be that + the command handler does its action. */ + if (nread > 1) + TRACE0 (DEBUG_CTX, "gpgme:read_status", 0, + "error: unexpected data"); + + add_io_cb (gpg, gpg->cmd.fd, 0, + command_handler, gpg, + &gpg->fd_data_map[gpg->cmd.idx].tag); + gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd; + gpg->cmd.fd = -1; + } + else if (gpg->status.fnc) + { + gpgme_error_t err; + err = gpg->status.fnc (gpg->status.fnc_value, + r->code, rest); + if (err) + return err; + } + + if (r->code == GPGME_STATUS_END_STREAM) + { + if (gpg->cmd.used) + { + /* Before we can actually add the + command fd, we might have to flush + the linked output data pipe. */ + if (gpg->cmd.linked_idx != -1 + && gpg->fd_data_map[gpg->cmd.linked_idx].fd + != -1) + { + struct io_select_fd_s fds; + fds.fd = + gpg->fd_data_map[gpg->cmd.linked_idx].fd; + fds.for_read = 1; + fds.for_write = 0; + fds.opaque = NULL; + do + { + fds.signaled = 0; + _gpgme_io_select (&fds, 1, 1); + if (fds.signaled) + _gpgme_data_inbound_handler + (gpg->cmd.linked_data, fds.fd); + } + while (fds.signaled); + } + + /* XXX We must check if there are any + more fds active after removing this + one. */ + (*gpg->io_cbs.remove) + (gpg->fd_data_map[gpg->cmd.idx].tag); + gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd; + gpg->fd_data_map[gpg->cmd.idx].fd = -1; + } + } + } + } + /* To reuse the buffer for the next line we have to + shift the remaining data to the buffer start and + restart the loop Hmmm: We can optimize this function + by looking forward in the buffer to see whether a + second complete line is available and in this case + avoid the memmove for this line. */ + nread--; p++; + if (nread) + memmove (buffer, p, nread); + readpos = 0; + break; /* the for loop */ + } + else + readpos++; + } + } + + /* Update the gpg object. */ + gpg->status.bufsize = bufsize; + gpg->status.buffer = buffer; + gpg->status.readpos = readpos; + return 0; +} + + +static gpgme_error_t +status_handler (void *opaque, int fd) +{ + engine_gpg_t gpg = opaque; + int err; + + assert (fd == gpg->status.fd[0]); + err = read_status (gpg); + if (err) + return err; + if (gpg->status.eof) + _gpgme_io_close (fd); + return 0; +} + + +static gpgme_error_t +read_colon_line (engine_gpg_t gpg) +{ + char *p; + int nread; + size_t bufsize = gpg->colon.bufsize; + char *buffer = gpg->colon.buffer; + size_t readpos = gpg->colon.readpos; + + assert (buffer); + if (bufsize - readpos < 256) + { + /* Need more room for the read. */ + bufsize += 1024; + buffer = realloc (buffer, bufsize); + if (!buffer) + return gpg_error_from_errno (errno); + } + + nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos); + if (nread == -1) + return gpg_error_from_errno (errno); + + if (!nread) + { + gpg->colon.eof = 1; + assert (gpg->colon.fnc); + gpg->colon.fnc (gpg->colon.fnc_value, NULL); + return 0; + } + + while (nread > 0) + { + for (p = buffer + readpos; nread; nread--, p++) + { + if ( *p == '\n' ) + { + /* (we require that the last line is terminated by a LF) + and we skip empty lines. Note: we use UTF8 encoding + and escaping of special characters. We require at + least one colon to cope with some other printed + information. */ + *p = 0; + if (*buffer && strchr (buffer, ':')) + { + char *line = NULL; + + if (gpg->colon.preprocess_fnc) + { + gpgme_error_t err; + + err = gpg->colon.preprocess_fnc (buffer, &line); + if (err) + return err; + } + + assert (gpg->colon.fnc); + gpg->colon.fnc (gpg->colon.fnc_value, line ? line : buffer); + if (line) + free (line); + } + + /* To reuse the buffer for the next line we have to + shift the remaining data to the buffer start and + restart the loop Hmmm: We can optimize this function + by looking forward in the buffer to see whether a + second complete line is available and in this case + avoid the memmove for this line. */ + nread--; p++; + if (nread) + memmove (buffer, p, nread); + readpos = 0; + break; /* The for loop. */ + } + else + readpos++; + } + } + + /* Update the gpg object. */ + gpg->colon.bufsize = bufsize; + gpg->colon.buffer = buffer; + gpg->colon.readpos = readpos; + return 0; +} + + +/* This colonline handler thing is not the clean way to do it. It + might be better to enhance the gpgme_data_t object to act as a wrapper + for a callback. Same goes for the status thing. For now we use + this thing here because it is easier to implement. */ +static gpgme_error_t +colon_line_handler (void *opaque, int fd) +{ + engine_gpg_t gpg = opaque; + gpgme_error_t rc = 0; + + assert (fd == gpg->colon.fd[0]); + rc = read_colon_line (gpg); + if (rc) + return rc; + if (gpg->colon.eof) + _gpgme_io_close (fd); + return 0; +} + + +static gpgme_error_t +start (engine_gpg_t gpg) +{ + gpgme_error_t rc; + int saved_errno; + int i, n; + int status; + struct spawn_fd_item_s *fd_list; + pid_t pid; + + if (!gpg) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!gpg->file_name && !_gpgme_get_gpg_path ()) + return gpg_error (GPG_ERR_INV_ENGINE); + + if (gpg->lc_ctype) + { + rc = add_arg_ext (gpg, gpg->lc_ctype, 1); + if (!rc) + rc = add_arg_ext (gpg, "--lc-ctype", 1); + if (rc) + return rc; + } + + if (gpg->lc_messages) + { + rc = add_arg_ext (gpg, gpg->lc_messages, 1); + if (!rc) + rc = add_arg_ext (gpg, "--lc-messages", 1); + if (rc) + return rc; + } + + rc = build_argv (gpg); + if (rc) + return rc; + + /* status_fd, colon_fd and end of list. */ + n = 3; + for (i = 0; gpg->fd_data_map[i].data; i++) + n++; + fd_list = calloc (n, sizeof *fd_list); + if (! fd_list) + return gpg_error_from_errno (errno); + + /* Build the fd list for the child. */ + n = 0; + fd_list[n].fd = gpg->status.fd[1]; + fd_list[n].dup_to = -1; + fd_list[n].arg_loc = gpg->status.arg_loc; + n++; + if (gpg->colon.fnc) + { + fd_list[n].fd = gpg->colon.fd[1]; + fd_list[n].dup_to = 1; + n++; + } + for (i = 0; gpg->fd_data_map[i].data; i++) + { + fd_list[n].fd = gpg->fd_data_map[i].peer_fd; + fd_list[n].dup_to = gpg->fd_data_map[i].dup_to; + fd_list[n].arg_loc = gpg->fd_data_map[i].arg_loc; + n++; + } + fd_list[n].fd = -1; + fd_list[n].dup_to = -1; + + status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name : + _gpgme_get_gpg_path (), gpg->argv, fd_list, &pid); + saved_errno = errno; + + free (fd_list); + if (status == -1) + return gpg_error_from_errno (saved_errno); + + /*_gpgme_register_term_handler ( closure, closure_value, pid );*/ + + rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg, + &gpg->status.tag); + if (rc) + /* FIXME: kill the child */ + return rc; + + if (gpg->colon.fnc) + { + assert (gpg->colon.fd[0] != -1); + rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg, + &gpg->colon.tag); + if (rc) + /* FIXME: kill the child */ + return rc; + } + + for (i = 0; gpg->fd_data_map[i].data; i++) + { + if (gpg->cmd.used && i == gpg->cmd.idx) + { + /* Park the cmd fd. */ + gpg->cmd.fd = gpg->fd_data_map[i].fd; + gpg->fd_data_map[i].fd = -1; + } + else + { + rc = add_io_cb (gpg, gpg->fd_data_map[i].fd, + gpg->fd_data_map[i].inbound, + gpg->fd_data_map[i].inbound + ? _gpgme_data_inbound_handler + : _gpgme_data_outbound_handler, + gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag); + + if (rc) + /* FIXME: kill the child */ + return rc; + } + } + + _gpgme_allow_set_foregound_window (pid); + + gpg_io_event (gpg, GPGME_EVENT_START, NULL); + + /* fixme: check what data we can release here */ + return 0; +} + + +static gpgme_error_t +gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain) +{ + engine_gpg_t gpg = engine; + gpgme_error_t err; + + err = add_arg (gpg, "--decrypt"); + + /* Tell the gpg object about the data. */ + if (!err) + err = add_arg (gpg, "--output"); + if (!err) + err = add_arg (gpg, "-"); + if (!err) + err = add_data (gpg, plain, 1, 1); + if (!err) + err = add_arg (gpg, "--"); + if (!err) + err = add_data (gpg, ciph, -1, 0); + + if (!err) + start (gpg); + return err; +} + +static gpgme_error_t +gpg_delete (void *engine, gpgme_key_t key, int allow_secret) +{ + engine_gpg_t gpg = engine; + gpgme_error_t err; + + err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key" + : "--delete-key"); + if (!err) + err = add_arg (gpg, "--"); + if (!err) + { + if (!key->subkeys || !key->subkeys->fpr) + return gpg_error (GPG_ERR_INV_VALUE); + else + err = add_arg (gpg, key->subkeys->fpr); + } + + if (!err) + start (gpg); + return err; +} + + +static gpgme_error_t +append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */) +{ + gpgme_error_t err = 0; + int i; + gpgme_key_t key; + + for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++) + { + const char *s = key->subkeys ? key->subkeys->keyid : NULL; + if (s) + { + if (!err) + err = add_arg (gpg, "-u"); + if (!err) + err = add_arg (gpg, s); + } + gpgme_key_unref (key); + if (err) break; + } + return err; +} + + +static gpgme_error_t +append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */) +{ + gpgme_error_t err = 0; + gpgme_sig_notation_t notation; + + notation = gpgme_sig_notation_get (ctx); + + while (!err && notation) + { + if (notation->name + && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE)) + err = gpg_error (GPG_ERR_INV_VALUE); + else if (notation->name) + { + char *arg; + + /* Maximum space needed is one byte for the "critical" flag, + the name, one byte for '=', the value, and a terminating + '\0'. */ + + arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1); + if (!arg) From cvs at cvs.gnupg.org Mon Jan 19 17:15:34 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 19 Jan 2009 17:15:34 +0100 Subject: [svn] GnuPG - r4919 - in trunk: common po Message-ID: Author: wk Date: 2009-01-19 17:15:30 +0100 (Mon, 19 Jan 2009) New Revision: 4919 Modified: trunk/common/ChangeLog trunk/common/audit.c trunk/common/convert.c trunk/po/ChangeLog trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po Log: Add a few translations to the audit-log. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-01-13 14:01:56 UTC (rev 4918) +++ trunk/common/ChangeLog 2009-01-19 16:15:30 UTC (rev 4919) @@ -1,3 +1,10 @@ +2009-01-19 Werner Koch + + * audit.c (writeout_li): Translate a few more result strings. + Fixes bug#970. + + * convert.c (hex2str): Fix optimization to append a nul character. + 2008-12-05 Werner Koch * percent.c, t-percent.c: New. @@ -1309,7 +1316,7 @@ Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008 Free Software Foundation, Inc. + 2008, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2009-01-13 14:01:56 UTC (rev 4918) +++ trunk/po/ChangeLog 2009-01-19 16:15:30 UTC (rev 4919) @@ -1,3 +1,7 @@ +2009-01-19 Werner Koch + + * de.po: Translated a few new audit-log related strings. + 2009-01-12 Maxim Britov (wk) * ru.po: Update. Modified: trunk/common/audit.c =================================================================== --- trunk/common/audit.c 2009-01-13 14:01:56 UTC (rev 4918) +++ trunk/common/audit.c 2009-01-19 16:15:30 UTC (rev 4919) @@ -451,18 +451,42 @@ if (ctx->use_html && format && oktext) { - if (!strcmp (oktext, "Yes")) + if (!strcmp (oktext, "Yes") + || !strcmp (oktext, "good") ) color = "green"; - else if (!strcmp (oktext, "No")) + else if (!strcmp (oktext, "No") + || !strcmp (oktext, "bad") ) color = "red"; } if (format && oktext) { + const char *s = NULL; + if (!strcmp (oktext, "Yes")) oktext = _("Yes"); else if (!strcmp (oktext, "No")) oktext = _("No"); + else if (!strcmp (oktext, "good")) + { + /* TRANSLATORS: Copy the prefix between the vertical bars + verbatim. It will not be printed. */ + oktext = _("|audit-log-result|Good"); + } + else if (!strcmp (oktext, "bad")) + oktext = _("|audit-log-result|Bad"); + else if (!strcmp (oktext, "unsupported")) + oktext = _("|audit-log-result|Not supported"); + else if (!strcmp (oktext, "no-cert")) + oktext = _("|audit-log-result|No certificate"); + else if (!strcmp (oktext, "error")) + oktext = _("|audit-log-result|Error"); + else + s = ""; + + /* If we have set a prefix, skip it. */ + if (!s && *oktext == '|' && (s=strchr (oktext+1,'|'))) + oktext = s+1; } if (ctx->use_html) Modified: trunk/common/convert.c =================================================================== --- trunk/common/convert.c 2009-01-13 14:01:56 UTC (rev 4918) +++ trunk/common/convert.c 2009-01-19 16:15:30 UTC (rev 4919) @@ -194,7 +194,9 @@ ; if (*s && (!isascii (*s) || !isspace (*s)) ) return NULL; /* Not followed by Nul or white space. */ - need_nul = !(s[-2] == '0' && s[-1] == '0'); + /* We need to append a nul character. However we don't want that if + the hexstring already ends with "00". */ + need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0')); if (need_nul) count++; Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Tue Jan 20 20:24:25 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 20 Jan 2009 20:24:25 +0100 Subject: [svn] GnuPG - r4920 - in trunk: doc jnlib po tools Message-ID: Author: wk Date: 2009-01-20 20:24:24 +0100 (Tue, 20 Jan 2009) New Revision: 4920 Modified: trunk/doc/tools.texi trunk/jnlib/stringhelp.c trunk/po/de.po trunk/tools/ChangeLog trunk/tools/gpgconf.c Log: Print more directories with gpgconf --list-dirs. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-01-19 16:15:30 UTC (rev 4919) +++ trunk/tools/ChangeLog 2009-01-20 19:24:24 UTC (rev 4920) @@ -1,3 +1,7 @@ +2009-01-20 Werner Koch + + * gpgconf.c (main): Print more directories. + 2008-12-09 Werner Koch * gpg-check-pattern.c (main): Call i18n_init before Modified: trunk/doc/tools.texi =================================================================== --- trunk/doc/tools.texi 2009-01-19 16:15:30 UTC (rev 4919) +++ trunk/doc/tools.texi 2009-01-20 19:24:24 UTC (rev 4920) @@ -239,10 +239,13 @@ @item --list-dirs Lists the directories used by @command{gpgconf}. One directory is -listed per line, and each line consists of a colon-separated list -where the first field names the directory type (for example - at code{sysconfdir}) and the second field contains the percent-escaped -directory. +listed per line, and each line consists of a colon-separated list where +the first field names the directory type (for example @code{sysconfdir}) +and the second field contains the percent-escaped directory. Although +they are not directories, the socket file names used by + at command{gpg-agent} and @command{dirmngr} are printed as well. Note +that the socket file names and the @code{homedir} lines are the default +names and they may be overridden by command line switches. @item --list-config [@var{filename}] List the global configuration file in a colon separated format. If Modified: trunk/jnlib/stringhelp.c =================================================================== --- trunk/jnlib/stringhelp.c 2009-01-19 16:15:30 UTC (rev 4919) +++ trunk/jnlib/stringhelp.c 2009-01-20 19:24:24 UTC (rev 4920) @@ -314,8 +314,8 @@ /* Implementation of make_filename and make_filename_try. We need to - use macros here toa void the use of the soemtimes problematic - va_copy fucntion which is not available on all systems. */ + use macros here to avoid the use of the sometimes problematic + va_copy function which is not available on all systems. */ #define MAKE_FILENAME_PART1 \ va_list arg_ptr; \ size_t n; \ Modified: trunk/po/de.po [not shown] Modified: trunk/tools/gpgconf.c =================================================================== --- trunk/tools/gpgconf.c 2009-01-19 16:15:30 UTC (rev 4919) +++ trunk/tools/gpgconf.c 2009-01-20 19:24:24 UTC (rev 4920) @@ -258,12 +258,51 @@ break; case aListDirs: - /* Show the system configuration directory for gpgconf. */ + /* Show the system configuration directories for gpgconf. */ get_outfp (&outfp); fprintf (outfp, "sysconfdir:%s\n", gc_percent_escape (gnupg_sysconfdir ())); fprintf (outfp, "bindir:%s\n", gc_percent_escape (gnupg_bindir ())); + fprintf (outfp, "libexecdir:%s\n", + gc_percent_escape (gnupg_libexecdir ())); + fprintf (outfp, "libdir:%s\n", + gc_percent_escape (gnupg_libdir ())); + fprintf (outfp, "datadir:%s\n", + gc_percent_escape (gnupg_datadir ())); + fprintf (outfp, "localedir:%s\n", + gc_percent_escape (gnupg_localedir ())); + fprintf (outfp, "dirmngr-socket:%s\n", + gc_percent_escape (dirmngr_socket_name ())); + { + char *infostr = getenv ("GPG_AGENT_INFO"); + + if (!infostr || !*infostr) + infostr = make_filename (default_homedir (), "S.gpg-agent", NULL); + else + { + char *tmp; + + infostr = xstrdup (infostr); + tmp = strchr (infostr, PATHSEP_C); + if (!tmp || tmp == infostr) + { + xfree (infostr); + infostr = NULL; + } + else + *tmp = 0; + } + fprintf (outfp, "agent-socket:%s\n", + infostr? gc_percent_escape (infostr) : ""); + xfree (infostr); + } + { + /* We need to use make_filename to expand a possible "~/". */ + char *tmp = make_filename (default_homedir (), NULL); + fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp)); + xfree (tmp); + } break; } From cvs at cvs.gnupg.org Wed Jan 21 18:46:55 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 21 Jan 2009 18:46:55 +0100 Subject: [svn] gcry - r1376 - in trunk: cipher doc tests Message-ID: Author: wk Date: 2009-01-21 18:46:55 +0100 (Wed, 21 Jan 2009) New Revision: 1376 Modified: trunk/cipher/ChangeLog trunk/cipher/rmd160.c trunk/doc/gcrypt.texi trunk/tests/ChangeLog trunk/tests/cavs_driver.pl trunk/tests/fipsdrv.c trunk/tests/pubkey.c Log: Fix for dsa signature verifciation in fipsdrv. Other small changes. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/cipher/ChangeLog 2009-01-21 17:46:55 UTC (rev 1376) @@ -1,3 +1,7 @@ +2009-01-06 Werner Koch + + * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier. + 2008-12-10 Werner Koch * dsa.c (generate): Add arg DOMAIN and use it if specified. @@ -3881,7 +3885,7 @@ Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006 - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/tests/ChangeLog 2009-01-21 17:46:55 UTC (rev 1376) @@ -1,3 +1,10 @@ +2009-01-21 Werner Koch + + * fipsdrv.c (run_dsa_verify): Use hash of the data. + + * pubkey.c (get_dsa_key_fips186_with_seed_new): New. + (check_run): Call it. + 2008-12-11 Werner Koch * fipsdrv.c (run_rsa_derive): New. Modified: trunk/cipher/rmd160.c =================================================================== --- trunk/cipher/rmd160.c 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/cipher/rmd160.c 2009-01-21 17:46:55 UTC (rev 1376) @@ -559,7 +559,9 @@ { /* rsaSignatureWithripemd160 */ { "1.3.36.3.3.1.2" }, - { NULL }, + /* TeleTrust hash algorithm. */ + { "1.3.36.3.2.1" }, + { NULL } }; gcry_md_spec_t _gcry_digest_spec_rmd160 = Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/doc/gcrypt.texi 2009-01-21 17:46:55 UTC (rev 1376) @@ -2789,8 +2789,8 @@ @item use-fips186-2 Force the use of the FIPS 186-2 key generation algorithm instead of -the default algorithm. This algorithm has a slighlty different from -FIPS 186-3 and allws only 1024 bit keys. This flag is only meaningful +the default algorithm. This algorithm is slighlty different from +FIPS 186-3 and allows only 1024 bit keys. This flag is only meaningful for DSA and only required for FIPS testing backward compatibility. Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/tests/cavs_driver.pl 2009-01-21 17:46:55 UTC (rev 1376) @@ -1,6 +1,6 @@ #!/usr/bin/env perl # -# $Id: cavs_driver.pl 1395 2008-11-10 15:18:03Z smueller $ +# $Id: cavs_driver.pl 1488 2009-01-16 14:29:00Z smueller $ # # CAVS test driver (based on the OpenSSL driver) # Written by: Stephan M?ller @@ -138,21 +138,20 @@ # # Derive an RSA key from the given X9.31 parameters. # $1: modulus size -# $2: E in hex form -# $3: Xp1 in hex form -# $4: Xp2 in hex form -# $5: Xp in hex form -# $6: Xq1 in hex form -# $7: Xq2 in hex form -# $8: Xq in hex form +# $2: E in hex form +# $3: Xp1 in hex form +# $4: Xp2 in hex form +# $5: Xp in hex form +# $6: Xq1 in hex form +# $7: Xq2 in hex form +# $8: Xq in hex form # return: string with the calculated values in hex format, where each value -# is separated from the previous with a \n in the following order: +# is separated from the previous with a \n in the following order: # P\n # Q\n # D\n my $rsa_derive; - # Sign a message with RSA # $1: data to be signed in hex form # $2: Hash algo @@ -241,10 +240,9 @@ # $2: P in hex form # $3: Q in hex form # $4: G in hex form -# $5: Y in hex form +# $5: Y in hex form my $dsa_genpubkey; - # Verify a message with DSA # $1: data to be verified in hex form # $2: file holding the public DSA key in PEM format @@ -378,31 +376,32 @@ sub libgcrypt_rsa_derive($$$$$$$$) { my $n = shift; - my $e = shift; - my $xp1 = shift; - my $xp2 = shift; - my $xp = shift; - my $xq1 = shift; - my $xq2 = shift; - my $xq = shift; - my $sexp; - my @tmp; + my $e = shift; + my $xp1 = shift; + my $xp2 = shift; + my $xp = shift; + my $xq1 = shift; + my $xq2 = shift; + my $xq = shift; + my $sexp; + my @tmp; - $n = sprintf ("%u", $n); - $e = sprintf ("%u", hex($e)); - $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" - . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")" - . "(derive-parms" - . "(Xp1 #$xp1#)" - . "(Xp2 #$xp2#)" - . "(Xp #$xp#)" - . "(Xq1 #$xq1#)" - . "(Xq2 #$xq2#)" - . "(Xq #$xq#))))\n"; + $n = sprintf ("%u", $n); + $e = sprintf ("%u", hex($e)); + $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" + . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")" + . "(derive-parms" + . "(Xp1 #$xp1#)" + . "(Xp2 #$xp2#)" + . "(Xp #$xp#)" + . "(Xq1 #$xq1#)" + . "(Xq2 #$xq2#)" + . "(Xq #$xq#))))\n"; - return pipe_through_program($sexp, "fipsdrv rsa-derive"); + return pipe_through_program($sexp, "fipsdrv rsa-derive"); } + sub libgcrypt_rsa_sign($$$) { my $data = shift; my $hashalgo = shift; @@ -510,16 +509,16 @@ my $file = shift; my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; - my $tmp; - my %ret; + my $tmp; + my %ret; die "ARCFOUR not available for DSA" if $opt{'R'}; - $tmp = pipe_through_program("", $program); + $tmp = pipe_through_program("", $program); die "dsa key gen failed: file $file not created" if (! -f $file); - @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); - return %ret; + @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); + return %ret; } sub libgcrypt_dsa_genpubkey($$$$$) { @@ -529,26 +528,26 @@ my $g = shift; my $y = shift; - my $sexp; + my $sexp; - $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))"; + $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))"; open(FH, ">", $filename) or die; print FH $sexp; - close FH; + close FH; } sub libgcrypt_dsa_sign($$) { my $data = shift; my $keyfile = shift; - my $tmp; - my %ret; - + my $tmp; + my %ret; + die "ARCFOUR not available for DSA" if $opt{'R'}; $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign"); - @ret{'Y', 'R', 'S'} = split(/\n/, $tmp); - return %ret; + @ret{'Y', 'R', 'S'} = split(/\n/, $tmp); + return %ret; } sub libgcrypt_dsa_verify($$$$) { @@ -556,25 +555,23 @@ my $keyfile = shift; my $r = shift; my $s = shift; - - my $ret; + my $ret; + die "ARCFOUR not available for DSA" if $opt{'R'}; my $sigfile = "$keyfile.sig"; open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; - print FH "(sig-val(dsa(r #$r)(s #$s#)))"; + print FH "(sig-val(dsa(r #$r#)(s #$s#)))"; close FH; - $ret = pipe_through_program($data, - "fipsdrv --verbose --key $keyfile --signature $sigfile dsa-verify"); - unlink ($sigfile); + $ret = pipe_through_program($data, + "fipsdrv --verbose --key $keyfile --signature $sigfile dsa-verify"); + unlink ($sigfile); # Parse through the output information return ($ret =~ /GOOD signature/); } - - ######### End of libgcrypt implementation ################ ################################################################ @@ -1216,10 +1213,14 @@ # TDES inner loop implements logic within driver if ($cipher =~ /des/) { + # Need to provide a dummy IV in case of ECB mode. + my $iv_arg = (defined($iv) && $iv ne "") + ? bin2hex($iv) + : "00"x(length($source_data)); print $CI "1\n" .$iloop."\n" .bin2hex($key1)."\n" - .bin2hex($iv)."\n" + .$iv_arg."\n" .bin2hex($source_data)."\n\n" or die; chomp(my $line = <$CO>); $calc_data = hex2bin($line); @@ -1228,7 +1229,7 @@ chomp($line = <$CO>); $old_old_calc_data = hex2bin($line); chomp($line = <$CO>); - $iv = hex2bin($line); + $iv = hex2bin($line) if (defined($iv) && $iv ne ""); chomp($line = <$CO>); $next_source = hex2bin($line); # Skip over empty line. @@ -1309,13 +1310,13 @@ } elsif (!$enc && $cipher =~ /des-ede3-cfb/) { #TDES decryption CFB has a special rule $source_data = $next_source; + } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) { + #No resetting of IV as the IV is all zero set initially (i.e. no IV) + $source_data = $calc_data; } elsif (! $enc && $ciph =~ /des/ ) { #TDES in decryption mode has a special rule $iv = $old_calc_data; $source_data = $calc_data; - } elsif ( $ciph =~ /rc4/ || $cipher =~ /ecb/ ) { - #No resetting of IV as the IV is all zero set initially (i.e. no IV) - $source_data = $calc_data; } else { $iv = $calc_data; $source_data = $old_calc_data; @@ -1539,7 +1540,7 @@ # but since it is not run on a security sensitive # system, I hope that this is fine my $keyfile = "dsa_sigver.tmp.$$"; - &dsa_genpubkey($keyfile, $p, $q, $g, $y); + &$dsa_genpubkey($keyfile, $p, $q, $g, $y); $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n"); @@ -1614,7 +1615,6 @@ my $capital_g = ""; my $capital_y = ""; my $capital_r = ""; - my $capital_s = ""; my $mode = ""; @@ -1696,7 +1696,7 @@ ##### Identify the test type if ($tmpline =~ /SigVer/ && $opt{'D'} ) { $tt = 12; - die "Interface function dsa_verify or dsa_genpubey for dSA verification not defined for tested library" + die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library" if (!defined($dsa_verify) || !defined($dsa_genpubkey)); } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { $tt = 11; @@ -1873,44 +1873,39 @@ if ($tlen ne ""); $tlen=$1; } - elsif ($line =~ /^N\s*=\s*(.)/) { #DSA PQGGen + elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen die "N seen twice - check input file" if ($capital_n); $capital_n = $1; } - elsif ($line =~ /^P\s*=\s*(.)/) { #DSA SigVer + elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer die "P seen twice - check input file" if ($capital_p); $capital_p = $1; $out .= $line . "\n"; # print it } - elsif ($line =~ /^Q\s*=\s*(.)/) { #DSA SigVer + elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer die "Q seen twice - check input file" if ($capital_q); $capital_q = $1; $out .= $line . "\n"; # print it } - elsif ($line =~ /^G\s*=\s*(.)/) { #DSA SigVer + elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer die "G seen twice - check input file" if ($capital_g); $capital_g = $1; $out .= $line . "\n"; # print it } - elsif ($line =~ /^Y\s*=\s*(.)/) { #DSA SigVer + elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer die "Y seen twice - check input file" if ($capital_y); $capital_y = $1; } - elsif ($line =~ /^R\s*=\s*(.)/) { #DSA SigVer + elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer die "R seen twice - check input file" if ($capital_r); $capital_r = $1; } - elsif ($line =~ /^S\s*=\s*(.)/) { #DSA SigVer - die "S seen twice - check input file" - if ($capital_s); - $capital_s = $1; - } else { $out .= $line . "\n"; } @@ -2009,7 +2004,7 @@ $capital_g ne "" && $capital_y ne "" && $capital_r ne "" && - $capital_s ne "" && + $signature ne "" && $pt ne "") { $out .= dsa_sigver($modulus, $capital_p, @@ -2017,7 +2012,7 @@ $capital_g, $capital_y, $capital_r, - $capital_s, + $signature, $pt); # We do not clear the domain values PQG and @@ -2027,7 +2022,7 @@ # are already printed above $capital_y = ""; $capital_r = ""; - $capital_s = ""; + $signature = ""; $pt = ""; } } @@ -2051,7 +2046,8 @@ unlink("rsa_sigver.tmp.$$.sig"); unlink("rsa_sigver.tmp.$$.der"); unlink("rsa_sigver.tmp.$$.cnf"); - + unlink("dsa_siggen.tmp.$$"); + unlink("dsa_sigver.tmp.$$"); unlink("dsa_sigver.tmp.$$.sig"); exit; } @@ -2087,10 +2083,10 @@ $state_rng = \&libgcrypt_state_rng; $hmac = \&libgcrypt_hmac; $dsa_pqggen = \&libgcrypt_dsa_pqggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; + $gen_dsakey = \&libgcrypt_gen_dsakey; + $dsa_sign = \&libgcrypt_dsa_sign; + $dsa_verify = \&libgcrypt_dsa_verify; + $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; } else { die "Invalid interface option given"; } @@ -2121,8 +2117,6 @@ # Do the job parse($infile, $outfile); - unlink("rsa_siggen.tmp.$$"); - } ########################################### Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/tests/fipsdrv.c 2009-01-21 17:46:55 UTC (rev 1376) @@ -1915,15 +1915,11 @@ { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig; - gcry_mpi_t tmpmpi; + char hash[20]; - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, data, datalen, NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, - "(data (flags raw)(value %m))", tmpmpi); - gcry_mpi_release (tmpmpi); - } + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %b))", 20, hash); if (err) die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); Modified: trunk/tests/pubkey.c =================================================================== --- trunk/tests/pubkey.c 2008-12-11 15:07:41 UTC (rev 1375) +++ trunk/tests/pubkey.c 2009-01-21 17:46:55 UTC (rev 1376) @@ -505,6 +505,46 @@ static void +get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + "(genkey" + " (dsa" + " (nbits 4:1024)" + " (use-fips186)" + " (transient-key)" + " (derive-parms" + " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1 || 1) + show_sexp ("generated DSA key (fips 186 with seed):\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void check_run (void) { gpg_error_t err; @@ -592,6 +632,13 @@ /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n"); + get_dsa_key_fips186_with_seed_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); } From cvs at cvs.gnupg.org Wed Jan 21 19:05:24 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 21 Jan 2009 19:05:24 +0100 Subject: [svn] gcry - r1377 - trunk/tests Message-ID: Author: wk Date: 2009-01-21 19:05:24 +0100 (Wed, 21 Jan 2009) New Revision: 1377 Modified: trunk/tests/ChangeLog trunk/tests/fipsdrv.c Log: Fix last change. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-01-21 17:46:55 UTC (rev 1376) +++ trunk/tests/ChangeLog 2009-01-21 18:05:24 UTC (rev 1377) @@ -1,5 +1,7 @@ 2009-01-21 Werner Koch + * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again. + * fipsdrv.c (run_dsa_verify): Use hash of the data. * pubkey.c (get_dsa_key_fips186_with_seed_new): New. Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2009-01-21 17:46:55 UTC (rev 1376) +++ trunk/tests/fipsdrv.c 2009-01-21 18:05:24 UTC (rev 1377) @@ -1916,10 +1916,18 @@ gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig; char hash[20]; - + gcry_mpi_t tmpmpi; + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); - err = gcry_sexp_build (&s_data, NULL, - "(data (flags raw)(value %b))", 20, hash); + /* Note that we can't simply use %b with HASH to build the + S-expression, because that might yield a negative value. */ + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmpmpi); + gcry_mpi_release (tmpmpi); + } if (err) die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); From cvs at cvs.gnupg.org Wed Jan 21 19:44:57 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 21 Jan 2009 19:44:57 +0100 Subject: [svn] gcry - r1378 - trunk/tests Message-ID: Author: wk Date: 2009-01-21 19:44:57 +0100 (Wed, 21 Jan 2009) New Revision: 1378 Modified: trunk/tests/ChangeLog trunk/tests/cavs_driver.pl trunk/tests/fipsdrv.c Log: print N value for rsa-derive. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-01-21 18:05:24 UTC (rev 1377) +++ trunk/tests/ChangeLog 2009-01-21 18:44:57 UTC (rev 1378) @@ -1,6 +1,7 @@ 2009-01-21 Werner Koch * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again. + (run_rsa_derive): Also print N. * fipsdrv.c (run_dsa_verify): Use hash of the data. Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2009-01-21 18:05:24 UTC (rev 1377) +++ trunk/tests/cavs_driver.pl 2009-01-21 18:44:57 UTC (rev 1378) @@ -149,6 +149,7 @@ # is separated from the previous with a \n in the following order: # P\n # Q\n +# N\ # D\n my $rsa_derive; Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2009-01-21 18:05:24 UTC (rev 1377) +++ trunk/tests/fipsdrv.c 2009-01-21 18:44:57 UTC (rev 1378) @@ -1282,7 +1282,7 @@ /* Derive an RSA key using the S-expression in (DATA,DATALEN). This S-expression is used directly as input to gcry_pk_genkey. The result is printed to stdout with one parameter per line in hex - format and in this order: p, q, d. */ + format and in this order: p, q, n, d. */ static void run_rsa_derive (const void *data, size_t datalen) { @@ -1308,13 +1308,13 @@ /* P and Q might have been swapped but we need to to return them in the proper order. Build the parameter list accordingly. */ - parmlist = "pqd"; + parmlist = "pqnd"; s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0); if (s_top) { l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0); if (l1) - parmlist = "qpd"; + parmlist = "qpnd"; gcry_sexp_release (l1); gcry_sexp_release (s_top); } From cvs at cvs.gnupg.org Thu Jan 22 11:38:22 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 11:38:22 +0100 Subject: [svn] gcry - r1379 - trunk/tests Message-ID: Author: wk Date: 2009-01-22 11:38:22 +0100 (Thu, 22 Jan 2009) New Revision: 1379 Modified: trunk/tests/ChangeLog trunk/tests/cavs_driver.pl trunk/tests/fipsdrv.c trunk/tests/pubkey.c Log: Six DSA sign test. Add stuff to help debugging. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-01-21 18:44:57 UTC (rev 1378) +++ trunk/tests/ChangeLog 2009-01-22 10:38:22 UTC (rev 1379) @@ -1,3 +1,13 @@ +2009-01-22 Werner Koch + + * fipsdrv.c (run_dsa_sign): Use hash of the data. + (dsa_gen_with_seed): New. + (run_dsa_pqg_gen): Add args SEED and SEEDLEN and use them. + (main): Optically take a seed for dsa-pgq-gen. + (standalone_mode): New. + (main): Add option --standalone. + (print_dsa_domain_parameters): Implement standalone mode. + 2009-01-21 Werner Koch * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again. Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2009-01-21 18:44:57 UTC (rev 1378) +++ trunk/tests/cavs_driver.pl 2009-01-22 10:38:22 UTC (rev 1379) @@ -1,6 +1,6 @@ #!/usr/bin/env perl # -# $Id: cavs_driver.pl 1488 2009-01-16 14:29:00Z smueller $ +# $Id: cavs_driver.pl 1494 2009-01-21 19:30:16Z smueller $ # # CAVS test driver (based on the OpenSSL driver) # Written by: Stephan M?ller @@ -65,6 +65,7 @@ # SigVer15 # (SigVerRSA is not applicable for OpenSSL as X9.31 padding # is not done through openssl dgst) +# KeyGen RSA X9.31 # # SHA # SHA[1|224|256|384|512]ShortMsg @@ -149,7 +150,7 @@ # is separated from the previous with a \n in the following order: # P\n # Q\n -# N\ +# N\n # D\n my $rsa_derive; @@ -567,7 +568,7 @@ close FH; $ret = pipe_through_program($data, - "fipsdrv --verbose --key $keyfile --signature $sigfile dsa-verify"); + "fipsdrv --key $keyfile --signature $sigfile dsa-verify"); unlink ($sigfile); # Parse through the output information return ($ret =~ /GOOD signature/); @@ -1418,6 +1419,48 @@ return $out; } +# RSA X9.31 key generation test +# $1 modulus size +# $2 e +# $3 xp1 +# $4 xp2 +# $5 Xp +# $6 xq1 +# $7 xq2 +# $8 Xq +# return: string formatted as expected by CAVS +sub rsa_keygen($$$$$$$$) { + my $modulus = shift; + my $e = shift; + my $xp1 = shift; + my $xp2 = shift; + my $Xp = shift; + my $xq1 = shift; + my $xq2 = shift; + my $Xq = shift; + + my $out = ""; + + my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq); + + my ($P, $Q, $N, $D) = split(/\n/, $ret); + + $out .= "e = $e\n"; + $out .= "xp1 = $xp1\n"; + $out .= "xp2 = $xp2\n"; + $out .= "Xp = $Xp\n"; + $out .= "p = $P\n"; + $out .= "xq1 = $xq1\n"; + $out .= "xq2 = $xq2\n"; + $out .= "Xq = $Xq\n"; + $out .= "q = $Q\n"; + $out .= "n = $N\n"; + $out .= "d = $D\n\n"; + + return $out; + +} + # X9.31 RNG test # $1 key for the AES cipher # $2 DT value @@ -1616,6 +1659,12 @@ my $capital_g = ""; my $capital_y = ""; my $capital_r = ""; + my $xp1 = ""; + my $xp2 = ""; + my $Xp = ""; + my $xq1 = ""; + my $xq2 = ""; + my $Xq = ""; my $mode = ""; @@ -1646,7 +1695,7 @@ ##### Extract cipher # XXX there may be more - to be added - if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen)/) { + if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { if ($tmpline =~ /CBC/) { $mode="cbc"; } elsif ($tmpline =~ /ECB/) { $mode="ecb"; } elsif ($tmpline =~ /OFB/) { $mode="ofb"; } @@ -1695,7 +1744,11 @@ if ($tt == 0) { ##### Identify the test type - if ($tmpline =~ /SigVer/ && $opt{'D'} ) { + if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { + $tt = 13; + die "Interface function rsa_derive for RSA key generation not defined for tested library" + if (!defined($rsa_derive)); + } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) { $tt = 12; die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library" if (!defined($dsa_verify) || !defined($dsa_genpubkey)); @@ -1907,6 +1960,36 @@ if ($capital_r); $capital_r = $1; } + elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen + die "xp1 seen twice - check input file" + if ($xp1); + $xp1 = $1; + } + elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen + die "xp2 seen twice - check input file" + if ($xp2); + $xp2 = $1; + } + elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen + die "Xp seen twice - check input file" + if ($Xp); + $Xp = $1; + } + elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen + die "xq1 seen twice - check input file" + if ($xq1); + $xq1 = $1; + } + elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen + die "xq2 seen twice - check input file" + if ($xq2); + $xq2 = $1; + } + elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen + die "Xq seen twice - check input file" + if ($Xq); + $Xq = $1; + } else { $out .= $line . "\n"; } @@ -2027,6 +2110,32 @@ $pt = ""; } } + elsif ($tt == 13) { + if($modulus ne "" && + $e ne "" && + $xp1 ne "" && + $xp2 ne "" && + $Xp ne "" && + $xq1 ne "" && + $xq2 ne "" && + $Xq ne "") { + $out .= rsa_keygen($modulus, + $e, + $xp1, + $xp2, + $Xp, + $xq1, + $xq2, + $Xq); + $e = ""; + $xp1 = ""; + $xp2 = ""; + $Xp = ""; + $xq1 = ""; + $xq2 = ""; + $Xq = ""; + } + } elsif ($tt > 0) { die "Test case $tt not defined"; } @@ -2078,6 +2187,7 @@ $rsa_sign = \&libgcrypt_rsa_sign; $rsa_verify = \&libgcrypt_rsa_verify; $gen_rsakey = \&libgcrypt_gen_rsakey; + $rsa_derive = \&libgcrypt_rsa_derive; $hash = \&libgcrypt_hash; $state_cipher = \&libgcrypt_state_cipher; $state_cipher_des = \&libgcrypt_state_cipher_des; Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2009-01-21 18:44:57 UTC (rev 1378) +++ trunk/tests/fipsdrv.c 2009-01-22 10:38:22 UTC (rev 1379) @@ -76,10 +76,14 @@ /* Base64 output flag. */ static int base64_output; -/* We need to know whetehr we are in loop_mode. */ +/* We need to know whether we are in loop_mode. */ static int loop_mode; +/* If true some functions are modified to print the output in the CAVS + response file format. */ +static int standalone_mode; + /* ASN.1 classes. */ enum { @@ -890,7 +894,7 @@ p = buf; if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p +=2; + p += 2; printf ("%s\n", p); if (ferror (stdout)) @@ -1693,6 +1697,36 @@ } +/* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ +static gcry_sexp_t +dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) +{ + gpg_error_t err; + gcry_sexp_t keyspec, key; + + err = gcry_sexp_build (&keyspec, NULL, + "(genkey" + " (dsa" + " (nbits %d)" + " (use-fips186-2)" + " (derive-parms" + " (seed %b))))", + keysize, (int)seedlen, seed); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); + + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (keyspec); + + return key; +} + + /* Print the domain parameter as well as the derive information. KEY is the complete key as returned by dsa_gen. We print to stdout with one parameter per line in hex format using this order: p, q, @@ -1727,6 +1761,8 @@ if (!mpi) die ("no value for %c parameter in returned public key\n","pqg"[idx]); gcry_sexp_release (l2); + if (standalone_mode) + printf ("%c = ", "PQG"[idx]); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); } @@ -1749,6 +1785,8 @@ data = gcry_sexp_nth_data (l2, 1, &datalen); if (!data) die ("no seed value in returned key\n"); + if (standalone_mode) + printf ("Seed = "); print_data_line (data, datalen); gcry_sexp_release (l2); @@ -1758,7 +1796,10 @@ string = gcry_sexp_nth_string (l2, 1); if (!string) die ("no counter value in returned key\n"); - printf ("%lX\n", strtoul (string, NULL, 10)); + if (standalone_mode) + printf ("c = %ld\n", strtoul (string, NULL, 10)); + else + printf ("%lX\n", strtoul (string, NULL, 10)); gcry_free (string); gcry_sexp_release (l2); @@ -1768,6 +1809,8 @@ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); if (!mpi) die ("no h value in returned key\n"); + if (standalone_mode) + printf ("H = "); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); gcry_sexp_release (l2); @@ -1778,13 +1821,17 @@ /* Generate DSA domain parameters for a modulus size of KEYSIZE. The result is printed to stdout with one parameter per line in hex - format and in this order: p, q, g, seed, counter, h. */ + format and in this order: p, q, g, seed, counter, h. If SEED is + not NULL this seed value will be used for the generation. */ static void -run_dsa_pqg_gen (int keysize) +run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) { gcry_sexp_t key; - key = dsa_gen (keysize); + if (seed) + key = dsa_gen_with_seed (keysize, seed, seedlen); + else + key = dsa_gen (keysize); print_dsa_domain_parameters (key); gcry_sexp_release (key); } @@ -1825,9 +1872,11 @@ { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; + char hash[20]; gcry_mpi_t tmpmpi; - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, data, datalen, NULL); + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); if (!err) { err = gcry_sexp_build (&s_data, NULL, @@ -2121,6 +2170,11 @@ mct_server = 1; argc--; argv++; } + else if (!strcmp (*argv, "--standalone")) + { + standalone_mode = 1; + argc--; argv++; + } } if (!argc || argc > 2) @@ -2163,7 +2217,6 @@ && !mct_server && strcmp (mode_string, "random") && strcmp (mode_string, "rsa-gen") - && strcmp (mode_string, "dsa-pqg-gen") && strcmp (mode_string, "dsa-gen") ) { data = read_file (input, !binary_input, &datalen); @@ -2415,7 +2468,7 @@ keysize = keysize_string? atoi (keysize_string) : 0; if (keysize < 1024 || keysize > 3072) die ("invalid keysize specified; needs to be 1024 .. 3072\n"); - run_dsa_pqg_gen (keysize); + run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); } else if (!strcmp (mode_string, "dsa-gen")) { Modified: trunk/tests/pubkey.c =================================================================== --- trunk/tests/pubkey.c 2009-01-21 18:44:57 UTC (rev 1378) +++ trunk/tests/pubkey.c 2009-01-22 10:38:22 UTC (rev 1379) @@ -527,7 +527,7 @@ if (rc) die ("error generating DSA key: %s\n", gcry_strerror (rc)); - if (verbose > 1 || 1) + if (verbose > 1) show_sexp ("generated DSA key (fips 186 with seed):\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); From cvs at cvs.gnupg.org Thu Jan 22 12:51:22 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 12:51:22 +0100 Subject: [svn] gcry - r1380 - in trunk: . tests Message-ID: Author: wk Date: 2009-01-22 12:51:22 +0100 (Thu, 22 Jan 2009) New Revision: 1380 Modified: trunk/THANKS trunk/tests/ChangeLog trunk/tests/cavs_driver.pl trunk/tests/cavs_tests.sh Log: DSA Tweak for the CAVS test script Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-01-22 10:38:22 UTC (rev 1379) +++ trunk/tests/ChangeLog 2009-01-22 11:51:22 UTC (rev 1380) @@ -1,5 +1,7 @@ 2009-01-22 Werner Koch + * cavs_tests.sh: Pass option -D to driver if required. + * fipsdrv.c (run_dsa_sign): Use hash of the data. (dsa_gen_with_seed): New. (run_dsa_pqg_gen): Add args SEED and SEEDLEN and use them. Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-01-22 10:38:22 UTC (rev 1379) +++ trunk/THANKS 2009-01-22 11:51:22 UTC (rev 1380) @@ -119,6 +119,7 @@ Simon Josefsson jas at extundo.com SL Baur steve at xemacs.org Stephan Austermuehle au at hcsd.de +Stephan M?ller smueller at atsec com Stephane Corthesy stephane at sente.ch Stefan Karrmann S.Karrmann at gmx.net Stefan Keller dres at cs.tu-berlin.de Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2009-01-22 10:38:22 UTC (rev 1379) +++ trunk/tests/cavs_driver.pl 2009-01-22 11:51:22 UTC (rev 1380) @@ -1,6 +1,6 @@ #!/usr/bin/env perl # -# $Id: cavs_driver.pl 1494 2009-01-21 19:30:16Z smueller $ +# $Id: cavs_driver.pl 1495 2009-01-22 10:47:13Z smueller $ # # CAVS test driver (based on the OpenSSL driver) # Written by: Stephan M?ller @@ -1518,6 +1518,11 @@ die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" if (!defined($P) || !defined($Q) || !defined($G) || !defined($Seed) || !defined($c) || !defined($H)); + + # now change the counter to decimal as CAVS wants decimal + # counter value although all other is HEX + $c = hex($c); + $out .= "P = $P\n"; $out .= "Q = $Q\n"; $out .= "G = $G\n"; Modified: trunk/tests/cavs_tests.sh =================================================================== --- trunk/tests/cavs_tests.sh 2009-01-22 10:38:22 UTC (rev 1379) +++ trunk/tests/cavs_tests.sh 2009-01-22 11:51:22 UTC (rev 1380) @@ -46,6 +46,7 @@ local rspfile local tmprspfile local respdir + local dflag="" tmprspfile=$(echo "$reqfile" | sed 's,.req$,.rsp,') rspfile=$(echo "$tmprspfile" | sed 's,/req/,/resp/,' ) @@ -53,8 +54,12 @@ [ -f "$tmprspfile" ] && rm "$tmprspfile" [ -d "$respdir" ] || mkdir "$respdir" [ -f "$rspfile" ] && rm "$rspfile" + + if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then + dflag="-D" + fi - if ./cavs_driver.pl -I libgcrypt "$reqfile"; then + if ./cavs_driver.pl -I libgcrypt $dflag "$reqfile"; then if [ -f "$tmprspfile" ]; then mv "$tmprspfile" "$rspfile" else @@ -119,7 +124,7 @@ if [ -f "$errors_seen_file" ]; then rm "$errors_seen_file" - echo "Error enountered - not packing up response file" >&2 + echo "Error encountered - not packing up response file" >&2 exit 1 fi From cvs at cvs.gnupg.org Thu Jan 22 16:06:28 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 16:06:28 +0100 Subject: [svn] assuan - r293 - in trunk: . src Message-ID: Author: wk Date: 2009-01-22 16:06:28 +0100 (Thu, 22 Jan 2009) New Revision: 293 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/src/assuan-connect.c Log: Tweak test for nanosleep. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-11-03 18:27:11 UTC (rev 292) +++ trunk/ChangeLog 2009-01-22 15:06:28 UTC (rev 293) @@ -1,3 +1,7 @@ +2009-01-22 Werner Koch + + * configure.ac: Check for nanoleep only in libc. + 2008-11-03 Marcus Brinkmann * tests/fdpassing.c (register_commands): Add missing initializer Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-11-03 18:27:11 UTC (rev 292) +++ trunk/NEWS 2009-01-22 15:06:28 UTC (rev 293) @@ -11,7 +11,7 @@ * Minor fixes. - * Build library for GNU/LInux as PIC. + * Build library for GNU/Linux as PIC. Noteworthy changes in version 1.0.4 (2007-12-12) Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-11-03 18:27:11 UTC (rev 292) +++ trunk/configure.ac 2009-01-22 15:06:28 UTC (rev 293) @@ -208,10 +208,21 @@ AM_CONDITIONAL(USE_DESCRIPTOR_PASSING, test "$use_descriptor_passing" = "yes") +# # Checks for library functions. +# +AC_CHECK_FUNCS([flockfile funlockfile]) -AC_CHECK_FUNCS([flockfile funlockfile nanosleep]) +# On some systems (e.g. Solaris) nanosleep requires linking to librl. +# Given that we use nanosleep only as an optimization over a select +# based wait function we want it only if it is available in libc. +_save_libs="$LIBS" +AC_SEARCH_LIBS([nanosleep], [], + [AC_DEFINE(HAVE_NANOSLEEP,1, + [Define to 1 if you have the `nanosleep' function in libc.])]) +LIBS="$_save_libs" + # Check for funopen AC_CHECK_FUNCS(funopen) if test $ac_cv_func_funopen != yes; then Modified: trunk/src/assuan-connect.c =================================================================== --- trunk/src/assuan-connect.c 2008-11-03 18:27:11 UTC (rev 292) +++ trunk/src/assuan-connect.c 2009-01-22 15:06:28 UTC (rev 293) @@ -58,8 +58,8 @@ #ifndef HAVE_W32_SYSTEM -/* Return user credentials. PID, UID and GID amy be gived as NULL if - you are not interested in this value. For getting the pid of the +/* Return user credentials. PID, UID and GID may be given as NULL if + you are not interested in a value. For getting the pid of the peer the assuan_get_pid is usually better suited. */ assuan_error_t assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid) From cvs at cvs.gnupg.org Thu Jan 22 16:12:29 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 16:12:29 +0100 Subject: [svn] gcry - r1381 - trunk/tests Message-ID: Author: wk Date: 2009-01-22 16:12:28 +0100 (Thu, 22 Jan 2009) New Revision: 1381 Modified: trunk/tests/cavs_driver.pl Log: Last tweak for the driver. Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2009-01-22 11:51:22 UTC (rev 1380) +++ trunk/tests/cavs_driver.pl 2009-01-22 15:12:28 UTC (rev 1381) @@ -1,6 +1,6 @@ #!/usr/bin/env perl # -# $Id: cavs_driver.pl 1495 2009-01-22 10:47:13Z smueller $ +# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ # # CAVS test driver (based on the OpenSSL driver) # Written by: Stephan M?ller @@ -1139,7 +1139,7 @@ $out .= "Tlen = $tlen\n"; $out .= "Key = $key\n"; $out .= "Msg = $msg\n"; - $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n\n"; + $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; return $out; } @@ -2233,6 +2233,8 @@ # Do the job parse($infile, $outfile); + cleanup(); + } ########################################### From cvs at cvs.gnupg.org Thu Jan 22 17:05:17 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 17:05:17 +0100 Subject: [svn] GpgEX - r62 - in trunk: . po Message-ID: Author: wk Date: 2009-01-22 17:05:17 +0100 (Thu, 22 Jan 2009) New Revision: 62 Modified: trunk/ChangeLog trunk/po/ar.po trunk/po/de.po trunk/po/es.po trunk/po/ru.po Log: Translation changes (de.po) Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-09 10:09:39 UTC (rev 61) +++ trunk/ChangeLog 2009-01-22 16:05:17 UTC (rev 62) @@ -1,3 +1,7 @@ +2009-01-22 Werner Koch + + * po/de.po: Change "verifizeren" to "?berpr?fen". + 2008-06-04 Werner Koch * doc/gpgex.texi (Assuan Protocol): Replace the spec by a Modified: trunk/po/ar.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/ru.po [not shown] From cvs at cvs.gnupg.org Thu Jan 22 20:06:01 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 20:06:01 +0100 Subject: [svn] gcry - r1382 - in trunk: . cipher doc m4 random src Message-ID: Author: wk Date: 2009-01-22 20:06:01 +0100 (Thu, 22 Jan 2009) New Revision: 1382 Modified: trunk/AUTHORS trunk/ChangeLog trunk/NEWS trunk/README trunk/THANKS trunk/cipher/ChangeLog trunk/cipher/ecc.c trunk/configure.ac trunk/doc/gcrypt.texi trunk/m4/ChangeLog trunk/m4/noexecstack.m4 trunk/random/ChangeLog trunk/random/random.c trunk/src/ChangeLog trunk/src/fips.c trunk/src/gcrypt.h.in trunk/src/hmac256.c Log: Preparing Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/ChangeLog 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,3 +1,9 @@ +2009-01-22 Werner Koch + + Release 1.4.4. + + * configure.ac: Bump LT version to C16/A5/R2. + 2008-10-30 Werner Koch * configure.ac: Remove option --enable-gcc-warnings. Autodetect @@ -1326,8 +1332,8 @@ * Makefile.am: Likewise - Copyright 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, + 2007, 2008, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/cipher/ChangeLog 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,3 +1,7 @@ +2009-01-22 Werner Koch + + * ecc.c (compute_keygrip): Remove superfluous const. + 2009-01-06 Werner Koch * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier. Modified: trunk/m4/ChangeLog =================================================================== --- trunk/m4/ChangeLog 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/m4/ChangeLog 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,3 +1,8 @@ +2009-01-22 Werner Koch + + * noexecstack.m4: Replace non portable grep -q. Reported by + Albert Chin. + 2007-02-22 Werner Koch * noexecstack.m4: Change default to enable it. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/random/ChangeLog 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,3 +1,8 @@ +2009-01-22 Werner Koch + + * random.c (_gcry_random_deinit_external_test): Do not return a + value. Reported Albert Chin. + 2008-09-16 Werner Koch * random-fips.c (x931_aes_driver): No re-seeding with test contexts. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/src/ChangeLog 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,3 +1,9 @@ +2009-01-22 Werner Koch + + * fips.c (_gcry_initialize_fips_mode): Remove superfluous const + from static string. Reported by Albert Chin. + * hmac256.c (selftest): Ditto and change to unsigned char. + 2008-12-10 Werner Koch * hmac256.c (finalize): Fix for big endian hosts. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/AUTHORS 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,4 +1,5 @@ Library: Libgcrypt +Homepage: http://www.gnu.org/software/libgcrypt/ Maintainer: Werner Koch Bug reports: or http://bugs.gnupg.org Security related bug reports: @@ -116,8 +117,8 @@ security corporation. See the file for details. - Copyright 1998, 1999, 2000, 2001, 2002, 2003, - 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2006, + 2007, 2008, 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/NEWS 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,4 +1,4 @@ -Noteworthy changes in version 1.4.4 +Noteworthy changes in version 1.4.4 (2009-01-22) ------------------------------------------------ * Publish GCRY_MODULE_ID_USER and GCRY_MODULE_ID_USER_LAST constants. @@ -12,7 +12,7 @@ and DSA keys using the FIPS 186-2 algorithm. * The transient-key flag is now also supported for DSA key - generation. DSA domain parameters may given as well. + generation. DSA domain parameters may be given as well. Noteworthy changes in version 1.4.3 (2008-09-18) @@ -585,7 +585,8 @@ into into libgcrypt and GnuPG. -Copyright 2001, 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc. +Copyright 2001, 2002, 2003, 2004, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/README =================================================================== --- trunk/README 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/README 2009-01-22 19:06:01 UTC (rev 1382) @@ -3,8 +3,8 @@ Version 1.4.4 - Copyright 2000, 2002, 2003, 2004, 2007, - 2008 Free Software Foundation, Inc. + Copyright 2000, 2002, 2003, 2004, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/THANKS 2009-01-22 19:06:01 UTC (rev 1382) @@ -2,6 +2,7 @@ helped in GnuPG and Libgcrypt development. Please help us to keep it complete and free of errors. +Albert Chin china at thewrittenword com Allan Clark allanc at sco.com Anand Kumria wildfire at progsoc.uts.edu.au Andreas Metzler ametzler at downhill.at.eu.org Modified: trunk/cipher/ecc.c =================================================================== --- trunk/cipher/ecc.c 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/cipher/ecc.c 2009-01-22 19:06:01 UTC (rev 1382) @@ -1208,9 +1208,9 @@ static gpg_err_code_t compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) { + static const char names[] = "pabgnq"; gpg_err_code_t ec = 0; gcry_sexp_t l1; - static const char const names[] = "pabgnq"; gcry_mpi_t values[6]; int idx; Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/configure.ac 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,6 +1,6 @@ # Configure.ac script for Libgcrypt # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, -# 2007, 2008 Free Software Foundation, Inc. +# 2007, 2008, 2009 Free Software Foundation, Inc. # # This file is part of Libgcrypt. # @@ -27,7 +27,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [1.4.4]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -40,7 +40,7 @@ # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=16 LIBGCRYPT_LT_AGE=5 -LIBGCRYPT_LT_REVISION=1 +LIBGCRYPT_LT_REVISION=2 # If the API is changed in an incompatible way: increment the next counter. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/doc/gcrypt.texi 2009-01-22 19:06:01 UTC (rev 1382) @@ -2844,7 +2844,7 @@ @strong{This interface has a few known problems; most noteworthy an inherent tendency to leak memory. It might not be available in -forthcoming versions Libgcrypt.} +forthcoming versions of Libgcrypt.} @menu Modified: trunk/m4/noexecstack.m4 =================================================================== --- trunk/m4/noexecstack.m4 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/m4/noexecstack.m4 2009-01-22 19:06:01 UTC (rev 1382) @@ -37,7 +37,7 @@ EOF if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS -S -o conftest.s conftest.c >/dev/null]) \ - && grep -q .note.GNU-stack conftest.s \ + && grep .note.GNU-stack conftest.s >/dev/null \ && AC_TRY_COMMAND([${CCAS} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack -c -o conftest.o conftest.s >/dev/null]) then Modified: trunk/random/random.c =================================================================== --- trunk/random/random.c 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/random/random.c 2009-01-22 19:06:01 UTC (rev 1382) @@ -319,5 +319,5 @@ _gcry_random_deinit_external_test (void *context) { if (fips_mode ()) - return _gcry_rngfips_deinit_external_test (context); + _gcry_rngfips_deinit_external_test (context); } Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/src/fips.c 2009-01-22 19:06:01 UTC (rev 1382) @@ -136,9 +136,9 @@ /* Checking based on /proc file properties. */ { + static const char procfname[] = "/proc/sys/crypto/fips_enabled"; FILE *fp; int saved_errno; - static const char const procfname[] = "/proc/sys/crypto/fips_enabled"; fp = fopen (procfname, "r"); if (fp) Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/src/gcrypt.h.in 2009-01-22 19:06:01 UTC (rev 1382) @@ -1,6 +1,6 @@ /* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 - 2007, 2008 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Libgcrypt. Modified: trunk/src/hmac256.c =================================================================== --- trunk/src/hmac256.c 2009-01-22 15:12:28 UTC (rev 1381) +++ trunk/src/hmac256.c 2009-01-22 19:06:01 UTC (rev 1382) @@ -522,7 +522,7 @@ const char * const desc; const char * const data; const char * const key; - const char const expect[32]; + const unsigned char expect[32]; } tv[] = { { "data-28 key-4", From cvs at cvs.gnupg.org Thu Jan 22 20:28:43 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 20:28:43 +0100 Subject: [svn] gcry - r1383 - tags Message-ID: Author: wk Date: 2009-01-22 20:28:43 +0100 (Thu, 22 Jan 2009) New Revision: 1383 Added: tags/libgcrypt-1.4.4/ Log: Tag release From cvs at cvs.gnupg.org Thu Jan 22 20:30:09 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 20:30:09 +0100 Subject: [svn] gcry - r1384 - branches Message-ID: Author: wk Date: 2009-01-22 20:30:09 +0100 (Thu, 22 Jan 2009) New Revision: 1384 Added: branches/LIBGCRYPT-1-4-BRANCH/ Log: Create 1.4 branch. From cvs at cvs.gnupg.org Thu Jan 22 20:36:02 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 22 Jan 2009 20:36:02 +0100 Subject: [svn] gcry - r1385 - trunk Message-ID: Author: wk Date: 2009-01-22 20:36:02 +0100 (Thu, 22 Jan 2009) New Revision: 1385 Modified: trunk/ChangeLog trunk/NEWS trunk/README trunk/configure.ac Log: Prepare for new developments. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-22 19:30:09 UTC (rev 1384) +++ trunk/ChangeLog 2009-01-22 19:36:02 UTC (rev 1385) @@ -1,5 +1,10 @@ 2009-01-22 Werner Koch + * configure.ac: Bump LT version to C17/A7/R0 to mark the start of + a new development series. + +2009-01-22 Werner Koch + Release 1.4.4. * configure.ac: Bump LT version to C16/A5/R2. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-22 19:30:09 UTC (rev 1384) +++ trunk/NEWS 2009-01-22 19:36:02 UTC (rev 1385) @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.5.x (unreleased) +------------------------------------------------ + + Noteworthy changes in version 1.4.4 (2009-01-22) ------------------------------------------------ Modified: trunk/README =================================================================== --- trunk/README 2009-01-22 19:30:09 UTC (rev 1384) +++ trunk/README 2009-01-22 19:36:02 UTC (rev 1385) @@ -1,7 +1,9 @@ Libgcrypt - The GNU Crypto Library ------------------------------------ - Version 1.4.4 + Version 1.5.x + WARNING: THIS VERSION OF LIBGCRYPT IS UNDER DEVELOPMENT. + THE STABLE VERSION IS THE 1.4. Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-22 19:30:09 UTC (rev 1384) +++ trunk/configure.ac 2009-01-22 19:36:02 UTC (rev 1385) @@ -26,8 +26,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.4.4]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.5.0]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -38,9 +38,10 @@ # (Interfaces removed: CURRENT++, AGE=0, REVISION=0) # (Interfaces added: CURRENT++, AGE++, REVISION=0) # (No interfaces changed: REVISION++) -LIBGCRYPT_LT_CURRENT=16 -LIBGCRYPT_LT_AGE=5 -LIBGCRYPT_LT_REVISION=2 +# NOTE: As an exception the the LT versions are already set for 1.5.0! +LIBGCRYPT_LT_CURRENT=17 +LIBGCRYPT_LT_AGE=6 +LIBGCRYPT_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. From cvs at cvs.gnupg.org Mon Jan 26 10:58:19 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 26 Jan 2009 10:58:19 +0100 Subject: [svn] gcry - r1386 - trunk/doc Message-ID: Author: wk Date: 2009-01-26 10:58:18 +0100 (Mon, 26 Jan 2009) New Revision: 1386 Modified: trunk/doc/gcrypt.texi Log: Add some comments on hash algorithm security. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-01-22 19:36:02 UTC (rev 1385) +++ trunk/doc/gcrypt.texi 2009-01-26 09:58:18 UTC (rev 1386) @@ -2431,9 +2431,9 @@ PKCS#1 block type 1 style padding. @var{hash-algo} is a string with the hash algorithm to be encoded into the signature, this may be any hash algorithm name as supported by Libgcrypt. Most likely, this will be -"sha1", "rmd160" or "md5". It is obvious that the length of @var{block} -must match the size of that message digests; the function checks that -this and other constraints are valid. +"sha256" or "sha1". It is obvious that the length of @var{block} must +match the size of that message digests; the function checks that this +and other constraints are valid. @noindent If PKCS#1 padding is not required (because the caller does already @@ -3410,26 +3410,36 @@ @item GCRY_MD_SHA1 This is the SHA-1 algorithm which yields a message digest of 20 bytes. +Note that SHA-1 begins to show some weaknesses and it is suggested to +fade out its use if strong cryptographic properties are required. @item GCRY_MD_RMD160 This is the 160 bit version of the RIPE message digest (RIPE-MD-160). -Like SHA-1 it also yields a digest of 20 bytes. +Like SHA-1 it also yields a digest of 20 bytes. This algorithm share a +lot of design properties with SHA-1 and thus it is advisable not to use +it for new protocols. @item GCRY_MD_MD5 This is the well known MD5 algorithm, which yields a message digest of -16 bytes. +16 bytes. Note that the MD5 algorithm has severe weaknesses, for +example it is easy to compute two messages yielding the same hash +(collision attack). The use of this algorithm is only justified for +non-cryptographic application. + @item GCRY_MD_MD4 This is the MD4 algorithm, which yields a message digest of 16 bytes. +This algorithms ha severe weaknesses and should not be used. @item GCRY_MD_MD2 This is an reserved identifier for MD-2; there is no implementation yet. +This algorithm has severe weaknesses and should not be used. @item GCRY_MD_TIGER This is the TIGER/192 algorithm which yields a message digest of 24 bytes. @item GCRY_MD_HAVAL -This is an reserved for the HAVAL algorithm with 5 passes and 160 +This is an reserved value for the HAVAL algorithm with 5 passes and 160 bit. It yields a message digest of 20 bytes. Note that there is no implementation yet available. @@ -3450,16 +3460,19 @@ See FIPS 180-2 for the specification. @item GCRY_MD_CRC32 -This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It -yields an output of 4 bytes. +This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It yields +an output of 4 bytes. Note that this is not a hash algorithm in the +cryptographic sense. @item GCRY_MD_CRC32_RFC1510 This is the above cyclic redundancy check function, as modified by RFC -1510. It yields an output of 4 bytes. +1510. It yields an output of 4 bytes. Note that this is not a hash +algorithm in the cryptographic sense. @item GCRY_MD_CRC24_RFC2440 This is the OpenPGP cyclic redundancy check function. It yields an -output of 3 bytes. +output of 3 bytes. Note that this is not a hash algorithm in the +cryptographic sense. @item GCRY_MD_WHIRLPOOL This is the Whirlpool algorithm which yields a message digest of 64 From cvs at cvs.gnupg.org Mon Jan 26 11:21:11 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 26 Jan 2009 11:21:11 +0100 Subject: [svn] gpgme - r1353 - in trunk: . src tests tests/opassuan Message-ID: Author: wk Date: 2009-01-26 11:21:10 +0100 (Mon, 26 Jan 2009) New Revision: 1353 Added: trunk/src/dirinfo.c trunk/src/engine-assuan.c trunk/src/opassuan.c trunk/tests/opassuan/ trunk/tests/opassuan/Makefile.am trunk/tests/opassuan/t-command.c Modified: trunk/ChangeLog trunk/Makefile.am trunk/NEWS trunk/autogen.sh trunk/configure.ac trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/context.h trunk/src/engine-backend.h trunk/src/engine-gpg.c trunk/src/engine-gpgconf.c trunk/src/engine-gpgsm.c trunk/src/engine.c trunk/src/engine.h trunk/src/gpgme.c trunk/src/gpgme.def trunk/src/gpgme.h.in trunk/src/libgpgme.vers trunk/src/util.h trunk/src/version.c trunk/tests/ChangeLog trunk/tests/Makefile.am Log: First take on the low-level assuan interface. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/ChangeLog 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,3 +1,7 @@ +2009-01-26 Werner Koch + + * configure.ac (AC_CONFIG_FILES): Add tests/opassuan/Makefile. + 2008-12-08 Marcus Brinkmann Release GPGME 1.1.8. @@ -720,8 +724,8 @@ * configure.ac (AC_INIT): Bump version to 0.3.3. * jnlib/Makefile.am: Rever to older version that includes xmalloc - but not dotlock and some other files. Reported by St?phane - Corth?sy. + but not dotlock and some other files. Reported by St??phane + Corth??sy. 2002-02-10 Marcus Brinkmann Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/ChangeLog 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,3 +1,36 @@ +2009-01-26 Werner Koch + + * opassuan.c, dirinfo.c, engine-assuan.c: New. + * Makefile.am: Add them. + * engine-backend.h: Add _gpgme_engine_ops_assuan. + (struct engine_ops): Add field OPASSUAN_TRANSACT. Update all + engine intializers. + * Makefile.am (gpgsm_components): Add engine-assuan.c. + * gpgme.h.in (gpgme_protocol_t): Add GPGME_PROTOCOL_ASSUAN. + (gpgme_assuan_data_cb_t, gpgme_assuan_sendfnc_ctx_t) + (gpgme_assuan_inquire_cb_t, gpgme_assuan_status_cb_t): New. + (gpgme_op_assuan_transact_start, gpgme_op_assuan_transact): New. + * gpgme.c (gpgme_get_protocol_name): Ditto. + (gpgme_set_protocol): Support it. + * engine.c (gpgme_get_engine_info): Ditto. + (engine_ops): Register it. + (_gpgme_engine_op_assuan_transact): New. + * libgpgme.vers (gpgme_op_assuan_transact_start) + (gpgme_op_assuan_transact): New. + * gpgme.def (gpgme_op_assuan_transact_start) + (gpgme_op_assuan_transact): New. + * engine-backend.h (struct engine_ops): Add GET_HOME_DIR and + initialize to NULL for all engines. + * engine.c (engine_get_home_dir): New. + (gpgme_get_engine_info): Use it. + (_gpgme_set_engine_info): Use it. + * engine.h (engine_assuan_result_cb_t): New. + * context.h (ctx_op_data_id_t): Add OPDATA_ASSUAN. + + * util.h (GPG_ERR_UNFINISHED): Define if not yet defined. + + * version.c (gpgme_check_version): Protect trace arg against NULL. + 2009-01-19 Werner Koch * rungpg.c: Rename to engine-gpg.c @@ -803,7 +836,7 @@ * engine.c (gpgme_engine_check_version): Reimplemented to allow checking the version correctly even after changing the engine - information. Bug reported by St?phane Corth?sy. + information. Bug reported by St??phane Corth??sy. * rungpg.c (read_colon_line): Invoke colon preprocess handler if it is set. @@ -868,7 +901,7 @@ 2005-11-27 Marcus Brinkmann * engine.c (_gpgme_set_engine_info): Use new_file_name in - engine_get_version invocation. Reported by St?phane Corth?sy. + engine_get_version invocation. Reported by St??phane Corth??sy. 2005-11-24 Marcus Brinkmann @@ -1818,7 +1851,7 @@ * gpgme-config.in (gpg_error_libs): Quote GPG_ERROR_CFLAGS and GPG_ERROR_LIBS when setting the corresponding variables. - Reported by St?phane Corth?sy. + Reported by St??phane Corth??sy. 2003-07-22 Marcus Brinkmann @@ -3707,7 +3740,7 @@ 2002-09-28 Marcus Brinkmann * conversion.c (_gpgme_hextobyte): Prevent superfluous - multiplication with base. Reported by St?phane Corth?sy. + multiplication with base. Reported by St??phane Corth??sy. * keylist.c (gpgme_op_keylist_ext_start): Use private asynchronous operation type in invocation of _gpgme_op_reset. @@ -3820,7 +3853,7 @@ variables encrypt_info and encrypt_info_len. * trustlist.c (gpgme_op_trustlist_start): Set colon line handler. * posix-sema.c (sema_fatal): Remove function. - All these reported by St?phane Corth?sy. + All these reported by St??phane Corth??sy. 2002-08-23 Werner Koch @@ -3993,7 +4026,7 @@ * vasprintf.c: Update to more recent libiberty version. * debug.h: Replace #elsif with #elif. - Submitted by St?phane Corth?sy: + Submitted by St??phane Corth??sy: * util.h (vasprintf): Correct prototype. * encrypt-sign.c: Include . (encrypt_sign_status_handler): Change type of ENCRYPT_INFO_LEN to @@ -4003,14 +4036,14 @@ 2002-07-25 Marcus Brinkmann - * wait.c (fdt_global): Make static. Reported by St?phane - Corth?sy. + * wait.c (fdt_global): Make static. Reported by St??phane + Corth??sy. * rungpg.c (_gpgme_gpg_op_keylist_ext): Skip empty string - patterns. Reported by St?phane Corth?sy. + patterns. Reported by St??phane Corth??sy. * key.c (gpgme_key_get_as_xml): Add OTRUST attribute. Requested - by St?phane Corth?sy. + by St??phane Corth??sy. (gpgme_key_get_string_attr): Add GPGME_ATTR_SIG_SUMMARY case to silence gcc warning. @@ -5060,7 +5093,7 @@ 2001-12-19 Marcus Brinkmann - * engine.c: Include `string.h'. Reported by St?phane Corth?sy. + * engine.c: Include `string.h'. Reported by St??phane Corth??sy. * version.c (get_engine_info): Remove prototype. @@ -5597,7 +5630,7 @@ callers to use this function without a check for tmp_key. * keylist.c (gpgme_op_keylist_next): Reset the key_cond after - emptying the queue. Bug reported by St?phane Corth?sy. + emptying the queue. Bug reported by St??phane Corth??sy. 2001-09-12 Werner Koch @@ -5679,7 +5712,7 @@ * version.c (gpgme_check_engine): Stop version number parsing at the opening angle and not the closing one. By Tommy Reynolds. -2001-05-01 Jos? Carlos Garc?a Sogo +2001-05-01 Jos?? Carlos Garc??a Sogo * encrypt.c (gpgme_op_encrypt_start): Deleted the assert ( !c->gpg ) line, because it gave an error if another operation had been made @@ -5865,8 +5898,8 @@ * rungpg.c (_gpgme_gpg_spawn): Use new function to get GPG's path. * signers.c (gpgme_signers_add): Ooops, one should test code and - not just write it; the newarr was not assigned. Thanks to Jos? - for pointing this out. Hmmm, still not tested, why shoudl a coder + not just write it; the newarr was not assigned. Thanks to Jos?? + for pointing this out. Hmmm, still not tested, why should a coder test his fix :-) * w32-io.c: Does now use reader threads, so that we can use Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/tests/ChangeLog 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,3 +1,9 @@ +2009-01-26 Werner Koch + + * opassuan/: New. + * opassuan/Makefile.am: New. + * opassuan/t-command.c: New. + 2008-12-03 Marcus Brinkmann * Makefile.am (INCLUDES): Fix path to include file. Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/Makefile.am 2009-01-26 10:21:10 UTC (rev 1353) @@ -15,8 +15,7 @@ # Public License for more details. # # You should have received a copy of the GNU Lesser General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# License along with this program; if not, see . ## Process this file with automake to produce Makefile.in Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/NEWS 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,3 +1,19 @@ +Noteworthy changes in version 1.1.9 +------------------------------------------------ + + * Interface changes relative to the 1.1.7 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPGME_PROTOCOL_ASSUAN NEW. + gpgme_assuan_data_cb_t NEW. + gpgme_assuan_sendfnc_ctx_t NEW. + gpgme_assuan_inquire_cb_t NEW. + gpgme_assuan_status_cb_t NEW. + gpgme_op_assuan_transact_start NEW. + gpgme_op_assuan_transact NEW. + gpgme_op_assuan_result NEW. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Noteworthy changes in version 1.1.8 (2008-12-08) ------------------------------------------------ Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/autogen.sh 2009-01-26 10:21:10 UTC (rev 1353) @@ -159,4 +159,6 @@ echo "Running autoconf${FORCE} ..." $AUTOCONF${FORCE} -echo "You may now run \"./configure --enable-maintainer-mode && make\"." +echo "You may now run: + ./configure --enable-maintainer-mode && make +" Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/configure.ac 2009-01-26 10:21:10 UTC (rev 1353) @@ -31,8 +31,8 @@ # specific feature can already be done under the assumption that the # SVN version is the most recent one in a branch. To disable the SVN # version for the real release, set the my_issvn macro to no. -m4_define(my_version, [1.1.8]) -m4_define(my_issvn, [no]) +m4_define(my_version, [1.1.9]) +m4_define(my_issvn, [yes]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) @@ -744,7 +744,10 @@ # Create config files AC_CONFIG_FILES(Makefile assuan/Makefile src/Makefile - tests/Makefile tests/gpg/Makefile tests/gpgsm/Makefile + tests/Makefile + tests/gpg/Makefile + tests/gpgsm/Makefile + tests/opassuan/Makefile doc/Makefile complus/Makefile src/versioninfo.rc src/gpgme.h) Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/Makefile.am 2009-01-26 10:21:10 UTC (rev 1353) @@ -78,7 +78,7 @@ endif if HAVE_GPGSM -gpgsm_components = engine-gpgsm.c +gpgsm_components = engine-gpgsm.c engine-assuan.c else gpgsm_components = endif @@ -105,9 +105,10 @@ sign.c passphrase.c progress.c \ key.c keylist.c trust-item.c trustlist.c \ import.c export.c genkey.c delete.c edit.c getauditlog.c \ + opassuan.c \ engine.h engine-backend.h engine.c engine-gpg.c status-table.h \ $(gpgsm_components) $(gpgconf_components) gpgconf.c \ - sema.h priv-io.h $(system_components) \ + sema.h priv-io.h $(system_components) dirinfo.c \ debug.c debug.h gpgme.c version.c error.c libgpgme_la_SOURCES = $(main_sources) \ Modified: trunk/src/context.h =================================================================== --- trunk/src/context.h 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/context.h 2009-01-26 10:21:10 UTC (rev 1353) @@ -36,7 +36,7 @@ { OPDATA_DECRYPT, OPDATA_SIGN, OPDATA_ENCRYPT, OPDATA_PASSPHRASE, OPDATA_IMPORT, OPDATA_GENKEY, OPDATA_KEYLIST, OPDATA_EDIT, - OPDATA_VERIFY, OPDATA_TRUSTLIST + OPDATA_VERIFY, OPDATA_TRUSTLIST, OPDATA_ASSUAN } ctx_op_data_id_t; @@ -51,7 +51,7 @@ ctx_op_data_id_t type; /* The function to release HOOK and all its associated resources. - Can be NULL if no special dealllocation routine is necessary. */ + Can be NULL if no special deallocation routine is necessary. */ void (*cleanup) (void *hook); /* The hook that points to the operation data. */ Added: trunk/src/dirinfo.c =================================================================== --- trunk/src/dirinfo.c (rev 0) +++ trunk/src/dirinfo.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -0,0 +1,189 @@ +/* dirinfo.c - Get directory information + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "gpgme.h" +#include "util.h" +#include "priv-io.h" +#include "debug.h" +#include "sema.h" + +DEFINE_STATIC_LOCK (dirinfo_lock); + +/* Constants used internally to select the data. */ +enum + { + WANT_HOMEDIR, + WANT_AGENT_SOCKET + }; + +/* Values retrieved via gpgconf and cached here. */ +static struct { + int valid; /* Cached information is valid. */ + char *homedir; + char *agent_socket; +} dirinfo; + + +/* Parse the output of "gpgconf --list-dirs". This function expects + that DIRINFO_LOCK is held by the caller. */ +static void +parse_output (char *line) +{ + char *value, *p; + + value = strchr (line, ':'); + if (!value) + return; + *value++ = 0; + p = strchr (value, ':'); + if (p) + *p = 0; + if (_gpgme_decode_percent_string (value, &value, strlen (value)+1, 0)) + return; + if (!*value) + return; + + if (!strcmp (line, "homedir") && !dirinfo.homedir) + dirinfo.homedir = strdup (value); + else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket) + dirinfo.agent_socket = strdup (value); +} + + +/* Read the directory information from gpgconf. This function expects + that DIRINFO_LOCK is held by the caller. */ +static void +read_gpgconf_dirs (void) +{ + const char *pgmname; + char linebuf[1024] = {0}; + int linelen = 0; + char * argv[3]; + int rp[2]; + struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */, -1, 0}, + {-1, -1} }; + int status; + int nread; + char *mark = NULL; + + pgmname = _gpgme_get_gpgconf_path (); + if (!pgmname) + return; /* No way. */ + + argv[0] = (char *)pgmname; + argv[1] = "--list-dirs"; + argv[2] = NULL; + + if (_gpgme_io_pipe (rp, 1) < 0) + return; + + cfd[0].fd = rp[1]; + + status = _gpgme_io_spawn (pgmname, argv, cfd, NULL); + if (status < 0) + { + _gpgme_io_close (rp[0]); + _gpgme_io_close (rp[1]); + return; + } + + do + { + nread = _gpgme_io_read (rp[0], + linebuf + linelen, + sizeof linebuf - linelen - 1); + if (nread > 0) + { + char *line; + const char *lastmark = NULL; + size_t nused; + + linelen += nread; + linebuf[linelen] = '\0'; + + for (line=linebuf; (mark = strchr (line, '\n')); line = mark+1 ) + { + lastmark = mark; + if (mark > line && mark[-1] == '\r') + mark[-1] = '\0'; + else + mark[0] = '\0'; + + parse_output (line); + } + + nused = lastmark? (lastmark + 1 - linebuf) : 0; + memmove (linebuf, linebuf + nused, linelen - nused); + linelen -= nused; + } + } + while (nread > 0 && linelen < sizeof linebuf - 1); + + _gpgme_io_close (rp[0]); +} + + +static const char * +get_gpgconf_dir (int what) +{ + const char *result = NULL; + + LOCK (dirinfo_lock); + if (!dirinfo.valid) + { + read_gpgconf_dirs (); + /* Even if the reading of the directories failed (e.g. due to an + too old version gpgconf or no gpgconf at all), we need to + mark the entries as valid so that we won't try over and over + to read them. Note further that we are not able to change + the read values later because they are practically statically + allocated. */ + dirinfo.valid = 1; + } + switch (what) + { + case WANT_HOMEDIR: result = dirinfo.homedir; break; + case WANT_AGENT_SOCKET: result = dirinfo.agent_socket; break; + } + UNLOCK (dirinfo_lock); + return result; +} + + +/* Return the default home directory. Returns NULL if not known. */ +const char * +_gpgme_get_default_homedir (void) +{ + return get_gpgconf_dir (WANT_HOMEDIR); +} + +/* Return the default gpg-agent socket name. Returns NULL if not known. */ +const char * +_gpgme_get_default_agent_socket (void) +{ + return get_gpgconf_dir (WANT_AGENT_SOCKET); +} + Added: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c (rev 0) +++ trunk/src/engine-assuan.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -0,0 +1,744 @@ +/* engine-assuan.c - Low-level Assuan protocol engine + * Copyright (C) 2009 g10 Code GmbH + * + * This file is part of GPGME. + * + * GPGME is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * GPGME is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +/* + Note: This engine requires a modern Assuan server which uses + gpg-error codes. In particular there is no backward compatible + mapping of old Assuan error codes implemented. +*/ + + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "gpgme.h" +#include "util.h" +#include "ops.h" +#include "wait.h" +#include "priv-io.h" +#include "sema.h" + +#include "assuan.h" +#include "debug.h" + +#include "engine-backend.h" + + +typedef struct +{ + int fd; /* FD we talk about. */ + int server_fd;/* Server FD for this connection. */ + int dir; /* Inbound/Outbound, maybe given implicit? */ + void *data; /* Handler-specific data. */ + void *tag; /* ID from the user for gpgme_remove_io_callback. */ +} iocb_data_t; + +/* Engine instance data. */ +struct engine_llass +{ + assuan_context_t assuan_ctx; + + int lc_ctype_set; + int lc_messages_set; + + iocb_data_t status_cb; + + struct gpgme_io_cbs io_cbs; + + /* Internal callbacks. */ + engine_assuan_result_cb_t result_cb; + void *result_cb_value; + + /* User provided callbacks. */ + struct { + gpgme_assuan_data_cb_t data_cb; + void *data_cb_value; + + gpgme_assuan_inquire_cb_t inq_cb; + void *inq_cb_value; + + gpgme_assuan_status_cb_t status_cb; + void *status_cb_value; + } user; + + /* Option flags. */ + struct { + int gpg_agent:1; /* Assume this is a gpg-agent connection. */ + } opt; + +}; +typedef struct engine_llass *engine_llass_t; + +/* Helper to pass data to a callback. */ +struct _gpgme_assuan_sendfnc_ctx +{ + assuan_context_t assuan_ctx; +}; + + + +/* Prototypes. */ +static void llass_io_event (void *engine, + gpgme_event_io_t type, void *type_data); + + + + + +/* return the default home directory. */ +static const char * +llass_get_home_dir (void) +{ + /* For this engine the home directory is not a filename but a string + used to convey options. The exclamation mark is a marker to show + that this is not a directory name. Options are strings delimited + by a space. The only option defined for now is GPG_AGENT to + enable GPG_AGENT specific commands to send to the server at + connection startup. */ + return "!GPG_AGENT"; +} + +static char * +llass_get_version (const char *file_name) +{ + return strdup ("1.0"); +} + + +static const char * +llass_get_req_version (void) +{ + return "1.0"; +} + + +static void +close_notify_handler (int fd, void *opaque) +{ + engine_llass_t llass = opaque; + + assert (fd != -1); + if (llass->status_cb.fd == fd) + { + if (llass->status_cb.tag) + llass->io_cbs.remove (llass->status_cb.tag); + llass->status_cb.fd = -1; + llass->status_cb.tag = NULL; + } +} + + + +static gpgme_error_t +llass_cancel (void *engine) +{ + engine_llass_t llass = engine; + + if (!llass) + return gpg_error (GPG_ERR_INV_VALUE); + + if (llass->status_cb.fd != -1) + _gpgme_io_close (llass->status_cb.fd); + + if (llass->assuan_ctx) + { + assuan_disconnect (llass->assuan_ctx); + llass->assuan_ctx = NULL; + } + + return 0; +} + + +static void +llass_release (void *engine) +{ + engine_llass_t llass = engine; + + if (!llass) + return; + + llass_cancel (engine); + + free (llass); +} + + +/* Create a new instance. If HOME_DIR is NULL standard options for use + with gpg-agent are issued. */ +static gpgme_error_t +llass_new (void **engine, const char *file_name, const char *home_dir) +{ + gpgme_error_t err = 0; + engine_llass_t llass; + char *optstr; + + llass = calloc (1, sizeof *llass); + if (!llass) + return gpg_error_from_syserror (); + + llass->status_cb.fd = -1; + llass->status_cb.dir = 1; + llass->status_cb.tag = 0; + llass->status_cb.data = llass; + + /* Parse_options. */ + if (home_dir && *home_dir == '!') + { + home_dir++; + /* Very simple parser only working for the one option we support. */ + if (!strncmp (home_dir, "GPG_AGENT", 9) + && (!home_dir[9] || home_dir[9] == ' ')) + llass->opt.gpg_agent = 1; + } + + err = assuan_socket_connect (&llass->assuan_ctx, file_name, 0); + if (err) + goto leave; + + if (llass->opt.gpg_agent) + { + char *dft_display = NULL; + + err = _gpgme_getenv ("DISPLAY", &dft_display); + if (err) + goto leave; + if (dft_display) + { + if (asprintf (&optstr, "OPTION display=%s", dft_display) < 0) + { + err = gpg_error_from_syserror (); + free (dft_display); + goto leave; + } + free (dft_display); + + err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL, + NULL, NULL, NULL); + free (optstr); + if (err) + goto leave; + } + } + + if (llass->opt.gpg_agent && isatty (1)) + { + int rc; + char dft_ttyname[64]; + char *dft_ttytype = NULL; + + rc = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); + if (rc) + { + err = gpg_error_from_errno (rc); + goto leave; + } + else + { + if (asprintf (&optstr, "OPTION ttyname=%s", dft_ttyname) < 0) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, NULL, + NULL, NULL, NULL); + free (optstr); + if (err) + goto leave; + + err = _gpgme_getenv ("TERM", &dft_ttytype); + if (err) + goto leave; + if (dft_ttytype) + { + if (asprintf (&optstr, "OPTION ttytype=%s", dft_ttytype) < 0) + { + err = gpg_error_from_syserror (); + free (dft_ttytype); + goto leave; + } + free (dft_ttytype); + + err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, + NULL, NULL, NULL, NULL); + free (optstr); + if (err) + goto leave; + } + } + } + + +#ifdef HAVE_W32_SYSTEM + /* Under Windows we need to use AllowSetForegroundWindow. Tell + llass to tell us when it needs it. */ + if (!err && llass->opt.gpg_agent) + { + err = assuan_transact (llass->assuan_ctx, "OPTION allow-pinentry-notify", + NULL, NULL, NULL, NULL, NULL, NULL); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* This work only with recent gpg-agents. */ + } +#endif /*HAVE_W32_SYSTEM*/ + + + leave: + /* Close the server ends of the pipes (because of this, we must use + the stored server_fd_str in the function start). Our ends are + closed in llass_release(). */ + + if (err) + llass_release (llass); + else + *engine = llass; + + return err; +} + + +static gpgme_error_t +llass_set_locale (void *engine, int category, const char *value) +{ + gpgme_error_t err; + engine_llass_t llass = engine; + char *optstr; + char *catstr; + + if (!llass->opt.gpg_agent) + return 0; + + /* FIXME: If value is NULL, we need to reset the option to default. + But we can't do this. So we error out here. gpg-agent needs + support for this. */ + if (category == LC_CTYPE) + { + catstr = "lc-ctype"; + if (!value && llass->lc_ctype_set) + return gpg_error (GPG_ERR_INV_VALUE); + if (value) + llass->lc_ctype_set = 1; + } +#ifdef LC_MESSAGES + else if (category == LC_MESSAGES) + { + catstr = "lc-messages"; + if (!value && llass->lc_messages_set) + return gpg_error (GPG_ERR_INV_VALUE); + if (value) + llass->lc_messages_set = 1; + } +#endif /* LC_MESSAGES */ + else + return gpg_error (GPG_ERR_INV_VALUE); + + /* FIXME: Reset value to default. */ + if (!value) + return 0; + + if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + err = gpg_error_from_errno (errno); + else + { + err = assuan_transact (llass->assuan_ctx, optstr, NULL, NULL, + NULL, NULL, NULL, NULL); + free (optstr); + } + return err; +} + + + +static gpgme_error_t +inquire_cb_sendfnc (gpgme_assuan_sendfnc_ctx_t ctx, + const void *data, size_t datalen) +{ + if (data && datalen) + return assuan_send_data (ctx->assuan_ctx, data, datalen); + else + return 0; /* Don't allow an inquire to send a flush. */ +} + + +/* This is the inquiry callback. It handles stuff which ee need to + handle here and passes everything on to the user callback. */ +static gpgme_error_t +inquire_cb (engine_llass_t llass, const char *keyword, const char *args) +{ + gpg_error_t err; + + if (llass->opt.gpg_agent && !strcmp (keyword, "PINENTRY_LAUNCHED")) + { + _gpgme_allow_set_foregound_window ((pid_t)strtoul (args, NULL, 10)); + } + + if (llass->user.inq_cb) + { + struct _gpgme_assuan_sendfnc_ctx sendfnc_ctx; + + sendfnc_ctx.assuan_ctx = llass->assuan_ctx; + err = llass->user.inq_cb (llass->user.inq_cb_value, + keyword, args, + inquire_cb_sendfnc, &sendfnc_ctx); + } + else + err = 0; + + return err; +} + + +static gpgme_error_t +llass_status_handler (void *opaque, int fd) +{ + gpgme_error_t err = 0; + engine_llass_t llass = opaque; + char *line; + size_t linelen; + + do + { + err = assuan_read_line (llass->assuan_ctx, &line, &linelen); + if (err) + { + TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: error reading assuan line: %s", + fd, gpg_strerror (err)); + } + else if (linelen >= 2 && line[0] == 'D' && line[1] == ' ') + { + char *src = line + 2; + char *end = line + linelen; + char *dst = src; + + linelen = 0; + while (src < end) + { + if (*src == '%' && src + 2 < end) + { + /* Handle escaped characters. */ + ++src; + *dst++ = _gpgme_hextobyte (src); + src += 2; + } + else + *dst++ = *src++; + + linelen++; + } + + src = line + 2; + if (linelen && llass->user.data_cb) + err = llass->user.data_cb (llass->user.data_cb_value, + src, linelen); + else + err = 0; + + TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: D inlinedata; status from cb: %s", + fd, (llass->user.data_cb ? + (err? gpg_strerror (err):"ok"):"no callback")); + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + && (line[3] == '\0' || line[3] == ' ')) + { + /* END received. Tell the data callback. */ + if (llass->user.data_cb) + err = llass->user.data_cb (llass->user.data_cb_value, NULL, 0); + else + err = 0; + + TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: END line; status from cb: %s", + fd, (llass->user.data_cb ? + (err? gpg_strerror (err):"ok"):"no callback")); + } + else if (linelen > 2 && line[0] == 'S' && line[1] == ' ') + { + char *args; + char *src; + + for (src=line+2; *src == ' '; src++) + ; + + args = strchr (src, ' '); + if (!args) + args = line + linelen; /* Let it point to an empty string. */ + else + *(args++) = 0; + + while (*args == ' ') + args++; + + if (llass->user.status_cb) + err = llass->user.status_cb (llass->user.status_cb_value, + src, args); + else + err = 0; + + TRACE3 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: S line (%s) - status from cb: %s", + fd, line+2, (llass->user.status_cb ? + (err? gpg_strerror (err):"ok"):"no callback")); + } + else if (linelen >= 7 + && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q' + && line[3] == 'U' && line[4] == 'I' && line[5] == 'R' + && line[6] == 'E' + && (line[7] == '\0' || line[7] == ' ')) + { + char *src; + char *args; + + for (src=line+7; *src == ' '; src++) + ; + + args = strchr (src, ' '); + if (!args) + args = line + linelen; /* Let it point to an empty string. */ + else + *(args++) = 0; + + while (*args == ' ') + args++; + + err = inquire_cb (llass, src, args); + if (!err) /* Flush and send END. */ + err = assuan_send_data (llass->assuan_ctx, NULL, 0); + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' + && (line[3] == '\0' || line[3] == ' ')) + { + if (line[3] == ' ') + err = atoi (line+4); + else + err = gpg_error (GPG_ERR_GENERAL); + TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: ERR line: %s", + fd, err ? gpg_strerror (err) : "ok"); + if (llass->result_cb) + err = llass->result_cb (llass->result_cb_value, err); + else + err = 0; + if (!err) + { + _gpgme_io_close (llass->status_cb.fd); + return 0; + } + } + else if (linelen >= 2 + && line[0] == 'O' && line[1] == 'K' + && (line[2] == '\0' || line[2] == ' ')) + { + TRACE1 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: OK line", fd); + if (llass->result_cb) + err = llass->result_cb (llass->result_cb_value, 0); + else + err = 0; + if (!err) + { + _gpgme_io_close (llass->status_cb.fd); + return 0; + } + } + else + { + /* Comment line or invalid line. */ + } + + } + while (!err && assuan_pending_line (llass->assuan_ctx)); + + return err; +} + + +static gpgme_error_t +add_io_cb (engine_llass_t llass, iocb_data_t *iocbd, gpgme_io_cb_t handler) +{ + gpgme_error_t err; + + TRACE_BEG2 (DEBUG_ENGINE, "engine-assuan:add_io_cb", llass, + "fd %d, dir %d", iocbd->fd, iocbd->dir); + err = (*llass->io_cbs.add) (llass->io_cbs.add_priv, + iocbd->fd, iocbd->dir, + handler, iocbd->data, &iocbd->tag); + if (err) + return TRACE_ERR (err); + if (!iocbd->dir) + /* FIXME Kludge around poll() problem. */ + err = _gpgme_io_set_nonblocking (iocbd->fd); + return TRACE_ERR (err); +} + + +static gpgme_error_t +start (engine_llass_t llass, const char *command) +{ + gpgme_error_t err; + int fdlist[5]; + int nfds; + + /* We need to know the fd used by assuan for reads. We do this by + using the assumption that the first returned fd from + assuan_get_active_fds() is always this one. */ + nfds = assuan_get_active_fds (llass->assuan_ctx, 0 /* read fds */, + fdlist, DIM (fdlist)); + if (nfds < 1) + return gpg_error (GPG_ERR_GENERAL); /* FIXME */ + + /* We "duplicate" the file descriptor, so we can close it here (we + can't close fdlist[0], as that is closed by libassuan, and + closing it here might cause libassuan to close some unrelated FD + later). Alternatively, we could special case status_fd and + register/unregister it manually as needed, but this increases + code duplication and is more complicated as we can not use the + close notifications etc. A third alternative would be to let + Assuan know that we closed the FD, but that complicates the + Assuan interface. */ + + llass->status_cb.fd = _gpgme_io_dup (fdlist[0]); + if (llass->status_cb.fd < 0) + return gpg_error_from_syserror (); + + if (_gpgme_io_set_close_notify (llass->status_cb.fd, + close_notify_handler, llass)) + { + _gpgme_io_close (llass->status_cb.fd); + llass->status_cb.fd = -1; + return gpg_error (GPG_ERR_GENERAL); + } + + err = add_io_cb (llass, &llass->status_cb, llass_status_handler); + if (!err) + err = assuan_write_line (llass->assuan_ctx, command); + + /* FIXME: If *command == '#' no answer is expected. */ + + if (!err) + llass_io_event (llass, GPGME_EVENT_START, NULL); + + return err; +} + + + +static gpgme_error_t +llass_transact (void *engine, + const char *command, + engine_assuan_result_cb_t result_cb, + void *result_cb_value, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + engine_llass_t llass = engine; + gpgme_error_t err; + + if (!llass || !command || !*command) + return gpg_error (GPG_ERR_INV_VALUE); + + llass->result_cb = result_cb; + llass->result_cb_value = result_cb_value; + llass->user.data_cb = data_cb; + llass->user.data_cb_value = data_cb_value; + llass->user.inq_cb = inq_cb; + llass->user.inq_cb_value = inq_cb_value; + llass->user.status_cb = status_cb; + llass->user.status_cb_value = status_cb_value; + + err = start (llass, command); + return err; +} + + + +static void +llass_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs) +{ + engine_llass_t llass = engine; + llass->io_cbs = *io_cbs; +} + + +static void +llass_io_event (void *engine, gpgme_event_io_t type, void *type_data) +{ + engine_llass_t llass = engine; + + TRACE3 (DEBUG_ENGINE, "gpgme:llass_io_event", llass, + "event %p, type %d, type_data %p", + llass->io_cbs.event, type, type_data); + if (llass->io_cbs.event) + (*llass->io_cbs.event) (llass->io_cbs.event_priv, type, type_data); +} + + +struct engine_ops _gpgme_engine_ops_assuan = + { + /* Static functions. */ + _gpgme_get_default_agent_socket, + llass_get_home_dir, + llass_get_version, + llass_get_req_version, + llass_new, + + /* Member functions. */ + llass_release, + NULL, /* reset */ + NULL, /* set_status_handler */ + NULL, /* set_command_handler */ + NULL, /* set_colon_line_handler */ + llass_set_locale, + NULL, /* decrypt */ + NULL, /* delete */ + NULL, /* edit */ + NULL, /* encrypt */ + NULL, /* encrypt_sign */ + NULL, /* export */ + NULL, /* export_ext */ + NULL, /* genkey */ + NULL, /* import */ + NULL, /* keylist */ + NULL, /* keylist_ext */ + NULL, /* sign */ + NULL, /* trustlist */ + NULL, /* verify */ + NULL, /* getauditlog */ + llass_transact, /* opassuan_transact */ + NULL, /* conf_load */ + NULL, /* conf_save */ + llass_set_io_cbs, + llass_io_event, + llass_cancel + }; Modified: trunk/src/engine-backend.h =================================================================== --- trunk/src/engine-backend.h 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/engine-backend.h 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,5 +1,5 @@ /* engine-backend.h - A crypto backend for the engine interface. - Copyright (C) 2002, 2003, 2004 g10 Code GmbH + Copyright (C) 2002, 2003, 2004, 2009 g10 Code GmbH This file is part of GPGME. @@ -14,9 +14,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + License along with this program; if not, see . + */ #ifndef ENGINE_BACKEND_H #define ENGINE_BACKEND_H @@ -35,6 +34,11 @@ /* Return the default file name for the binary of this engine. */ const char *(*get_file_name) (void); + /* Return the default home dir for the binary of this engine. If + this function pointer is not set, the standard default home dir + of the engine is used. */ + const char *(*get_home_dir) (void); + /* Returns a malloced string containing the version of the engine with the given binary file name (or the default if FILE_NAME is NULL. */ @@ -96,6 +100,16 @@ gpgme_data_t plaintext); gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output, unsigned int flags); + gpgme_error_t (*opassuan_transact) (void *engine, + const char *command, + engine_assuan_result_cb_t result_cb, + void *result_cb_value, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value); gpgme_error_t (*conf_load) (void *engine, gpgme_conf_comp_t *conf_p); gpgme_error_t (*conf_save) (void *engine, gpgme_conf_comp_t conf); @@ -114,5 +128,8 @@ #ifdef ENABLE_GPGCONF extern struct engine_ops _gpgme_engine_ops_gpgconf; /* gpg-conf. */ #endif +#ifdef ENABLE_GPGSM /* If this is enabled we also have assuan support. */ +extern struct engine_ops _gpgme_engine_ops_assuan; /* Low-level Assuan. */ +#endif #endif /* ENGINE_BACKEND_H */ Modified: trunk/src/engine-gpg.c =================================================================== --- trunk/src/engine-gpg.c 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/engine-gpg.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -2158,6 +2158,7 @@ { /* Static functions. */ _gpgme_get_gpg_path, + NULL, gpg_get_version, gpg_get_req_version, gpg_new, @@ -2184,6 +2185,7 @@ gpg_trustlist, gpg_verify, NULL, /* getauditlog */ + NULL, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ gpg_set_io_cbs, Modified: trunk/src/engine-gpgconf.c =================================================================== --- trunk/src/engine-gpgconf.c 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/engine-gpgconf.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -885,6 +885,7 @@ { /* Static functions. */ _gpgme_get_gpgconf_path, + NULL, gpgconf_get_version, gpgconf_get_req_version, gpgconf_new, @@ -911,6 +912,7 @@ NULL, /* trustlist */ NULL, /* verify */ NULL, /* getauditlog */ + NULL, /* opassuan_transact */ gpgconf_conf_load, gpgconf_conf_save, gpgconf_set_io_cbs, Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/engine-gpgsm.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -1922,6 +1922,7 @@ { /* Static functions. */ _gpgme_get_gpgsm_path, + NULL, gpgsm_get_version, gpgsm_get_req_version, gpgsm_new, @@ -1952,6 +1953,7 @@ NULL, /* trustlist */ gpgsm_verify, gpgsm_getauditlog, + NULL, /* opassuan_transact */ NULL, /* conf_load */ NULL, /* conf_save */ gpgsm_set_io_cbs, Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/engine.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,6 +1,6 @@ /* engine.c - GPGME engine support. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2006 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009 g10 Code GmbH This file is part of GPGME. @@ -15,9 +15,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + License along with this program; if not, see . +*/ #ifdef HAVE_CONFIG_H #include @@ -52,8 +51,13 @@ NULL, #endif #ifdef ENABLE_GPGCONF - &_gpgme_engine_ops_gpgconf /* gpg-conf. */ + &_gpgme_engine_ops_gpgconf, /* gpg-conf. */ #else + NULL, +#endif +#ifdef ENABLE_GPGSM /* This indicates that we have assuan support. */ + &_gpgme_engine_ops_assuan /* Low-Level Assuan. */ +#else NULL #endif }; @@ -78,6 +82,20 @@ } +/* Get the standard home dir of the engine for PROTOCOL. */ +static const char * +engine_get_home_dir (gpgme_protocol_t proto) +{ + if (proto > DIM (engine_ops)) + return NULL; + + if (engine_ops[proto] && engine_ops[proto]->get_home_dir) + return (*engine_ops[proto]->get_home_dir) (); + else + return NULL; +} + + /* Get a malloced string containing the version number of the engine for PROTOCOL. */ static char * @@ -175,18 +193,22 @@ gpgme_engine_info_t *lastp = &engine_info; gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_CMS, - GPGME_PROTOCOL_GPGCONF }; + GPGME_PROTOCOL_GPGCONF, + GPGME_PROTOCOL_ASSUAN }; unsigned int proto; for (proto = 0; proto < DIM (proto_list); proto++) { const char *ofile_name = engine_get_file_name (proto_list[proto]); + const char *ohome_dir = engine_get_home_dir (proto_list[proto]); char *file_name; + char *home_dir; if (!ofile_name) continue; file_name = strdup (ofile_name); + home_dir = ohome_dir? strdup (ohome_dir): NULL; *lastp = malloc (sizeof (*engine_info)); if (!*lastp || !file_name) @@ -198,6 +220,8 @@ if (file_name) free (file_name); + if (home_dir) + free (home_dir); UNLOCK (engine_info_lock); return gpg_error_from_errno (saved_errno); @@ -205,7 +229,7 @@ (*lastp)->protocol = proto_list[proto]; (*lastp)->file_name = file_name; - (*lastp)->home_dir = NULL; + (*lastp)->home_dir = home_dir; (*lastp)->version = engine_get_version (proto_list[proto], NULL); (*lastp)->req_version = engine_get_req_version (proto_list[proto]); (*lastp)->next = NULL; @@ -347,7 +371,20 @@ } } else - new_home_dir = NULL; + { + const char *ohome_dir = engine_get_home_dir (proto); + if (ohome_dir) + { + new_home_dir = strdup (ohome_dir); + if (!new_home_dir) + { + free (new_file_name); + return gpg_error_from_errno (errno); + } + } + else + new_home_dir = NULL; + } /* Remove the old members. */ assert (info->file_name); @@ -731,6 +768,33 @@ gpgme_error_t +_gpgme_engine_op_assuan_transact (engine_t engine, + const char *command, + engine_assuan_result_cb_t result_cb, + void *result_cb_value, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->opassuan_transact) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->opassuan_transact) (engine->engine, + command, + result_cb, result_cb_value, + data_cb, data_cb_value, + inq_cb, inq_cb_value, + status_cb, status_cb_value); +} + + +gpgme_error_t _gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p) { if (!engine) Modified: trunk/src/engine.h =================================================================== --- trunk/src/engine.h 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/engine.h 2009-01-26 10:21:10 UTC (rev 1353) @@ -35,7 +35,10 @@ gpgme_status_code_t code, const char *keyword, int fd, int *processed); +typedef gpgme_error_t (*engine_assuan_result_cb_t) (void *priv, + gpgme_error_t result); + /* Get a deep copy of the engine info and return it in INFO. */ gpgme_error_t _gpgme_engine_info_copy (gpgme_engine_info_t *r_info); @@ -126,6 +129,17 @@ gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output, unsigned int flags); +gpgme_error_t _gpgme_engine_op_assuan_transact + (engine_t engine, + const char *command, + engine_assuan_result_cb_t result_cb, + void *result_cb_value, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t status_cb, + void *status_cb_value); gpgme_error_t _gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p); Modified: trunk/src/gpgme.c =================================================================== --- trunk/src/gpgme.c 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/gpgme.c 2009-01-26 10:21:10 UTC (rev 1353) @@ -192,7 +192,9 @@ protocol, gpgme_get_protocol_name (protocol) ? gpgme_get_protocol_name (protocol) : "unknown"); - if (protocol != GPGME_PROTOCOL_OpenPGP && protocol != GPGME_PROTOCOL_CMS) + if (protocol != GPGME_PROTOCOL_OpenPGP + && protocol != GPGME_PROTOCOL_CMS + && protocol != GPGME_PROTOCOL_ASSUAN) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (ctx->protocol != protocol) @@ -233,6 +235,9 @@ case GPGME_PROTOCOL_CMS: return "CMS"; + case GPGME_PROTOCOL_ASSUAN: + return "Assuan"; + case GPGME_PROTOCOL_UNKNOWN: return "unknown"; Modified: trunk/src/gpgme.def =================================================================== --- trunk/src/gpgme.def 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/gpgme.def 2009-01-26 10:21:10 UTC (rev 1353) @@ -167,5 +167,9 @@ gpgme_op_conf_save @130 gpgme_cancel_async @131 + + gpgme_op_assuan_result @132 + gpgme_op_assuan_transact_start @133 + gpgme_op_assuan_transact @134 ; END Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-01-19 14:44:13 UTC (rev 1352) +++ trunk/src/gpgme.h.in 2009-01-26 10:21:10 UTC (rev 1353) @@ -1,6 +1,6 @@ /* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*- Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 g10 Code GmbH This file is part of GPGME. @@ -301,6 +301,7 @@ GPGME_PROTOCOL_OpenPGP = 0, /* The default mode. */ GPGME_PROTOCOL_CMS = 1, GPGME_PROTOCOL_GPGCONF = 2, /* Special code for gpgconf. */ + GPGME_PROTOCOL_ASSUAN = 3, /* Low-level access to an Assuan server. */ GPGME_PROTOCOL_UNKNOWN = 255 } gpgme_protocol_t; @@ -746,6 +747,8 @@ gpgme_status_code_t status, const char *args, int fd); + + /* Context management functions. */ @@ -1656,7 +1659,52 @@ gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output, unsigned int flags); + +/* Low-level Assuan protocol access. */ +typedef gpgme_error_t (*gpgme_assuan_data_cb_t) + (void *opaque, const void *data, size_t datalen); + +struct _gpgme_assuan_sendfnc_ctx; +typedef struct _gpgme_assuan_sendfnc_ctx *gpgme_assuan_sendfnc_ctx_t; +typedef gpgme_error_t (*gpgme_assuan_sendfnc_t) + (gpgme_assuan_sendfnc_ctx_t ctx, const void *data, size_t datalen); + +typedef gpgme_error_t (*gpgme_assuan_inquire_cb_t) + (void *opaque, const char *name, const char *args, + gpgme_assuan_sendfnc_t sendfnc, + gpgme_assuan_sendfnc_ctx_t sendfnc_ctx); + +typedef gpgme_error_t (*gpgme_assuan_status_cb_t) + (void *opaque, const char *status, const char *args); + +/* Return the result of the last Assuan command. */ +gpgme_error_t gpgme_op_assuan_result (gpgme_ctx_t ctx); + +/* Send the Assuan COMMAND and return results via the callbacks. + Asynchronous variant. */ +gpgme_error_t gpgme_op_assuan_transact_start (gpgme_ctx_t ctx, + const char *command, + gpgme_assuan_data_cb_t data_cb, + void *data_cb_value, + gpgme_assuan_inquire_cb_t inq_cb, + void *inq_cb_value, + gpgme_assuan_status_cb_t stat_cb, + void *stat_cb_value); + From cvs at cvs.gnupg.org Tue Jan 27 12:30:03 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 27 Jan 2009 12:30:03 +0100 Subject: [svn] GnuPG - r4921 - in trunk: . g10 jnlib keyserver scd Message-ID: Author: wk Date: 2009-01-27 12:30:02 +0100 (Tue, 27 Jan 2009) New Revision: 4921 Added: trunk/scd/app-geldkarte.c Modified: trunk/AUTHORS trunk/g10/ChangeLog trunk/g10/card-util.c trunk/jnlib/ChangeLog trunk/jnlib/t-support.c trunk/keyserver/ChangeLog trunk/keyserver/Makefile.am trunk/scd/ChangeLog trunk/scd/Makefile.am trunk/scd/app-common.h trunk/scd/app.c Log: Add a Geldkarte gadget application. Minor other changes. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/g10/ChangeLog 2009-01-27 11:30:02 UTC (rev 4921) @@ -1,3 +1,7 @@ +2009-01-26 Werner Koch + + * card-util.c (card_status): Detect a Geldkarte. + 2009-01-13 Werner Koch * call-agent.c (dummy_data_cb): New. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/jnlib/ChangeLog 2009-01-27 11:30:02 UTC (rev 4921) @@ -1,3 +1,8 @@ +2009-01-22 Werner Koch + + * t-support.c (gpg_err_code_from_errno) + (gpg_err_code_from_syserror): New. + 2008-11-20 Werner Koch * argparse.c (arg_parse): Fix last change. Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/keyserver/ChangeLog 2009-01-27 11:30:02 UTC (rev 4921) @@ -1,3 +1,8 @@ +2009-01-22 Werner Koch + + * Makefile.am (gpg2keys_curl_LDADD, gpg2keys_hkp_LDADD): Add all + standard libs. + 2008-10-20 Werner Koch * curl-shim.c (curl_global_init): Mark usused arg. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/scd/ChangeLog 2009-01-27 11:30:02 UTC (rev 4921) @@ -1,3 +1,14 @@ +2009-01-27 Werner Koch + + * app.c (app_munge_serialno): Add case for no serialno. + (app_get_serial_and_stamp): Ditto. + +2009-01-26 Werner Koch + + * app-geldkarte.c: New. + * Makefile.am (card_apps): Add new file. + * app.c (select_application): Test for geldkarte. + 2009-01-12 Werner Koch * command.c (send_client_notifications) [HAVE_W32_SYSTEM]: Fix Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/AUTHORS 2009-01-27 11:30:02 UTC (rev 4921) @@ -1,5 +1,6 @@ Program: GnuPG -Maintainer: Werner Koch +Homepage: http://www.gnupg.org +Maintainer: Werner Koch Bug reports: Security related bug reports: License: GPLv3+ Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/g10/card-util.c 2009-01-27 11:30:02 UTC (rev 4921) @@ -387,6 +387,12 @@ fputs ("pkcs15-card:\n", fp); log_info ("this is a PKCS#15 compliant card\n"); } + else if (info.apptype && !strcmp (info.apptype, "GELDKARTE")) + { + if (opt.with_colons) + fputs ("geldkarte-card:\n", fp); + log_info ("this is a Geldkarte compliant card\n"); + } else { if (opt.with_colons) Modified: trunk/jnlib/t-support.c =================================================================== --- trunk/jnlib/t-support.c 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/jnlib/t-support.c 2009-01-27 11:30:02 UTC (rev 4921) @@ -22,9 +22,11 @@ #include #include #include +#include #include "t-support.h" + /* Replacements for the malloc functions as used here. */ static void @@ -107,3 +109,31 @@ if (a) free (a); } + + + +/* Stubs for gpg-error functions required because some compilers do + not eliminate the supposed-to-be-unused-inline-functions and thus + require functions called from these inline fucntions. Although we + do not use gpg-error, gpg-error.h may get included via gcrypt.h if + it happens to be used used in libjnlib-config.h. */ +int +gpg_err_code_from_errno (int err) +{ + assert (!"stub function"); + return -1; +} + + +/* Retrieve the error code directly from the ERRNO variable. This + returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped + (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */ +int +gpg_err_code_from_syserror (void) +{ + assert (!"stub function"); + return -1; +} + + + Modified: trunk/keyserver/Makefile.am =================================================================== --- trunk/keyserver/Makefile.am 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/keyserver/Makefile.am 2009-01-27 11:30:02 UTC (rev 4921) @@ -1,4 +1,6 @@ -# Copyright (C) 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. +# Makefile.am - Makefile for keyservers +# Copyright (C) 2001, 2002, 2004, 2005, 2006, +# 2009 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -66,14 +68,17 @@ gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \ $(other_libs) else +# Note that we need to include all other libs here as well because +# some compilers don't care about inline fucntions and insert +# references to symbols used in unused inline functions. gpg2keys_curl_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS) -gpg2keys_curl_LDADD = $(LIBCURL) $(GETOPT) +gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \ + $(other_libs) $(LIBCURL) $(GETOPT) gpg2keys_hkp_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS) -gpg2keys_hkp_LDADD = $(LIBCURL) $(GETOPT) +gpg2keys_hkp_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \ + $(other_libs) $(LIBCURL) $(GETOPT) endif # Make sure that all libs are build before we use them. This is # important for things like make -j2. $(PROGRAMS): $(common_libs) - - Modified: trunk/scd/Makefile.am =================================================================== --- trunk/scd/Makefile.am 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/scd/Makefile.am 2009-01-27 11:30:02 UTC (rev 4921) @@ -30,7 +30,7 @@ $(KSBA_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) -card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c +card_apps = app-openpgp.c app-nks.c app-dinsig.c app-p15.c app-geldkarte.c scdaemon_SOURCES = \ scdaemon.c scdaemon.h \ Modified: trunk/scd/app-common.h =================================================================== --- trunk/scd/app-common.h 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/scd/app-common.h 2009-01-27 11:30:02 UTC (rev 4921) @@ -207,7 +207,10 @@ /*-- app-p15.c --*/ gpg_error_t app_select_p15 (app_t app); +/*-- app-geldkarte.c --*/ +gpg_error_t app_select_geldkarte (app_t app); + #endif Added: trunk/scd/app-geldkarte.c =================================================================== --- trunk/scd/app-geldkarte.c (rev 0) +++ trunk/scd/app-geldkarte.c 2009-01-27 11:30:02 UTC (rev 4921) @@ -0,0 +1,337 @@ +/* app-geldkarte.c - The German Geldkarte application + * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +/* This is a read-only application to quickly dump information of a + German Geldkarte (debit card for small amounts). + + Because this application does no use an AID it is best to test for + it after the test for other applications. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scdaemon.h" + +#include "i18n.h" +#include "iso7816.h" +#include "app-common.h" +#include "tlv.h" + + + +/* Object with application (i.e. Geldkarte) specific data. */ +struct app_local_s +{ + char kblz[2+1+4+1]; + const char *banktype; + char *cardno; + char expires[7+1]; + char validfrom[10+1]; + char *country; + char currency[3+1]; + unsigned int currency_mult100; + unsigned char chipid; + unsigned char osvers; +}; + + + + +/* Deconstructor. */ +static void +do_deinit (app_t app) +{ + if (app && app->app_local) + { + xfree (app->app_local->cardno); + xfree (app->app_local->country); + xfree (app->app_local); + app->app_local = NULL; + } +} + + +static gpg_error_t +send_one_string (ctrl_t ctrl, const char *name, const char *string) +{ + if (!name || !string) + return 0; + send_status_info (ctrl, name, string, strlen (string), NULL, 0); + return 0; +} + +/* Implement the GETATTR command. This is similar to the LEARN + command but returns just one value via the status interface. */ +static gpg_error_t +do_getattr (app_t app, ctrl_t ctrl, const char *name) +{ + gpg_error_t err; + struct app_local_s *ld = app->app_local; + char numbuf[100]; + + if (!strcmp (name, "X-KBLZ")) + err = send_one_string (ctrl, name, ld->kblz); + else if (!strcmp (name, "X-BANKINFO")) + err = send_one_string (ctrl, name, ld->banktype); + else if (!strcmp (name, "X-CARDNO")) + err = send_one_string (ctrl, name, ld->cardno); + else if (!strcmp (name, "X-EXPIRES")) + err = send_one_string (ctrl, name, ld->expires); + else if (!strcmp (name, "X-VALIDFROM")) + err = send_one_string (ctrl, name, ld->validfrom); + else if (!strcmp (name, "X-COUNTRY")) + err = send_one_string (ctrl, name, ld->country); + else if (!strcmp (name, "X-CURRENCY")) + err = send_one_string (ctrl, name, ld->currency); + else if (!strcmp (name, "X-CRNCMULT")) + { + snprintf (numbuf, sizeof numbuf, "%u", ld->currency_mult100); + err = send_one_string (ctrl, name, numbuf); + } + else if (!strcmp (name, "X-ZKACHIPID")) + { + snprintf (numbuf, sizeof numbuf, "0x%02X", ld->chipid); + err = send_one_string (ctrl, name, numbuf); + } + else if (!strcmp (name, "X-OSVERSION")) + { + snprintf (numbuf, sizeof numbuf, "0x%02X", ld->osvers); + err = send_one_string (ctrl, name, numbuf); + } + else + err = gpg_error (GPG_ERR_INV_NAME); + + return err; +} + + +static gpg_error_t +do_learn_status (app_t app, ctrl_t ctrl) +{ + static const char *names[] = { + "X-KBLZ", + "X-BANKINFO", + "X-CARDNO", + "X-EXPIRES", + "X-VALIDFROM", + "X-COUNTRY", + "X-CURRENCY", + "X-CRNCMULT", + "X-ZKACHIPID", + "X-OSVERSION", + NULL + }; + gpg_error_t err = 0; + int idx; + + for (idx=0; names[idx] && !err; idx++) + err = do_getattr (app, ctrl, names[idx]); + return err; +} + + +static char * +copy_bcd (const unsigned char *string, size_t length) +{ + const unsigned char *s; + size_t n; + size_t needed; + char *buffer, *dst; + + if (!length) + return xtrystrdup (""); + + /* Skip leading zeroes. */ + for (; length && !*string; length--, string++) + ; + s = string; + n = length; + needed = 0; + for (; n ; n--, s++) + { + if (!needed && !(*s & 0xf0)) + ; /* Skip the leading zero in the first nibble. */ + else + { + if ( ((*s >> 4) & 0x0f) > 9 ) + { + errno = EINVAL; + return NULL; + } + needed++; + } + if ( n == 1 && (*s & 0x0f) > 9 ) + ; /* Ignore the last digit if it has the sign. */ + else + { + needed++; + if ( (*s & 0x0f) > 9 ) + { + errno = EINVAL; + return NULL; + } + } + + } + if (!needed) /* If it is all zero, print a "0". */ + needed++; + + buffer = dst = xtrymalloc (needed+1); + if (!buffer) + return NULL; + + s = string; + n = length; + needed = 0; + for (; n ; n--, s++) + { + if (!needed && !(*s & 0xf0)) + ; /* Skip the leading zero in the first nibble. */ + else + { + *dst++ = '0' + ((*s >> 4) & 0x0f); + needed++; + } + + if ( n == 1 && (*s & 0x0f) > 9 ) + ; /* Ignore the last digit if it has the sign. */ + else + { + *dst++ = '0' + (*s & 0x0f); + needed++; + } + } + if (!needed) + *dst++ = '0'; + *dst = 0; + + return buffer; +} + + + + +/* Select the Geldkarte application. */ +gpg_error_t +app_select_geldkarte (app_t app) +{ + gpg_error_t err; + int slot = app->slot; + unsigned char *result = NULL; + size_t resultlen; + struct app_local_s *ld; + const char *banktype; + + err = iso7816_select_file (slot, 0x3f00, 1, NULL, NULL); + if (err) + goto leave; /* Oops. */ + + /* Read short EF 0xbc. We require this record to be at least 24 + bytes with the the first byte 0x67 and a correct the filler + byte. */ + err = iso7816_read_record (slot, 1, 1, 0xbc, &result, &resultlen); + if (err) + goto leave; /* No such record or other error - not a Geldkarte. */ + if (resultlen < 24 || *result != 0x67 || result[22]) + { + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } + + /* The short Bankleitzahl consists of 3 bytes at offset 1. */ + switch (result[1]) + { + case 0x21: banktype = "Oeffentlich-rechtliche oder private Bank"; break; + case 0x22: banktype = "Privat- oder Geschaeftsbank"; break; + case 0x25: banktype = "Sparkasse"; break; + case 0x26: + case 0x29: banktype = "Genossenschaftsbank"; break; + default: + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; /* Probably not a Geldkarte. */ + } + + app->apptype = "GELDKARTE"; + app->fnc.deinit = do_deinit; + + app->app_local = ld = xtrycalloc (1, sizeof *app->app_local); + if (!app->app_local) + { + err = gpg_err_code_from_syserror (); + goto leave; + } + + snprintf (ld->kblz, sizeof ld->kblz, "%02X-%02X%02X", + result[1], result[2], result[3]); + ld->banktype = banktype; + ld->cardno = copy_bcd (result+4, 5); + if (!ld->cardno) + { + err = gpg_err_code_from_syserror (); + goto leave; + } + + snprintf (ld->expires, sizeof ld->expires, "20%02X-%02X", + result[10], result[11]); + snprintf (ld->validfrom, sizeof ld->validfrom, "20%02X-%02X-%02X", + result[12], result[13], result[14]); + + ld->country = copy_bcd (result+15, 2); + if (!ld->country) + { + err = gpg_err_code_from_syserror (); + goto leave; + } + + snprintf (ld->currency, sizeof ld->currency, "%c%c%c", + isascii (result[17])? result[17]:' ', + isascii (result[18])? result[18]:' ', + isascii (result[19])? result[19]:' '); + + ld->currency_mult100 = (result[20] == 0x01? 1: + result[20] == 0x02? 10: + result[20] == 0x04? 100: + result[20] == 0x08? 1000: + result[20] == 0x10? 10000: + result[20] == 0x20? 100000:0); + + ld->chipid = result[21]; + ld->osvers = result[23]; + + /* Setup the rest of the methods. */ + app->fnc.learn_status = do_learn_status; + app->fnc.getattr = do_getattr; + + + leave: + xfree (result); + if (err) + do_deinit (app); + return err; +} Modified: trunk/scd/app.c =================================================================== --- trunk/scd/app.c 2009-01-20 19:24:24 UTC (rev 4920) +++ trunk/scd/app.c 2009-01-27 11:30:02 UTC (rev 4921) @@ -352,6 +352,9 @@ err = app_select_p15 (app); if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig"))) err = app_select_dinsig (app); + if (err && is_app_allowed ("geldkarte") + && (!name || !strcmp (name, "geldkarte"))) + err = app_select_geldkarte (app); if (err && name) err = gpg_error (GPG_ERR_NOT_SUPPORTED); @@ -440,6 +443,7 @@ FF 00 00 = For serial numbers starting with an FF FF 01 00 = Some german p15 cards return an empty serial number so the serial number from the EF(TokenInfo) is used instead. + FF 7F 00 = No serialno. All other serial number not starting with FF are used as they are. */ @@ -452,13 +456,23 @@ requires that we put our default prefix "FF0000" in front. */ unsigned char *p = xtrymalloc (app->serialnolen + 3); if (!p) - return gpg_error (gpg_err_code_from_errno (errno)); + return gpg_error_from_syserror (); memcpy (p, "\xff\0", 3); memcpy (p+3, app->serialno, app->serialnolen); app->serialnolen += 3; xfree (app->serialno); app->serialno = p; } + else if (!app->serialnolen) + { + unsigned char *p = xtrymalloc (3); + if (!p) + return gpg_error_from_syserror (); + memcpy (p, "\xff\x7f", 3); + app->serialnolen = 3; + xfree (app->serialno); + app->serialno = p; + } return 0; } @@ -482,7 +496,10 @@ if (stamp) *stamp = 0; /* not available */ - buf = bin2hex (app->serialno, app->serialnolen, NULL); + if (!app->serialnolen) + buf = xtrystrdup ("FF7F00"); + else + buf = bin2hex (app->serialno, app->serialnolen, NULL); if (!buf) return gpg_error_from_syserror (); From cvs at cvs.gnupg.org Tue Jan 27 17:38:33 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 27 Jan 2009 17:38:33 +0100 Subject: [svn] GnuPG - r4922 - trunk/scd Message-ID: Author: wk Date: 2009-01-27 17:38:33 +0100 (Tue, 27 Jan 2009) New Revision: 4922 Modified: trunk/scd/ChangeLog trunk/scd/app-geldkarte.c Log: Return the balance of a Geldkarte. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-01-27 11:30:02 UTC (rev 4921) +++ trunk/scd/ChangeLog 2009-01-27 16:38:33 UTC (rev 4922) @@ -1,5 +1,7 @@ 2009-01-27 Werner Koch + * app-geldkarte.c: Changed to use an AID. + * app.c (app_munge_serialno): Add case for no serialno. (app_get_serial_and_stamp): Ditto. Modified: trunk/scd/app-geldkarte.c =================================================================== --- trunk/scd/app-geldkarte.c 2009-01-27 11:30:02 UTC (rev 4921) +++ trunk/scd/app-geldkarte.c 2009-01-27 16:38:33 UTC (rev 4922) @@ -20,10 +20,9 @@ /* This is a read-only application to quickly dump information of a - German Geldkarte (debit card for small amounts). - - Because this application does no use an AID it is best to test for - it after the test for other applications. + German Geldkarte (debit card for small amounts). We only support + newer Geldkarte (with the AID DF_BOERSE_NEU) issued since 2000 or + even earlier. */ @@ -58,6 +57,9 @@ unsigned int currency_mult100; unsigned char chipid; unsigned char osvers; + int balance; + int maxamount; + int maxamount1; }; @@ -109,11 +111,6 @@ err = send_one_string (ctrl, name, ld->country); else if (!strcmp (name, "X-CURRENCY")) err = send_one_string (ctrl, name, ld->currency); - else if (!strcmp (name, "X-CRNCMULT")) - { - snprintf (numbuf, sizeof numbuf, "%u", ld->currency_mult100); - err = send_one_string (ctrl, name, numbuf); - } else if (!strcmp (name, "X-ZKACHIPID")) { snprintf (numbuf, sizeof numbuf, "0x%02X", ld->chipid); @@ -124,6 +121,24 @@ snprintf (numbuf, sizeof numbuf, "0x%02X", ld->osvers); err = send_one_string (ctrl, name, numbuf); } + else if (!strcmp (name, "X-BALANCE")) + { + snprintf (numbuf, sizeof numbuf, "%.2f", + (double)ld->balance / 100 * ld->currency_mult100); + err = send_one_string (ctrl, name, numbuf); + } + else if (!strcmp (name, "X-MAXAMOUNT")) + { + snprintf (numbuf, sizeof numbuf, "%.2f", + (double)ld->maxamount / 100 * ld->currency_mult100); + err = send_one_string (ctrl, name, numbuf); + } + else if (!strcmp (name, "X-MAXAMOUNT1")) + { + snprintf (numbuf, sizeof numbuf, "%.2f", + (double)ld->maxamount1 / 100 * ld->currency_mult100); + err = send_one_string (ctrl, name, numbuf); + } else err = gpg_error (GPG_ERR_INV_NAME); @@ -142,9 +157,11 @@ "X-VALIDFROM", "X-COUNTRY", "X-CURRENCY", - "X-CRNCMULT", "X-ZKACHIPID", "X-OSVERSION", + "X-BALANCE", + "X-MAXAMOUNT", + "X-MAXAMOUNT1", NULL }; gpg_error_t err = 0; @@ -235,12 +252,28 @@ } +/* Convert the BCD number at STING of LENGTH into an integer and store + that at RESULT. Return 0 on success. */ +static gpg_error_t +bcd_to_int (const unsigned char *string, size_t length, int *result) +{ + char *tmp; + tmp = copy_bcd (string, length); + if (!tmp) + return gpg_error (GPG_ERR_BAD_DATA); + *result = strtol (tmp, NULL, 10); + xfree (tmp); + return 0; +} + /* Select the Geldkarte application. */ gpg_error_t app_select_geldkarte (app_t app) { + static unsigned char const aid[] = + { 0xD2, 0x76, 0x00, 0x00, 0x25, 0x45, 0x50, 0x02, 0x00 }; gpg_error_t err; int slot = app->slot; unsigned char *result = NULL; @@ -248,16 +281,16 @@ struct app_local_s *ld; const char *banktype; - err = iso7816_select_file (slot, 0x3f00, 1, NULL, NULL); + err = iso7816_select_application (slot, aid, sizeof aid, 0); if (err) - goto leave; /* Oops. */ - - /* Read short EF 0xbc. We require this record to be at least 24 - bytes with the the first byte 0x67 and a correct the filler - byte. */ - err = iso7816_read_record (slot, 1, 1, 0xbc, &result, &resultlen); + goto leave; + + /* Read the first record of EF_ID (SFI=0x17). We require this + record to be at least 24 bytes with the the first byte 0x67 and a + correct filler byte. */ + err = iso7816_read_record (slot, 1, 1, ((0x17 << 3)|4), &result, &resultlen); if (err) - goto leave; /* No such record or other error - not a Geldkarte. */ + goto leave; /* Oops - not a Geldkarte. */ if (resultlen < 24 || *result != 0x67 || result[22]) { err = gpg_error (GPG_ERR_NOT_FOUND); @@ -280,6 +313,23 @@ app->apptype = "GELDKARTE"; app->fnc.deinit = do_deinit; + /* If we don't have a serialno yet construct it from the EF_ID. */ + if (!app->serialno) + { + app->serialno = xtrymalloc (10); + if (!app->serialno) + { + err = gpg_error_from_syserror (); + goto leave; + } + memcpy (app->serialno, result, 10); + app->serialnolen = 10; + err = app_munge_serialno (app); + if (err) + goto leave; + } + + app->app_local = ld = xtrycalloc (1, sizeof *app->app_local); if (!app->app_local) { @@ -324,6 +374,26 @@ ld->chipid = result[21]; ld->osvers = result[23]; + /* Read the first record of EF_BETRAG (SFI=0x18). */ + xfree (result); + err = iso7816_read_record (slot, 1, 1, ((0x18 << 3)|4), &result, &resultlen); + if (err) + goto leave; /* It does not make sense to continue. */ + if (resultlen < 12) + { + err = gpg_error (GPG_ERR_NOT_FOUND); + goto leave; + } + err = bcd_to_int (result+0, 3, &ld->balance); + if (!err) + err = bcd_to_int (result+3, 3, &ld->maxamount); + if (!err) + err = bcd_to_int (result+6, 3, &ld->maxamount1); + /* The next 3 bytes are the maximum amount chargable without using a + MAC. This is usually 0. */ + if (err) + goto leave; + /* Setup the rest of the methods. */ app->fnc.learn_status = do_learn_status; app->fnc.getattr = do_getattr; From cvs at cvs.gnupg.org Wed Jan 28 11:08:27 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Jan 2009 11:08:27 +0100 Subject: [svn] GpgOL - r293 - in trunk: . po src Message-ID: Author: wk Date: 2009-01-28 11:08:26 +0100 (Wed, 28 Jan 2009) New Revision: 293 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/po/de.po trunk/po/sv.po trunk/src/ChangeLog trunk/src/mimeparser.c Log: Fix for OL created S/MIME signed mails. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-16 17:50:09 UTC (rev 292) +++ trunk/ChangeLog 2009-01-28 10:08:26 UTC (rev 293) @@ -1,3 +1,9 @@ +2009-01-28 Werner Koch + + Release 0.10.18. + + * po/de.po: s/Unterschrift/Signatur/. + 2008-11-14 Werner Koch Release 0.10.17. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-16 17:50:09 UTC (rev 292) +++ trunk/src/ChangeLog 2009-01-28 10:08:26 UTC (rev 293) @@ -1,3 +1,9 @@ +2009-01-28 Werner Koch + + * mimeparser.c (t2body): Take care of x-pkcs7-mime as used by + native OL signed messages. + (mime_decrypt): Ditto. + 2009-01-16 Werner Koch * engine-assuan.c (attach_thread_input_wndw_proc) Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-16 17:50:09 UTC (rev 292) +++ trunk/NEWS 2009-01-28 10:08:26 UTC (rev 293) @@ -1,7 +1,9 @@ -Noteworthy changes for version 0.10.18 (unreleased) +Noteworthy changes for version 0.10.18 (2009-01-28) =================================================== + * Handle OL created S/MIME messages. + Noteworthy changes for version 0.10.17 (2008-11-14) =================================================== Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-16 17:50:09 UTC (rev 292) +++ trunk/configure.ac 2009-01-28 10:08:26 UTC (rev 293) @@ -17,7 +17,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [0.10.18]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) Modified: trunk/po/de.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/src/mimeparser.c =================================================================== --- trunk/src/mimeparser.c 2009-01-16 17:50:09 UTC (rev 292) +++ trunk/src/mimeparser.c 2009-01-28 10:08:26 UTC (rev 293) @@ -864,7 +864,9 @@ /* Check whether this attachment is an opaque signed S/MIME part. We use a counter to later check that there is only one such part. */ - if (!strcmp (ctmain, "application") && !strcmp (ctsub, "pkcs7-mime")) + if (!strcmp (ctmain, "application") + && (!strcmp (ctsub, "pkcs7-mime") + || !strcmp (ctsub, "x-pkcs7-mime"))) { const char *smtype = rfc822parse_query_parameter (field, "smime-type", 0); @@ -1986,7 +1988,9 @@ for (i=0; !table[i].end_of_table; i++) if (table[i].attach_type == ATTACHTYPE_FROMMOSS && table[i].content_type - && !strcmp (table[i].content_type, "application/pkcs7-mime")) + && (!strcmp (table[i].content_type, "application/pkcs7-mime") + || !strcmp (table[i].content_type, "application/x-pkcs7-mime")) + ) break; if (table[i].end_of_table) { From cvs at cvs.gnupg.org Wed Jan 28 11:27:15 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Jan 2009 11:27:15 +0100 Subject: [svn] GpgEX - r63 - in trunk: . src Message-ID: Author: wk Date: 2009-01-28 11:27:15 +0100 (Wed, 28 Jan 2009) New Revision: 63 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/src/versioninfo.rc.in Log: Preparing a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-01-22 16:05:17 UTC (rev 62) +++ trunk/ChangeLog 2009-01-28 10:27:15 UTC (rev 63) @@ -1,3 +1,7 @@ +2009-01-28 Werner Koch + + Release 0.9.2. + 2009-01-22 Werner Koch * po/de.po: Change "verifizeren" to "??berpr??fen". Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-22 16:05:17 UTC (rev 62) +++ trunk/NEWS 2009-01-28 10:27:15 UTC (rev 63) @@ -1,3 +1,9 @@ +Noteworthy changes for version 0.9.2 (2009-01-28) +------------------------------------------------- + +* Translation changes. + + Noteworthy changes for version 0.9.1 (2008-09-09) ------------------------------------------------- Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-01-22 16:05:17 UTC (rev 62) +++ trunk/configure.ac 2009-01-28 10:27:15 UTC (rev 63) @@ -16,7 +16,7 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [0.9.1]) +m4_define([my_version], [0.9.2]) m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ Modified: trunk/src/versioninfo.rc.in =================================================================== --- trunk/src/versioninfo.rc.in 2009-01-22 16:05:17 UTC (rev 62) +++ trunk/src/versioninfo.rc.in 2009-01-28 10:27:15 UTC (rev 63) @@ -1,5 +1,5 @@ /* versioninfo.rc.in - * Copyright (C) 2005, 2007 g10 Code GmbH + * Copyright (C) 2005, 2007, 2009 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 @@ -39,7 +39,7 @@ VALUE "FileDescription", "GpgEX - GnuPG shell extensions\0" VALUE "FileVersion", "@VERSION@\0" VALUE "InternalName", "gpgex\0" - VALUE "LegalCopyright", "Copyright ? 2007 g10 Code GmbH\0" + VALUE "LegalCopyright", "Copyright ? 2009 g10 Code GmbH\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "gpgex.dll\0" VALUE "PrivateBuild", "\0" From cvs at cvs.gnupg.org Wed Jan 28 11:27:50 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Jan 2009 11:27:50 +0100 Subject: [svn] GpgOL - r294 - tags Message-ID: Author: wk Date: 2009-01-28 11:27:50 +0100 (Wed, 28 Jan 2009) New Revision: 294 Added: tags/gpgol-0.10.18/ Log: Release tag. From cvs at cvs.gnupg.org Wed Jan 28 15:18:44 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 28 Jan 2009 15:18:44 +0100 Subject: [svn] GnuPG - r4923 - in trunk: . doc po scd tools Message-ID: Author: wk Date: 2009-01-28 15:18:40 +0100 (Wed, 28 Jan 2009) New Revision: 4923 Modified: trunk/NEWS trunk/doc/scdaemon.texi trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po trunk/scd/ChangeLog trunk/scd/scdaemon.c trunk/tools/gpgconf-comp.c Log: Make --allow-admin the default. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-01-27 16:38:33 UTC (rev 4922) +++ trunk/scd/ChangeLog 2009-01-28 14:18:40 UTC (rev 4923) @@ -1,3 +1,8 @@ +2009-01-28 Werner Koch + + * scdaemon.c (main): Make --allow-admin the default and make the + option a dummy. + 2009-01-27 Werner Koch * app-geldkarte.c: Changed to use an AID. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-27 16:38:33 UTC (rev 4922) +++ trunk/NEWS 2009-01-28 14:18:40 UTC (rev 4923) @@ -1,7 +1,9 @@ Noteworthy changes in version 2.0.11 (unreleased) ------------------------------------------------- + * [scdaemon] --allow-admin is now the default. + Noteworthy changes in version 2.0.10 (2009-01-12) ------------------------------------------------- Modified: trunk/doc/scdaemon.texi =================================================================== --- trunk/doc/scdaemon.texi 2009-01-27 16:38:33 UTC (rev 4922) +++ trunk/doc/scdaemon.texi 2009-01-28 14:18:40 UTC (rev 4923) @@ -272,15 +272,17 @@ Even if a card reader features a keypad, do not try to use it. - at item --allow-admin - at itemx --deny-admin + at item --deny-admin + at opindex deny-admin @opindex allow-admin - at opindex deny-admin -This enables the use of Admin class commands for card applications -where this is supported. Currently we support it for the OpenPGP -card. Deny is the default. This commands is useful to inhibit -accidental access to admin class command which could ultimately lock -the card through wrong PIN numbers. +This option disables the use of admin class commands for card +applications where this is supported. Currently we support it for the +OpenPGP card. This commands is useful to inhibit accidental access to +admin class command which could ultimately lock the card through wrong +PIN numbers. Note that GnuPG versions older than 2.0.11 featured an + at option{--allow-admin} command which was required to use such admin +commands. This option has no more effect today because the default is +now to allow admin commands. @item --disable-application @var{name} @opindex disable-application @@ -305,16 +307,19 @@ * NKS Card:: The Telesec NetKey card application * DINSIG Card:: The DINSIG card application * PKCS#15 Card:: The PKCS#15 card application +* Geldkarte Card:: The Geldkarte application @end menu @node OpenPGP Card @subsection The OpenPGP card application ``openpgp'' This application is currently only used by @command{gpg} but may in -future also be useful with @command{gpgsm}. +future also be useful with @command{gpgsm}. Version 1 and version 2 of +the card is supported. -The specification for such a card is available at - at uref{http://g10code.com/docs/openpgp-card-1.0.pdf}. +The specifications for these cards are available at + at uref{http://g10code.com/docs/openpgp-card-1.0.pdf} and + at uref{http://g10code.com/docs/openpgp-card-2.0.pdf}. @node NKS Card @subsection The Telesec NetKey card ``nks'' @@ -336,7 +341,14 @@ This is common fraqmework for smart card applications. It is used by @command{gpgsm}. + at node Geldkarte Card + at subsection The Geldkarte card application ``geldkarte'' +This is a simple application to display information of a German +Geldkarte. The Geldkarte is a small amount debit card application which +comes with almost all German banking cards. + + @c ******************************************* @c *************** **************** @c *************** FILES **************** Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-01-27 16:38:33 UTC (rev 4922) +++ trunk/scd/scdaemon.c 2009-01-28 14:18:40 UTC (rev 4923) @@ -136,9 +136,9 @@ N_("|N|disconnect the card after N seconds of inactivity")), ARGPARSE_s_n (oDisableKeypad, "disable-keypad", N_("do not use a reader's keypad")), - ARGPARSE_s_n (oAllowAdmin, "allow-admin", - N_("allow the use of admin card commands")), - ARGPARSE_s_n (oDenyAdmin, "deny-admin", "@"), + ARGPARSE_s_n (oAllowAdmin, "allow-admin", "@"), + ARGPARSE_s_n (oDenyAdmin, "deny-admin", + N_("deny the use of admin card commands")), ARGPARSE_s_s (oDisableApplication, "disable-application", "@"), ARGPARSE_end () @@ -399,6 +399,7 @@ may_coredump = disable_core_dumps (); /* Set default options. */ + opt.allow_admin = 1; opt.pcsc_driver = DEFAULT_PCSC_DRIVER; #ifdef HAVE_W32_SYSTEM @@ -534,7 +535,8 @@ case oDisableKeypad: opt.disable_keypad = 1; break; - case oAllowAdmin: opt.allow_admin = 1; break; + case oAllowAdmin: /* Dummy because allow is now the default. */ + break; case oDenyAdmin: opt.allow_admin = 0; break; case oCardTimeout: opt.card_timeout = pargs.r.ret_ulong; break; @@ -629,7 +631,7 @@ #ifdef HAVE_LIBUSB printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE ); #endif - printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE ); + printf ("deny-admin:%lu:\n", GC_OPT_FLAG_NONE ); printf ("disable-keypad:%lu:\n", GC_OPT_FLAG_NONE ); printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0); Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2009-01-27 16:38:33 UTC (rev 4922) +++ trunk/tools/gpgconf-comp.c 2009-01-28 14:18:40 UTC (rev 4923) @@ -622,8 +622,8 @@ { "Security", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, "gnupg", N_("Options controlling the security") }, - { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, - "gnupg", "allow the use of admin card commands", + { "deny-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "deny the use of admin card commands", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON },