Closed
Bug 67132
Opened 24 years ago
Closed 24 years ago
certutil -C command crashes (and fails to use -a)
Categories
(NSS :: Tools, enhancement, P3)
Tracking
(Not tracked)
RESOLVED
FIXED
Future
People
(Reporter: nelson, Assigned: bugz)
Details
Attachments
(2 files)
|
3.59 KB,
patch
|
Details | Diff | Splinter Review | |
|
3.59 KB,
patch
|
Details | Diff | Splinter Review |
certutil -C command crashes on HPUX, and probably other platforms.
Looks like it's been broken since before 3.0.
The problem is this. in main(), privkey is never generated for
the -C command, but is passed in to CreateCert, which passes it
in to SignCert, which crashes on the null pointer.
I think this patch should fix it.
diff -u -r1.20 certutil.c
--- certutil.c 2001/01/25 04:14:22 1.20
+++ certutil.c 2001/01/31 05:11:17
@@ -2540,6 +2540,7 @@
/* These commands require keygen. */
if (certutil.commands[cmd_CertReq].activated ||
certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_CreateNewCert].activated ||
certutil.commands[cmd_GenKeyPair].activated) {
/* XXX Give it a nickname. */
privkey =
| Reporter | ||
Comment 1•24 years ago
|
||
That patch is _not_ the solution. Rather than generating
a new keypair, certutil should be reusing a previously
generated one, probably one identified via the public key
in the binary cert request.
Priority: -- → P1
Target Milestone: --- → 3.2
| Assignee | ||
Comment 2•24 years ago
|
||
summarizing user comments from email:
User has a token with a key pair on it. User has used that key pair to generate
a certificate request. User then wishes to use certutil to self-sign the
request.
Based on the usage/documentation for certutil, this should be a possibility.
However, it is not something I have ever tried or something that has been
tested. Our QA uses the following certutil semantics:
generate a self-signed cert with certutil -S -x
generate cert requests with certutil -R
sign the requests using the self-signed cert and certutil -C
Using certutil -C -x is simply a combination that has been overlooked.
Actually, I believe I know what the problem is. I think using the -x option has
always meant "generate a key pair". However, at one time there was a "-k
shortkeyid" option for finding keys by the first few bytes of their modulus.
This option floated around in a different version of certutil, and relyea said
that it should not be included because we wanted to move away from referring to
keys by their short key id.
What certutil needs here is a way to locate the key. In this case, that
involves a combination of a token name (using -h, which works) and then some way
to identify the key, which is lacking. However, this is an even more special
case, since the cert request contains the public key, so it would simply be a
matter of using PKCS#11 to find the matching private key on the token (which
shouldn't be difficult).
Bob, do you have any suggestions? I'm going to look into this. I think (in the
course of writing this) that certutil -C -x should mean "sign this request using
the private key that matches the public key in the request." I don't think
certutil was ever able to do that, but it seems reasonable enough.
| Assignee | ||
Comment 3•24 years ago
|
||
pk11func.h has the following functions that return a private key:
SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot,
CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk,
PRBool isPerm, PRBool isSensitive, void *wincx);
SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx);
SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx);
SECKEYPrivateKey * PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx);
SECKEYPrivateKey * PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID,
void *wincx);
SECKEYPrivateKey *PK11_FindKeyByDERCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx);
SECKEYPrivateKey * PK11_FindPrivateKeyFromNickname(char *nickname, void *wincx);
Since there is no certificate yet, it looks like the only one that will work is
PK11_FindKeyByKeyID (also assuming that the key does not have a "nickname"
attribute set). But this gets back to referring to keys using the short key id.
Bob, a more specific question is, is there any way to use a public key to find a
private key in a slot? Or do we need to use the short key id?
Comment 4•24 years ago
|
||
Yes, the solution is to look up the private key based on the public key. This is
very doable because that's how we find a private key based on the cert (public
key is extracted from the cert and used to look up the private key.
The correct low level function is PK11_FindKeybyKeyID(). There is another
function (I'd have to search the source) which makes a keyID from a public key.
What we probably need, though, is to define a new PK11 functions which takes a
public key and finds the private key that uses PK11_FindPrivateKeyByKeyID().
bob
| Assignee | ||
Comment 5•24 years ago
|
||
I tried the following patch:
Index: certutil.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/cmd/certutil/certutil.c,v
retrieving revision 1.20
diff -c -r1.20 certutil.c
*** certutil.c 2001/01/25 04:14:22 1.20
--- certutil.c 2001/01/31 19:02:54
***************
*** 1901,1906 ****
--- 1901,1907 ----
static SECStatus
CreateCert(
CERTCertDBHandle *handle,
+ PK11SlotInfo *slot,
char * issuerNickName,
PRFileDesc *inFile,
PRFileDesc *outFile,
***************
*** 1993,1998 ****
--- 1994,2011 ----
CERT_FinishExtensions(extHandle);
+ /* self-signing the cert request, find priv key on token */
+ if (selfsign && selfsignprivkey == NULL) {
+ /*SECItem *keyId = PK11_GetKeyIDFromCert(subjectCert, NULL);*/
+ SECItem *keyId = PK11_MakeIDFromPubKey(&subjectCert->derPublicKey);
+ selfsignprivkey = PK11_FindKeyByKeyID(slot, keyId, NULL);
+ if (selfsignprivkey == NULL) {
+ fprintf(stderr, "Failed to find private key to sign with.\n");
+ rv = SECFailure;
+ break;
+ }
+ }
+
certDER = SignCert (handle, subjectCert, selfsign, selfsignprivkey,
issuerNickName,pwarg);
if (certDER)
***************
*** 2152,2158 ****
char commandToRun = '\0';
secuPWData pwdata = { PW_NONE, 0 };
! SECKEYPrivateKey *privkey;
SECKEYPublicKey *pubkey = NULL;
int i;
--- 2165,2171 ----
char commandToRun = '\0';
secuPWData pwdata = { PW_NONE, 0 };
! SECKEYPrivateKey *privkey = NULL;
SECKEYPublicKey *pubkey = NULL;
int i;
***************
*** 2602,2608 ****
/* Create a certificate (-C or -S). */
if (certutil.commands[cmd_CreateAndAddCert].activated ||
certutil.commands[cmd_CreateNewCert].activated) {
! rv = CreateCert(certHandle,
certutil.options[opt_IssuerName].arg,
inFile, outFile, privkey, &pwdata,
serialNumber, warpmonths, validitylength,
--- 2615,2621 ----
/* Create a certificate (-C or -S). */
if (certutil.commands[cmd_CreateAndAddCert].activated ||
certutil.commands[cmd_CreateNewCert].activated) {
! rv = CreateCert(certHandle, slot,
certutil.options[opt_IssuerName].arg,
inFile, outFile, privkey, &pwdata,
serialNumber, warpmonths, validitylength,
I generated a key using certutil and then attempted to sign a cert request with
it using certutil -C -x. I thought I could "fake" a token by using the internal
slot, but I don't believe that will work (I don't think it will find keys by id
on the internal token). So I think the above code *should* work for a real
token, but I'm not sure. Does it look correct to you bob? Julien, do you want
to try this patch?
Comment 6•24 years ago
|
||
The only way to find keys in any token is by ID. Either the ID is generated from
the public key, or it is matched by looking up the cert and matching the cert's ID.
In any case this code should work for both internal and external tokens. If it
doesn't work for the internal token there's still a bug somewhere.
bob
| Reporter | ||
Comment 7•24 years ago
|
||
The cert request contains the public key. The code should extract
the public key from the cert request and lookup the private key
by that.
Does "subjectCert->derPublicKey point to the public key extracted
from the cert request??
| Assignee | ||
Comment 8•24 years ago
|
||
Whilst we debate the validity of using the -C -x combination, I'm renaming this
bug. The fact that -C disregards -a (ascii input) is clearly a bug, and I will
endeavor to have that fixed by 3.2. As far as the original intent of the bug, I
believe the goal is to have NSS report an error claiming that -C -x is invalid,
and remove that combination from the usage. Kirk, I believe you volunteered to
do that?
Summary: certutil -C command crashes → certutil -C command crashes (and fails to use -a)
| Assignee | ||
Comment 9•24 years ago
|
||
okay, I have a patch that fixed -C -a and reports an error on -C -x (I figured I
was in there already so I would just do it, to avoid merging problems). Anyone
care to review?
| Assignee | ||
Comment 10•24 years ago
|
||
| Assignee | ||
Comment 11•24 years ago
|
||
Comment 12•24 years ago
|
||
I reviewed Ian's patch. It looks fine.
| Assignee | ||
Comment 13•24 years ago
|
||
patch checked in.
Not marking this bug as fixed, since I consider the -C -x combination to be an
open issue still. But at this point I think it's fair to call it an
enhancement.
-C -a now works as expected.
Severity: major → enhancement
OS: HP-UX → All
Priority: P1 → P3
Hardware: HP → All
Target Milestone: 3.2 → Future
| Assignee | ||
Comment 14•24 years ago
|
||
Per wtc's request, marking this as fixed so it shows up in NSS 3.2's bugs fixed.
Note the crash and missing feature described in the subject are both fixed. The
continued review of -C -x will occur in bug 67890.
Status: NEW → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•