On 04/07/2016 05:13 PM, Julien Pierre wrote:
David,

On 4/7/2016 15:49, David Woodhouse wrote:
On Thu, 2016-04-07 at 05:01 -0700, Julien Pierre wrote:
The problem really stems from the design of NSS, specifically the
CERTCertificate*, which maps to a unique DER encoded cert, but not to
a single PKCS#11 object in a single token. Since the same cert can
exist in multiple tokens, but there can only be one CERTCertificate*
pointer for all of them, the only way to resolve the issue would be
for the lookup function to return something other than just
CERTCertificate* alone. PK11_ListCerts does that.
Hm, I thought PK11_ListCerts tried to eliminate duplicates too, which
is why it has that crappy O(n²) behaviour? Does it *really* return more
than one of the 'same' certificate? Don't you *still* get a randomly-
chosen one with unpredictable contents of cert->slot?
It depends on the argument to PK11_ListCerts .

typedef enum {
     PK11CertListUnique = 0,     /* get one instance of all certs */
     PK11CertListUser = 1,       /* get all instances of user certs */
PK11CertListRootUnique = 2, /* get one instance of CA certs without a private key.
                                  * deprecated. Use PK11CertListCAUnique
                                  */
     PK11CertListCA = 3,         /* get all instances of CA certs */
     PK11CertListCAUnique = 4,   /* get one instance of CA certs */
     PK11CertListUserUnique = 5, /* get one instance of user certs */
     PK11CertListAll = 6         /* get all instances of all certs */
} PK11CertListType;

The cert->slot is still random.
Well it's not exactly random. It's the first token referenced unless that token is the internal token. Then its the next token referenced. If the cert->slot is the internal token you can be sure that the cert is only in the internal token.

But you will get multiple cert list entries with the same CERTCertificate*, but a different appData, if you use the value that don't have "Unique" in the name.
Julien is exactly right here.

OK, but you have the cert in your hand; it doesn't matter where it came
from as long as it's the right one. Hell, in OpenConnect I support
modes where the cert is in a file and only the key is in PKCS#11 or
TPM. Who *cares* where the cert came from?

It's only the *key* which really needs to be found in the right place,
since you have to *use* it from there, right?
In theory, yes, the slot for the key is what matters. The problem is if you use cert->slot to look for the key (or even a NULL slot, to search all slots).
The key doesn't accept NULL. I think cert->slot will usually get you to the key if it exists. If you are worried you can use PK11_GetAllSlotsForCertificate() and search for them all.
You might end up with the "wrong" key object. Unlike for CERTCertificate, identical keys in multiple tokens don't share a single SECKEYPrivateKey object.
No, but the all the keys should match the CERTCertificate. The more likely failure is one token has the cert but no key for it.
Of course, since the private key may not be extractable, it's not really possible to compare private keys between tokens. But you could match them by public key.

If they match the cert, they should be identical (functionally) since they must match the public key in the cert or nothing works;).

Upshot: if you are in a case where you care which token the key is in, then you use that token throughout. If you just looked up the cert and are looking for the key.


I believe there can be multiple SECKEYPublicKeyStr objects also, even if they are identical public keys, but not 100% sure.

Yes, they are usually generated on the fly and destroyed. They aren't reference counted like the certificates.


bob

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to