From 0c924641e6d47761c493f80b10eecb97c7aab298 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 18 Apr 2019 16:14:16 +0200 Subject: [PATCH] pki: Add different output options for --keyid Makes machine-processing these identifiers easier. --- src/pki/commands/keyid.c | 116 ++++++++++++++++++++++++++++++++--- src/pki/man/pki---keyid.1.in | 37 ++++++++--- 2 files changed, 138 insertions(+), 15 deletions(-) diff --git a/src/pki/commands/keyid.c b/src/pki/commands/keyid.c index 001b9ff5c1..10651f5ca7 100644 --- a/src/pki/commands/keyid.c +++ b/src/pki/commands/keyid.c @@ -21,6 +21,46 @@ #include #include +typedef enum { + FORMAT_PRETTY, + FORMAT_HEX, + FORMAT_BASE64, + FORMAT_BINARY, +} format_t; + +/** + * Print a single keyid in the requested format + */ +static bool print_id(chunk_t id, format_t format, char *desc) +{ + chunk_t chunk; + + switch (format) + { + case FORMAT_PRETTY: + printf("%s:\n %#B\n", desc, &id); + break; + case FORMAT_HEX: + chunk = chunk_to_hex(id, NULL, FALSE); + printf("%.*s\n", (int)chunk.len, chunk.ptr); + chunk_free(&chunk); + break; + case FORMAT_BASE64: + chunk = chunk_to_base64(id, NULL); + printf("%.*s\n", (int)chunk.len, chunk.ptr); + chunk_free(&chunk); + break; + case FORMAT_BINARY: + if (fwrite(id.ptr, id.len, 1, stdout) != 1) + { + fprintf(stderr, "writing %s failed\n", desc); + return FALSE; + } + break; + } + return TRUE; +} + /** * Calculate the keyid of a key/certificate */ @@ -31,9 +71,15 @@ static int keyid() certificate_t *cert; private_key_t *private; public_key_t *public; + format_t format = FORMAT_PRETTY; + enum { + ID_TYPE_ALL, + ID_TYPE_SPK, + ID_TYPE_SPKI, + } id_type = FORMAT_PRETTY; char *file = NULL, *keyid = NULL; void *cred; - chunk_t id; + chunk_t id, spk = chunk_empty, spki = chunk_empty; char *arg; while (TRUE) @@ -86,6 +132,38 @@ static int keyid() return command_usage( "invalid input type"); } continue; + case 'I': + if (streq(arg, "spk")) + { + id_type = ID_TYPE_SPK; + } + else if (streq(arg, "spki")) + { + id_type = ID_TYPE_SPKI; + } + else if (!streq(arg, "all")) + { + return command_usage( "invalid id type"); + } + continue; + case 'f': + if (streq(arg, "hex")) + { + format = FORMAT_HEX; + } + else if (streq(arg, "base64")) + { + format = FORMAT_BASE64; + } + else if (streq(arg, "bin")) + { + format = FORMAT_BINARY; + } + else if (!streq(arg, "pretty")) + { + return command_usage( "invalid output format"); + } + continue; case 'i': file = arg; continue; @@ -138,11 +216,11 @@ static int keyid() private = cred; if (private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &id)) { - printf("subjectKeyIdentifier: %#B\n", &id); + spk = chunk_clone(id); } if (private->get_fingerprint(private, KEYID_PUBKEY_INFO_SHA1, &id)) { - printf("subjectPublicKeyInfo hash: %#B\n", &id); + spki = chunk_clone(id); } private->destroy(private); } @@ -151,11 +229,11 @@ static int keyid() public = cred; if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &id)) { - printf("subjectKeyIdentifier: %#B\n", &id); + spk = chunk_clone(id); } if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &id)) { - printf("subjectPublicKeyInfo hash: %#B\n", &id); + spki = chunk_clone(id); } public->destroy(public); } @@ -170,15 +248,34 @@ static int keyid() } if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &id)) { - printf("subjectKeyIdentifier: %#B\n", &id); + spk = chunk_clone(id); } if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &id)) { - printf("subjectPublicKeyInfo hash: %#B\n", &id); + spki = chunk_clone(id); } public->destroy(public); cert->destroy(cert); } + + if (id_type == ID_TYPE_ALL || id_type == ID_TYPE_SPK) + { + if (!spk.len || + !print_id(spk, format, "subjkey (SHA-1 of subjectPublicKey)")) + { + return 1; + } + } + if (id_type == ID_TYPE_ALL || id_type == ID_TYPE_SPKI) + { + if (!spki.len || + !print_id(spki, format, "keyid (SHA-1 of subjectPublicKeyInfo)")) + { + return 1; + } + } + chunk_free(&spk); + chunk_free(&spki); return 0; } @@ -190,12 +287,15 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { keyid, 'k', "keyid", "calculate key identifiers of a key/certificate", - {"[--in file|--keyid hex] [--type priv|rsa|ecdsa|bliss|pub|pkcs10|x509]"}, + {"[--in file|--keyid hex] [--type priv|rsa|ecdsa|bliss|pub|pkcs10|x509]", + "[--id all|spk|spki] [--format pretty|hex|base64|bin]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, {"keyid", 'x', 1, "smartcard or TPM private key object handle"}, {"type", 't', 1, "type of key, default: priv"}, + {"id", 'I', 1, "type of identifier, default: all"}, + {"format", 'f', 1, "output format, default: pretty"}, } }); } diff --git a/src/pki/man/pki---keyid.1.in b/src/pki/man/pki---keyid.1.in index 148b95ec3c..594643a22c 100644 --- a/src/pki/man/pki---keyid.1.in +++ b/src/pki/man/pki---keyid.1.in @@ -1,4 +1,4 @@ -.TH "PKI \-\-KEYID" 1 "2013-07-31" "@PACKAGE_VERSION@" "strongSwan" +.TH "PKI \-\-KEYID" 1 "2019-04-29" "@PACKAGE_VERSION@" "strongSwan" . .SH "NAME" . @@ -11,6 +11,8 @@ pki \-\-keyid \- Calculate key identifiers of a key or certificate .IR file | \fB\-\-keyid\fR .IR hex ] .OP \-\-type type +.OP \-\-id id-type +.OP \-\-format format .OP \-\-debug level .YS . @@ -54,23 +56,44 @@ Type of input. One of \fIpriv\fR (private key), \fIrsa\fR (RSA private key), \fIecdsa\fR (ECDSA private key), \fIbliss\fR (BLISS private key), \fIpub\fR (public key), \fIpkcs10\fR (PKCS#10 certificate request), \fIx509\fR (X.509 certificate), defaults to \fIpriv\fR. +.TP +.BI "\-I, \-\-id " id-type +Type of identifier. One of \fIall\fR (all identifiers), \fIspk\fR (SHA-1 hash +of subjectPublicKey), \fIspki\fR (SHA-1 hash of subjectPublicKeyInfo), defaults +to \fIall\fR. +.TP +.BI "\-f, \-\-format " format +Output format. One of \fIpretty\fR (user-readable output), \fIhex\fR +(hexadecimal encoding), \fIbase64\fR (Base64 encoding), \fIbin\fR (raw binary +data), defaults to \fIpretty\fR. . .SH "EXAMPLES" . Calculate key identifiers of an RSA private key: .PP .EX - pki --keyid --in key.der - subjectKeyIdentifier: 6a:9c:74:d1:f8:89:79:89:f6:5a:94:e9:89:f1... - subjectPublicKeyInfo hash: 6e:55:dc:7e:9c:a5:58:d9:5b:e3:c7:13:14:e1... + $ pki --keyid --in key.der + subjkey (SHA-1 of subjectPublicKey): + 6a:9c:74:d1:f8:89:79:89:f6:5a:94:e9:89:f1... + keyid (SHA-1 of subjectPublicKeyInfo): + 6e:55:dc:7e:9c:a5:58:d9:5b:e3:c7:13:14:e1... .EE .PP Calculate key identifiers of an X.509 certificate: .PP .EX - pki --keyid --in cert.der --type x509 - subjectKeyIdentifier: 6a:9c:74:d1:f8:89:79:89:f6:5a:94:e9:89:f1... - subjectPublicKeyInfo hash: 6e:55:dc:7e:9c:a5:58:d9:5b:e3:c7:13:14:e1... + $ pki --keyid --in cert.der --type x509 + subjkey (SHA-1 of subjectPublicKey): + 6a:9c:74:d1:f8:89:79:89:f6:5a:94:e9:89:f1... + keyid (SHA-1 of subjectPublicKeyInfo): + 6e:55:dc:7e:9c:a5:58:d9:5b:e3:c7:13:14:e1... +.EE +.PP +Calculate keyid in simple hex encoding of an X.509 certificate: +.PP +.EX + $ pki --keyid --in cert.der --type x509 --id spki --format hex + 6e55dc7e9ca558d95be3c71314e1... .EE .PP . -- 2.47.2