summaryrefslogtreecommitdiff
path: root/lib/ssl
diff options
context:
space:
mode:
authorRobert Relyea <rrelyea@redhat.com>2019-03-07 15:53:21 -0800
committerRobert Relyea <rrelyea@redhat.com>2019-03-07 15:53:21 -0800
commit780474003a81bdd84895cf4fd6b32fcc28aceb6c (patch)
tree737868f6a4e28df88893f02c22f0f28e303cff83 /lib/ssl
parentb36763e466622576bf509098b5b48b9c1786c607 (diff)
downloadnss-hg-780474003a81bdd84895cf4fd6b32fcc28aceb6c.tar.gz
Bug 1530472 - handle issue when server ECC key is in a token that doesn't handle the TLS mechanisms.
Differential Revision: https://phabricator.services.mozilla.com/D22625
Diffstat (limited to 'lib/ssl')
-rw-r--r--lib/ssl/ssl3con.c49
-rw-r--r--lib/ssl/sslimpl.h8
-rw-r--r--lib/ssl/tls13con.c4
3 files changed, 55 insertions, 6 deletions
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
index 9592cced1..c10116337 100644
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -8626,6 +8626,45 @@ loser:
return SECFailure;
}
+/* unwrap helper function to handle the case where the wrapKey doesn't wind
+ * up in the correct token for the master secret */
+PK11SymKey *
+ssl_unwrapSymKey(PK11SymKey *wrapKey,
+ CK_MECHANISM_TYPE wrapType, SECItem *param,
+ SECItem *wrappedKey,
+ CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
+ int keySize, CK_FLAGS keyFlags, void *pinArg)
+{
+ PK11SymKey *unwrappedKey;
+
+ /* unwrap the master secret. */
+ unwrappedKey = PK11_UnwrapSymKeyWithFlags(wrapKey, wrapType, param,
+ wrappedKey, target, operation, keySize,
+ keyFlags);
+ if (!unwrappedKey) {
+ PK11SlotInfo *targetSlot = PK11_GetBestSlot(target, pinArg);
+ PK11SymKey *newWrapKey;
+
+ /* it's possible that we failed to unwrap because the wrapKey is in
+ * a slot that can't handle target. Move the wrapKey to a slot that
+ * can handle this mechanism and retry the operation */
+ if (targetSlot == NULL) {
+ return NULL;
+ }
+ newWrapKey = PK11_MoveSymKey(targetSlot, CKA_UNWRAP, 0,
+ PR_FALSE, wrapKey);
+ PK11_FreeSlot(targetSlot);
+ if (newWrapKey == NULL) {
+ return NULL;
+ }
+ unwrappedKey = PK11_UnwrapSymKeyWithFlags(newWrapKey, wrapType, param,
+ wrappedKey, target, operation, keySize,
+ keyFlags);
+ PK11_FreeSymKey(newWrapKey);
+ }
+ return unwrappedKey;
+}
+
static SECStatus
ssl3_UnwrapMasterSecretServer(sslSocket *ss, sslSessionID *sid, PK11SymKey **ms)
{
@@ -8647,12 +8686,14 @@ ssl3_UnwrapMasterSecretServer(sslSocket *ss, sslSessionID *sid, PK11SymKey **ms)
keyFlags = CKF_SIGN | CKF_VERIFY;
}
- /* unwrap the master secret. */
- *ms = PK11_UnwrapSymKeyWithFlags(wrapKey, sid->u.ssl3.masterWrapMech,
- NULL, &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
- CKA_DERIVE, SSL3_MASTER_SECRET_LENGTH, keyFlags);
+ *ms = ssl_unwrapSymKey(wrapKey, sid->u.ssl3.masterWrapMech, NULL,
+ &wrappedMS, CKM_SSL3_MASTER_KEY_DERIVE,
+ CKA_DERIVE, SSL3_MASTER_SECRET_LENGTH,
+ keyFlags, ss->pkcs11PinArg);
PK11_FreeSymKey(wrapKey);
if (!*ms) {
+ SSL_TRC(10, ("%d: SSL3[%d]: server wrapping key found, but couldn't unwrap MasterSecret. wrapMech=0x%0lx",
+ SSL_GETPID(), ss->fd, sid->u.ssl3.masterWrapMech));
return SECFailure;
}
return SECSuccess;
diff --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
index 2dbf60436..255c66aa1 100644
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -1734,6 +1734,14 @@ SECStatus ssl_DecodeResumptionToken(sslSessionID *sid, const PRUint8 *encodedTic
PRUint32 encodedTicketLen);
PRBool ssl_IsResumptionTokenUsable(sslSocket *ss, sslSessionID *sid);
+/* unwrap helper function to handle the case where the wrapKey doesn't wind
+ * * up in the correct token for the master secret */
+PK11SymKey *ssl_unwrapSymKey(PK11SymKey *wrapKey,
+ CK_MECHANISM_TYPE wrapType, SECItem *param,
+ SECItem *wrappedKey,
+ CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
+ int keySize, CK_FLAGS keyFlags, void *pinArg);
+
/* Remove when stable. */
SECStatus SSLExp_SetResumptionTokenCallback(PRFileDesc *fd,
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
index 5e028727b..9c6606d63 100644
--- a/lib/ssl/tls13con.c
+++ b/lib/ssl/tls13con.c
@@ -974,13 +974,13 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
wrappedMS.len = sid->u.ssl3.keys.wrapped_master_secret_len;
/* unwrap the "master secret" which is actually RMS. */
- ss->ssl3.hs.resumptionMasterSecret = PK11_UnwrapSymKeyWithFlags(
+ ss->ssl3.hs.resumptionMasterSecret = ssl_unwrapSymKey(
wrapKey, sid->u.ssl3.masterWrapMech,
NULL, &wrappedMS,
CKM_SSL3_MASTER_KEY_DERIVE,
CKA_DERIVE,
tls13_GetHashSizeForHash(hashType),
- CKF_SIGN | CKF_VERIFY);
+ CKF_SIGN | CKF_VERIFY, ss->pkcs11PinArg);
PK11_FreeSymKey(wrapKey);
if (!ss->ssl3.hs.resumptionMasterSecret) {
return SECFailure;