зеркало из 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
|
static SECStatus
|
||||||
ListCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
|
ListCerts(CERTCertDBHandle *handle, char *nickname, PK11SlotInfo *slot,
|
||||||
PRBool raw, PRBool ascii, PRFileDesc *outfile, secuPWData *pwdata)
|
PRBool raw, PRBool ascii, PRFileDesc *outfile, secuPWData *pwdata)
|
||||||
{
|
{
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
|
@ -557,7 +557,7 @@ ListCerts(CERTCertDBHandle *handle, char *name, PK11SlotInfo *slot,
|
||||||
CERT_DestroyCertList(list);
|
CERT_DestroyCertList(list);
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
} else {
|
} else {
|
||||||
rv = listCerts(handle,name,slot,raw,ascii,outfile,pwdata);
|
rv = listCerts(handle,nickname,slot,raw,ascii,outfile,pwdata);
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -697,67 +697,158 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* callback for listing certs through pkcs11 */
|
static PRBool
|
||||||
static SECStatus
|
ItemIsPrintableASCII(const SECItem * item)
|
||||||
secu_PrintKey(FILE *out, int count, SECKEYPrivateKey *key)
|
|
||||||
{
|
{
|
||||||
char *name;
|
unsigned char *src = item->data;
|
||||||
|
unsigned int len = item->len;
|
||||||
name = PK11_GetPrivateKeyNickname(key);
|
while (len-- > 0) {
|
||||||
if (name == NULL) {
|
unsigned char uc = *src++;
|
||||||
/* should look up associated cert */
|
if (uc < 0x20 || uc > 0x7e)
|
||||||
name = PORT_Strdup("< orphaned >");
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
fprintf(out, "<%d> %s\n", count, name);
|
return PR_TRUE;
|
||||||
PORT_Free(name);
|
}
|
||||||
|
|
||||||
|
/* 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;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SECStatus
|
static SECStatus
|
||||||
listKeys(PK11SlotInfo *slot, KeyType keyType, void *pwarg)
|
ListKeysInSlot(PK11SlotInfo *slot, const char *nickName, KeyType keyType,
|
||||||
|
void *pwarg)
|
||||||
{
|
{
|
||||||
SECKEYPrivateKeyList *list;
|
SECKEYPrivateKeyList *list;
|
||||||
SECKEYPrivateKeyListNode *node;
|
SECKEYPrivateKeyListNode *node;
|
||||||
int count;
|
int count = 0;
|
||||||
|
|
||||||
if (PK11_NeedLogin(slot))
|
if (PK11_NeedLogin(slot))
|
||||||
PK11_Authenticate(slot, PR_TRUE, pwarg);
|
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) {
|
if (list == NULL) {
|
||||||
SECU_PrintError(progName, "problem listing keys");
|
SECU_PrintError(progName, "problem listing keys");
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
for (count=0, node=PRIVKEY_LIST_HEAD(list) ; !PRIVKEY_LIST_END(node,list);
|
for (node=PRIVKEY_LIST_HEAD(list);
|
||||||
node= PRIVKEY_LIST_NEXT(node),count++) {
|
!PRIVKEY_LIST_END(node,list);
|
||||||
secu_PrintKey(stdout, count, node->key);
|
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);
|
SECKEY_DestroyPrivateKeyList(list);
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
fprintf(stderr, "%s: no keys found\n", progName);
|
PR_fprintf(PR_STDOUT, "%s: no keys found\n", progName);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SECStatus
|
static SECStatus
|
||||||
ListKeys(PK11SlotInfo *slot, char *keyname, int index,
|
ListKeys(PK11SlotInfo *slot, const char *nickName, int index,
|
||||||
KeyType keyType, PRBool dopriv, secuPWData *pwdata)
|
KeyType keyType, PRBool dopriv, secuPWData *pwdata)
|
||||||
{
|
{
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECFailure;
|
||||||
|
|
||||||
if (slot == NULL) {
|
if (slot == NULL) {
|
||||||
PK11SlotList *list;
|
PK11SlotList *list;
|
||||||
PK11SlotListElement *le;
|
PK11SlotListElement *le;
|
||||||
|
|
||||||
list= PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,pwdata);
|
list= PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,pwdata);
|
||||||
if (list) for (le = list->head; le; le = le->next) {
|
if (list) {
|
||||||
rv = listKeys(le->slot,keyType,pwdata);
|
for (le = list->head; le; le = le->next) {
|
||||||
|
rv &= ListKeysInSlot(le->slot,nickName,keyType,pwdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rv = listKeys(slot,keyType,pwdata);
|
rv = ListKeysInSlot(slot,nickName,keyType,pwdata);
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -1019,18 +1110,19 @@ static void LongUsage(char *progName)
|
||||||
" -X");
|
" -X");
|
||||||
FPS "\n");
|
FPS "\n");
|
||||||
|
|
||||||
FPS "%-15s List all keys\n", /*, or print out a single named key\n",*/
|
FPS "%-15s List all private keys\n",
|
||||||
"-K");
|
"-K");
|
||||||
FPS "%-20s Name of token in which to look for keys (default is internal,"
|
FPS "%-20s Name of token to search (\"all\" for all tokens)\n",
|
||||||
" use \"all\" to list keys on all tokens)\n",
|
|
||||||
" -h token-name ");
|
" -h token-name ");
|
||||||
|
|
||||||
|
FPS "%-20s Key type (\"all\" (default), \"dsa\","
|
||||||
#ifdef NSS_ENABLE_ECC
|
#ifdef NSS_ENABLE_ECC
|
||||||
FPS "%-20s Type of key pair to list (\"all\", \"dsa\", \"ec\", \"rsa\" (default))\n",
|
" \"ec\","
|
||||||
" -k key-type");
|
|
||||||
#else
|
|
||||||
FPS "%-20s Type of key pair to list (\"all\", \"dsa\", \"rsa\" (default))\n",
|
|
||||||
" -k key-type");
|
|
||||||
#endif
|
#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",
|
FPS "%-20s Specify the password file\n",
|
||||||
" -f password-file");
|
" -f password-file");
|
||||||
FPS "%-20s Key database directory (default is ~/.netscape)\n",
|
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 */
|
/* use an existing private/public key pair */
|
||||||
keysource = arg;
|
keysource = arg;
|
||||||
}
|
}
|
||||||
|
} else if (certutil.commands[cmd_ListKeys].activated) {
|
||||||
|
keytype = nullKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -m serial number */
|
/* -m serial number */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче