Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 572018 Details for
Bug 805640
Enhance PSM's key generation strategy with tokens/escrow
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch v4 from upstream (smaller context version)
p4-u5-681937.patch (text/plain), 14.94 KB, created by
Kai Engert (:kaie) (inactive account)
on 2012-03-22 15:11:03 UTC
(
hide
)
Description:
Patch v4 from upstream (smaller context version)
Filename:
MIME Type:
Creator:
Kai Engert (:kaie) (inactive account)
Created:
2012-03-22 15:11:03 UTC
Size:
14.94 KB
patch
obsolete
>diff --git a/security/manager/ssl/src/nsCrypto.cpp b/security/manager/ssl/src/nsCrypto.cpp >--- a/security/manager/ssl/src/nsCrypto.cpp >+++ b/security/manager/ssl/src/nsCrypto.cpp >@@ -684,20 +684,25 @@ cryptojs_generateOneKeyPair(JSContext *c > PRInt32 keySize, char *params, > nsIInterfaceRequestor *uiCxt, > PK11SlotInfo *slot, bool willEscrow) > > { >+ const PK11AttrFlags sensitiveFlags = (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE); >+ const PK11AttrFlags temporarySessionFlags = PK11_ATTR_SESSION; >+ const PK11AttrFlags permanentTokenFlags = PK11_ATTR_TOKEN; >+ const PK11AttrFlags extractableFlags = PK11_ATTR_EXTRACTABLE; >+ > nsIGeneratingKeypairInfoDialogs * dialogs; > nsKeygenThread *KeygenRunnable = 0; > nsCOMPtr<nsIKeygenThread> runnable; > > PRUint32 mechanism = cryptojs_convert_to_mechanism(keyPairInfo->keyGenType); > void *keyGenParams = nsConvertToActualKeyGenParams(mechanism, params, > (params) ? strlen(params):0, > keySize, keyPairInfo); > >- if (!keyGenParams) { >+ if (!keyGenParams || !slot) { > return NS_ERROR_INVALID_ARG; > } > > // Make sure the token has password already set on it before trying > // to generate the key. >@@ -707,35 +712,39 @@ cryptojs_generateOneKeyPair(JSContext *c > return rv; > > if (PK11_Authenticate(slot, true, uiCxt) != SECSuccess) > return NS_ERROR_FAILURE; > >- > // Smart cards will not let you extract a private key once > // it is on the smart card. If we've been told to escrow >- // a private key that will ultimately wind up on a smart card, >- // then we'll generate the private key on the internal slot >- // as a temporary key, then move it to the destination slot. >+ // a private key that will be stored on a smart card, >+ // then we'll use the following strategy to ensure we can escrow it. >+ // We'll attempt to generate the key on our internal token, >+ // because this is expected to avoid some problems. >+ // If it works, we'll escrow, move the key to the smartcard, done. >+ // If it didn't work (or the internal key doesn't support the desired >+ // mechanism), then we'll attempt to generate the key on >+ // the destination token, with the EXTRACTABLE flag set. >+ // If it works, we'll extract, escrow, done. >+ // If it failed, then we're unable to escrow and return failure. > // NOTE: We call PK11_GetInternalSlot instead of PK11_GetInternalKeySlot > // so that the key has zero chance of being store in the > // user's key3.db file. Which the slot returned by > // PK11_GetInternalKeySlot has access to and PK11_GetInternalSlot > // does not. > PK11SlotInfo *intSlot = nsnull; > PK11SlotInfoCleaner siCleaner(intSlot); > >- PK11SlotInfo *origSlot = nsnull; >- bool isPerm; >- > if (willEscrow && !PK11_IsInternal(slot)) { > intSlot = PK11_GetInternalSlot(); > NS_ASSERTION(intSlot,"Couldn't get the internal slot"); >- isPerm = false; >- origSlot = slot; >- slot = intSlot; >- } else { >- isPerm = true; >+ >+ if (!PK11_DoesMechanism(intSlot, mechanism)) { >+ // Set to null, and the subsequent code will not attempt to use it. >+ PK11_FreeSlot(intSlot); >+ intSlot = nsnull; >+ } > } > > rv = getNSSDialogs((void**)&dialogs, > NS_GET_IID(nsIGeneratingKeypairInfoDialogs), > NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID); >@@ -744,18 +753,70 @@ cryptojs_generateOneKeyPair(JSContext *c > KeygenRunnable = new nsKeygenThread(); > if (KeygenRunnable) { > NS_ADDREF(KeygenRunnable); > } > } >- >+ >+ // "firstAttemptSlot" and "secondAttemptSlot" are alternative names >+ // for better code readability, we don't increase the reference counts. >+ >+ PK11SlotInfo *firstAttemptSlot = NULL; >+ PK11AttrFlags firstAttemptFlags = 0; >+ >+ PK11SlotInfo *secondAttemptSlot = slot; >+ PK11AttrFlags secondAttemptFlags = sensitiveFlags | permanentTokenFlags; >+ >+ if (willEscrow) { >+ secondAttemptFlags |= extractableFlags; >+ } >+ >+ if (!intSlot || PK11_IsInternal(slot)) { >+ // if we cannot use the internal slot, then there is only one attempt >+ // if the destination slot is the internal slot, then there is only one attempt >+ firstAttemptSlot = secondAttemptSlot; >+ firstAttemptFlags = secondAttemptFlags; >+ secondAttemptSlot = NULL; >+ secondAttemptFlags = 0; >+ } >+ else { >+ firstAttemptSlot = intSlot; >+ firstAttemptFlags = sensitiveFlags | temporarySessionFlags; >+ >+ // We always need the extractable flag on the first attempt, >+ // because we want to move the key to another slot - ### is this correct? >+ firstAttemptFlags |= extractableFlags; >+ } >+ >+ bool mustMoveKey = false; >+ > if (NS_FAILED(rv) || !KeygenRunnable) { >+ /* execute key generation on this thread */ > rv = NS_OK; >- keyPairInfo->privKey = PK11_GenerateKeyPair(slot, mechanism, keyGenParams, >- &keyPairInfo->pubKey, isPerm, >- isPerm, uiCxt); >+ >+ keyPairInfo->privKey = >+ PK11_GenerateKeyPairWithFlags(firstAttemptSlot, mechanism, >+ keyGenParams, &keyPairInfo->pubKey, >+ firstAttemptFlags, uiCxt); >+ >+ if (keyPairInfo->privKey) { >+ // success on first attempt >+ if (secondAttemptSlot) { >+ mustMoveKey = true; >+ } >+ } >+ else { >+ keyPairInfo->privKey = >+ PK11_GenerateKeyPairWithFlags(secondAttemptSlot, mechanism, >+ keyGenParams, &keyPairInfo->pubKey, >+ secondAttemptFlags, uiCxt); >+ } >+ > } else { >- KeygenRunnable->SetParams( slot, mechanism, keyGenParams, isPerm, isPerm, uiCxt ); >+ /* execute key generation on separate thread */ >+ KeygenRunnable->SetParams( firstAttemptSlot, firstAttemptFlags, >+ secondAttemptSlot, secondAttemptFlags, >+ mechanism, keyGenParams, uiCxt ); > > runnable = do_QueryInterface(KeygenRunnable); > > if (runnable) { > { >@@ -771,30 +832,42 @@ cryptojs_generateOneKeyPair(JSContext *c > } > } > > NS_RELEASE(dialogs); > if (NS_SUCCEEDED(rv)) { >- rv = KeygenRunnable->GetParams(&keyPairInfo->privKey, &keyPairInfo->pubKey); >+ PK11SlotInfo *used_slot = NULL; >+ rv = KeygenRunnable->ConsumeResult(&used_slot, >+ &keyPairInfo->privKey, &keyPairInfo->pubKey); >+ >+ if (NS_SUCCEEDED(rv)) { >+ if ((used_slot == firstAttemptSlot) && (secondAttemptSlot != NULL)) { >+ mustMoveKey = true; >+ } >+ >+ PK11_FreeSlot(used_slot); >+ } > } > } > } > >+ firstAttemptSlot = NULL; >+ secondAttemptSlot = NULL; >+ > nsFreeKeyGenParams(mechanism, keyGenParams); > > if (KeygenRunnable) { > NS_RELEASE(KeygenRunnable); > } > > if (!keyPairInfo->privKey || !keyPairInfo->pubKey) { > return NS_ERROR_FAILURE; > } > >- > //If we generated the key pair on the internal slot because the > // keys were going to be escrowed, move the keys over right now. >- if (willEscrow && intSlot) { >- SECKEYPrivateKey *newPrivKey = PK11_LoadPrivKey(origSlot, >+ if (mustMoveKey) { >+ SECKEYPrivateKey *newPrivKey = PK11_LoadPrivKey(slot, > keyPairInfo->privKey, > keyPairInfo->pubKey, > true, true); > SECKEYPrivateKeyCleaner pkCleaner(newPrivKey); > >diff --git a/security/manager/ssl/src/nsKeygenHandler.cpp b/security/manager/ssl/src/nsKeygenHandler.cpp >--- a/security/manager/ssl/src/nsKeygenHandler.cpp >+++ b/security/manager/ssl/src/nsKeygenHandler.cpp >@@ -528,10 +528,13 @@ nsKeygenFormProcessor::GetPublicKey(nsAS > CERTPublicKeyAndChallenge pkac; > pkac.challenge.data = nsnull; > nsIGeneratingKeypairInfoDialogs * dialogs; > nsKeygenThread *KeygenRunnable = 0; > nsCOMPtr<nsIKeygenThread> runnable; >+ >+ // permanent and sensitive flags for keygen >+ PK11AttrFlags attrFlags = PK11_ATTR_TOKEN | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE; > > // Get the key size // > for (size_t i = 0; i < number_of_key_size_choices; ++i) { > if (aValue.Equals(mSECKeySizeChoiceList[i].name)) { > keysize = mSECKeySizeChoiceList[i].size; >@@ -673,14 +676,15 @@ nsKeygenFormProcessor::GetPublicKey(nsAS > NS_IF_ADDREF(KeygenRunnable); > } > > if (NS_FAILED(rv) || !KeygenRunnable) { > rv = NS_OK; >- privateKey = PK11_GenerateKeyPair(slot, keyGenMechanism, params, >- &publicKey, true, true, m_ctx); >+ privateKey = PK11_GenerateKeyPairWithFlags(slot, keyGenMechanism, params, >+ &publicKey, attrFlags, m_ctx); > } else { >- KeygenRunnable->SetParams( slot, keyGenMechanism, params, true, true, m_ctx ); >+ KeygenRunnable->SetParams( slot, attrFlags, nsnull, 0, >+ keyGenMechanism, params, m_ctx ); > > runnable = do_QueryInterface(KeygenRunnable); > > if (runnable) { > { >@@ -696,11 +700,15 @@ nsKeygenFormProcessor::GetPublicKey(nsAS > } > } > > NS_RELEASE(dialogs); > if (NS_SUCCEEDED(rv)) { >- rv = KeygenRunnable->GetParams(&privateKey, &publicKey); >+ PK11SlotInfo *used_slot = nsnull; >+ rv = KeygenRunnable->ConsumeResult(&used_slot, &privateKey, &publicKey); >+ if (NS_SUCCEEDED(rv) && used_slot) { >+ PK11_FreeSlot(used_slot); >+ } > } > } > } > > if (NS_FAILED(rv) || !privateKey) { >diff --git a/security/manager/ssl/src/nsKeygenThread.cpp b/security/manager/ssl/src/nsKeygenThread.cpp >--- a/security/manager/ssl/src/nsKeygenThread.cpp >+++ b/security/manager/ssl/src/nsKeygenThread.cpp >@@ -57,55 +57,65 @@ nsKeygenThread::nsKeygenThread() > statusDialogClosed(false), > alreadyReceivedParams(false), > privateKey(nsnull), > publicKey(nsnull), > slot(nsnull), >+ flags(0), >+ altSlot(nsnull), >+ altFlags(0), >+ usedSlot(nsnull), > keyGenMechanism(0), > params(nsnull), >- isPerm(false), >- isSensitive(false), > wincx(nsnull), > threadHandle(nsnull) > { > } > > nsKeygenThread::~nsKeygenThread() > { >+ // clean up in the unlikely case that nobody consumed our results >+ >+ if (privateKey) >+ SECKEY_DestroyPrivateKey(privateKey); >+ >+ if (publicKey) >+ SECKEY_DestroyPublicKey(publicKey); >+ >+ if (usedSlot) >+ PK11_FreeSlot(usedSlot); > } > > void nsKeygenThread::SetParams( > PK11SlotInfo *a_slot, >+ PK11AttrFlags a_flags, >+ PK11SlotInfo *a_alternative_slot, >+ PK11AttrFlags a_alternative_flags, > PRUint32 a_keyGenMechanism, > void *a_params, >- bool a_isPerm, >- bool a_isSensitive, > void *a_wincx ) > { > nsNSSShutDownPreventionLock locker; > MutexAutoLock lock(mutex); > > if (!alreadyReceivedParams) { > alreadyReceivedParams = true; >- if (a_slot) { >- slot = PK11_ReferenceSlot(a_slot); >- } >- else { >- slot = nsnull; >- } >+ slot = (a_slot) ? PK11_ReferenceSlot(a_slot) : nsnull; >+ flags = a_flags; >+ altSlot = (a_alternative_slot) ? PK11_ReferenceSlot(a_alternative_slot) : nsnull; >+ altFlags = a_alternative_flags; > keyGenMechanism = a_keyGenMechanism; > params = a_params; >- isPerm = a_isPerm; >- isSensitive = a_isSensitive; > wincx = a_wincx; > } > } > >-nsresult nsKeygenThread::GetParams( >+nsresult nsKeygenThread::ConsumeResult( >+ PK11SlotInfo **a_used_slot, > SECKEYPrivateKey **a_privateKey, > SECKEYPublicKey **a_publicKey) > { >- if (!a_privateKey || !a_publicKey) { >+ if (!a_used_slot || !a_privateKey || !a_publicKey) { > return NS_ERROR_FAILURE; > } > > nsresult rv; > >@@ -116,13 +126,15 @@ nsresult nsKeygenThread::GetParams( > NS_ASSERTION(keygenReady, "logic error in nsKeygenThread::GetParams"); > > if (keygenReady) { > *a_privateKey = privateKey; > *a_publicKey = publicKey; >+ *a_used_slot = usedSlot; > > privateKey = 0; > publicKey = 0; >+ usedSlot = 0; > > rv = NS_OK; > } > else { > rv = NS_ERROR_FAILURE; >@@ -201,14 +213,27 @@ void nsKeygenThread::Run(void) > canGenerate = true; > keygenReady = false; > } > } > >- if (canGenerate) >- privateKey = PK11_GenerateKeyPair(slot, keyGenMechanism, >- params, &publicKey, >- isPerm, isSensitive, wincx); >+ if (canGenerate) { >+ privateKey = PK11_GenerateKeyPairWithFlags(slot, keyGenMechanism, >+ params, &publicKey, >+ flags, wincx); >+ >+ if (privateKey) { >+ usedSlot = PK11_ReferenceSlot(slot); >+ } >+ else if (altSlot) { >+ privateKey = PK11_GenerateKeyPairWithFlags(altSlot, keyGenMechanism, >+ params, &publicKey, >+ altFlags, wincx); >+ if (privateKey) { >+ usedSlot = PK11_ReferenceSlot(altSlot); >+ } >+ } >+ } > > // This call gave us ownership over privateKey and publicKey. > // But as the params structure is owner by our caller, > // we effectively transferred ownership to the caller. > // As long as key generation can't be canceled, we don't need >@@ -224,10 +249,14 @@ void nsKeygenThread::Run(void) > // forget our parameters > if (slot) { > PK11_FreeSlot(slot); > slot = 0; > } >+ if (altSlot) { >+ PK11_FreeSlot(altSlot); >+ altSlot = 0; >+ } > keyGenMechanism = 0; > params = 0; > wincx = 0; > > if (!statusDialogClosed && mNotifyObserver) >diff --git a/security/manager/ssl/src/nsKeygenThread.h b/security/manager/ssl/src/nsKeygenThread.h >--- a/security/manager/ssl/src/nsKeygenThread.h >+++ b/security/manager/ssl/src/nsKeygenThread.h >@@ -61,14 +61,16 @@ private: > bool alreadyReceivedParams; > > SECKEYPrivateKey *privateKey; > SECKEYPublicKey *publicKey; > PK11SlotInfo *slot; >+ PK11AttrFlags flags; >+ PK11SlotInfo *altSlot; >+ PK11AttrFlags altFlags; >+ PK11SlotInfo *usedSlot; > PRUint32 keyGenMechanism; > void *params; >- bool isPerm; >- bool isSensitive; > void *wincx; > > PRThread *threadHandle; > > public: >@@ -78,17 +80,19 @@ public: > NS_DECL_NSIKEYGENTHREAD > NS_DECL_ISUPPORTS > > void SetParams( > PK11SlotInfo *a_slot, >+ PK11AttrFlags a_flags, >+ PK11SlotInfo *a_alternative_slot, >+ PK11AttrFlags a_alternative_flags, > PRUint32 a_keyGenMechanism, > void *a_params, >- bool a_isPerm, >- bool a_isSensitive, > void *a_wincx ); > >- nsresult GetParams( >+ nsresult ConsumeResult( >+ PK11SlotInfo **a_used_slot, > SECKEYPrivateKey **a_privateKey, > SECKEYPublicKey **a_publicKey); > > void Join(void); >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 805640
: 572018