nsKeyModule.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #include "nsCOMPtr.h"
  5. #include "nsComponentManagerUtils.h"
  6. #include "nsKeyModule.h"
  7. #include "nsString.h"
  8. using namespace mozilla;
  9. using namespace mozilla::psm;
  10. NS_IMPL_ISUPPORTS(nsKeyObject, nsIKeyObject)
  11. nsKeyObject::nsKeyObject()
  12. : mSymKey(nullptr)
  13. {
  14. }
  15. nsKeyObject::~nsKeyObject()
  16. {
  17. nsNSSShutDownPreventionLock locker;
  18. if (isAlreadyShutDown()) {
  19. return;
  20. }
  21. destructorSafeDestroyNSSReference();
  22. shutdown(ShutdownCalledFrom::Object);
  23. }
  24. void
  25. nsKeyObject::virtualDestroyNSSReference()
  26. {
  27. destructorSafeDestroyNSSReference();
  28. }
  29. void
  30. nsKeyObject::destructorSafeDestroyNSSReference()
  31. {
  32. mSymKey = nullptr;
  33. }
  34. //////////////////////////////////////////////////////////////////////////////
  35. // nsIKeyObject
  36. NS_IMETHODIMP
  37. nsKeyObject::InitKey(int16_t aAlgorithm, PK11SymKey* aKey)
  38. {
  39. if (!aKey || aAlgorithm != nsIKeyObject::HMAC) {
  40. return NS_ERROR_INVALID_ARG;
  41. }
  42. nsNSSShutDownPreventionLock locker;
  43. if (isAlreadyShutDown()) {
  44. return NS_ERROR_NOT_AVAILABLE;
  45. }
  46. mSymKey.reset(aKey);
  47. return NS_OK;
  48. }
  49. NS_IMETHODIMP
  50. nsKeyObject::GetKeyObj(PK11SymKey** _retval)
  51. {
  52. if (!_retval) {
  53. return NS_ERROR_INVALID_ARG;
  54. }
  55. *_retval = nullptr;
  56. nsNSSShutDownPreventionLock locker;
  57. if (isAlreadyShutDown()) {
  58. return NS_ERROR_NOT_AVAILABLE;
  59. }
  60. if (!mSymKey) {
  61. return NS_ERROR_NOT_INITIALIZED;
  62. }
  63. *_retval = mSymKey.get();
  64. return NS_OK;
  65. }
  66. NS_IMETHODIMP
  67. nsKeyObject::GetType(int16_t *_retval)
  68. {
  69. if (!_retval) {
  70. return NS_ERROR_INVALID_ARG;
  71. }
  72. *_retval = nsIKeyObject::SYM_KEY;
  73. return NS_OK;
  74. }
  75. //////////////////////////////////////////////////////////////////////////////
  76. // nsIKeyObjectFactory
  77. NS_IMPL_ISUPPORTS(nsKeyObjectFactory, nsIKeyObjectFactory)
  78. nsKeyObjectFactory::nsKeyObjectFactory()
  79. {
  80. }
  81. nsKeyObjectFactory::~nsKeyObjectFactory()
  82. {
  83. nsNSSShutDownPreventionLock locker;
  84. if (isAlreadyShutDown()) {
  85. return;
  86. }
  87. shutdown(ShutdownCalledFrom::Object);
  88. }
  89. NS_IMETHODIMP
  90. nsKeyObjectFactory::KeyFromString(int16_t aAlgorithm, const nsACString& aKey,
  91. nsIKeyObject** _retval)
  92. {
  93. if (!_retval || aAlgorithm != nsIKeyObject::HMAC) {
  94. return NS_ERROR_INVALID_ARG;
  95. }
  96. nsNSSShutDownPreventionLock locker;
  97. if (isAlreadyShutDown()) {
  98. return NS_ERROR_NOT_AVAILABLE;
  99. }
  100. CK_MECHANISM_TYPE cipherMech = CKM_GENERIC_SECRET_KEY_GEN;
  101. CK_ATTRIBUTE_TYPE cipherOperation = CKA_SIGN;
  102. nsresult rv;
  103. nsCOMPtr<nsIKeyObject> key(
  104. do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv));
  105. if (NS_FAILED(rv)) {
  106. return rv;
  107. }
  108. // Convert the raw string into a SECItem
  109. const nsCString& flatKey = PromiseFlatCString(aKey);
  110. SECItem keyItem;
  111. keyItem.data = (unsigned char*)flatKey.get();
  112. keyItem.len = flatKey.Length();
  113. UniquePK11SlotInfo slot(PK11_GetBestSlot(cipherMech, nullptr));
  114. if (!slot) {
  115. return NS_ERROR_FAILURE;
  116. }
  117. UniquePK11SymKey symKey(PK11_ImportSymKey(slot.get(), cipherMech,
  118. PK11_OriginUnwrap, cipherOperation,
  119. &keyItem, nullptr));
  120. if (!symKey) {
  121. return NS_ERROR_FAILURE;
  122. }
  123. rv = key->InitKey(aAlgorithm, symKey.release());
  124. if (NS_FAILED(rv)) {
  125. return rv;
  126. }
  127. key.swap(*_retval);
  128. return NS_OK;
  129. }