SecretDecoderRing.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. *
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #include "SecretDecoderRing.h"
  7. #include "ScopedNSSTypes.h"
  8. #include "mozilla/Base64.h"
  9. #include "mozilla/Casting.h"
  10. #include "mozilla/Services.h"
  11. #include "nsCOMPtr.h"
  12. #include "nsIInterfaceRequestor.h"
  13. #include "nsIInterfaceRequestorUtils.h"
  14. #include "nsIObserverService.h"
  15. #include "nsIServiceManager.h"
  16. #include "nsITokenPasswordDialogs.h"
  17. #include "nsNSSComponent.h"
  18. #include "nsNSSHelper.h"
  19. #include "pk11func.h"
  20. #include "pk11sdr.h" // For PK11SDR_Encrypt, PK11SDR_Decrypt
  21. #include "ssl.h" // For SSL_ClearSessionCache
  22. using namespace mozilla;
  23. // NOTE: Should these be the thread-safe versions?
  24. NS_IMPL_ISUPPORTS(SecretDecoderRing, nsISecretDecoderRing)
  25. SecretDecoderRing::SecretDecoderRing()
  26. {
  27. }
  28. SecretDecoderRing::~SecretDecoderRing()
  29. {
  30. nsNSSShutDownPreventionLock locker;
  31. if (isAlreadyShutDown()) {
  32. return;
  33. }
  34. shutdown(ShutdownCalledFrom::Object);
  35. }
  36. nsresult
  37. SecretDecoderRing::Encrypt(const nsACString& data, /*out*/ nsACString& result)
  38. {
  39. nsNSSShutDownPreventionLock locker;
  40. if (isAlreadyShutDown()) {
  41. return NS_ERROR_NOT_AVAILABLE;
  42. }
  43. UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
  44. if (!slot) {
  45. return NS_ERROR_NOT_AVAILABLE;
  46. }
  47. /* Make sure token is initialized. */
  48. nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
  49. nsresult rv = setPassword(slot.get(), ctx, locker);
  50. if (NS_FAILED(rv)) {
  51. return rv;
  52. }
  53. /* Force authentication */
  54. if (PK11_Authenticate(slot.get(), true, ctx) != SECSuccess) {
  55. return NS_ERROR_FAILURE;
  56. }
  57. /* Use default key id */
  58. SECItem keyid;
  59. keyid.data = nullptr;
  60. keyid.len = 0;
  61. SECItem request;
  62. request.data = BitwiseCast<unsigned char*, const char*>(data.BeginReading());
  63. request.len = data.Length();
  64. ScopedAutoSECItem reply;
  65. if (PK11SDR_Encrypt(&keyid, &request, &reply, ctx) != SECSuccess) {
  66. return NS_ERROR_FAILURE;
  67. }
  68. result.Assign(BitwiseCast<char*, unsigned char*>(reply.data), reply.len);
  69. return NS_OK;
  70. }
  71. nsresult
  72. SecretDecoderRing::Decrypt(const nsACString& data, /*out*/ nsACString& result)
  73. {
  74. nsNSSShutDownPreventionLock locker;
  75. if (isAlreadyShutDown()) {
  76. return NS_ERROR_NOT_AVAILABLE;
  77. }
  78. /* Find token with SDR key */
  79. UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
  80. if (!slot) {
  81. return NS_ERROR_NOT_AVAILABLE;
  82. }
  83. /* Force authentication */
  84. nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
  85. if (PK11_Authenticate(slot.get(), true, ctx) != SECSuccess) {
  86. return NS_ERROR_NOT_AVAILABLE;
  87. }
  88. SECItem request;
  89. request.data = BitwiseCast<unsigned char*, const char*>(data.BeginReading());
  90. request.len = data.Length();
  91. ScopedAutoSECItem reply;
  92. if (PK11SDR_Decrypt(&request, &reply, ctx) != SECSuccess) {
  93. return NS_ERROR_FAILURE;
  94. }
  95. result.Assign(BitwiseCast<char*, unsigned char*>(reply.data), reply.len);
  96. return NS_OK;
  97. }
  98. NS_IMETHODIMP
  99. SecretDecoderRing::EncryptString(const nsACString& text,
  100. /*out*/ nsACString& encryptedBase64Text)
  101. {
  102. nsAutoCString encryptedText;
  103. nsresult rv = Encrypt(text, encryptedText);
  104. if (NS_FAILED(rv)) {
  105. return rv;
  106. }
  107. rv = Base64Encode(encryptedText, encryptedBase64Text);
  108. if (NS_FAILED(rv)) {
  109. return rv;
  110. }
  111. return NS_OK;
  112. }
  113. NS_IMETHODIMP
  114. SecretDecoderRing::DecryptString(const nsACString& encryptedBase64Text,
  115. /*out*/ nsACString& decryptedText)
  116. {
  117. nsAutoCString encryptedText;
  118. nsresult rv = Base64Decode(encryptedBase64Text, encryptedText);
  119. if (NS_FAILED(rv)) {
  120. return rv;
  121. }
  122. rv = Decrypt(encryptedText, decryptedText);
  123. if (NS_FAILED(rv)) {
  124. return rv;
  125. }
  126. return NS_OK;
  127. }
  128. NS_IMETHODIMP
  129. SecretDecoderRing::ChangePassword()
  130. {
  131. nsNSSShutDownPreventionLock locker;
  132. if (isAlreadyShutDown()) {
  133. return NS_ERROR_NOT_AVAILABLE;
  134. }
  135. UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
  136. if (!slot) {
  137. return NS_ERROR_NOT_AVAILABLE;
  138. }
  139. NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(slot.get()));
  140. nsCOMPtr<nsITokenPasswordDialogs> dialogs;
  141. nsresult rv = getNSSDialogs(getter_AddRefs(dialogs),
  142. NS_GET_IID(nsITokenPasswordDialogs),
  143. NS_TOKENPASSWORDSDIALOG_CONTRACTID);
  144. if (NS_FAILED(rv)) {
  145. return rv;
  146. }
  147. nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
  148. bool canceled; // Ignored
  149. return dialogs->SetPassword(ctx, tokenName.get(), &canceled);
  150. }
  151. NS_IMETHODIMP
  152. SecretDecoderRing::Logout()
  153. {
  154. static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
  155. nsresult rv;
  156. nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  157. if (NS_FAILED(rv))
  158. return rv;
  159. {
  160. nsNSSShutDownPreventionLock locker;
  161. if (isAlreadyShutDown()) {
  162. return NS_ERROR_NOT_AVAILABLE;
  163. }
  164. PK11_LogoutAll();
  165. SSL_ClearSessionCache();
  166. }
  167. return NS_OK;
  168. }
  169. NS_IMETHODIMP
  170. SecretDecoderRing::LogoutAndTeardown()
  171. {
  172. static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
  173. nsresult rv;
  174. nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  175. if (NS_FAILED(rv))
  176. return rv;
  177. {
  178. nsNSSShutDownPreventionLock locker;
  179. if (isAlreadyShutDown()) {
  180. return NS_ERROR_NOT_AVAILABLE;
  181. }
  182. PK11_LogoutAll();
  183. SSL_ClearSessionCache();
  184. }
  185. rv = nssComponent->LogoutAuthenticatedPK11();
  186. // After we just logged out, we need to prune dead connections to make
  187. // sure that all connections that should be stopped, are stopped. See
  188. // bug 517584.
  189. nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
  190. if (os)
  191. os->NotifyObservers(nullptr, "net:prune-dead-connections", nullptr);
  192. return rv;
  193. }