Closed Bug 321584 Opened 19 years ago Closed 17 years ago

NSS PKCS12 decoder fails to import bags without nicknames

Categories

(NSS :: Libraries, defect, P2)

defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: nelson, Assigned: nelson)

References

Details

Attachments

(3 files, 1 obsolete file)

Subtitle: PKCS12 decoder nickname collision callback prototype deficient

The PKCS12 standard defines optional (user) "friendly name" attributes 
(also known as nicknames) for objects in the file.  NSS requires them.  
Windows allows them, but does not require them.  At least one other product 
that uses PKCS12 files for import/export of user certs never puts friendly 
names into PKCS12 files that it creates, and ignores friendly names in files 
that it inputs.  NSS is essentially unable to import PKCS12 files produced 
without friendly names.

NSS's PKCS12 decoder API features a callback API by which the decoder can
ask the calling application to come up with a new/better nickname. 
It is used in the cases where the PKCS12 decoder has found a "bag" in the
pkcs12 file that 
(a) has no nickname, or 
(b) has a nickname that is already used in the cert DB as the nickname 
for another cert with a different subject name.  

This "nickname collision" callback API was intended to allow an application
to import PKCS12 files that lacked nicknames, or had duplicative nicknames.
But sadly the API (prototype) for this "nickname collision" callback is not 
well designed.  In particular, the callback function arguments provide no 
information about which "bag" (or cert, or key) is the cause of the 
callback.  

If the PKCS12 file being decoded contains multiple certs (as is common),
the callback function has no way of knowing which of those certs has 
the missing or in-use nickname.  Regardless of the number of certs in the
file, the callback has no access to the information in the cert for which 
it is being called, information with which it might be able to construct 
a new nickname, or prompt the user to do so.  

Consequently, all NSS-based programs that import PKCS12 files are 
effectively unable to import PKCS12 files whose certs lack PKCS12 
friendly names.  Mozilla works around this by using a "default" 
nickname string, which obviously does not help the user to know
which cert is named by it.  pk12util simply fails without trying to
find a new name.  

The nickname collision callback has this prototype:

typedef SECItem * (PR_CALLBACK * SEC_PKCS12NicknameCollisionCallback)(
          SECItem *old_nickname, PRBool *cancel, void *arg);

The "arg" value is a value that the application provides to the decoder
when the decoder context is created, the third argument to the function
SEC_PKCS12DecoderStart.  Since this value is established before the 
decoder starts, it CANNOT contain any information that identifies the 
specific "bag" (cert, key) within the decoded file that has the problem.

I found 3 implemementations of the callback function in mozilla's source
repository, and NONE of them use the "arg" value AT ALL.  

There are several possible ways to attempt to fix this, including:
a) change the callback prototype, adding one or more missing arguments.
b) change the decoder to pass a different value for the "arg" argument
to the callback function. (same prototype, different void* value)
c) create a new callback prototype that includes the additional argument(s),
and create a new variant of SEC_PKCS12DecoderValidateBags that uses the 
new prototype instead of the old one.  

Choice a breaks source and binary compatibility.  It would not even work 
with the existing callback functions that ignore the "arg" argument, and 
so is unacceptable.

Choice c is the most elegant, most backwards compatible, and most work. 
An API addition of that magnitude should wait for the next minor NSS release.

Choice b would continue to work with the existing known callback functions
(all of which ignore the arg argument).  If there are any callback 
functions that, unknown to us, actually use the arg argument now, this 
change would break them.  Also, ideally, the callback would pass BOTH
the appliation-supplied info and the decoder context specific info 
(as with choice c), rather than just one or the other (as with choice b).

I propose to implement choice b in the short term, but I am open to being 
dissuaded.
This patch doesn't fix any of the problems described in this bug.
It is merely a large cleanup of the existing pkcs12 decoder.  
It eliminates MANY erroneous PORT_SetError calls that set a false
SEC_ERROR_NO_MEMORY error code, hiding the correct (and previously
set) error code.
It adds MANY PORT_SetError calls, to set SEC_ERROR_INVALID_ARGS 
when a function detects that the arguments it was passed were
invalid.  
It fixes at least one crash (using a null pointer after testing it 
for being NULL :-).
This patch should differ from the first patch by only a few lines.
These changes are the ones that fix the issues with the NSS PKCS12
library reported in this bug.
The next patch (to follow) changes pk12util to use the new definition
of the nickname collision callback arguments.
Attachment #207063 - Attachment description: PKCS12 patch to implement new nickname collision callback → pk12util patch, implements new nickname collision callback
QA Contact: jason.m.reid → libraries
Priority: -- → P2
Target Milestone: --- → 3.11.2
Attachment #206901 - Flags: review?(neil.williams)
Attachment #207062 - Flags: review?
Attachment #207063 - Flags: review?
Comment on attachment 206901 [details] [diff] [review]
Preliminary patch 1 (checked in on trunk) 

Pretty extensive cleanup.
Attachment #206901 - Flags: review?(neil.williams) → review+
Comment on attachment 207062 [details] [diff] [review]
Patch 2: fixes this bug, also includes patch 1 above

This patch obsoletes previous, I believe, and the following patch is to be applied in addition?
Attachment #207062 - Flags: review? → review+
Use this link to see the differences between the first two patches:
<https://bugzilla.mozilla.org/attachment.cgi?oldid=206901&action=interdiff&newid=207062&headers=1>
Comment on attachment 206901 [details] [diff] [review]
Preliminary patch 1 (checked in on trunk) 

Checked in on trunk
Checking in p12d.c;     new revision: 1.31; previous revision: 1.30
Checking in p12local.c; new revision: 1.9;  previous revision: 1.8
Attachment #206901 - Attachment description: Preliminary patch → Preliminary patch (checked in on trunk)
Attachment #207062 - Attachment description: above patch plus fixes for this bug → Patch 2: fixes this bug, also includes patch 1 above
Attachment #206901 - Attachment description: Preliminary patch (checked in on trunk) → Preliminary patch 1 (checked in on trunk)
Patch 2 above includes patch 1, too.
This patch is the diffs between patches 1 and 2 above.
This is patch 2, without patch 1 also being included.
This is what I expect to check in, now that patch 1 has been 
checked in.
Comment on attachment 207063 [details] [diff] [review]
patch 3, pk12util patch, implements new nickname collision callback (checked in on trunk)

This patch needs to be checked in at the same time as patch 2.  So, the checkin for patch 2 needs to wait for this patch to be reviewed.
Attachment #207063 - Attachment description: pk12util patch, implements new nickname collision callback → patch 3, pk12util patch, implements new nickname collision callback
Attachment #207063 - Flags: review? → review?(neil.williams)
Retargetting all P2s to 3.11.3 .
Target Milestone: 3.11.2 → 3.11.3
Comment on attachment 207063 [details] [diff] [review]
patch 3, pk12util patch, implements new nickname collision callback (checked in on trunk)

This patch looks good but I noticed a quibble with the previous one that's makes it harder to verify this one:
sec_pkcs12_validate_cert (which is private to p12d.c) takes as a last argument wincx which it no longer uses, passing leafCert instead. I'd recommend removing that arg from the function definition.
Attachment #207063 - Flags: review?(neil.williams) → review+
Checked in on trunk
lib/pkcs12/p12d.c;       new revision: 1.35; previous revision: 1.34
cmd/pk12util/pk12util.c; new revision: 1.35; previous revision: 1.34

Need second reviews for branch.
Status: NEW → ASSIGNED
Target Milestone: 3.11.3 → 3.11.5
Attachment #207062 - Attachment is obsolete: true
Attachment #207063 - Attachment description: patch 3, pk12util patch, implements new nickname collision callback → patch 3, pk12util patch, implements new nickname collision callback (checked in on trunk)
Attachment #218454 - Attachment description: Patch 2: (by itself, excluding patch 1) → Patch 2: (by itself, excluding patch 1) (checked in on trunk)
Comment on attachment 207063 [details] [diff] [review]
patch 3, pk12util patch, implements new nickname collision callback (checked in on trunk)

Alexei, please SR both patches attached to this bug.
Attachment #207063 - Flags: superreview?(alexei.volkov.bugs)
Comment on attachment 218454 [details] [diff] [review]
Patch 2: (by itself, excluding patch 1) (checked in on trunk)

Alexei, please SR both patches attached to this bug.
Attachment #218454 - Flags: superreview?(alexei.volkov.bugs)
Comment on attachment 206901 [details] [diff] [review]
Preliminary patch 1 (checked in on trunk) 

Alexei, please SR all 3 patches attached to this bug, for the 3.11 branch.
Attachment #206901 - Flags: superreview?(alexei.volkov.bugs)
Target Milestone: 3.11.5 → 3.11.6
Comment on attachment 206901 [details] [diff] [review]
Preliminary patch 1 (checked in on trunk) 

r=alexei.volkov.bugs
Attachment #206901 - Flags: superreview?(alexei.volkov.bugs) → superreview+
Comment on attachment 207063 [details] [diff] [review]
patch 3, pk12util patch, implements new nickname collision callback (checked in on trunk)


Just a miner notice:
cancel is no longer set by the function. It is not a problem for the function that calls this callback since it preset cancel to PR_TRUE before the call, but would to explicitelly set it to PR_FALSE.
>+#if 0
>     /* XXX not handled yet  */
>     *cancel = PR_TRUE;
>     return NULL;
> #else
Attachment #207063 - Flags: superreview?(alexei.volkov.bugs) → superreview+
Comment on attachment 218454 [details] [diff] [review]
Patch 2: (by itself, excluding patch 1) (checked in on trunk)

r=alexei.volkov.bugs
Attachment #218454 - Flags: superreview?(alexei.volkov.bugs) → superreview+
Target Milestone: 3.11.6 → 3.11.7
This is fixed on the trunk, and I just don't have time to fix it on the branch.
Status: ASSIGNED → RESOLVED
Closed: 17 years ago
Resolution: --- → FIXED
Summary: NSS PKCS12 decoder fails to import files without nicknames → NSS PKCS12 decoder fails to import bags without nicknames
Target Milestone: 3.11.7 → 3.12
Blocks: 586163
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: