diff options
author | wolfbeast <mcwerewolf@gmail.com> | 2018-12-17 14:12:04 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@gmail.com> | 2018-12-17 14:12:04 +0100 |
commit | 51b821b3fdc5a7eab2369cb6a6680598a6264b08 (patch) | |
tree | f3608a518bbb9e31b0a42b9a10742fb11ef5b39b /security/nss/cmd/certutil | |
parent | 8e44bbb43789e585fab9fc1ce8becc94b45d566c (diff) | |
parent | 680c3eadb6aaec1f3653636db081a519e0f62ef5 (diff) | |
download | UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar.gz UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar.lz UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.tar.xz UXP-51b821b3fdc5a7eab2369cb6a6680598a6264b08.zip |
Merge branch 'master' into Sync-weave
Diffstat (limited to 'security/nss/cmd/certutil')
-rw-r--r-- | security/nss/cmd/certutil/certutil.c | 168 |
1 files changed, 124 insertions, 44 deletions
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index dbb93c922..df02e4439 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -741,6 +741,9 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date, case 'V': usage = certificateUsageSSLServer; break; + case 'I': + usage = certificateUsageIPsec; + break; case 'S': usage = certificateUsageEmailSigner; break; @@ -856,41 +859,59 @@ SECItemToHex(const SECItem *item, char *dst) } static const char *const keyTypeName[] = { - "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec", "rsaPss" + "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec", "rsaPss", "rsaOaep" }; #define MAX_CKA_ID_BIN_LEN 20 #define MAX_CKA_ID_STR_LEN 40 -/* print key number, key ID (in hex or ASCII), key label (nickname) */ -static SECStatus -PrintKey(PRFileDesc *out, const char *nickName, int count, - SECKEYPrivateKey *key, void *pwarg) +/* output human readable key ID in buffer, which should have at least + * MAX_CKA_ID_STR_LEN + 3 octets (quotations and a null terminator) */ +static void +formatPrivateKeyID(SECKEYPrivateKey *privkey, char *buffer) { SECItem *ckaID; - char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; - pwarg = NULL; - ckaID = PK11_GetLowLevelKeyIDForPrivateKey(key); + ckaID = PK11_GetLowLevelKeyIDForPrivateKey(privkey); if (!ckaID) { - strcpy(ckaIDbuf, "(no CKA_ID)"); + strcpy(buffer, "(no CKA_ID)"); } else if (ItemIsPrintableASCII(ckaID)) { int len = PR_MIN(MAX_CKA_ID_STR_LEN, ckaID->len); - ckaIDbuf[0] = '"'; - memcpy(ckaIDbuf + 1, ckaID->data, len); - ckaIDbuf[1 + len] = '"'; - ckaIDbuf[2 + len] = '\0'; + buffer[0] = '"'; + memcpy(buffer + 1, ckaID->data, len); + buffer[1 + len] = '"'; + buffer[2 + len] = '\0'; } else { /* print ckaid in hex */ SECItem idItem = *ckaID; if (idItem.len > MAX_CKA_ID_BIN_LEN) idItem.len = MAX_CKA_ID_BIN_LEN; - SECItemToHex(&idItem, ckaIDbuf); + SECItemToHex(&idItem, buffer); } + SECITEM_ZfreeItem(ckaID, PR_TRUE); +} + +/* print key number, key ID (in hex or ASCII), key label (nickname) */ +static SECStatus +PrintKey(PRFileDesc *out, const char *nickName, int count, + SECKEYPrivateKey *key, void *pwarg) +{ + char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; + CERTCertificate *cert; + KeyType keyType; + + pwarg = NULL; + formatPrivateKeyID(key, ckaIDbuf); + cert = PK11_GetCertFromPrivateKey(key); + if (cert) { + keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo); + CERT_DestroyCertificate(cert); + } else { + keyType = key->keyType; + } PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count, - keyTypeName[key->keyType], ckaIDbuf, nickName); - SECITEM_ZfreeItem(ckaID, PR_TRUE); + keyTypeName[keyType], ckaIDbuf, nickName); return SECSuccess; } @@ -1002,7 +1023,7 @@ ListKeys(PK11SlotInfo *slot, const char *nickName, int index, } static SECStatus -DeleteKey(char *nickname, secuPWData *pwdata) +DeleteCertAndKey(char *nickname, secuPWData *pwdata) { SECStatus rv; CERTCertificate *cert; @@ -1031,6 +1052,61 @@ DeleteKey(char *nickname, secuPWData *pwdata) return rv; } +static SECKEYPrivateKey * +findPrivateKeyByID(PK11SlotInfo *slot, const char *ckaID, secuPWData *pwarg) +{ + PORTCheapArenaPool arena; + SECItem ckaIDItem = { 0 }; + SECKEYPrivateKey *privkey = NULL; + SECStatus rv; + + if (PK11_NeedLogin(slot)) { + rv = PK11_Authenticate(slot, PR_TRUE, pwarg); + if (rv != SECSuccess) { + SECU_PrintError(progName, "could not authenticate to token %s.", + PK11_GetTokenName(slot)); + return NULL; + } + } + + if (0 == PL_strncasecmp("0x", ckaID, 2)) { + ckaID += 2; /* skip leading "0x" */ + } + PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE); + if (SECU_HexString2SECItem(&arena.arena, &ckaIDItem, ckaID)) { + privkey = PK11_FindKeyByKeyID(slot, &ckaIDItem, pwarg); + } + PORT_DestroyCheapArena(&arena); + return privkey; +} + +static SECStatus +DeleteKey(SECKEYPrivateKey *privkey, secuPWData *pwarg) +{ + SECStatus rv; + PK11SlotInfo *slot; + + slot = PK11_GetSlotFromPrivateKey(privkey); + if (PK11_NeedLogin(slot)) { + rv = PK11_Authenticate(slot, PR_TRUE, pwarg); + if (rv != SECSuccess) { + SECU_PrintError(progName, "could not authenticate to token %s.", + PK11_GetTokenName(slot)); + return SECFailure; + } + } + + rv = PK11_DeleteTokenPrivateKey(privkey, PR_TRUE); + if (rv != SECSuccess) { + char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4]; + formatPrivateKeyID(privkey, ckaIDbuf); + SECU_PrintError("problem deleting private key \"%s\"\n", ckaIDbuf); + } + + PK11_FreeSlot(slot); + return rv; +} + /* * L i s t M o d u l e s * @@ -1100,7 +1176,9 @@ PrintSyntax() "\t\t [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -E -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n", progName); - FPS "\t%s -F -n nickname [-d certdir] [-P dbprefix]\n", + FPS "\t%s -F -n cert-name [-d certdir] [-P dbprefix]\n", + progName); + FPS "\t%s -F -k key-id [-d certdir] [-P dbprefix]\n", progName); FPS "\t%s -G -n key-name [-h token-name] [-k rsa] [-g key-size] [-y exp]\n" "\t\t [-f pwfile] [-z noisefile] [-d certdir] [-P dbprefix]\n", progName); @@ -1390,6 +1468,8 @@ luF(enum usage_level ul, const char *command) return; FPS "%-20s The nickname of the key to delete\n", " -n cert-name"); + FPS "%-20s The key id of the key to delete, obtained using -K\n", + " -k key-id"); FPS "%-20s Cert database directory (default is ~/.netscape)\n", " -d certdir"); FPS "%-20s Cert & Key database prefix\n", @@ -1629,6 +1709,7 @@ luV(enum usage_level ul, const char *command) FPS "%-20s Specify certificate usage:\n", " -u certusage"); FPS "%-25s C \t SSL Client\n", ""); FPS "%-25s V \t SSL Server\n", ""); + FPS "%-25s I \t IPsec\n", ""); FPS "%-25s L \t SSL CA\n", ""); FPS "%-25s A \t Any CA\n", ""); FPS "%-25s Y \t Verify CA\n", ""); @@ -2944,10 +3025,9 @@ certutil_main(int argc, char **argv, PRBool initialize) readOnly = !certutil.options[opt_RW].activated; } - /* -A, -D, -F, -M, -S, -V, and all require -n */ + /* -A, -D, -M, -S, -V, and all require -n */ if ((certutil.commands[cmd_AddCert].activated || certutil.commands[cmd_DeleteCert].activated || - certutil.commands[cmd_DeleteKey].activated || certutil.commands[cmd_DumpChain].activated || certutil.commands[cmd_ModifyCertTrust].activated || certutil.commands[cmd_CreateAndAddCert].activated || @@ -3034,6 +3114,16 @@ certutil_main(int argc, char **argv, PRBool initialize) return 255; } + /* Delete needs a nickname or a key ID */ + if (certutil.commands[cmd_DeleteKey].activated && + !(certutil.options[opt_Nickname].activated || keysource)) { + PR_fprintf(PR_STDERR, + "%s -%c: specify a nickname (-n) or\n" + " a key ID (-k).\n", + commandToRun, progName); + return 255; + } + /* Upgrade/Merge needs a source database and a upgrade id. */ if (certutil.commands[cmd_UpgradeMerge].activated && !(certutil.options[opt_SourceDir].activated && @@ -3396,7 +3486,19 @@ certutil_main(int argc, char **argv, PRBool initialize) } /* Delete key (-F) */ if (certutil.commands[cmd_DeleteKey].activated) { - rv = DeleteKey(name, &pwdata); + if (certutil.options[opt_Nickname].activated) { + rv = DeleteCertAndKey(name, &pwdata); + } else { + privkey = findPrivateKeyByID(slot, keysource, &pwdata); + if (!privkey) { + SECU_PrintError(progName, "%s is not a key-id", keysource); + rv = SECFailure; + } else { + rv = DeleteKey(privkey, &pwdata); + /* already destroyed by PK11_DeleteTokenPrivateKey */ + privkey = NULL; + } + } goto shutdown; } /* Modify trust attribute for cert (-M) */ @@ -3468,30 +3570,8 @@ certutil_main(int argc, char **argv, PRBool initialize) if (keycert) { privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata); } else { - PLArenaPool *arena = NULL; - SECItem keyidItem = { 0 }; - char *keysourcePtr = keysource; /* Interpret keysource as CKA_ID */ - if (PK11_NeedLogin(slot)) { - rv = PK11_Authenticate(slot, PR_TRUE, &pwdata); - if (rv != SECSuccess) { - SECU_PrintError(progName, "could not authenticate to token %s.", - PK11_GetTokenName(slot)); - return SECFailure; - } - } - if (0 == PL_strncasecmp("0x", keysource, 2)) { - keysourcePtr = keysource + 2; // skip leading "0x" - } - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - SECU_PrintError(progName, "unable to allocate arena"); - return SECFailure; - } - if (SECU_HexString2SECItem(arena, &keyidItem, keysourcePtr)) { - privkey = PK11_FindKeyByKeyID(slot, &keyidItem, &pwdata); - } - PORT_FreeArena(arena, PR_FALSE); + privkey = findPrivateKeyByID(slot, keysource, &pwdata); } if (!privkey) { |