diff --git a/doc/DETAILS b/doc/DETAILS index bab961499..b8f360e35 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -1171,7 +1171,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: Status codes are also used between the components of the GnuPG system via the Assuan S lines. Some of them are documented here: -*** PUBKEY_INFO +*** PUBKEY_INFO The type of the public key in the following D-lines or communicated via a pipe. is the value of =enum pubkey_types= and the Unique Blob ID (UBID) which is the fingerprint of @@ -1179,6 +1179,10 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB: that the keyboxd SEARCH command can be used to lookup the public key using the prefixed with a caret (^). + is a string extra information about the blob. The first + byte is either '-' for standard key or 'e' for an ephemeral key. + The second byte is either '-' or 'r' for a known revoked key. + *** KEYPAIRINFO [] [] This status is emitted by scdaemon and gpg-agent to convey brief diff --git a/kbx/backend-cache.c b/kbx/backend-cache.c index eaef01cf4..c52bcc5de 100644 --- a/kbx/backend-cache.c +++ b/kbx/backend-cache.c @@ -1016,7 +1016,7 @@ be_cache_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request, if (b) { err = be_return_pubkey (ctrl, b->data, b->datalen, - b->pktype, desc[n].u.ubid); + b->pktype, desc[n].u.ubid, 0, 0); blob_unref (b); reqpart->cache_seqno.ubid++; } @@ -1058,7 +1058,7 @@ be_cache_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request, if (b) { err = be_return_pubkey (ctrl, b->data, b->datalen, - PUBKEY_TYPE_OPGP, bl->ubid); + PUBKEY_TYPE_OPGP, bl->ubid, 0, 0); blob_unref (b); } else diff --git a/kbx/backend-kbx.c b/kbx/backend-kbx.c index d70b76097..b48795296 100644 --- a/kbx/backend-kbx.c +++ b/kbx/backend-kbx.c @@ -277,7 +277,8 @@ be_kbx_search (ctrl_t ctrl, backend_handle_t backend_hd, db_request_t request, &pubkey_type, ubid); if (err) goto leave; - err = be_return_pubkey (ctrl, buffer, buflen, pubkey_type, ubid); + /* FIXME: Return the ephemeral flag. */ + err = be_return_pubkey (ctrl, buffer, buflen, pubkey_type, ubid, 0, 0); if (!err) be_cache_pubkey (ctrl, ubid, buffer, buflen, pubkey_type); xfree (buffer); diff --git a/kbx/backend-sqlite.c b/kbx/backend-sqlite.c index 3576d3d6d..ce3521317 100644 --- a/kbx/backend-sqlite.c +++ b/kbx/backend-sqlite.c @@ -115,6 +115,10 @@ static struct "ubid BLOB NOT NULL PRIMARY KEY," /* The type of the public key: 1 = openpgp, 2 = X.509. */ "type INTEGER NOT NULL," + /* The Ephemeral flag as used by gpgsm. Values: 0 or 1. */ + "ephemeral INTEGER NOT NULL DEFAULT 0," + /* The Revoked flag as set by gpgsm. Values: 0 or 1. */ + "revoked INTEGER NOT NULL DEFAULT 0," /* The OpenPGP keyblock or X.509 certificate. */ "keyblob BLOB NOT NULL" ")" }, @@ -752,17 +756,18 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_EXACT: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, userid as u" " WHERE p.ubid = u.ubid AND u.uid = ?1", extra, &ctx->select_stmt); if (!err) err = run_sql_bind_text (ctx->select_stmt, 1, desc[descidx].u.name); break; - case KEYDB_SEARCH_MODE_MAIL: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, userid as u" " WHERE p.ubid = u.ubid AND u.addrspec = ?1", extra, &ctx->select_stmt); @@ -772,7 +777,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_MAILSUB: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, userid as u" " WHERE p.ubid = u.ubid AND u.addrspec LIKE ?1", extra, &ctx->select_stmt); @@ -783,7 +789,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_SUBSTR: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, userid as u" " WHERE p.ubid = u.ubid AND u.uid LIKE ?1", extra, &ctx->select_stmt); @@ -799,7 +806,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_ISSUER: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, issuer as i" " WHERE p.ubid = i.ubid" " AND i.dn = $1", @@ -819,7 +827,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, else { if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral," + " p.revoked, p.keyblob" " FROM pubkey as p, issuer as i" " WHERE p.ubid = i.ubid" " AND i.sn = $1 AND i.dn = $2", @@ -841,7 +850,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, break; case KEYDB_SEARCH_MODE_SUBJECT: - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, userid as u" " WHERE p.ubid = u.ubid" " AND u.uid = $1", @@ -860,7 +870,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_LONG_KID: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral," + " p.revoked, p.keyblob" " FROM pubkey as p, fingerprint as f" " WHERE p.ubid = f.ubid AND f.kid = ?1", extra, &ctx->select_stmt); @@ -871,7 +882,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_FPR: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral," + " p.revoked, p.keyblob" " FROM pubkey as p, fingerprint as f" " WHERE p.ubid = f.ubid AND f.fpr = ?1", extra, &ctx->select_stmt); @@ -882,7 +894,8 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_KEYGRIP: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT p.ubid, p.type, p.keyblob" + err = run_sql_prepare ("SELECT p.ubid, p.type, p.ephemeral, p.revoked," + " p.keyblob" " FROM pubkey as p, fingerprint as f" " WHERE p.ubid = f.ubid AND f.keygrip = ?1", extra, &ctx->select_stmt); @@ -893,7 +906,7 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, case KEYDB_SEARCH_MODE_UBID: if (!ctx->select_stmt) - err = run_sql_prepare ("SELECT ubid, type, keyblob" + err = run_sql_prepare ("SELECT ubid, type, ephemeral, revoked, keyblob" " FROM pubkey as p" " WHERE ubid = ?1", extra, &ctx->select_stmt); @@ -914,7 +927,7 @@ run_select_statement (ctrl_t ctrl, be_sqlite_local_t ctx, else extra = " ORDER by ubid"; - err = run_sql_prepare ("SELECT ubid, type, keyblob" + err = run_sql_prepare ("SELECT ubid, type, ephemeral, keyblob" " FROM pubkey as p", extra, &ctx->select_stmt); } @@ -992,6 +1005,7 @@ be_sqlite_search (ctrl_t ctrl, const void *ubid, *keyblob; size_t keybloblen; enum pubkey_types pubkey_type; + int is_ephemeral, is_revoked; ubid = sqlite3_column_blob (ctx->select_stmt, 0); n = sqlite3_column_bytes (ctx->select_stmt, 0); @@ -1024,8 +1038,30 @@ be_sqlite_search (ctrl_t ctrl, } pubkey_type = n; - keyblob = sqlite3_column_blob (ctx->select_stmt, 2); - n = sqlite3_column_bytes (ctx->select_stmt, 2); + n = sqlite3_column_int (ctx->select_stmt, 2); + if (!n && sqlite3_errcode (database_hd) == SQLITE_NOMEM) + { + err = gpg_error (gpg_err_code_from_sqlite (SQLITE_NOMEM)); + show_sqlstmt (ctx->select_stmt); + log_error ("error in returned SQL column EPHEMERAL: %s)\n", + gpg_strerror (err)); + goto leave; + } + is_ephemeral = !!n; + + n = sqlite3_column_int (ctx->select_stmt, 3); + if (!n && sqlite3_errcode (database_hd) == SQLITE_NOMEM) + { + err = gpg_error (gpg_err_code_from_sqlite (SQLITE_NOMEM)); + show_sqlstmt (ctx->select_stmt); + log_error ("error in returned SQL column REVOKED: %s)\n", + gpg_strerror (err)); + goto leave; + } + is_revoked = !!n; + + keyblob = sqlite3_column_blob (ctx->select_stmt, 4); + n = sqlite3_column_bytes (ctx->select_stmt, 4); if (!keyblob || n < 0) { if (!keyblob && sqlite3_errcode (database_hd) == SQLITE_NOMEM) @@ -1039,7 +1075,8 @@ be_sqlite_search (ctrl_t ctrl, } keybloblen = n; - err = be_return_pubkey (ctrl, keyblob, keybloblen, pubkey_type, ubid); + err = be_return_pubkey (ctrl, keyblob, keybloblen, pubkey_type, + ubid, is_ephemeral, is_revoked); if (!err) be_cache_pubkey (ctrl, ubid, keyblob, keybloblen, pubkey_type); } diff --git a/kbx/backend-support.c b/kbx/backend-support.c index 7a7d11b90..a35088c74 100644 --- a/kbx/backend-support.c +++ b/kbx/backend-support.c @@ -166,13 +166,17 @@ be_find_request_part (backend_handle_t backend_hd, db_request_t request, * PUBKEY_TYPE to the caller. */ gpg_error_t be_return_pubkey (ctrl_t ctrl, const void *buffer, size_t buflen, - enum pubkey_types pubkey_type, const unsigned char *ubid) + enum pubkey_types pubkey_type, const unsigned char *ubid, + int is_ephemeral, int is_revoked) { gpg_error_t err; char hexubid[2*UBID_LEN+1]; bin2hex (ubid, UBID_LEN, hexubid); - err = status_printf (ctrl, "PUBKEY_INFO", "%d %s", pubkey_type, hexubid); + err = status_printf (ctrl, "PUBKEY_INFO", "%d %s %c%c", + pubkey_type, hexubid, + is_ephemeral? 'e':'-', + is_revoked? 'r':'-' ); if (err) goto leave; diff --git a/kbx/backend.h b/kbx/backend.h index 7086ac900..a857fc77c 100644 --- a/kbx/backend.h +++ b/kbx/backend.h @@ -115,7 +115,8 @@ gpg_error_t be_find_request_part (backend_handle_t backend_hd, db_request_part_t *r_part); gpg_error_t be_return_pubkey (ctrl_t ctrl, const void *buffer, size_t buflen, enum pubkey_types pubkey_type, - const unsigned char *ubid); + const unsigned char *ubid, + int is_ephemeral, int is_revoked); int be_is_x509_blob (const unsigned char *blob, size_t bloblen); gpg_error_t be_ubid_from_blob (const void *blob, size_t bloblen, enum pubkey_types *r_pktype, char *r_ubid);