From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- security/manager/pki/moz.build | 26 + security/manager/pki/nsASN1Tree.cpp | 573 +++++++++++++++++++++ security/manager/pki/nsASN1Tree.h | 72 +++ security/manager/pki/nsIASN1Tree.idl | 25 + security/manager/pki/nsNSSDialogHelper.cpp | 56 ++ security/manager/pki/nsNSSDialogHelper.h | 38 ++ security/manager/pki/nsNSSDialogs.cpp | 441 ++++++++++++++++ security/manager/pki/nsNSSDialogs.h | 44 ++ security/manager/pki/nsPKIModule.cpp | 40 ++ .../manager/pki/resources/content/CAOverlay.xul | 55 ++ .../manager/pki/resources/content/MineOverlay.xul | 64 +++ .../pki/resources/content/OrphanOverlay.xul | 47 ++ .../pki/resources/content/OthersOverlay.xul | 54 ++ .../pki/resources/content/WebSitesOverlay.xul | 57 ++ .../manager/pki/resources/content/certDump.xul | 44 ++ .../manager/pki/resources/content/certManager.js | 542 +++++++++++++++++++ .../manager/pki/resources/content/certManager.xul | 51 ++ .../manager/pki/resources/content/certViewer.js | 354 +++++++++++++ .../manager/pki/resources/content/certViewer.xul | 40 ++ .../pki/resources/content/changepassword.js | 270 ++++++++++ .../pki/resources/content/changepassword.xul | 78 +++ .../manager/pki/resources/content/choosetoken.js | 44 ++ .../manager/pki/resources/content/choosetoken.xul | 34 ++ .../manager/pki/resources/content/clientauthask.js | 158 ++++++ .../pki/resources/content/clientauthask.xul | 49 ++ .../pki/resources/content/createCertInfo.js | 39 ++ .../pki/resources/content/createCertInfo.xul | 30 ++ .../manager/pki/resources/content/deletecert.js | 134 +++++ .../manager/pki/resources/content/deletecert.xul | 28 + .../pki/resources/content/device_manager.js | 509 ++++++++++++++++++ .../pki/resources/content/device_manager.xul | 90 ++++ .../manager/pki/resources/content/downloadcert.js | 92 ++++ .../manager/pki/resources/content/downloadcert.xul | 69 +++ .../manager/pki/resources/content/editcacert.js | 58 +++ .../manager/pki/resources/content/editcacert.xul | 36 ++ .../pki/resources/content/exceptionDialog.js | 368 +++++++++++++ .../pki/resources/content/exceptionDialog.xul | 89 ++++ .../manager/pki/resources/content/load_device.xul | 42 ++ security/manager/pki/resources/content/pippki.js | 191 +++++++ .../manager/pki/resources/content/protectedAuth.js | 42 ++ .../pki/resources/content/protectedAuth.xul | 33 ++ .../manager/pki/resources/content/resetpassword.js | 47 ++ .../pki/resources/content/resetpassword.xul | 35 ++ .../pki/resources/content/setp12password.js | 128 +++++ .../pki/resources/content/setp12password.xul | 51 ++ .../pki/resources/content/viewCertDetails.xul | 104 ++++ security/manager/pki/resources/jar.mn | 43 ++ security/manager/pki/resources/moz.build | 7 + 48 files changed, 5521 insertions(+) create mode 100644 security/manager/pki/moz.build create mode 100644 security/manager/pki/nsASN1Tree.cpp create mode 100644 security/manager/pki/nsASN1Tree.h create mode 100644 security/manager/pki/nsIASN1Tree.idl create mode 100644 security/manager/pki/nsNSSDialogHelper.cpp create mode 100644 security/manager/pki/nsNSSDialogHelper.h create mode 100644 security/manager/pki/nsNSSDialogs.cpp create mode 100644 security/manager/pki/nsNSSDialogs.h create mode 100644 security/manager/pki/nsPKIModule.cpp create mode 100644 security/manager/pki/resources/content/CAOverlay.xul create mode 100644 security/manager/pki/resources/content/MineOverlay.xul create mode 100644 security/manager/pki/resources/content/OrphanOverlay.xul create mode 100644 security/manager/pki/resources/content/OthersOverlay.xul create mode 100644 security/manager/pki/resources/content/WebSitesOverlay.xul create mode 100644 security/manager/pki/resources/content/certDump.xul create mode 100644 security/manager/pki/resources/content/certManager.js create mode 100644 security/manager/pki/resources/content/certManager.xul create mode 100644 security/manager/pki/resources/content/certViewer.js create mode 100644 security/manager/pki/resources/content/certViewer.xul create mode 100644 security/manager/pki/resources/content/changepassword.js create mode 100644 security/manager/pki/resources/content/changepassword.xul create mode 100644 security/manager/pki/resources/content/choosetoken.js create mode 100644 security/manager/pki/resources/content/choosetoken.xul create mode 100644 security/manager/pki/resources/content/clientauthask.js create mode 100644 security/manager/pki/resources/content/clientauthask.xul create mode 100644 security/manager/pki/resources/content/createCertInfo.js create mode 100644 security/manager/pki/resources/content/createCertInfo.xul create mode 100644 security/manager/pki/resources/content/deletecert.js create mode 100644 security/manager/pki/resources/content/deletecert.xul create mode 100644 security/manager/pki/resources/content/device_manager.js create mode 100644 security/manager/pki/resources/content/device_manager.xul create mode 100644 security/manager/pki/resources/content/downloadcert.js create mode 100644 security/manager/pki/resources/content/downloadcert.xul create mode 100644 security/manager/pki/resources/content/editcacert.js create mode 100644 security/manager/pki/resources/content/editcacert.xul create mode 100644 security/manager/pki/resources/content/exceptionDialog.js create mode 100644 security/manager/pki/resources/content/exceptionDialog.xul create mode 100644 security/manager/pki/resources/content/load_device.xul create mode 100644 security/manager/pki/resources/content/pippki.js create mode 100644 security/manager/pki/resources/content/protectedAuth.js create mode 100644 security/manager/pki/resources/content/protectedAuth.xul create mode 100644 security/manager/pki/resources/content/resetpassword.js create mode 100644 security/manager/pki/resources/content/resetpassword.xul create mode 100644 security/manager/pki/resources/content/setp12password.js create mode 100644 security/manager/pki/resources/content/setp12password.xul create mode 100644 security/manager/pki/resources/content/viewCertDetails.xul create mode 100644 security/manager/pki/resources/jar.mn create mode 100644 security/manager/pki/resources/moz.build (limited to 'security/manager/pki') diff --git a/security/manager/pki/moz.build b/security/manager/pki/moz.build new file mode 100644 index 000000000..9a8038922 --- /dev/null +++ b/security/manager/pki/moz.build @@ -0,0 +1,26 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += ['resources'] + +XPIDL_SOURCES += [ + 'nsIASN1Tree.idl', +] + +XPIDL_MODULE = 'pippki' + +UNIFIED_SOURCES += [ + 'nsASN1Tree.cpp', + 'nsNSSDialogHelper.cpp', + 'nsNSSDialogs.cpp', + 'nsPKIModule.cpp', +] + +LOCAL_INCLUDES += [ + '!/dist/public/nss', +] + +FINAL_LIBRARY = 'xul' diff --git a/security/manager/pki/nsASN1Tree.cpp b/security/manager/pki/nsASN1Tree.cpp new file mode 100644 index 000000000..ce9672d8d --- /dev/null +++ b/security/manager/pki/nsASN1Tree.cpp @@ -0,0 +1,573 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "nsASN1Tree.h" + +#include "mozilla/Assertions.h" +#include "nsArrayUtils.h" +#include "nsDebug.h" +#include "nsIMutableArray.h" +#include "nsString.h" + +NS_IMPL_ISUPPORTS(nsNSSASN1Tree, nsIASN1Tree, nsITreeView) + +nsNSSASN1Tree::nsNSSASN1Tree() + : mTopNode(nullptr) +{ +} + +nsNSSASN1Tree::~nsNSSASN1Tree() +{ + ClearNodes(); +} + +void +nsNSSASN1Tree::ClearNodesRecursively(myNode* n) +{ + // Note: |n| is allowed to be null. + + myNode *walk = n; + while (walk) { + myNode *kill = walk; + + if (walk->child) { + ClearNodesRecursively(walk->child); + } + + walk = walk->next; + delete kill; + } +} + +void +nsNSSASN1Tree::ClearNodes() +{ + ClearNodesRecursively(mTopNode); + mTopNode = nullptr; +} + +void +nsNSSASN1Tree::InitChildsRecursively(myNode* n) +{ + MOZ_ASSERT(n); + if (!n) { + return; + } + + if (!n->obj) + return; + + n->seq = do_QueryInterface(n->obj); + if (!n->seq) + return; + + // If the object is a sequence, there might still be a reason + // why it should not be displayed as a container. + // If we decide that it has all the properties to justify + // displaying as a container, we will create a new child chain. + // If we decide, it does not make sense to display as a container, + // we forget that it is a sequence by erasing n->seq. + // That way, n->seq and n->child will be either both set or both null. + + bool isContainer; + n->seq->GetIsValidContainer(&isContainer); + if (!isContainer) { + n->seq = nullptr; + return; + } + + nsCOMPtr asn1Objects; + n->seq->GetASN1Objects(getter_AddRefs(asn1Objects)); + uint32_t numObjects; + asn1Objects->GetLength(&numObjects); + if (!numObjects) { + n->seq = nullptr; + return; + } + + myNode *walk = nullptr; + myNode *prev = nullptr; + for (uint32_t i = 0; i < numObjects; i++) { + if (0 == i) { + n->child = walk = new myNode; + } + else { + walk = new myNode; + } + + walk->parent = n; + if (prev) { + prev->next = walk; + } + + walk->obj = do_QueryElementAt(asn1Objects, i); + + InitChildsRecursively(walk); + + prev = walk; + } +} + +void +nsNSSASN1Tree::InitNodes() +{ + ClearNodes(); + + mTopNode = new myNode; + mTopNode->obj = mASN1Object; + + InitChildsRecursively(mTopNode); +} + +NS_IMETHODIMP +nsNSSASN1Tree::LoadASN1Structure(nsIASN1Object* asn1Object) +{ + // Note: |asn1Object| is allowed to be null. + + // The tree won't automatically re-draw if the contents + // have been changed. So I do a quick test here to let + // me know if I should forced the tree to redraw itself + // by calling RowCountChanged on it. + // + bool redraw = (mASN1Object && mTree); + int32_t rowsToDelete = 0; + + if (redraw) { + // This is the number of rows we will be deleting after + // the contents have changed. + rowsToDelete = 0-CountVisibleNodes(mTopNode); + } + + mASN1Object = asn1Object; + InitNodes(); + + if (redraw) { + // The number of rows in the new content. + int32_t newRows = CountVisibleNodes(mTopNode); + mTree->BeginUpdateBatch(); + // Erase all of the old rows. + mTree->RowCountChanged(0, rowsToDelete); + // Replace them with the new contents + mTree->RowCountChanged(0, newRows); + mTree->EndUpdateBatch(); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetRowCount(int32_t* aRowCount) +{ + NS_ENSURE_ARG_POINTER(aRowCount); + + if (mASN1Object) { + *aRowCount = CountVisibleNodes(mTopNode); + } else { + *aRowCount = 0; + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetSelection(nsITreeSelection** aSelection) +{ + NS_ENSURE_ARG_POINTER(aSelection); + *aSelection = mSelection; + NS_IF_ADDREF(*aSelection); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::SetSelection(nsITreeSelection* aSelection) +{ + // Note: |aSelection| is allowed to be null. + mSelection = aSelection; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetRowProperties(int32_t, nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetCellProperties(int32_t, nsITreeColumn*, nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetColumnProperties(nsITreeColumn*, nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsContainer(int32_t index, bool* _retval) +{ + NS_ENSURE_ARG_MIN(index, 0); + NS_ENSURE_ARG_POINTER(_retval); + + myNode *n = FindNodeFromIndex(index); + if (!n) + return NS_ERROR_FAILURE; + + *_retval = (n->seq != nullptr); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsContainerOpen(int32_t index, bool* _retval) +{ + NS_ENSURE_ARG_MIN(index, 0); + NS_ENSURE_ARG_POINTER(_retval); + + myNode *n = FindNodeFromIndex(index); + if (!n || !n->seq) + return NS_ERROR_FAILURE; + + return n->seq->GetIsExpanded(_retval); +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsContainerEmpty(int32_t, bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsSeparator(int32_t, bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetLevel(int32_t index, int32_t* _retval) +{ + NS_ENSURE_ARG_MIN(index, 0); + NS_ENSURE_ARG_POINTER(_retval); + + int32_t nodeLevel; + myNode* n = FindNodeFromIndex(index, nullptr, &nodeLevel); + if (!n) + return NS_ERROR_FAILURE; + + *_retval = nodeLevel; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetImageSrc(int32_t, nsITreeColumn*, nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetProgressMode(int32_t, nsITreeColumn*, int32_t*) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetCellValue(int32_t, nsITreeColumn*, nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetCellText(int32_t row, nsITreeColumn*, nsAString& _retval) +{ + NS_ENSURE_ARG_MIN(row, 0); + + _retval.Truncate(); + + myNode* n = FindNodeFromIndex(row); + if (!n) + return NS_ERROR_FAILURE; + + // There's only one column for ASN1 dump. + return n->obj->GetDisplayName(_retval); +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetDisplayData(uint32_t index, nsAString& _retval) +{ + myNode *n = FindNodeFromIndex(index); + if (!n) + return NS_ERROR_FAILURE; + + return n->obj->GetDisplayValue(_retval); +} + +NS_IMETHODIMP +nsNSSASN1Tree::SetTree(nsITreeBoxObject* tree) +{ + // Note: |tree| is allowed to be null. + mTree = tree; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::ToggleOpenState(int32_t index) +{ + NS_ENSURE_ARG_MIN(index, 0); + + myNode *n = FindNodeFromIndex(index); + if (!n) + return NS_ERROR_FAILURE; + + if (!n->seq) + return NS_ERROR_FAILURE; + + bool IsExpanded; + n->seq->GetIsExpanded(&IsExpanded); + int32_t rowCountChange; + if (IsExpanded) { + rowCountChange = -CountVisibleNodes(n->child); + n->seq->SetIsExpanded(false); + } else { + n->seq->SetIsExpanded(true); + rowCountChange = CountVisibleNodes(n->child); + } + if (mTree) + mTree->RowCountChanged(index, rowCountChange); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::CycleHeader(nsITreeColumn*) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::SelectionChanged() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNSSASN1Tree::CycleCell(int32_t, nsITreeColumn*) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsEditable(int32_t, nsITreeColumn*, bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsSelectable(int32_t, nsITreeColumn*, bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::SetCellValue(int32_t, nsITreeColumn*, const nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::SetCellText(int32_t, nsITreeColumn*, const nsAString&) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::PerformAction(const char16_t*) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::PerformActionOnRow(const char16_t*, int32_t) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::PerformActionOnCell(const char16_t*, int32_t, nsITreeColumn*) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::CanDrop(int32_t, int32_t, nsIDOMDataTransfer*, bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::Drop(int32_t, int32_t, nsIDOMDataTransfer*) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::IsSorted(bool* _retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::GetParentIndex(int32_t rowIndex, int32_t* _retval) +{ + NS_ENSURE_ARG_MIN(rowIndex, 0); + NS_ENSURE_ARG_POINTER(_retval); + + int32_t parentIndex = -1; + + myNode *n = FindNodeFromIndex(rowIndex, &parentIndex); + if (!n) + return NS_ERROR_FAILURE; + + *_retval = parentIndex; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSASN1Tree::HasNextSibling(int32_t rowIndex, int32_t afterIndex, + bool* _retval) +{ + NS_ENSURE_ARG_MIN(rowIndex, 0); + NS_ENSURE_ARG_MIN(afterIndex, 0); + NS_ENSURE_ARG_POINTER(_retval); + + myNode *n = FindNodeFromIndex(rowIndex); + if (!n) + return NS_ERROR_FAILURE; + + if (!n->next) { + *_retval = false; + } + else { + int32_t nTotalSize = CountVisibleNodes(n); + int32_t nLastChildPos = rowIndex + nTotalSize -1; + int32_t nextSiblingPos = nLastChildPos +1; + *_retval = (nextSiblingPos > afterIndex); + } + + return NS_OK; +} + +int32_t +nsNSSASN1Tree::CountVisibleNodes(myNode* n) +{ + if (!n) + return 0; + + myNode *walk = n; + int32_t count = 0; + while (walk) { + ++count; + + if (walk->seq) { + bool IsExpanded; + walk->seq->GetIsExpanded(&IsExpanded); + if (IsExpanded) { + count += CountVisibleNodes(walk->child); + } + } + + walk = walk->next; + } + + return count; +} + +// Entry point for find +nsNSSASN1Tree::myNode* +nsNSSASN1Tree::FindNodeFromIndex(int32_t wantedIndex, + int32_t* optionalOutParentIndex, + int32_t* optionalOutLevel) +{ + MOZ_ASSERT(wantedIndex >= 0); + if (wantedIndex < 0) { + return nullptr; + } + + if (0 == wantedIndex) { + if (optionalOutLevel) { + *optionalOutLevel = 0; + } + if (optionalOutParentIndex) { + *optionalOutParentIndex = -1; + } + return mTopNode; + } + + int32_t index = 0; + int32_t level = 0; + return FindNodeFromIndex(mTopNode, wantedIndex, index, level, + optionalOutParentIndex, optionalOutLevel); +} + +// Internal recursive helper function +nsNSSASN1Tree::myNode* +nsNSSASN1Tree::FindNodeFromIndex(myNode* n, int32_t wantedIndex, + int32_t& indexCounter, int32_t& levelCounter, + int32_t* optionalOutParentIndex, + int32_t* optionalOutLevel) +{ + MOZ_ASSERT(wantedIndex >= 0); + MOZ_ASSERT(indexCounter >= 0); + MOZ_ASSERT(levelCounter >= 0); + if (!n || wantedIndex < 0 || indexCounter < 0 || levelCounter < 0) { + return nullptr; + } + + myNode *walk = n; + int32_t parentIndex = indexCounter - 1; + + while (walk) { + if (indexCounter == wantedIndex) { + if (optionalOutLevel) { + *optionalOutLevel = levelCounter; + } + if (optionalOutParentIndex) { + *optionalOutParentIndex = parentIndex; + } + return walk; + } + + if (walk->seq) { + bool IsExpanded; + walk->seq->GetIsExpanded(&IsExpanded); + if (IsExpanded) { + ++indexCounter; // set to walk->child + + ++levelCounter; + myNode* found = FindNodeFromIndex(walk->child, wantedIndex, indexCounter, + levelCounter, optionalOutParentIndex, + optionalOutLevel); + --levelCounter; + + if (found) + return found; + } + } + + walk = walk->next; + if (walk) { + ++indexCounter; + } + } + + return nullptr; +} diff --git a/security/manager/pki/nsASN1Tree.h b/security/manager/pki/nsASN1Tree.h new file mode 100644 index 000000000..bb2325b7a --- /dev/null +++ b/security/manager/pki/nsASN1Tree.h @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef _NSSASNTREE_H_ +#define _NSSASNTREE_H_ + +#include "nscore.h" +#include "nsIX509Cert.h" +#include "nsIASN1Tree.h" +#include "nsIASN1Object.h" +#include "nsIASN1Sequence.h" +#include "nsITreeView.h" +#include "nsITreeBoxObject.h" +#include "nsITreeSelection.h" +#include "nsCOMPtr.h" + +//4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606 +#define NS_NSSASN1OUTINER_CID { \ + 0x4bfaa9f0, \ + 0x1dd2, \ + 0x11b2, \ + {0xaf,0xae,0xa8,0x2c,0xba,0xa0,0xb6,0x06} \ + } + + +class nsNSSASN1Tree : public nsIASN1Tree +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIASN1TREE + NS_DECL_NSITREEVIEW + + nsNSSASN1Tree(); +protected: + virtual ~nsNSSASN1Tree(); + + class myNode + { + public: + nsCOMPtr obj; + nsCOMPtr seq; + myNode *child; + myNode *next; + myNode *parent; + + myNode() { + child = next = parent = nullptr; + } + }; + + myNode *mTopNode; + + nsCOMPtr mASN1Object; + nsCOMPtr mSelection; + nsCOMPtr mTree; + + void InitNodes(); + void InitChildsRecursively(myNode *n); + + void ClearNodes(); + void ClearNodesRecursively(myNode *n); + + int32_t CountVisibleNodes(myNode *n); + myNode *FindNodeFromIndex(myNode *n, int32_t wantedIndex, + int32_t &index_counter, int32_t &level_counter, + int32_t *optionalOutParentIndex, int32_t *optionalOutLevel); + myNode *FindNodeFromIndex(int32_t wantedIndex, + int32_t *optionalOutParentIndex = nullptr, + int32_t *optionalOutLevel = nullptr); + +}; +#endif //_NSSASNTREE_H_ diff --git a/security/manager/pki/nsIASN1Tree.idl b/security/manager/pki/nsIASN1Tree.idl new file mode 100644 index 000000000..a0e2a265a --- /dev/null +++ b/security/manager/pki/nsIASN1Tree.idl @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsITreeView.idl" +#include "nsIX509Cert.idl" + +[scriptable, uuid(de142307-7b88-4e0a-b232-250f310e25d8)] +interface nsIASN1Tree : nsITreeView { + + void loadASN1Structure(in nsIASN1Object asn1Object); + + AString getDisplayData(in unsigned long index); + +}; + +%{C++ + +#define NS_ASN1TREE_CONTRACTID "@mozilla.org/security/nsASN1Tree;1" + +%} + diff --git a/security/manager/pki/nsNSSDialogHelper.cpp b/security/manager/pki/nsNSSDialogHelper.cpp new file mode 100644 index 000000000..1ec161b81 --- /dev/null +++ b/security/manager/pki/nsNSSDialogHelper.cpp @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsNSSDialogHelper.h" + +#include "mozilla/dom/ScriptSettings.h" +#include "nsCOMPtr.h" +#include "nsIDOMWindow.h" +#include "nsIServiceManager.h" +#include "nsIWindowWatcher.h" + +static const char kOpenDialogParam[] = "centerscreen,chrome,modal,titlebar"; +static const char kOpenWindowParam[] = "centerscreen,chrome,titlebar"; + +nsresult +nsNSSDialogHelper::openDialog(mozIDOMWindowProxy* window, const char* url, + nsISupports* params, bool modal) +{ +#ifdef MOZ_WIDGET_GONK + // On b2g devices, we need to proxy the dialog creation & management + // to Gaia. + return NS_ERROR_NOT_IMPLEMENTED; +#endif + + nsresult rv; + nsCOMPtr windowWatcher = + do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr parent = window; + + if (!parent) { + windowWatcher->GetActiveWindow(getter_AddRefs(parent)); + } + + // We're loading XUL into this window, and it's happening on behalf of the + // system, not on behalf of content. Make sure the initial about:blank window + // gets a system principal, otherwise we'll bork when trying to wrap the + // nsIKeyGenThread |arguments| property into the unprivileged scoope. + MOZ_ASSERT(!strncmp("chrome://", url, strlen("chrome://"))); + mozilla::dom::AutoNoJSAPI nojsapi; + + nsCOMPtr newWindow; + rv = windowWatcher->OpenWindow(parent, + url, + "_blank", + modal + ? kOpenDialogParam + : kOpenWindowParam, + params, + getter_AddRefs(newWindow)); + return rv; +} diff --git a/security/manager/pki/nsNSSDialogHelper.h b/security/manager/pki/nsNSSDialogHelper.h new file mode 100644 index 000000000..87605da5f --- /dev/null +++ b/security/manager/pki/nsNSSDialogHelper.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsNSSDialogHelper_h +#define nsNSSDialogHelper_h + +class mozIDOMWindowProxy; +class nsISupports; + +/** + * Helper class that uses the window watcher service to open a standard dialog, + * with or without a parent context. + */ +class nsNSSDialogHelper +{ +public: + /** + * Opens a XUL dialog. + * + * @param window + * Parent window of the dialog, or nullptr to signal no parent. + * @param url + * URL to the XUL dialog. + * @param params + * Parameters to pass to the dialog. Same semantics as the + * nsIWindowWatcher.openWindow() |aArguments| parameter. + * @param modal + * true if the dialog should be modal, false otherwise. + * @return The result of opening the dialog. + */ + static nsresult openDialog(mozIDOMWindowProxy* window, const char* url, + nsISupports* params, bool modal = true); +}; + +#endif // nsNSSDialogHelper_h diff --git a/security/manager/pki/nsNSSDialogs.cpp b/security/manager/pki/nsNSSDialogs.cpp new file mode 100644 index 000000000..831bce57e --- /dev/null +++ b/security/manager/pki/nsNSSDialogs.cpp @@ -0,0 +1,441 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Dialog services for PIP. + */ + +#include "nsNSSDialogs.h" + +#include "mozIDOMWindow.h" +#include "nsArray.h" +#include "nsEmbedCID.h" +#include "nsHashPropertyBag.h" +#include "nsIDialogParamBlock.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIKeygenThread.h" +#include "nsIPromptService.h" +#include "nsIProtectedAuthThread.h" +#include "nsIWindowWatcher.h" +#include "nsIX509CertDB.h" +#include "nsIX509Cert.h" +#include "nsNSSDialogHelper.h" +#include "nsString.h" +#include "nsVariant.h" + +#define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties" + +nsNSSDialogs::nsNSSDialogs() +{ +} + +nsNSSDialogs::~nsNSSDialogs() +{ +} + +NS_IMPL_ISUPPORTS(nsNSSDialogs, nsITokenPasswordDialogs, + nsICertificateDialogs, + nsIClientAuthDialogs, + nsITokenDialogs, + nsIGeneratingKeypairInfoDialogs) + +nsresult +nsNSSDialogs::Init() +{ + nsresult rv; + + nsCOMPtr service = + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = service->CreateBundle(PIPSTRING_BUNDLE_URL, + getter_AddRefs(mPIPStringBundle)); + return rv; +} + +nsresult +nsNSSDialogs::SetPassword(nsIInterfaceRequestor *ctx, + const char16_t *tokenName, bool* _canceled) +{ + nsresult rv; + + *_canceled = false; + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(ctx); + + nsCOMPtr block = + do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID); + if (!block) return NS_ERROR_FAILURE; + + rv = block->SetString(1, tokenName); + if (NS_FAILED(rv)) return rv; + + rv = nsNSSDialogHelper::openDialog(parent, + "chrome://pippki/content/changepassword.xul", + block); + + if (NS_FAILED(rv)) return rv; + + int32_t status; + + rv = block->GetInt(1, &status); + if (NS_FAILED(rv)) return rv; + + *_canceled = (status == 0)?true:false; + + return rv; +} + +NS_IMETHODIMP +nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor* ctx, + nsIX509Cert* cert, + /*out*/ uint32_t* trust, + /*out*/ bool* importConfirmed) +{ + // |ctx| is allowed to be null. + NS_ENSURE_ARG(cert); + NS_ENSURE_ARG(trust); + NS_ENSURE_ARG(importConfirmed); + + nsCOMPtr argArray = nsArrayBase::Create(); + if (!argArray) { + return NS_ERROR_FAILURE; + } + + nsresult rv = argArray->AppendElement(cert, false); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr retVals = new nsHashPropertyBag(); + rv = argArray->AppendElement(retVals, false); + if (NS_FAILED(rv)) { + return rv; + } + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(ctx); + rv = nsNSSDialogHelper::openDialog(parent, + "chrome://pippki/content/downloadcert.xul", + argArray); + if (NS_FAILED(rv)) { + return rv; + } + + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("importConfirmed"), + importConfirmed); + if (NS_FAILED(rv)) { + return rv; + } + + *trust = nsIX509CertDB::UNTRUSTED; + if (!*importConfirmed) { + return NS_OK; + } + + bool trustForSSL = false; + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForSSL"), + &trustForSSL); + if (NS_FAILED(rv)) { + return rv; + } + bool trustForEmail = false; + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForEmail"), + &trustForEmail); + if (NS_FAILED(rv)) { + return rv; + } + bool trustForObjSign = false; + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("trustForObjSign"), + &trustForObjSign); + if (NS_FAILED(rv)) { + return rv; + } + + *trust |= trustForSSL ? nsIX509CertDB::TRUSTED_SSL : 0; + *trust |= trustForEmail ? nsIX509CertDB::TRUSTED_EMAIL : 0; + *trust |= trustForObjSign ? nsIX509CertDB::TRUSTED_OBJSIGN : 0; + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx, + const nsACString& hostname, + int32_t port, + const nsACString& organization, + const nsACString& issuerOrg, + nsIArray* certList, + /*out*/ uint32_t* selectedIndex, + /*out*/ bool* certificateChosen) +{ + NS_ENSURE_ARG_POINTER(ctx); + NS_ENSURE_ARG_POINTER(certList); + NS_ENSURE_ARG_POINTER(selectedIndex); + NS_ENSURE_ARG_POINTER(certificateChosen); + + *certificateChosen = false; + + nsCOMPtr argArray = nsArrayBase::Create(); + if (!argArray) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr hostnameVariant = new nsVariant(); + nsresult rv = hostnameVariant->SetAsAUTF8String(hostname); + if (NS_FAILED(rv)) { + return rv; + } + rv = argArray->AppendElement(hostnameVariant, false); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr organizationVariant = new nsVariant(); + rv = organizationVariant->SetAsAUTF8String(organization); + if (NS_FAILED(rv)) { + return rv; + } + rv = argArray->AppendElement(organizationVariant, false); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr issuerOrgVariant = new nsVariant(); + rv = issuerOrgVariant->SetAsAUTF8String(issuerOrg); + if (NS_FAILED(rv)) { + return rv; + } + rv = argArray->AppendElement(issuerOrgVariant, false); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr portVariant = new nsVariant(); + rv = portVariant->SetAsInt32(port); + if (NS_FAILED(rv)) { + return rv; + } + rv = argArray->AppendElement(portVariant, false); + if (NS_FAILED(rv)) { + return rv; + } + + rv = argArray->AppendElement(certList, false); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr retVals = new nsHashPropertyBag(); + rv = argArray->AppendElement(retVals, false); + if (NS_FAILED(rv)) { + return rv; + } + + rv = nsNSSDialogHelper::openDialog(nullptr, + "chrome://pippki/content/clientauthask.xul", + argArray); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr extraResult = do_QueryInterface(ctx); + if (extraResult) { + bool rememberSelection = false; + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("rememberSelection"), + &rememberSelection); + if (NS_SUCCEEDED(rv)) { + extraResult->SetRememberClientAuthCertificate(rememberSelection); + } + } + + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("certChosen"), + certificateChosen); + if (NS_FAILED(rv)) { + return rv; + } + if (*certificateChosen) { + rv = retVals->GetPropertyAsUint32(NS_LITERAL_STRING("selectedIndex"), + selectedIndex); + if (NS_FAILED(rv)) { + return rv; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor* ctx, + /*out*/ nsAString& password, + /*out*/ bool* confirmedPassword) +{ + // |ctx| is allowed to be null. + NS_ENSURE_ARG(confirmedPassword); + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(ctx); + nsCOMPtr retVals = new nsHashPropertyBag(); + nsresult rv = + nsNSSDialogHelper::openDialog(parent, + "chrome://pippki/content/setp12password.xul", + retVals); + if (NS_FAILED(rv)) { + return rv; + } + + rv = retVals->GetPropertyAsBool(NS_LITERAL_STRING("confirmedPassword"), + confirmedPassword); + if (NS_FAILED(rv)) { + return rv; + } + + if (!*confirmedPassword) { + return NS_OK; + } + + return retVals->GetPropertyAsAString(NS_LITERAL_STRING("password"), password); +} + +NS_IMETHODIMP +nsNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor* ctx, + nsAString& _password, + bool* _retval) +{ + *_retval = false; + + nsCOMPtr promptSvc( + do_GetService(NS_PROMPTSERVICE_CONTRACTID)); + if (!promptSvc) { + return NS_ERROR_FAILURE; + } + + nsAutoString msg; + nsresult rv = mPIPStringBundle->GetStringFromName( + u"getPKCS12FilePasswordMessage", getter_Copies(msg)); + if (NS_FAILED(rv)) { + return rv; + } + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(ctx); + bool ignored = false; + char16_t* pwTemp = nullptr; + rv = promptSvc->PromptPassword(parent, nullptr, msg.get(), &pwTemp, nullptr, + &ignored, _retval); + if (NS_FAILED(rv)) { + return rv; + } + + if (*_retval) { + _password.Assign(pwTemp); + free(pwTemp); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSDialogs::ViewCert(nsIInterfaceRequestor* ctx, nsIX509Cert* cert) +{ + // |ctx| is allowed to be null. + NS_ENSURE_ARG(cert); + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(ctx); + return nsNSSDialogHelper::openDialog(parent, + "chrome://pippki/content/certViewer.xul", + cert, + false /*modal*/); +} + +NS_IMETHODIMP +nsNSSDialogs::DisplayGeneratingKeypairInfo(nsIInterfaceRequestor *aCtx, nsIKeygenThread *runnable) +{ + nsresult rv; + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(aCtx); + + rv = nsNSSDialogHelper::openDialog(parent, + "chrome://pippki/content/createCertInfo.xul", + runnable); + return rv; +} + +NS_IMETHODIMP +nsNSSDialogs::ChooseToken(nsIInterfaceRequestor *aCtx, const char16_t **aTokenList, uint32_t aCount, char16_t **aTokenChosen, bool *aCanceled) { + nsresult rv; + uint32_t i; + + *aCanceled = false; + + nsCOMPtr block = + do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID); + if (!block) return NS_ERROR_FAILURE; + + block->SetNumberStrings(aCount); + + for (i = 0; i < aCount; i++) { + rv = block->SetString(i, aTokenList[i]); + if (NS_FAILED(rv)) return rv; + } + + rv = block->SetInt(0, aCount); + if (NS_FAILED(rv)) return rv; + + rv = nsNSSDialogHelper::openDialog(nullptr, + "chrome://pippki/content/choosetoken.xul", + block); + if (NS_FAILED(rv)) return rv; + + int32_t status; + + rv = block->GetInt(0, &status); + if (NS_FAILED(rv)) return rv; + + *aCanceled = (status == 0)?true:false; + if (!*aCanceled) { + // retrieve the nickname + rv = block->GetString(0, aTokenChosen); + } + return rv; +} + +NS_IMETHODIMP +nsNSSDialogs::DisplayProtectedAuth(nsIInterfaceRequestor *aCtx, nsIProtectedAuthThread *runnable) +{ + // We cannot use nsNSSDialogHelper here. We cannot allow close widget + // in the window because protected authentication is interruptible + // from user interface and changing nsNSSDialogHelper's static variable + // would not be thread-safe + + nsresult rv = NS_ERROR_FAILURE; + + // Get the parent window for the dialog + nsCOMPtr parent = do_GetInterface(aCtx); + + nsCOMPtr windowWatcher = + do_GetService("@mozilla.org/embedcomp/window-watcher;1", &rv); + if (NS_FAILED(rv)) + return rv; + + if (!parent) { + windowWatcher->GetActiveWindow(getter_AddRefs(parent)); + } + + nsCOMPtr newWindow; + rv = windowWatcher->OpenWindow(parent, + "chrome://pippki/content/protectedAuth.xul", + "_blank", + "centerscreen,chrome,modal,titlebar,close=no", + runnable, + getter_AddRefs(newWindow)); + + return rv; +} diff --git a/security/manager/pki/nsNSSDialogs.h b/security/manager/pki/nsNSSDialogs.h new file mode 100644 index 000000000..164d661ee --- /dev/null +++ b/security/manager/pki/nsNSSDialogs.h @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsNSSDialogs_h +#define nsNSSDialogs_h + +#include "nsCOMPtr.h" +#include "nsICertificateDialogs.h" +#include "nsIClientAuthDialogs.h" +#include "nsIGenKeypairInfoDlg.h" +#include "nsIStringBundle.h" +#include "nsITokenDialogs.h" +#include "nsITokenPasswordDialogs.h" + +#define NS_NSSDIALOGS_CID \ + { 0x518e071f, 0x1dd2, 0x11b2, \ + { 0x93, 0x7e, 0xc4, 0x5f, 0x14, 0xde, 0xf7, 0x78 }} + +class nsNSSDialogs : public nsICertificateDialogs + , public nsIClientAuthDialogs + , public nsIGeneratingKeypairInfoDialogs + , public nsITokenDialogs + , public nsITokenPasswordDialogs +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSITOKENPASSWORDDIALOGS + NS_DECL_NSICERTIFICATEDIALOGS + NS_DECL_NSICLIENTAUTHDIALOGS + NS_DECL_NSITOKENDIALOGS + NS_DECL_NSIGENERATINGKEYPAIRINFODIALOGS + nsNSSDialogs(); + + nsresult Init(); + +protected: + virtual ~nsNSSDialogs(); + nsCOMPtr mPIPStringBundle; +}; + +#endif // nsNSSDialogs_h diff --git a/security/manager/pki/nsPKIModule.cpp b/security/manager/pki/nsPKIModule.cpp new file mode 100644 index 000000000..fc4c5689c --- /dev/null +++ b/security/manager/pki/nsPKIModule.cpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/ModuleUtils.h" +#include "nsASN1Tree.h" +#include "nsNSSDialogs.h" + +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNSSDialogs, Init) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsNSSASN1Tree) + +NS_DEFINE_NAMED_CID(NS_NSSDIALOGS_CID); +NS_DEFINE_NAMED_CID(NS_NSSASN1OUTINER_CID); + + +static const mozilla::Module::CIDEntry kPKICIDs[] = { + { &kNS_NSSDIALOGS_CID, false, nullptr, nsNSSDialogsConstructor }, + { &kNS_NSSASN1OUTINER_CID, false, nullptr, nsNSSASN1TreeConstructor }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kPKIContracts[] = { + { NS_TOKENPASSWORDSDIALOG_CONTRACTID, &kNS_NSSDIALOGS_CID }, + { NS_CERTIFICATEDIALOGS_CONTRACTID, &kNS_NSSDIALOGS_CID }, + { NS_CLIENTAUTHDIALOGS_CONTRACTID, &kNS_NSSDIALOGS_CID }, + { NS_TOKENDIALOGS_CONTRACTID, &kNS_NSSDIALOGS_CID }, + { NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID, &kNS_NSSDIALOGS_CID }, + { NS_ASN1TREE_CONTRACTID, &kNS_NSSASN1OUTINER_CID }, + { nullptr } +}; + +static const mozilla::Module kPKIModule = { + mozilla::Module::kVersion, + kPKICIDs, + kPKIContracts +}; + +NSMODULE_DEFN(PKI) = &kPKIModule; diff --git a/security/manager/pki/resources/content/CAOverlay.xul b/security/manager/pki/resources/content/CAOverlay.xul new file mode 100644 index 000000000..ba4f4abf8 --- /dev/null +++ b/security/manager/pki/resources/content/CAOverlay.xul @@ -0,0 +1,55 @@ + + + + + + + + + + + &certmgr.cas; + + + + + + + + + + + + + +