diff options
author | Robert Relyea <rrelyea@redhat.com> | 2019-03-07 15:53:21 -0800 |
---|---|---|
committer | Robert Relyea <rrelyea@redhat.com> | 2019-03-07 15:53:21 -0800 |
commit | 780474003a81bdd84895cf4fd6b32fcc28aceb6c (patch) | |
tree | 737868f6a4e28df88893f02c22f0f28e303cff83 /lib/ssl | |
parent | b36763e466622576bf509098b5b48b9c1786c607 (diff) | |
download | nss-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.c | 49 | ||||
-rw-r--r-- | lib/ssl/sslimpl.h | 8 | ||||
-rw-r--r-- | lib/ssl/tls13con.c | 4 |
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; |