Skip to content

Commit 210034b

Browse files
Merge pull request rnpgp#285 from riboseinc/dewyatt-add-key-flag-printing
Add key flag loading/printing in listed keys.
2 parents bb5dafa + 774d10a commit 210034b

File tree

4 files changed

+72
-3
lines changed

4 files changed

+72
-3
lines changed

src/lib/key_store_pgp.c

+4
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ cb_keyring_read(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
205205
revocation->code = pkt->u.ss_revocation.code;
206206
revocation->reason = rnp_strdup(pgp_show_ss_rr_code(pkt->u.ss_revocation.code));
207207
break;
208+
case PGP_PTAG_SS_KEY_FLAGS:
209+
key = &keyring->keys[keyring->keyc - 1];
210+
key->flags = pkt->u.ss_key_flags.contents[0];
211+
break;
208212
case PGP_PTAG_CT_SIGNATURE_FOOTER:
209213
case PGP_PARSER_ERRCODE:
210214
break;

src/lib/packet-print.c

+42-2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ __RCSID("$NetBSD: packet-print.c,v 1.42 2012/02/22 06:29:40 agc Exp $");
100100
#define SIGNATURE_PADDING " "
101101

102102
/* static functions */
103+
static bool format_key_usage(char *buffer, size_t size, uint8_t flags);
103104
extern ec_curve_desc_t ec_curves[PGP_CURVE_MAX];
104105

105106
static void
@@ -385,14 +386,17 @@ psubkeybinding(char *buf, size_t size, const pgp_key_t *key, const char *expired
385386
{
386387
char keyid[512];
387388
char t[32];
389+
char key_usage[8];
388390

391+
format_key_usage(key_usage, sizeof(key_usage), key->flags);
389392
return snprintf(buf,
390393
size,
391-
"encryption %d/%s %s %s %s\n",
394+
"encryption %d/%s %s %s [%s] %s\n",
392395
numkeybits(&key->enckey),
393396
pgp_show_pka(key->enckey.alg),
394397
rnp_strhexdump(keyid, key->encid, PGP_KEY_ID_SIZE, ""),
395398
ptimestr(t, sizeof(t), key->enckey.birthtime),
399+
key_usage,
396400
expired);
397401
}
398402

@@ -557,6 +561,29 @@ format_uid_notice(char * buffer,
557561
return n;
558562
}
559563

564+
static bool
565+
format_key_usage(char *buffer, size_t size, uint8_t flags)
566+
{
567+
static const pgp_bit_map_t flags_map[] = {
568+
{PGP_KF_ENCRYPT_COMMS | PGP_KF_ENCRYPT_STORAGE, "E"},
569+
{PGP_KF_SIGN, "S"},
570+
{PGP_KF_CERTIFY, "C"},
571+
{PGP_KF_AUTH, "A"},
572+
};
573+
574+
*buffer = '\0';
575+
for (size_t i = 0; i < PGP_ARRAY_SIZE(flags_map); i++) {
576+
if (flags & flags_map[i].mask) {
577+
const size_t current_length = strlen(buffer);
578+
if (current_length == size - 1) {
579+
return false;
580+
}
581+
strncat(buffer, flags_map[i].string, size - current_length - 1);
582+
}
583+
}
584+
return true;
585+
}
586+
560587
#ifndef KB
561588
#define KB(x) ((x) *1024)
562589
#endif
@@ -584,6 +611,7 @@ pgp_sprint_keydata(pgp_io_t * io,
584611
char fingerprint[(PGP_FINGERPRINT_SIZE * 3) + 1];
585612
char expiration_notice[128];
586613
char birthtime[32];
614+
char key_usage[8];
587615

588616
if (key->revoked)
589617
return -1;
@@ -628,6 +656,10 @@ pgp_sprint_keydata(pgp_io_t * io,
628656

629657
ptimestr(birthtime, sizeof(birthtime), pubkey->birthtime);
630658

659+
if (!format_key_usage(key_usage, sizeof(key_usage), key->flags)) {
660+
return -1;
661+
}
662+
631663
/* XXX: For now we assume that the output string won't exceed 16KiB
632664
* in length but this is completely arbitrary. What this
633665
* really needs is some objective facts to base this
@@ -639,12 +671,13 @@ pgp_sprint_keydata(pgp_io_t * io,
639671
if (string != NULL) {
640672
total_length = snprintf(string,
641673
KB(16),
642-
"%s %d/%s %s %s %s\nKey fingerprint: %s\n%s",
674+
"%s %d/%s %s %s [%s] %s\nKey fingerprint: %s\n%s",
643675
header,
644676
numkeybits(pubkey),
645677
pgp_show_pka(pubkey->alg),
646678
keyid,
647679
birthtime,
680+
key_usage,
648681
expiration_notice,
649682
fingerprint,
650683
uid_notices);
@@ -668,6 +701,7 @@ pgp_sprint_json(pgp_io_t * io,
668701
{
669702
char keyid[PGP_KEY_ID_SIZE * 3];
670703
char fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
704+
char key_usage[8];
671705
int r;
672706
unsigned i;
673707
unsigned j;
@@ -676,6 +710,10 @@ pgp_sprint_json(pgp_io_t * io,
676710
return -1;
677711
}
678712

713+
if (!format_key_usage(key_usage, sizeof(key_usage), key->flags)) {
714+
return -1;
715+
}
716+
679717
// add the top-level values
680718
json_object_object_add(keyjson, "header", json_object_new_string(header));
681719
json_object_object_add(keyjson, "key bits", json_object_new_int(numkeybits(pubkey)));
@@ -691,6 +729,8 @@ pgp_sprint_json(pgp_io_t * io,
691729
rnp_strhexdump(fp, key->sigfingerprint.fingerprint, key->sigfingerprint.length, "")));
692730
json_object_object_add(keyjson, "birthtime", json_object_new_int(pubkey->birthtime));
693731
json_object_object_add(keyjson, "duration", json_object_new_int(pubkey->duration));
732+
json_object_object_add(keyjson, "flags", json_object_new_int(key->flags));
733+
json_object_object_add(keyjson, "usage", json_object_new_string(key_usage));
694734

695735
// iterating through the uids
696736
for (i = 0; i < key->uidc; i++) {

src/lib/packet.h

+17
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,22 @@ typedef enum {
606606
PGP_SIG_3RD_PARTY = 0x50 /* Third-Party Confirmation signature */
607607
} pgp_sig_type_t;
608608

609+
/** Key Flags
610+
*
611+
* \see RFC4880 5.2.3.21
612+
*/
613+
typedef enum {
614+
PGP_KF_CERTIFY = 0x01, /* This key may be used to certify other keys. */
615+
PGP_KF_SIGN = 0x02, /* This key may be used to sign data. */
616+
PGP_KF_ENCRYPT_COMMS = 0x04, /* This key may be used to encrypt communications. */
617+
PGP_KF_ENCRYPT_STORAGE = 0x08, /* This key may be used to encrypt storage. */
618+
PGP_KF_SPLIT = 0x10, /* The private component of this key may have been split
619+
by a secret-sharing mechanism. */
620+
PGP_KF_AUTH = 0x20, /* This key may be used for authentication. */
621+
PGP_KF_SHARED = 0x80 /* The private component of this key may be in the
622+
possession of more than one person. */
623+
} pgp_key_flags_t;
624+
609625
/** Struct to hold params of an RSA signature */
610626
typedef struct pgp_rsa_sig_t {
611627
BIGNUM *sig; /* the signature value (m^d % n) */
@@ -1004,6 +1020,7 @@ typedef struct pgp_key_t {
10041020
DYNARRAY(pgp_revoke_t, revoke); /* array of signature revocations */
10051021
pgp_content_enum type; /* type of key */
10061022
pgp_keydata_key_t key; /* pubkey/seckey data */
1023+
uint8_t flags; /* key flags */
10071024
pgp_pubkey_t sigkey; /* signature key */
10081025
uint8_t sigid[PGP_KEY_ID_SIZE];
10091026
pgp_fingerprint_t sigfingerprint; /* pgp signature fingerprint */

src/lib/rnp.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ format_json_key(FILE *fp, json_object *obj, const int psigs)
325325
birthtime = (int64_t) strtoll(json_object_get_string(tmp), NULL, 10);
326326
p(fp, " ", ptimestr(tbuf, sizeof(tbuf), birthtime), NULL);
327327

328+
if (json_object_object_get_ex(obj, "usage", &tmp)) {
329+
p(fp, " [", json_object_get_string(tmp), "]", NULL);
330+
}
331+
328332
if (json_object_object_get_ex(obj, "duration", &tmp)) {
329333
duration = (int64_t) strtoll(json_object_get_string(tmp), NULL, 10);
330334
if (duration > 0) {
@@ -356,6 +360,7 @@ format_json_key(FILE *fp, json_object *obj, const int psigs)
356360

357361
if (json_object_object_get_ex(obj, "encryption", &tmp)) {
358362
if (!json_object_is_type(tmp, json_type_null)) {
363+
json_object *usage;
359364
p(fp, "encryption", NULL);
360365
pobj(fp, json_object_array_get_idx(tmp, 0), 1); /* size */
361366
p(fp, "/", NULL);
@@ -368,8 +373,11 @@ format_json_key(FILE *fp, json_object *obj, const int psigs)
368373
sizeof(tbuf),
369374
(time_t) strtoll(
370375
json_object_get_string(json_object_array_get_idx(tmp, 3)), NULL, 10)),
371-
"\n",
372376
NULL);
377+
if (json_object_object_get_ex(obj, "usage", &usage)) {
378+
p(fp, " [", json_object_get_string(usage), "]", NULL);
379+
}
380+
p(fp, "\n", NULL);
373381
}
374382
}
375383

0 commit comments

Comments
 (0)