зеркало из https://github.com/mozilla/pjs.git
[Bug 291384] certutil -K behavior doesn't match usage. r=rrelyea
This commit is contained in:
Родитель
94cd3fb8f5
Коммит
bcc5a811f7
|
@ -539,7 +539,7 @@ listCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
|
|||
}
|
||||
|
||||
static SECStatus
|
||||
ListCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
|
||||
ListCerts(CERTCertDBHandle *handle, char *nickname, PK11SlotInfo *slot,
|
||||
PRBool raw, PRBool ascii, PRFileDesc *outfile, secuPWData *pwdata)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
@ -557,7 +557,7 @@ ListCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
|
|||
CERT_DestroyCertList(list);
|
||||
return SECSuccess;
|
||||
} else {
|
||||
rv = listCerts(handle,name,slot,raw,ascii,outfile,pwdata);
|
||||
rv = listCerts(handle,nickname,slot,raw,ascii,outfile,pwdata);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -697,67 +697,158 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
|
|||
return (rv);
|
||||
}
|
||||
|
||||
/* callback for listing certs through pkcs11 */
|
||||
static SECStatus
|
||||
secu_PrintKey(FILE *out, int count, SECKEYPrivateKey *key)
|
||||
static PRBool
|
||||
ItemIsPrintableASCII(const SECItem * item)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = PK11_GetPrivateKeyNickname(key);
|
||||
if (name == NULL) {
|
||||
/* should look up associated cert */
|
||||
name = PORT_Strdup("< orphaned >");
|
||||
unsigned char *src = item->data;
|
||||
unsigned int len = item->len;
|
||||
while (len-- > 0) {
|
||||
unsigned char uc = *src++;
|
||||
if (uc < 0x20 || uc > 0x7e)
|
||||
return PR_FALSE;
|
||||
}
|
||||
fprintf(out, "<%d> %s\n", count, name);
|
||||
PORT_Free(name);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* Caller ensures that dst is at least item->len*2+1 bytes long */
|
||||
static void
|
||||
SECItemToHex(const SECItem * item, char * dst)
|
||||
{
|
||||
if (dst && item && item->data) {
|
||||
unsigned char * src = item->data;
|
||||
unsigned int len = item->len;
|
||||
for (; len > 0; --len, dst += 2) {
|
||||
sprintf(dst, "%02x", *src++);
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static const char * const keyTypeName[] = {
|
||||
"null", "rsa", "dsa", "fortezza", "dh", "kea", "ec" };
|
||||
|
||||
#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)
|
||||
{
|
||||
SECItem * ckaID;
|
||||
char ckaIDbuf[MAX_CKA_ID_STR_LEN + 4];
|
||||
|
||||
pwarg = NULL;
|
||||
ckaID = PK11_GetLowLevelKeyIDForPrivateKey(key);
|
||||
if (!ckaID) {
|
||||
strcpy(ckaIDbuf, "(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';
|
||||
} 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);
|
||||
}
|
||||
|
||||
PR_fprintf(out, "<%2d> %-8.8s %-42.42s %s\n", count,
|
||||
keyTypeName[key->keyType], ckaIDbuf, nickName);
|
||||
SECITEM_ZfreeItem(ckaID, PR_TRUE);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
listKeys(PK11SlotInfo *slot, KeyType keyType, void *pwarg)
|
||||
ListKeysInSlot(PK11SlotInfo *slot, const char *nickName, KeyType keyType,
|
||||
void *pwarg)
|
||||
{
|
||||
SECKEYPrivateKeyList *list;
|
||||
SECKEYPrivateKeyListNode *node;
|
||||
int count;
|
||||
int count = 0;
|
||||
|
||||
if (PK11_NeedLogin(slot))
|
||||
PK11_Authenticate(slot, PR_TRUE, pwarg);
|
||||
|
||||
list = PK11_ListPrivateKeysInSlot(slot);
|
||||
if (nickName && nickName[0])
|
||||
list = PK11_ListPrivKeysInSlot(slot, (char *)nickName, pwarg);
|
||||
else
|
||||
list = PK11_ListPrivateKeysInSlot(slot);
|
||||
if (list == NULL) {
|
||||
SECU_PrintError(progName, "problem listing keys");
|
||||
return SECFailure;
|
||||
}
|
||||
for (count=0, node=PRIVKEY_LIST_HEAD(list) ; !PRIVKEY_LIST_END(node,list);
|
||||
node= PRIVKEY_LIST_NEXT(node),count++) {
|
||||
secu_PrintKey(stdout, count, node->key);
|
||||
for (node=PRIVKEY_LIST_HEAD(list);
|
||||
!PRIVKEY_LIST_END(node,list);
|
||||
node=PRIVKEY_LIST_NEXT(node)) {
|
||||
char * keyName;
|
||||
static const char orphan[] = { "(orphan)" };
|
||||
|
||||
if (keyType != nullKey && keyType != node->key->keyType)
|
||||
continue;
|
||||
keyName = PK11_GetPrivateKeyNickname(node->key);
|
||||
if (!keyName || !keyName[0]) {
|
||||
/* Try extra hard to find nicknames for keys that lack them. */
|
||||
CERTCertificate * cert;
|
||||
PORT_Free((void *)keyName);
|
||||
keyName = NULL;
|
||||
cert = PK11_GetCertFromPrivateKey(node->key);
|
||||
if (cert) {
|
||||
if (cert->nickname && !cert->nickname[0]) {
|
||||
keyName = PORT_Strdup(cert->nickname);
|
||||
} else if (cert->emailAddr && cert->emailAddr[0]) {
|
||||
keyName = PORT_Strdup(cert->emailAddr);
|
||||
}
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
}
|
||||
if (nickName) {
|
||||
if (!keyName || PL_strcmp(keyName,nickName)) {
|
||||
/* PKCS#11 module returned unwanted keys */
|
||||
PORT_Free((void *)keyName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!keyName)
|
||||
keyName = (char *)orphan;
|
||||
|
||||
PrintKey(PR_STDOUT, keyName, count, node->key, pwarg);
|
||||
|
||||
if (keyName != (char *)orphan)
|
||||
PORT_Free((void *)keyName);
|
||||
count++;
|
||||
}
|
||||
SECKEY_DestroyPrivateKeyList(list);
|
||||
|
||||
if (count == 0) {
|
||||
fprintf(stderr, "%s: no keys found\n", progName);
|
||||
PR_fprintf(PR_STDOUT, "%s: no keys found\n", progName);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ListKeys(PK11SlotInfo *slot, char *keyname, int index,
|
||||
ListKeys(PK11SlotInfo *slot, const char *nickName, int index,
|
||||
KeyType keyType, PRBool dopriv, secuPWData *pwdata)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
if (slot == NULL) {
|
||||
PK11SlotList *list;
|
||||
PK11SlotListElement *le;
|
||||
|
||||
list= PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,pwdata);
|
||||
if (list) for (le = list->head; le; le = le->next) {
|
||||
rv = listKeys(le->slot,keyType,pwdata);
|
||||
if (list) {
|
||||
for (le = list->head; le; le = le->next) {
|
||||
rv &= ListKeysInSlot(le->slot,nickName,keyType,pwdata);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rv = listKeys(slot,keyType,pwdata);
|
||||
rv = ListKeysInSlot(slot,nickName,keyType,pwdata);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -1019,18 +1110,19 @@ static void LongUsage(char *progName)
|
|||
" -X");
|
||||
FPS "\n");
|
||||
|
||||
FPS "%-15s List all keys\n", /*, or print out a single named key\n",*/
|
||||
FPS "%-15s List all private keys\n",
|
||||
"-K");
|
||||
FPS "%-20s Name of token in which to look for keys (default is internal,"
|
||||
" use \"all\" to list keys on all tokens)\n",
|
||||
FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
|
||||
" -h token-name ");
|
||||
|
||||
FPS "%-20s Key type (\"all\" (default), \"dsa\","
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
FPS "%-20s Type of key pair to list (\"all\", \"dsa\", \"ec\", \"rsa\" (default))\n",
|
||||
" -k key-type");
|
||||
#else
|
||||
FPS "%-20s Type of key pair to list (\"all\", \"dsa\", \"rsa\" (default))\n",
|
||||
" -k key-type");
|
||||
" \"ec\","
|
||||
#endif
|
||||
" \"rsa\")\n",
|
||||
" -k key-type");
|
||||
FPS "%-20s The nickname of the key or associated certificate\n",
|
||||
" -n name");
|
||||
FPS "%-20s Specify the password file\n",
|
||||
" -f password-file");
|
||||
FPS "%-20s Key database directory (default is ~/.netscape)\n",
|
||||
|
@ -1737,6 +1829,8 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
|||
/* use an existing private/public key pair */
|
||||
keysource = arg;
|
||||
}
|
||||
} else if (certutil.commands[cmd_ListKeys].activated) {
|
||||
keytype = nullKey;
|
||||
}
|
||||
|
||||
/* -m serial number */
|
||||
|
|
Загрузка…
Ссылка в новой задаче