nss: update to 3.44.1, with vc2013 fix and gyp fix

This commit is contained in:
Roy Tam 2019-06-24 21:44:17 +08:00
commit d4b834111b
553 changed files with 1515569 additions and 1130 deletions

View file

@ -639,6 +639,11 @@ seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
return pubk;
break;
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
/* A basic sanity check on inputs. */
if (spki->algorithm.parameters.len == 0 || newOs.len == 0) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
break;
}
pubk->keyType = ecKey;
pubk->u.ec.size = 0;
@ -1206,6 +1211,37 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
return NULL;
}
/*
* Use the private key to find a public key handle. The handle will be on
* the same slot as the private key.
*/
static CK_OBJECT_HANDLE
seckey_FindPublicKeyHandle(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk)
{
CK_OBJECT_HANDLE keyID;
/* this helper function is only used below. If we want to make this more
* general, we would need to free up any already cached handles if the
* slot doesn't match up with the private key slot */
PORT_Assert(pubk->pkcs11ID == CK_INVALID_HANDLE);
/* first look for a matching public key */
keyID = PK11_MatchItem(privk->pkcs11Slot, privk->pkcs11ID, CKO_PUBLIC_KEY);
if (keyID != CK_INVALID_HANDLE) {
return keyID;
}
/* none found, create a temp one, make the pubk the owner */
pubk->pkcs11ID = PK11_DerivePubKeyFromPrivKey(privk);
if (pubk->pkcs11ID == CK_INVALID_HANDLE) {
/* end of the road. Token doesn't have matching public key, nor can
* token regenerate a new public key from and existing private key. */
return CK_INVALID_HANDLE;
}
pubk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
return pubk->pkcs11ID;
}
SECKEYPublicKey *
SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
{
@ -1213,6 +1249,8 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
PLArenaPool *arena;
CERTCertificate *cert;
SECStatus rv;
CK_OBJECT_HANDLE pubKeyHandle;
SECItem decodedPoint;
/*
* First try to look up the cert.
@ -1243,11 +1281,47 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
switch (privk->keyType) {
case nullKey:
case dhKey:
case dsaKey:
/* Nothing to query, if the cert isn't there, we're done -- no way
* to get the public key */
break;
case dsaKey:
pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
if (pubKeyHandle == CK_INVALID_HANDLE)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_BASE, arena, &pubk->u.dsa.params.base);
if (rv != SECSuccess)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_PRIME, arena, &pubk->u.dsa.params.prime);
if (rv != SECSuccess)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_SUBPRIME, arena, &pubk->u.dsa.params.subPrime);
if (rv != SECSuccess)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_VALUE, arena, &pubk->u.dsa.publicValue);
if (rv != SECSuccess)
break;
return pubk;
case dhKey:
pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
if (pubKeyHandle == CK_INVALID_HANDLE)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_BASE, arena, &pubk->u.dh.base);
if (rv != SECSuccess)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_PRIME, arena, &pubk->u.dh.prime);
if (rv != SECSuccess)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_VALUE, arena, &pubk->u.dh.publicValue);
if (rv != SECSuccess)
break;
return pubk;
case rsaKey:
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
CKA_MODULUS, arena, &pubk->u.rsa.modulus);
@ -1258,7 +1332,6 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
if (rv != SECSuccess)
break;
return pubk;
break;
case ecKey:
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams);
@ -1268,7 +1341,23 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) {
break;
pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
if (pubKeyHandle == CK_INVALID_HANDLE)
break;
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
if (rv != SECSuccess)
break;
}
/* ec.publicValue should be decoded, PKCS #11 defines CKA_EC_POINT
* as encoded, but it's not always. try do decoded it and if it
* succeeds store the decoded value */
rv = SEC_QuickDERDecodeItem(arena, &decodedPoint,
SEC_ASN1_GET(SEC_OctetStringTemplate), &pubk->u.ec.publicValue);
if (rv == SECSuccess) {
/* both values are in the public key arena, so it's safe to
* overwrite the old value */
pubk->u.ec.publicValue = decodedPoint;
}
pubk->u.ec.encoding = ECPoint_Undefined;
return pubk;
@ -1276,7 +1365,9 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
break;
}
PORT_FreeArena(arena, PR_FALSE);
/* must use Destroy public key here, because some paths create temporary
* PKCS #11 objects which need to be freed */
SECKEY_DestroyPublicKey(pubk);
return NULL;
}