Fix for Bug 78012 r=thayes sr=blizzard

Make the cert viewer more functional.
This commit is contained in:
javi%netscape.com 2001-05-02 05:38:26 +00:00
Родитель f6e293fd22
Коммит d41928522e
29 изменённых файлов: 2958 добавлений и 173 удалений

Просмотреть файл

@ -43,6 +43,7 @@ include $(DEPTH)/config/autoconf.mk
XPIDLSRCS = \
nsIPKIParamBlock.idl \
nsIASN1Outliner.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -50,6 +50,7 @@ XPIDL_INCLUDES=-I$(DEPTH)\dist\idl
XPIDLSRCS= \
.\nsIPKIParamBlock.idl \
.\nsIASN1Outliner.idl \
$(NULL)

Просмотреть файл

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Ian McGreer <mcgreer@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsISupports.idl"
#include "nsIOutlinerView.idl"
#include "nsIX509Cert.idl"
[scriptable, uuid(c727b2f2-1dd1-11b2-95df-f63c15b4cd35)]
interface nsIASN1Outliner : nsIOutlinerView {
void loadASN1Structure(in nsIASN1Object asn1Object);
wstring getDisplayData(in unsigned long index);
};
%{C++
#define NS_ASN1OUTLINER_CONTRACTID "@mozilla.org/security/nsASN1Outliner;1"
%}

Просмотреть файл

@ -0,0 +1,54 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Ian McGreer <mcgreer@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsISupports.idl"
#include "nsIOutlinerView.idl"
#include "nsIX509Cert.idl"
[scriptable, uuid(c727b2f2-1dd1-11b2-95df-f63c15b4cd35)]
interface nsIASN1Outliner : nsIOutlinerView {
void loadASN1Structure(in nsIASN1Object asn1Object);
wstring getDisplayData(in unsigned long index);
};
%{C++
#define NS_ASN1OUTLINER_CONTRACTID "@mozilla.org/security/nsASN1Outliner;1"
%}

Просмотреть файл

@ -38,7 +38,6 @@
[scriptable, uuid(b6fe3d78-1dd1-11b2-9058-ced9016984c8)]
interface nsIPKIParamBlock : nsISupports {
void setNumberISupports(in PRInt32 numISupports);
void setISupportAtIndex(in PRInt32 index, in nsISupports object);
nsISupports getISupportAtIndex(in PRInt32 index);
};

Просмотреть файл

@ -23,9 +23,7 @@
- Javier Delgadillo <javi@netscape.com>
-->
<?xml-stylesheet href="chrome://messenger/skin/messenger.css" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://pippki/locale/certManager.dtd">
<!DOCTYPE overlay SYSTEM "chrome://pippki/locale/certManager.dtd">
<overlay id="certDumpOverlay"
xmlns:html="http://www.w3.org/1999/xhtml"
@ -33,16 +31,27 @@
xmlns:cert="http://netscape.com/rdf-cert#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<box id="certPrettyPrint" orient="vertical">
<box orient="vertical" flex="1">
<box flex="0" height="100">
<tree id="treesetDump" debug="false" width="500" flex="1">
<treecolgroup flex="1">
<treecol flex="1"/>
</treecolgroup>
<treechildren id="chainDump" flex="1" />
</tree>
<box orient="vertical" flex="1">
<box flex="0" height="100">
<tree id="treesetDump" debug="false" width="500" flex="1">
<treecolgroup flex="1">
<treecol flex="1"/>
</treecolgroup>
<treechildren id="chainDump" flex="1" />
</tree>
</box>
</box>
<box id="prettyPrintBox" height="200" flex="1" orient="vertical" >
<outliner id="prettyDumpOutliner" flex="1">
<outlinercol flex ="1" id="certDataCol" label="&certmgr.details.label;"
primary="true" />
<splitter />
<outlinerbody flex="1" onselect="displaySelected();" />
</outliner>
</box>
<separator class="thin" />
<box id="selectValue" height="100" flex="1" orient="vertical">
<tree id="certDumpVal" debug="tr2e"/>
</box>
<box id="prettyPrintTree" orient="vertical" />
</box>
</box>
</overlay>

Просмотреть файл

@ -25,10 +25,11 @@
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://pippki/locale/certManager.dtd">
<?xul-overlay href="viewCertDetails.xul"?>
<?xul-overlay href="certDump.xul"?>
<!DOCTYPE window SYSTEM "chrome://pippki/locale/certManager.dtd">
<window
id="certDetails"

Просмотреть файл

@ -27,37 +27,36 @@ const nsIX509CertDB = Components.interfaces.nsIX509CertDB;
const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock;
const nsIASN1Object = Components.interfaces.nsIASN1Object;
const nsIASN1Sequence = Components.interfaces.nsIASN1Sequence;
const nsIASN1PrintableItem = Components.interfaces.nsIASN1PrintableItem;
const nsIASN1Outliner = Components.interfaces.nsIASN1Outliner;
const nsASN1Outliner = "@mozilla.org/security/nsASN1Outliner;1"
var bundle;
function AddCertChain(node, chain, idPrefix)
{
var idfier = idPrefix+"chain_";
var child = [document.getElementById(node)];
var item = document.createElement("treeitem");
item.setAttribute("id", idfier + "0");
item.setAttribute("container", "true");
item.setAttribute("open", "true");
var items = [item];
var rows = [document.createElement("treerow")];
var cell = document.createElement("treecell");
cell.setAttribute("class", "treecell-indent");
cell.setAttribute("label", chain[0]);
var cells = [cell];
for (var i=1; i<chain.length; i++) {
child[i] = items[i-1];
item = document.createElement("treeitem");
item.setAttribute("id", idfier + i);
item.setAttribute("container", "true");
items[i] = item;
rows[i] = document.createElement("treerow");
cell = document.createElement("treecell");
cell.setAttribute("class", "treecell-indent");
cell.setAttribute("label", chain[i]);
cells[i] = cell;
}
for (i=chain.length-1; i>=0; i--) {
rows[i].appendChild(cells[i]);
items[i].appendChild(rows[i]);
child[i].appendChild(items[i]);
var child = document.getElementById(node);
var numCerts = chain.Count();
var currCert;
var displayVal;
var addTwistie;
for (var i=numCerts-1; i>=0; i--) {
currCert = chain.GetElementAt(i);
currCert = currCert.QueryInterface(nsIX509Cert);
if (currCert.commonName) {
displayVal = currCert.commonName;
} else {
displayVal = currCert.windowTitle;
}
if (0 == i) {
addTwistie = false;
} else {
addTwistie = true;
}
child = addChildrenToTree(child, displayVal, null,addTwistie);
}
}
@ -76,13 +75,14 @@ function setWindowName()
{
// Get the cert from the cert database
var certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
var windowReference=document.getElementById('certDetails');
myName = self.name;
bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
var cert;
certDetails = bundle.GetStringFromName('certDetails');
if (myName != "_blank") {
windowReference.setAttribute("title","Certificate Detail: \""+myName+"\"");
windowReference.setAttribute("title",certDetails+'"'+myName+'"');
// Get the token
// XXX ignore this for now. NSS will find the cert on a token
// by "tokenname:certname", which is what we have.
@ -97,7 +97,7 @@ function setWindowName()
var isupport = pkiParams.getISupportAtIndex(1);
cert = isupport.QueryInterface(nsIX509Cert);
windowReference.setAttribute("title",
"Certificate Detail: \""+cert.windowTitle+'"');
certDetails+'"'+cert.windowTitle+'"');
}
//
@ -105,66 +105,88 @@ function setWindowName()
//
// The chain of trust
var chainEnum = cert.getChain();
chainEnum.first();
var c = 0;
var chain = [];
try {
while (true) {
var node = chainEnum.currentItem();
node = node.QueryInterface(nsIX509Cert);
chain[c++] = node.commonName;
chainEnum.next();
}
} catch (e) {}
AddCertChain("chain", chain.reverse(),"");
var chain = cert.getChain();
AddCertChain("chain", chain,"");
AddCertChain("chainDump", chain,"dump_");
DisplayGeneralDataFromCert(cert);
BuildPrettyPrint(cert);
}
function addTreeItemToTreeChild(treeChild, label)
function addChildrenToTree(parentTree,label,value,addTwistie)
{
var treeChild1 = document.createElement("treechildren");
var treeElement = addTreeItemToTreeChild(treeChild1,label,value,addTwistie);
parentTree.appendChild(treeChild1);
return treeElement;
}
function addTreeItemToTreeChild(treeChild,label,value,addTwistie)
{
var treeElem1 = document.createElement("treeitem");
treeElem1.setAttribute("container","true");
treeElem1.setAttribute("open","true");
treeElem1.setAttribute("class","treecell-indent");
if (addTwistie) {
treeElem1.setAttribute("container","true");
treeElem1.setAttribute("open","true");
}
var treeRow = document.createElement("treerow");
var treeCell = document.createElement("treecell");
treeCell.setAttribute("class", "treecell-indent");
treeCell.setAttribute("label",label);
if (value)
treeCell.setAttribute("display",value);
treeRow.appendChild(treeCell);
treeElem1.appendChild(treeRow);
treeChild.appendChild(treeElem1);
return treeElem1;
}
function addChildrenToTree(parentTree,label)
function removeChildrenInTree(tree)
{
var treeChild1 = document.createElement("treechildren");
var treeElement = addTreeItemToTreeChild(treeChild1, label);
parentTree.appendChild(treeChild1);
return treeElement;
while (tree.firstChild)
tree.removeChild(tree.firstChild);
}
function displaySelected() {
var asn1Outliner = document.getElementById('prettyDumpOutliner').
outlinerBoxObject.view.QueryInterface(nsIASN1Outliner);
var items = asn1Outliner.selection;
if (items.currentIndex != -1) {
var certDumpVal = document.getElementById('certDumpVal');
removeChildrenInTree(certDumpVal);
// Since the tree widget doesn't do the right thing for new lines,
// I'll interpret them here.
var value = asn1Outliner.getDisplayData(items.currentIndex);
var strings = value.split("\n");
var i;
var children = document.createElement("treechildren");
certDumpVal.appendChild(children);
for (i=0;strings[i]!=null;i++) {
addTreeItemToTreeChild(children,strings[i],null,false);
}
}
}
function BuildPrettyPrint(cert)
{
// For now, I'm just gonna build some dummy stuff
// just to get the helper functions I need up and
// running.
var prettyPrintBox = document.getElementById("prettyPrintTree");
var tree = document.createElement("tree");
prettyPrintBox.appendChild(tree);
var treeChildren = addChildrenToTree(tree,"Top Level");
var childOfFirstChild = addChildrenToTree(treeChildren, "Second Level:1");
var levelone2 = addChildrenToTree(treeChildren,"Second Level:2");
var levelthree1 = addChildrenToTree(childOfFirstChild,"Third Level:1");
var certDumpOutliner = Components.classes[nsASN1Outliner].
createInstance(nsIASN1Outliner);
certDumpOutliner.loadASN1Structure(cert.ASN1Structure);
document.getElementById('prettyDumpOutliner').
outlinerBoxObject.view = certDumpOutliner;
}
function addAttributeFromCert(nodeName, value)
{
var node = document.getElementById(nodeName);
if (!value) {
value = bundle.GetStringFromName('notPresent');
}
node.setAttribute('value',value)
}
function DisplayGeneralDataFromCert(cert)
{
// Verification and usage
var bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
var verifystr = "";
var o1 = {};
var o2 = {};
@ -197,37 +219,21 @@ function DisplayGeneralDataFromCert(cert)
}
// Common Name
var cn=document.getElementById('commonname');
cn.setAttribute("value", cert.commonName);
addAttributeFromCert('commonname', cert.commonName);
// Organization
var org=document.getElementById('organization');
org.setAttribute("value", cert.organization);
addAttributeFromCert('organization', cert.organization);
// Organizational Unit
var ou=document.getElementById('orgunit');
ou.setAttribute("value", cert.organizationalUnit);
addAttributeFromCert('orgunit', cert.organizationalUnit);
// Subject Name
var subn=document.getElementById('subjectname');
subn.setAttribute("value", cert.subjectName);
addAttributeFromCert('subjectname',cert.subjectName);
// Issuer Name
var issn=document.getElementById('issuername');
issn.setAttribute("value", cert.issuerName);
addAttributeFromCert('issuername',cert.issuerName);
// Serial Number
var sern=document.getElementById('serialnumber');
sern.setAttribute("value", cert.serialNumber);
addAttributeFromCert('serialnumber',cert.serialNumber);
// RSA Public Modulus
var rsap=document.getElementById('rsapubmodulus');
rsap.setAttribute("value", cert.rsaPubModulus);
addAttributeFromCert('rsapubmodulus',cert.rsaPubModulus);
// SHA1 Fingerprint
var sha1=document.getElementById('sha1fingerprint');
sha1.setAttribute("value", cert.sha1Fingerprint);
addAttributeFromCert('sha1fingerprint',cert.sha1Fingerprint);
// MD5 Fingerprint
var md5=document.getElementById('md5fingerprint');
md5.setAttribute("value", cert.md5Fingerprint);
addAttributeFromCert('md5fingerprint',cert.md5Fingerprint);
}

Просмотреть файл

@ -21,10 +21,7 @@
- Bob Lord <lord@netscape.com>
- Ian McGreer <mcgreer@netscape.com>
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://pippki/locale/certManager.dtd">
<!DOCTYPE overlay SYSTEM "chrome://pippki/locale/certManager.dtd">
<overlay id="certViewerOverlay"
xmlns:html="http://www.w3.org/1999/xhtml"

Просмотреть файл

@ -81,4 +81,5 @@
<!ENTITY certmgr.backup.label "Backup">
<!ENTITY certmgr.backupall.label "Backup All">
<!ENTITY certmgr.restore.label "Restore">
<!ENTITY certmgr.details.label "Certificate Layout">

Просмотреть файл

@ -55,3 +55,7 @@ certNotVerified_Unknown=Could not verify this certificate for unknown reasons.
#Client auth
clientAuthMessage1=Organization: "%S"
clientAuthMessage2=Issued Under: "%S"
#Cert Viewer
certDetails=Certificate Details:
notPresent=<Not Part Of Certificate>

Просмотреть файл

@ -52,6 +52,7 @@ CPPSRCS = \
nsNSSDialogs.cpp \
nsPKIModule.cpp \
nsPKIParamBlock.cpp \
nsASN1Outliner.cpp \
$(NULL)
REQUIRES = nspr security js xpcom string dom pref intl locale windowwatcher appshell necko pipnss

Просмотреть файл

@ -63,6 +63,7 @@ OBJS = \
.\$(OBJDIR)\nsNSSDialogs.obj \
.\$(OBJDIR)\nsPKIModule.obj \
.\$(OBJDIR)\nsPKIParamBlock.obj \
.\$(OBJDIR)\nsASN1Outliner.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>

Просмотреть файл

@ -0,0 +1,488 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsASN1Outliner.h"
#include "nsIComponentManager.h"
#include "nsString.h"
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1Outliner, nsIASN1Outliner,
nsIOutlinerView);
nsNSSASN1Outliner::nsNSSASN1Outliner()
{
NS_INIT_ISUPPORTS();
}
nsNSSASN1Outliner::~nsNSSASN1Outliner()
{
}
/* void loadASN1Structure (in nsIASN1Object asn1Object); */
NS_IMETHODIMP
nsNSSASN1Outliner::LoadASN1Structure(nsIASN1Object *asn1Object)
{
mASN1Object = asn1Object;
return NS_OK;
}
/* wstring getDisplayData (in unsigned long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetDisplayData(PRUint32 index, PRUnichar **_retval)
{
nsCOMPtr<nsIASN1Object> object;
GetASN1ObjectAtIndex(index, mASN1Object, getter_AddRefs(object));
if (object) {
object->GetDisplayValue(_retval);
} else {
*_retval = nsnull;
}
return NS_OK;
}
nsresult
nsNSSASN1Outliner::GetASN1ObjectAtIndex(PRUint32 index,
nsIASN1Object *sourceObject,
nsIASN1Object **retval)
{
if (mASN1Object == nsnull) {
*retval = nsnull;
} else {
if (index == 0) {
*retval = sourceObject;
NS_IF_ADDREF(*retval);
return NS_OK;
}
// the source object better be an nsIASN1Sequence, otherwise,
// the index better be 1. If neither of these is ture, then
// someting bad has happened.
nsCOMPtr<nsIASN1Sequence> sequence = do_QueryInterface(sourceObject);
if (sequence == nsnull) {
//Something really bad has happened. bail out.
*retval = nsnull;
return NS_ERROR_FAILURE;
} else {
PRBool showObjects;
sequence->GetShowObjects(&showObjects);
if (!showObjects) {
*retval = nsnull;
return NS_OK;
}
nsCOMPtr<nsISupportsArray>asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 numObjects;
asn1Objects->Count(&numObjects);
PRUint32 i;
nsCOMPtr<nsISupports>isupports;
nsCOMPtr<nsIASN1Object>currObject;
PRUint32 numObjectsCounted = 0;
PRUint32 numObjToDisplay;
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
numObjToDisplay = CountNumberOfVisibleRows(currObject);
if ((numObjectsCounted+numObjToDisplay) >= index) {
return GetASN1ObjectAtIndex(index-numObjectsCounted-1,
currObject, retval);
}
numObjectsCounted += numObjToDisplay;
}
}
}
// We should never get here.
return NS_ERROR_FAILURE;
}
PRUint32
nsNSSASN1Outliner::CountNumberOfVisibleRows(nsIASN1Object *asn1Object)
{
nsCOMPtr<nsIASN1Sequence> sequence;
PRUint32 count = 1;
sequence = do_QueryInterface(asn1Object);
if (sequence) {
PRBool showObjects;
sequence->GetShowObjects(&showObjects);
if (showObjects) {
nsCOMPtr<nsISupportsArray> asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 numObjects;
asn1Objects->Count(&numObjects);
PRUint32 i;
nsCOMPtr<nsISupports> isupports;
nsCOMPtr<nsIASN1Object> currObject;
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
count += CountNumberOfVisibleRows(currObject);
}
}
}
return count;
}
/* readonly attribute long rowCount; */
NS_IMETHODIMP
nsNSSASN1Outliner::GetRowCount(PRInt32 *aRowCount)
{
if (mASN1Object) {
*aRowCount = CountNumberOfVisibleRows(mASN1Object);
} else {
*aRowCount = 0;
}
return NS_OK;
}
/* attribute nsIOutlinerSelection selection; */
NS_IMETHODIMP
nsNSSASN1Outliner::GetSelection(nsIOutlinerSelection * *aSelection)
{
*aSelection = mSelection;
NS_IF_ADDREF(*aSelection);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Outliner::SetSelection(nsIOutlinerSelection * aSelection)
{
mSelection = aSelection;
return NS_OK;
}
/* void getRowProperties (in long index, in nsISupportsArray properties); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetRowProperties(PRInt32 index, nsISupportsArray *properties)
{
return NS_OK;
}
/* void getCellProperties (in long row, in wstring colID,
in nsISupportsArray properties); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetCellProperties(PRInt32 row, const PRUnichar *colID,
nsISupportsArray *properties)
{
return NS_OK;
}
/* void getColumnProperties (in wstring colID, in nsIDOMElement colElt,
in nsISupportsArray properties); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetColumnProperties(const PRUnichar *colID,
nsIDOMElement *colElt,
nsISupportsArray *properties)
{
return NS_OK;
}
/* boolean isContainer (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsContainer(PRInt32 index, PRBool *_retval)
{
nsCOMPtr<nsIASN1Object> object;
nsCOMPtr<nsIASN1Sequence> sequence;
nsresult rv = GetASN1ObjectAtIndex(index, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
sequence = do_QueryInterface(object);
if (sequence != nsnull) {
sequence->GetProcessObjects(_retval);
} else {
*_retval = PR_FALSE;
}
return NS_OK;
}
/* boolean isContainerOpen (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsContainerOpen(PRInt32 index, PRBool *_retval)
{
nsCOMPtr<nsIASN1Object> object;
nsCOMPtr<nsIASN1Sequence> sequence;
nsresult rv = GetASN1ObjectAtIndex(index, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
sequence = do_QueryInterface(object);
if (sequence == nsnull) {
*_retval = PR_FALSE;
} else {
sequence->GetShowObjects(_retval);
}
return NS_OK;
}
/* boolean isContainerEmpty (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsContainerEmpty(PRInt32 index, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
PRInt32
nsNSSASN1Outliner::GetParentOfObjectAtIndex(PRUint32 index,
nsIASN1Object *sourceObject)
{
if (index == 0) {
return -1;
} else {
PRUint32 numVisibleRows = CountNumberOfVisibleRows(sourceObject);
if (numVisibleRows > index) {
nsCOMPtr<nsIASN1Sequence>sequence(do_QueryInterface(sourceObject));
if (sequence == nsnull)
return -2;
nsCOMPtr<nsISupportsArray>asn1Objects;
nsCOMPtr<nsISupports>isupports;
nsCOMPtr<nsIASN1Object>currObject;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 indexCnt = 0;
PRUint32 i,numObjects;
asn1Objects->Count(&numObjects);
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
numVisibleRows = CountNumberOfVisibleRows(currObject);
if (numVisibleRows+indexCnt > index) {
//We're dealing with a sequence with visible elements
//that has the desired element.
PRInt32 subIndex = GetParentOfObjectAtIndex(index-indexCnt+1,
currObject);
if (subIndex == -1) {
return indexCnt+1;
} else if (subIndex == -2) {
return -2;
} else {
// This is a case where a subIndex was returned.
return indexCnt+1+subIndex;
}
}
indexCnt+=numVisibleRows;
if (indexCnt == index) {
// The passed in source object is the parent.
return -1;
}
}
}// the else case is an error, just let it fall through.
}
return -2;
}
/* long getParentIndex (in long rowIndex); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetParentIndex(PRInt32 rowIndex, PRInt32 *_retval)
{
*_retval = GetParentOfObjectAtIndex(rowIndex, mASN1Object);
return NS_OK;
}
/* boolean hasNextSibling (in long rowIndex, in long afterIndex); */
NS_IMETHODIMP
nsNSSASN1Outliner::HasNextSibling(PRInt32 rowIndex, PRInt32 afterIndex,
PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
PRInt32
nsNSSASN1Outliner::GetLevelsTilIndex(PRUint32 index,
nsIASN1Object *sourceObject)
{
if (index == 0) {
return 0;
} else {
nsCOMPtr<nsIASN1Sequence> sequence(do_QueryInterface(sourceObject));
nsCOMPtr<nsISupportsArray>asn1Objects;
if (sequence == nsnull)
return -1;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 numObjects,i,indexCnt=0,numVisibleRows;
asn1Objects->Count(&numObjects);
nsCOMPtr<nsISupports> isupports;
nsCOMPtr<nsIASN1Object> currObject;
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
numVisibleRows = CountNumberOfVisibleRows(currObject);
if ((numVisibleRows+indexCnt)>=index) {
PRInt32 numSubLayers;
numSubLayers = GetLevelsTilIndex(index-indexCnt-1,
currObject);
if (numSubLayers == -1) {
// This return value means the parent is not a child
// object, we're not adding any more layers to the nested
// levels.
return -1;
} else {
return 1+numSubLayers;
}
}
indexCnt += numVisibleRows;
}
}
return -2;
}
/* long getLevel (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetLevel(PRInt32 index, PRInt32 *_retval)
{
*_retval = GetLevelsTilIndex(index, mASN1Object);
return NS_OK;
}
/* wstring getCellText (in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetCellText(PRInt32 row, const PRUnichar *colID,
PRUnichar **_retval)
{
nsCOMPtr<nsIASN1Object> object;
*_retval = nsnull;
char *col = NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(colID).get());
nsresult rv = NS_OK;
if (strcmp(col, "certDataCol") == 0) {
rv = GetASN1ObjectAtIndex(row, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
//There's only one column for ASN1 dump.
rv = object->GetDisplayName(_retval);
}
return rv;
}
/* void setOutliner (in nsIOutlinerBoxObject outliner); */
NS_IMETHODIMP
nsNSSASN1Outliner::SetOutliner(nsIOutlinerBoxObject *outliner)
{
mOutliner = outliner;
return NS_OK;
}
/* void toggleOpenState (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::ToggleOpenState(PRInt32 index)
{
nsCOMPtr<nsIASN1Object> object;
nsresult rv = GetASN1ObjectAtIndex(index, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIASN1Sequence> sequence(do_QueryInterface(object));
if (sequence == nsnull)
return NS_ERROR_FAILURE;
PRBool showObjects;
sequence->GetShowObjects(&showObjects);
PRInt32 rowCountChange;
if (showObjects) {
rowCountChange = 1-CountNumberOfVisibleRows(object);
sequence->SetShowObjects(PR_FALSE);
} else {
sequence->SetShowObjects(PR_TRUE);
rowCountChange = CountNumberOfVisibleRows(object)-1;
}
if (mOutliner)
mOutliner->RowCountChanged(index, rowCountChange);
return NS_OK;
}
/* void cycleHeader (in wstring colID, in nsIDOMElement elt); */
NS_IMETHODIMP
nsNSSASN1Outliner::CycleHeader(const PRUnichar *colID, nsIDOMElement *elt)
{
return NS_OK;
}
/* void selectionChanged (); */
NS_IMETHODIMP
nsNSSASN1Outliner::SelectionChanged()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void cycleCell (in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::CycleCell(PRInt32 row, const PRUnichar *colID)
{
return NS_OK;
}
/* boolean isEditable (in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsEditable(PRInt32 row, const PRUnichar *colID,
PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
/* void setCellText (in long row, in wstring colID, in wstring value); */
NS_IMETHODIMP
nsNSSASN1Outliner::SetCellText(PRInt32 row, const PRUnichar *colID,
const PRUnichar *value)
{
return NS_OK;
}
/* void performAction (in wstring action); */
NS_IMETHODIMP
nsNSSASN1Outliner::PerformAction(const PRUnichar *action)
{
return NS_OK;
}
/* void performActionOnRow (in wstring action, in long row); */
NS_IMETHODIMP
nsNSSASN1Outliner::PerformActionOnRow(const PRUnichar *action, PRInt32 row)
{
return NS_OK;
}
/* void performActionOnCell (in wstring action, in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::PerformActionOnCell(const PRUnichar *action, PRInt32 row,
const PRUnichar *colID)
{
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,73 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef _NSSASNOUTLINER_H_
#define _NSSASNOUTLINER_H_
#include "nscore.h"
#include "nsIX509Cert.h"
#include "nsIASN1Outliner.h"
#include "nsIOutlinerView.h"
#include "nsIOutlinerBoxObject.h"
#include "nsIOutlinerSelection.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 nsNSSASN1Outliner : public nsIASN1Outliner
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIASN1OUTLINER
NS_DECL_NSIOUTLINERVIEW
nsNSSASN1Outliner();
virtual ~nsNSSASN1Outliner();
protected:
PRUint32 CountNumberOfVisibleRows(nsIASN1Object *asn1Object);
nsresult GetASN1ObjectAtIndex(PRUint32 index, nsIASN1Object *sourceObject,
nsIASN1Object **retval);
PRInt32 GetParentOfObjectAtIndex(PRUint32 index, nsIASN1Object *sourceObject);
PRInt32 GetLevelsTilIndex(PRUint32 index, nsIASN1Object *sourceObject);
nsCOMPtr<nsIASN1Object> mASN1Object;
nsCOMPtr<nsIOutlinerSelection> mSelection;
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
};
#endif //_NSSASNOUTLINER_H_

Просмотреть файл

@ -0,0 +1,488 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsASN1Outliner.h"
#include "nsIComponentManager.h"
#include "nsString.h"
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1Outliner, nsIASN1Outliner,
nsIOutlinerView);
nsNSSASN1Outliner::nsNSSASN1Outliner()
{
NS_INIT_ISUPPORTS();
}
nsNSSASN1Outliner::~nsNSSASN1Outliner()
{
}
/* void loadASN1Structure (in nsIASN1Object asn1Object); */
NS_IMETHODIMP
nsNSSASN1Outliner::LoadASN1Structure(nsIASN1Object *asn1Object)
{
mASN1Object = asn1Object;
return NS_OK;
}
/* wstring getDisplayData (in unsigned long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetDisplayData(PRUint32 index, PRUnichar **_retval)
{
nsCOMPtr<nsIASN1Object> object;
GetASN1ObjectAtIndex(index, mASN1Object, getter_AddRefs(object));
if (object) {
object->GetDisplayValue(_retval);
} else {
*_retval = nsnull;
}
return NS_OK;
}
nsresult
nsNSSASN1Outliner::GetASN1ObjectAtIndex(PRUint32 index,
nsIASN1Object *sourceObject,
nsIASN1Object **retval)
{
if (mASN1Object == nsnull) {
*retval = nsnull;
} else {
if (index == 0) {
*retval = sourceObject;
NS_IF_ADDREF(*retval);
return NS_OK;
}
// the source object better be an nsIASN1Sequence, otherwise,
// the index better be 1. If neither of these is ture, then
// someting bad has happened.
nsCOMPtr<nsIASN1Sequence> sequence = do_QueryInterface(sourceObject);
if (sequence == nsnull) {
//Something really bad has happened. bail out.
*retval = nsnull;
return NS_ERROR_FAILURE;
} else {
PRBool showObjects;
sequence->GetShowObjects(&showObjects);
if (!showObjects) {
*retval = nsnull;
return NS_OK;
}
nsCOMPtr<nsISupportsArray>asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 numObjects;
asn1Objects->Count(&numObjects);
PRUint32 i;
nsCOMPtr<nsISupports>isupports;
nsCOMPtr<nsIASN1Object>currObject;
PRUint32 numObjectsCounted = 0;
PRUint32 numObjToDisplay;
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
numObjToDisplay = CountNumberOfVisibleRows(currObject);
if ((numObjectsCounted+numObjToDisplay) >= index) {
return GetASN1ObjectAtIndex(index-numObjectsCounted-1,
currObject, retval);
}
numObjectsCounted += numObjToDisplay;
}
}
}
// We should never get here.
return NS_ERROR_FAILURE;
}
PRUint32
nsNSSASN1Outliner::CountNumberOfVisibleRows(nsIASN1Object *asn1Object)
{
nsCOMPtr<nsIASN1Sequence> sequence;
PRUint32 count = 1;
sequence = do_QueryInterface(asn1Object);
if (sequence) {
PRBool showObjects;
sequence->GetShowObjects(&showObjects);
if (showObjects) {
nsCOMPtr<nsISupportsArray> asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 numObjects;
asn1Objects->Count(&numObjects);
PRUint32 i;
nsCOMPtr<nsISupports> isupports;
nsCOMPtr<nsIASN1Object> currObject;
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
count += CountNumberOfVisibleRows(currObject);
}
}
}
return count;
}
/* readonly attribute long rowCount; */
NS_IMETHODIMP
nsNSSASN1Outliner::GetRowCount(PRInt32 *aRowCount)
{
if (mASN1Object) {
*aRowCount = CountNumberOfVisibleRows(mASN1Object);
} else {
*aRowCount = 0;
}
return NS_OK;
}
/* attribute nsIOutlinerSelection selection; */
NS_IMETHODIMP
nsNSSASN1Outliner::GetSelection(nsIOutlinerSelection * *aSelection)
{
*aSelection = mSelection;
NS_IF_ADDREF(*aSelection);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Outliner::SetSelection(nsIOutlinerSelection * aSelection)
{
mSelection = aSelection;
return NS_OK;
}
/* void getRowProperties (in long index, in nsISupportsArray properties); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetRowProperties(PRInt32 index, nsISupportsArray *properties)
{
return NS_OK;
}
/* void getCellProperties (in long row, in wstring colID,
in nsISupportsArray properties); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetCellProperties(PRInt32 row, const PRUnichar *colID,
nsISupportsArray *properties)
{
return NS_OK;
}
/* void getColumnProperties (in wstring colID, in nsIDOMElement colElt,
in nsISupportsArray properties); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetColumnProperties(const PRUnichar *colID,
nsIDOMElement *colElt,
nsISupportsArray *properties)
{
return NS_OK;
}
/* boolean isContainer (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsContainer(PRInt32 index, PRBool *_retval)
{
nsCOMPtr<nsIASN1Object> object;
nsCOMPtr<nsIASN1Sequence> sequence;
nsresult rv = GetASN1ObjectAtIndex(index, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
sequence = do_QueryInterface(object);
if (sequence != nsnull) {
sequence->GetProcessObjects(_retval);
} else {
*_retval = PR_FALSE;
}
return NS_OK;
}
/* boolean isContainerOpen (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsContainerOpen(PRInt32 index, PRBool *_retval)
{
nsCOMPtr<nsIASN1Object> object;
nsCOMPtr<nsIASN1Sequence> sequence;
nsresult rv = GetASN1ObjectAtIndex(index, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
sequence = do_QueryInterface(object);
if (sequence == nsnull) {
*_retval = PR_FALSE;
} else {
sequence->GetShowObjects(_retval);
}
return NS_OK;
}
/* boolean isContainerEmpty (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsContainerEmpty(PRInt32 index, PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
PRInt32
nsNSSASN1Outliner::GetParentOfObjectAtIndex(PRUint32 index,
nsIASN1Object *sourceObject)
{
if (index == 0) {
return -1;
} else {
PRUint32 numVisibleRows = CountNumberOfVisibleRows(sourceObject);
if (numVisibleRows > index) {
nsCOMPtr<nsIASN1Sequence>sequence(do_QueryInterface(sourceObject));
if (sequence == nsnull)
return -2;
nsCOMPtr<nsISupportsArray>asn1Objects;
nsCOMPtr<nsISupports>isupports;
nsCOMPtr<nsIASN1Object>currObject;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 indexCnt = 0;
PRUint32 i,numObjects;
asn1Objects->Count(&numObjects);
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
numVisibleRows = CountNumberOfVisibleRows(currObject);
if (numVisibleRows+indexCnt > index) {
//We're dealing with a sequence with visible elements
//that has the desired element.
PRInt32 subIndex = GetParentOfObjectAtIndex(index-indexCnt+1,
currObject);
if (subIndex == -1) {
return indexCnt+1;
} else if (subIndex == -2) {
return -2;
} else {
// This is a case where a subIndex was returned.
return indexCnt+1+subIndex;
}
}
indexCnt+=numVisibleRows;
if (indexCnt == index) {
// The passed in source object is the parent.
return -1;
}
}
}// the else case is an error, just let it fall through.
}
return -2;
}
/* long getParentIndex (in long rowIndex); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetParentIndex(PRInt32 rowIndex, PRInt32 *_retval)
{
*_retval = GetParentOfObjectAtIndex(rowIndex, mASN1Object);
return NS_OK;
}
/* boolean hasNextSibling (in long rowIndex, in long afterIndex); */
NS_IMETHODIMP
nsNSSASN1Outliner::HasNextSibling(PRInt32 rowIndex, PRInt32 afterIndex,
PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
PRInt32
nsNSSASN1Outliner::GetLevelsTilIndex(PRUint32 index,
nsIASN1Object *sourceObject)
{
if (index == 0) {
return 0;
} else {
nsCOMPtr<nsIASN1Sequence> sequence(do_QueryInterface(sourceObject));
nsCOMPtr<nsISupportsArray>asn1Objects;
if (sequence == nsnull)
return -1;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
PRUint32 numObjects,i,indexCnt=0,numVisibleRows;
asn1Objects->Count(&numObjects);
nsCOMPtr<nsISupports> isupports;
nsCOMPtr<nsIASN1Object> currObject;
for (i=0; i<numObjects; i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
numVisibleRows = CountNumberOfVisibleRows(currObject);
if ((numVisibleRows+indexCnt)>=index) {
PRInt32 numSubLayers;
numSubLayers = GetLevelsTilIndex(index-indexCnt-1,
currObject);
if (numSubLayers == -1) {
// This return value means the parent is not a child
// object, we're not adding any more layers to the nested
// levels.
return -1;
} else {
return 1+numSubLayers;
}
}
indexCnt += numVisibleRows;
}
}
return -2;
}
/* long getLevel (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetLevel(PRInt32 index, PRInt32 *_retval)
{
*_retval = GetLevelsTilIndex(index, mASN1Object);
return NS_OK;
}
/* wstring getCellText (in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::GetCellText(PRInt32 row, const PRUnichar *colID,
PRUnichar **_retval)
{
nsCOMPtr<nsIASN1Object> object;
*_retval = nsnull;
char *col = NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(colID).get());
nsresult rv = NS_OK;
if (strcmp(col, "certDataCol") == 0) {
rv = GetASN1ObjectAtIndex(row, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
//There's only one column for ASN1 dump.
rv = object->GetDisplayName(_retval);
}
return rv;
}
/* void setOutliner (in nsIOutlinerBoxObject outliner); */
NS_IMETHODIMP
nsNSSASN1Outliner::SetOutliner(nsIOutlinerBoxObject *outliner)
{
mOutliner = outliner;
return NS_OK;
}
/* void toggleOpenState (in long index); */
NS_IMETHODIMP
nsNSSASN1Outliner::ToggleOpenState(PRInt32 index)
{
nsCOMPtr<nsIASN1Object> object;
nsresult rv = GetASN1ObjectAtIndex(index, mASN1Object,
getter_AddRefs(object));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIASN1Sequence> sequence(do_QueryInterface(object));
if (sequence == nsnull)
return NS_ERROR_FAILURE;
PRBool showObjects;
sequence->GetShowObjects(&showObjects);
PRInt32 rowCountChange;
if (showObjects) {
rowCountChange = 1-CountNumberOfVisibleRows(object);
sequence->SetShowObjects(PR_FALSE);
} else {
sequence->SetShowObjects(PR_TRUE);
rowCountChange = CountNumberOfVisibleRows(object)-1;
}
if (mOutliner)
mOutliner->RowCountChanged(index, rowCountChange);
return NS_OK;
}
/* void cycleHeader (in wstring colID, in nsIDOMElement elt); */
NS_IMETHODIMP
nsNSSASN1Outliner::CycleHeader(const PRUnichar *colID, nsIDOMElement *elt)
{
return NS_OK;
}
/* void selectionChanged (); */
NS_IMETHODIMP
nsNSSASN1Outliner::SelectionChanged()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void cycleCell (in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::CycleCell(PRInt32 row, const PRUnichar *colID)
{
return NS_OK;
}
/* boolean isEditable (in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::IsEditable(PRInt32 row, const PRUnichar *colID,
PRBool *_retval)
{
*_retval = PR_FALSE;
return NS_OK;
}
/* void setCellText (in long row, in wstring colID, in wstring value); */
NS_IMETHODIMP
nsNSSASN1Outliner::SetCellText(PRInt32 row, const PRUnichar *colID,
const PRUnichar *value)
{
return NS_OK;
}
/* void performAction (in wstring action); */
NS_IMETHODIMP
nsNSSASN1Outliner::PerformAction(const PRUnichar *action)
{
return NS_OK;
}
/* void performActionOnRow (in wstring action, in long row); */
NS_IMETHODIMP
nsNSSASN1Outliner::PerformActionOnRow(const PRUnichar *action, PRInt32 row)
{
return NS_OK;
}
/* void performActionOnCell (in wstring action, in long row, in wstring colID); */
NS_IMETHODIMP
nsNSSASN1Outliner::PerformActionOnCell(const PRUnichar *action, PRInt32 row,
const PRUnichar *colID)
{
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,73 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef _NSSASNOUTLINER_H_
#define _NSSASNOUTLINER_H_
#include "nscore.h"
#include "nsIX509Cert.h"
#include "nsIASN1Outliner.h"
#include "nsIOutlinerView.h"
#include "nsIOutlinerBoxObject.h"
#include "nsIOutlinerSelection.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 nsNSSASN1Outliner : public nsIASN1Outliner
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIASN1OUTLINER
NS_DECL_NSIOUTLINERVIEW
nsNSSASN1Outliner();
virtual ~nsNSSASN1Outliner();
protected:
PRUint32 CountNumberOfVisibleRows(nsIASN1Object *asn1Object);
nsresult GetASN1ObjectAtIndex(PRUint32 index, nsIASN1Object *sourceObject,
nsIASN1Object **retval);
PRInt32 GetParentOfObjectAtIndex(PRUint32 index, nsIASN1Object *sourceObject);
PRInt32 GetLevelsTilIndex(PRUint32 index, nsIASN1Object *sourceObject);
nsCOMPtr<nsIASN1Object> mASN1Object;
nsCOMPtr<nsIOutlinerSelection> mSelection;
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
};
#endif //_NSSASNOUTLINER_H_

Просмотреть файл

@ -116,7 +116,8 @@ NS_IMPL_THREADSAFE_ISUPPORTS6(nsNSSDialogs, nsINSSDialogs,
nsISecurityWarningDialogs,
nsIBadCertListener,
nsICertificateDialogs,
nsIClientAuthDialogs)
nsIClientAuthDialogs);
nsresult
nsNSSDialogs::Init()
{

Просмотреть файл

@ -26,9 +26,11 @@
#include "nsNSSDialogs.h"
#include "nsPKIParamBlock.h"
#include "nsASN1Outliner.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNSSDialogs, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPKIParamBlock, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNSSASN1Outliner)
static nsModuleComponentInfo components[] =
{
@ -39,6 +41,13 @@ static nsModuleComponentInfo components[] =
nsNSSDialogsConstructor
},
{
"ASN1 Outliner",
NS_NSSASN1OUTINER_CID,
NS_ASN1OUTLINER_CONTRACTID,
nsNSSASN1OutlinerConstructor
},
{ "PKI Parm Block",
NS_PKIPARAMBLOCK_CID,
NS_PKIPARAMBLOCK_CONTRACTID,

Просмотреть файл

@ -40,7 +40,7 @@
NS_IMPL_THREADSAFE_ISUPPORTS2(nsPKIParamBlock, nsIPKIParamBlock,
nsIDialogParamBlock)
nsPKIParamBlock::nsPKIParamBlock() : mSupports(nsnull),mNumISupports(0)
nsPKIParamBlock::nsPKIParamBlock()
{
NS_INIT_REFCNT();
}
@ -54,17 +54,6 @@ nsPKIParamBlock::Init()
nsPKIParamBlock::~nsPKIParamBlock()
{
if (mNumISupports > 0) {
NS_ASSERTION (mSupports, "mNumISupports and mSupports out of sync");
if (mSupports) {
PRIntn i;
for (i=0; i<mNumISupports; i++) {
NS_IF_RELEASE(mSupports[i]);
}
delete [] mSupports;
}
}
}
@ -99,44 +88,17 @@ nsPKIParamBlock::SetString(PRInt32 inIndex, const PRUnichar *inString)
return mDialogParamBlock->SetString(inIndex, inString);
}
/* void setNumberISupports (in PRInt32 numISupports); */
NS_IMETHODIMP
nsPKIParamBlock::SetNumberISupports(PRInt32 numISupports)
{
if (mSupports) {
return NS_ERROR_ALREADY_INITIALIZED;
}
NS_ASSERTION(numISupports > 0, "passing in invalid number");
mNumISupports = numISupports;
mSupports = new nsISupports*[mNumISupports];
if (mSupports == nsnull) {
mNumISupports = 0;
return NS_ERROR_OUT_OF_MEMORY;
}
memset(mSupports, 0, sizeof(nsISupports*)*mNumISupports);
return NS_OK;
}
/* void setISupportAtIndex (in PRInt32 index, in nsISupports object); */
NS_IMETHODIMP
nsPKIParamBlock::SetISupportAtIndex(PRInt32 index, nsISupports *object)
{
if (!mSupports) {
mNumISupports = kNumISupports;
mSupports = new nsISupports*[mNumISupports];
mSupports = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
if (mSupports == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
memset(mSupports, 0, sizeof(nsISupports*)*mNumISupports);
}
nsresult rv = InBounds(index, mNumISupports);
if (rv != NS_OK)
return rv;
mSupports[index] = object;
NS_IF_ADDREF(mSupports[index]);
return NS_OK;
return mSupports->InsertElementAt(object, index-1);
}
/* nsISupports getISupportAtIndex (in PRInt32 index); */
@ -144,12 +106,8 @@ NS_IMETHODIMP
nsPKIParamBlock::GetISupportAtIndex(PRInt32 index, nsISupports **_retval)
{
NS_ENSURE_ARG(_retval);
nsresult rv = InBounds(index, mNumISupports);
if (rv != NS_OK)
return rv;
*_retval = mSupports[index];
NS_IF_ADDREF(*_retval);
*_retval = mSupports->ElementAt(index-1);
return NS_OK;
}

Просмотреть файл

@ -37,6 +37,7 @@
#include "nsCOMPtr.h"
#include "nsIPKIParamBlock.h"
#include "nsIDialogParamBlock.h"
#include "nsISupportsArray.h"
#define NS_PKIPARAMBLOCK_CID \
{ 0x0bec75a8, 0x1dd2, 0x11b2, \
@ -48,7 +49,6 @@ class nsPKIParamBlock : public nsIPKIParamBlock,
public nsIDialogParamBlock
{
public:
enum { kNumISupports = 4 };
nsPKIParamBlock();
virtual ~nsPKIParamBlock();
@ -58,16 +58,8 @@ public:
NS_DECL_NSIDIALOGPARAMBLOCK
NS_DECL_ISUPPORTS
private:
nsresult InBounds( PRInt32 inIndex, PRInt32 inMax )
{
if ( inIndex >= 0 && inIndex< inMax )
return NS_OK;
else
return NS_ERROR_ILLEGAL_VALUE;
}
nsCOMPtr<nsIDialogParamBlock> mDialogParamBlock;
nsISupports **mSupports;
PRIntn mNumISupports;
nsCOMPtr<nsISupportsArray> mSupports;
};
#endif //_NSPKIPARAMBLOCK_

Просмотреть файл

@ -34,7 +34,7 @@
*/
#include "nsISupports.idl"
#include "nsIEnumerator.idl"
#include "nsISupportsArray.idl"
[scriptable, uuid(e701dfd8-1dd1-11b2-a172-ffa6cc6156ad)]
interface nsIX509CertValidity : nsISupports {
@ -42,6 +42,68 @@ interface nsIX509CertValidity : nsISupports {
readonly attribute PRTime notAfter;
};
//
// Overview of how this ASN1 interface is intended to
// work.
//
// First off, the nsIASN1Sequence is any type in ASN1
// that consists of sub-elements (ie SEQUENCE, SET)
// nsIASN1Printable Items are all the other types that
// can be viewed by themselves without interpreting further.
// Examples would include INTEGER, UTF-8 STRING, OID.
// These are not intended to directly reflect the numberous
// types that exist in ASN1, but merely an interface to ease
// producing a tree display the ASN1 structure of any DER
// object.
//
[scriptable, uuid(ba8bf582-1dd1-11b2-898c-f40246bc9a63)]
interface nsIASN1Object : nsISupports {
const unsigned long ASN1_END_CONTENTS = 0;
const unsigned long ASN1_BOOLEAN = 1;
const unsigned long ASN1_INTEGER = 2;
const unsigned long ASN1_BIT_STRING = 3;
const unsigned long ASN1_OCTET_STRING = 4;
const unsigned long ASN1_NULL = 5;
const unsigned long ASN1_OBJECT_ID = 6;
const unsigned long ASN1_ENUMERATED = 10;
const unsigned long ASN1_UTF8_STRING = 12;
const unsigned long ASN1_SEQUENCE = 16;
const unsigned long ASN1_SET = 17;
const unsigned long ASN1_PRINTABLE_STRING = 19;
const unsigned long ASN1_T61_STRING = 20;
const unsigned long ASN1_IA5_STRING = 22;
const unsigned long ASN1_UTC_TIME = 23;
const unsigned long ASN1_GEN_TIME = 24;
const unsigned long ASN1_VISIBLE_STRING = 26;
const unsigned long ASN1_UNIVERSAL_STRING = 28;
const unsigned long ASN1_BMP_STRING = 30;
const unsigned long ASN1_HIGH_TAG_NUMBER = 31;
const unsigned long ASN1_CONTEXT_SPECIFIC = 32;
const unsigned long ASN1_APPLICATION = 33;
const unsigned long ASN1_PRIVATE = 34;
// This will be either one of the const
// values above.
attribute unsigned long type;
attribute unsigned long tag;
attribute wstring displayName;
attribute wstring displayValue;
};
[scriptable, uuid(b6b957e6-1dd1-11b2-89d7-e30624f50b00)]
interface nsIASN1Sequence : nsIASN1Object {
attribute nsISupportsArray ASN1Objects;
attribute boolean processObjects;
attribute boolean showObjects;
};
[scriptable, uuid(114e1142-1dd2-11b2-ac26-b6db19d9184a)]
interface nsIASN1PrintableItem : nsIASN1Object {
[noscript] void setData(in charPtr data, in unsigned long len);
[noscript] void getData(out charPtr data, out unsigned long len);
};
[scriptable, uuid(f0980f60-ee3d-11d4-998b-00b0d02354a0)]
interface nsIX509Cert : nsISupports {
@ -89,7 +151,7 @@ interface nsIX509Cert : nsISupports {
/*
* accessors for certs
*/
nsIEnumerator getChain();
nsISupportsArray getChain();
void getUsages(out PRUint32 verified,
out PRUint32 count,
@ -105,6 +167,13 @@ interface nsIX509Cert : nsISupports {
*/
void view();
/*
* This is the attribute which describes the ASN1 layout
* of the certificate. This can be used when doing a
* "pretty print" of the certificate's ASN1 structure.
*/
readonly attribute nsIASN1Object ASN1Structure;
[noscript] unsigned long getRawDER(out charPtr result);
};

Просмотреть файл

@ -17,6 +17,9 @@
# Rights Reserved.
#
# Contributor(s):
# Javier Delgadillo <javi@netscape.com>
# Brian Ryner <bryner@netscape.com>
# Terry Hayes <thayes@netscape.com>
#
SignedBy=Signed by %S
@ -43,6 +46,61 @@ VerifyUserImport=User Import Cert
VerifyCAVerifier=CA Verifier
VerifyStatusResponder=Status Responder Certificate
VerifyAnyCA=Any Certificate Authority
#These are the strings set for the ASN1 objects in a certificate.
CertDumpCertificate=Certificate
CertDumpVersion=Version
CertDumpVersion1=Version 1
CertDumpVersion2=Version 2
CertDumpVersion3=Version 3
CertDumpSerialNo=Serial Number
CertDumpOID=Object Identifier
CertDumpMD2WithRSA=PKCS #1 MD2 With RSA Encryption
CertDumpMD5WithRSA=PKCS #1 MD5 With RSA Encryption
CertDumpSHA1WithRSA=PKCS #1 SHA-1 With RSA Encryption
CertDumpDefOID=Object Identifier (%S)
CertDumpNULL=NULL
CertDumpIssuer=Issuer
CertDumpSubject=Subect
CertDumpRDN=Relative Distinguished Name
CertDumpATV=Attribute Type and Value
CertDumpAVACountry=Country Name
CertDumpAVAState=State Or Province Name
CertDumpAVALocality=Locality Name
CertDumpAVAOrg=Organization Name
CertDumpAVAOU=Organizational Unit Name
CertDumpAVACN=Common Name
CertDumpUserID=RFC1274 User ID
CertDumpPK9Email=PKCS #9 Email Address
CertDumpAVADN=Distinguished Name Qualifier
CertDumpAVADC=Domain Component
CertDumpValidity=Validity
CertDumpNotBefore=Not Before
CertDumpNotAfter=Not After
CertDumpSPKI=Subject Public Key Info
CertDumpSPKIAlg=Subject Public Key Algorithm
CertDumpAlgID=Algorithm Identifier
CertDumpParams=Algorithm Parameters
CertDumpRSAEncr=PKCS #1 RSA Encryption
CertDumpIssuerUniqueID=Issuer Unique ID
CertDumpSubjPubKey=Subject's Public Key
CertDumpSubjectUniqueID=Subject Unique ID
CertDumpExtensions=Extensions
CertDumpCertType=Netscape Ceritficate Type
CertDumpKeyUsage=Certifcate Key Usage
CertDumpAuthKeyID=Certificate Authority Key Identifier
CertDumpCertTypeEmail=Email
CertDumpEmailCA=Email Certificate Authority
CertDumpKUSign=Signing
CertDumpKUNonRep=Non-repudiation
CertDumpKUEnc=Key Encipherment
CertDumpKUDEnc=Data Encipherment
CertDumpKUKA=Key Agreement
CertDumpKUCertSign=Certificate Signer
CertDumpKUCRLSigner=CRL Signer
CertDumpCritical=Critical
CertDumpNonCritical=Not Critical
CertDumpSigAlg=Certificate Signature Algorithm
CertDumpCertSig=Certificate Signature Value
VerifySSLClient_p=Client
VerifySSLServer_p=Server
VerifySSLStepUp_p=Step-up

Просмотреть файл

@ -60,6 +60,7 @@ CPPSRCS = \
nsPK11TokenDB.cpp \
nsNSSCertificate.cpp \
nsPKCS12Blob.cpp \
nsNSSASN1Object.cpp \
nsCertOutliner.cpp \
$(NULL)

Просмотреть файл

@ -0,0 +1,474 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#include "nsNSSASN1Object.h"
#include "nsIComponentManager.h"
#include "secasn1.h"
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1Sequence, nsIASN1Sequence,
nsIASN1Object);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNSSASN1PrintableItem, nsIASN1PrintableItem,
nsIASN1Object);
// This function is used to interpret an integer that
// was encoded in a DER buffer. This function is used
// when converting a DER buffer into a nsIASN1Object
// structure. This interprets the buffer in data
// as defined by the DER (Distinguised Encoding Rules) of
// ASN1.
static int
getInteger256(unsigned char *data, unsigned int nb)
{
int val;
switch (nb) {
case 1:
val = data[0];
break;
case 2:
val = (data[0] << 8) | data[1];
break;
case 3:
val = (data[0] << 16) | (data[1] << 8) | data[2];
break;
case 4:
val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
break;
default:
return -1;
}
return val;
}
// This function is used to retrieve the lenght of a DER encoded
// item. It looks to see if this a multibyte length and then
// interprets the buffer accordingly to get the actual length value.
// This funciton is used mostly while parsing the DER headers.
//
// A DER encoded item has the following structure:
//
// <tag><length<data consisting of lenght bytes>
static PRInt32
getDERItemLength(unsigned char *data, unsigned char *end,
unsigned long *bytesUsed, PRBool *indefinite)
{
unsigned char lbyte = *data++;
PRInt32 length = -1;
*indefinite = PR_FALSE;
if (lbyte >= 0x80) {
// Multibyte length
unsigned nb = (unsigned) (lbyte & 0x7f);
if (nb > 4) {
return -1;
}
if (nb > 0) {
if ((data+nb) > end) {
return -1;
}
length = getInteger256(data, nb);
if (length < 0)
return -1;
} else {
*indefinite = PR_TRUE;
length = 0;
}
*bytesUsed = nb+1;
} else {
length = lbyte;
*bytesUsed = 1;
}
return length;
}
static nsresult
buildASN1ObjectFromDER(unsigned char *data,
unsigned char *end,
nsIASN1Sequence *parent)
{
nsresult rv;
nsCOMPtr<nsIASN1Sequence> sequence;
nsCOMPtr<nsIASN1PrintableItem> printableItem;
nsCOMPtr<nsIASN1Object> asn1Obj;
nsCOMPtr<nsISupportsArray> parentObjects;
NS_ENSURE_ARG_POINTER(parent);
if (data >= end)
return NS_OK;
unsigned char code, tagnum;
// A DER item has the form of |tag|len|data
// tag is one byte and describes the type of elment
// we are dealing with.
// len is a DER encoded int telling us how long the data is
// data is a buffer that is len bytes long and has to be
// interpreted according to its type.
unsigned long bytesUsed;
PRBool indefinite;
PRInt32 len;
PRUint32 type;
if (parent == nsnull) {
parent = new nsNSSASN1Sequence();
NS_IF_ADDREF(parent);
}
if (parent == nsnull)
return NS_ERROR_FAILURE;
rv = parent->GetASN1Objects(getter_AddRefs(parentObjects));
if (NS_FAILED(rv) || parentObjects == nsnull)
return NS_ERROR_FAILURE;
while (data < end) {
code = *data;
tagnum = code & SEC_ASN1_TAGNUM_MASK;
/*
* NOTE: This code does not (yet) handle the high-tag-number form!
*/
if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
return NS_ERROR_FAILURE;
}
data++;
len = getDERItemLength(data, end, &bytesUsed, &indefinite);
data += bytesUsed;
if ((len < 0) || ((data+len) > end))
return NS_ERROR_FAILURE;
if (code & SEC_ASN1_CONSTRUCTED) {
if (len > 0 || indefinite) {
sequence = new nsNSSASN1Sequence();
switch (code & SEC_ASN1_CLASS_MASK) {
case SEC_ASN1_UNIVERSAL:
type = tagnum;
break;
case SEC_ASN1_APPLICATION:
type = nsIASN1Object::ASN1_APPLICATION;
break;
case SEC_ASN1_CONTEXT_SPECIFIC:
type = nsIASN1Object::ASN1_CONTEXT_SPECIFIC;
break;
case SEC_ASN1_PRIVATE:
type = nsIASN1Object::ASN1_PRIVATE;
break;
default:
NS_ASSERTION(0,"Bad DER");
return NS_ERROR_FAILURE;
}
sequence->SetTag(tagnum);
sequence->SetType(type);
rv = buildASN1ObjectFromDER(data, (len == 0) ? end : data + len,
sequence);
asn1Obj = sequence;
}
} else {
printableItem = new nsNSSASN1PrintableItem();
asn1Obj = printableItem;
asn1Obj->SetType(tagnum);
asn1Obj->SetTag(tagnum);
printableItem->SetData((char*)data, len);
}
data += len;
parentObjects->AppendElement(asn1Obj);
}
return NS_OK;
}
nsresult
CreateFromDER(unsigned char *data,
unsigned int len,
nsIASN1Object **retval)
{
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence;
*retval = nsnull;
nsresult rv = buildASN1ObjectFromDER(data, data+len, sequence);
if (NS_SUCCEEDED(rv)) {
// The actual object will be the first element inserted
// into the sequence of the sequence variable we created.
nsCOMPtr<nsISupportsArray> elements;
sequence->GetASN1Objects(getter_AddRefs(elements));
nsCOMPtr<nsISupports> isupports = dont_AddRef(elements->ElementAt(0));
nsCOMPtr<nsIASN1Object> asn1Obj(do_QueryInterface(isupports));
*retval = asn1Obj;
if (*retval == nsnull)
return NS_ERROR_FAILURE;
NS_ADDREF(*retval);
}
return rv;
}
nsNSSASN1Sequence::nsNSSASN1Sequence() : mProcessObjects(PR_TRUE),
mShowObjects(PR_TRUE)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
nsNSSASN1Sequence::~nsNSSASN1Sequence()
{
/* destructor code */
}
/* attribute nsISupportsArray ASN1Objects; */
NS_IMETHODIMP
nsNSSASN1Sequence::GetASN1Objects(nsISupportsArray * *aASN1Objects)
{
if (mASN1Objects == nsnull) {
mASN1Objects = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
}
*aASN1Objects = mASN1Objects;
NS_IF_ADDREF(*aASN1Objects);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetASN1Objects(nsISupportsArray * aASN1Objects)
{
mASN1Objects = aASN1Objects;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetTag(PRUint32 *aTag)
{
*aTag = mTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetTag(PRUint32 aTag)
{
mTag = aTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::GetType(PRUint32 *aType)
{
*aType = mType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetType(PRUint32 aType)
{
mType = aType;
return NS_OK;
}
/* attribute wstring displayName; */
NS_IMETHODIMP
nsNSSASN1Sequence::GetDisplayName(PRUnichar * *aDisplayName)
{
NS_ENSURE_ARG_POINTER(aDisplayName);
*aDisplayName = mDisplayName.ToNewUnicode();
return (*aDisplayName) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetDisplayName(const PRUnichar * aDisplayName)
{
mDisplayName.Assign(aDisplayName);
return NS_OK;
}
/* attribute wstring displayValue; */
NS_IMETHODIMP
nsNSSASN1Sequence::GetDisplayValue(PRUnichar * *aDisplayValue)
{
NS_ENSURE_ARG_POINTER(aDisplayValue);
*aDisplayValue = mDisplayValue.ToNewUnicode();
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetDisplayValue(const PRUnichar * aDisplayValue)
{
mDisplayValue.Assign(aDisplayValue);
return NS_OK;
}
/* attribute boolean processObjects; */
NS_IMETHODIMP
nsNSSASN1Sequence::GetProcessObjects(PRBool *aProcessObjects)
{
NS_ENSURE_ARG_POINTER(aProcessObjects);
*aProcessObjects = mProcessObjects;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetProcessObjects(PRBool aProcessObjects)
{
mProcessObjects = aProcessObjects;
SetShowObjects(mProcessObjects);
return NS_OK;
}
/* attribute boolean showObjects; */
NS_IMETHODIMP
nsNSSASN1Sequence::GetShowObjects(PRBool *aShowObjects)
{
NS_ENSURE_ARG_POINTER(aShowObjects);
*aShowObjects = mShowObjects;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1Sequence::SetShowObjects(PRBool aShowObjects)
{
mShowObjects = aShowObjects;
return NS_OK;
}
nsNSSASN1PrintableItem::nsNSSASN1PrintableItem() : mData(nsnull),
mLen(0)
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
nsNSSASN1PrintableItem::~nsNSSASN1PrintableItem()
{
/* destructor code */
if (mData)
nsMemory::Free(mData);
}
/* readonly attribute wstring value; */
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetDisplayValue(PRUnichar * *aValue)
{
*aValue = mValue.ToNewUnicode();
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetDisplayValue(const PRUnichar * aValue)
{
mValue.Assign(aValue);
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetTag(PRUint32 *aTag)
{
*aTag = mTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetTag(PRUint32 aTag)
{
mTag = aTag;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetType(PRUint32 *aType)
{
*aType = mType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetType(PRUint32 aType)
{
mType = aType;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetData(char *data, PRUint32 len)
{
if (len > 0) {
if (mData) {
if (mLen < len)
nsMemory::Realloc(mData, len);
} else {
mData = (unsigned char*)nsMemory::Alloc(len);
}
if (mData == nsnull)
return NS_ERROR_FAILURE;
nsCRT::memcpy(mData, data, len);
} else if (len == 0) {
if (mData) {
nsMemory::Free(mData);
mData = nsnull;
}
} else {
NS_ASSERTION(0,"Passed in invalid buffer length to SetData");
return NS_ERROR_FAILURE;
}
mLen = len;
return NS_OK;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetData(char **outData, PRUint32 *outLen)
{
NS_ENSURE_ARG_POINTER(outData);
NS_ENSURE_ARG_POINTER(outLen);
*outData = (char*)mData;
*outLen = mLen;
return NS_OK;
}
/* attribute wstring displayName; */
NS_IMETHODIMP
nsNSSASN1PrintableItem::GetDisplayName(PRUnichar * *aDisplayName)
{
NS_ENSURE_ARG_POINTER(aDisplayName);
*aDisplayName = mDisplayName.ToNewUnicode();
return (*aDisplayName) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsNSSASN1PrintableItem::SetDisplayName(const PRUnichar * aDisplayName)
{
mDisplayName.Assign(aDisplayName);
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,92 @@
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Javier Delgadillo <javi@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient
* may use your version of this file under either the MPL or the
* GPL.
*/
#ifndef _NSSASN_H_
#define _NSSASN_H_
#include "nscore.h"
#include "nsIX509Cert.h"
#include "nsIASN1Outliner.h"
#include "nsIOutlinerView.h"
#include "nsIOutlinerSelection.h"
#include "nsCOMPtr.h"
#include "nsString.h"
//
// Read comments in nsIX509Cert.idl for a description of the desired
// purpose for this ASN1 interface implementation.
//
class nsNSSASN1Sequence : public nsIASN1Sequence
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIASN1SEQUENCE
NS_DECL_NSIASN1OBJECT
nsNSSASN1Sequence();
virtual ~nsNSSASN1Sequence();
/* additional members */
private:
nsCOMPtr<nsISupportsArray> mASN1Objects;
nsString mDisplayName;
nsString mDisplayValue;
PRUint32 mType;
PRUint32 mTag;
PRBool mProcessObjects;
PRBool mShowObjects;
};
class nsNSSASN1PrintableItem : public nsIASN1PrintableItem
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIASN1PRINTABLEITEM
NS_DECL_NSIASN1OBJECT
nsNSSASN1PrintableItem();
virtual ~nsNSSASN1PrintableItem();
/* additional members */
private:
nsString mDisplayName;
nsString mValue;
PRUint32 mType;
PRUint32 mTag;
unsigned char *mData;
PRUint32 mLen;
};
nsresult CreateFromDER(unsigned char *data,
unsigned int len,
nsIASN1Object **retval);
#endif //_NSSASN_H_

Просмотреть файл

@ -32,11 +32,12 @@
* may use your version of this file under either the MPL or the
* GPL.
*
* $Id: nsNSSCertificate.cpp,v 1.16 2001/05/01 23:23:20 mcgreer%netscape.com Exp $
* $Id: nsNSSCertificate.cpp,v 1.17 2001/05/02 05:38:26 javi%netscape.com Exp $
*/
#include "prmem.h"
#include "prerror.h"
#include "prprf.h"
#include "nsNSSComponent.h" // for PIPNSS string bundle calls.
#include "nsCOMPtr.h"
@ -46,16 +47,20 @@
#include "nsPKCS12Blob.h"
#include "nsIX509Cert.h"
#include "nsINSSDialogs.h"
#include "nsNSSASN1Object.h"
#include "nsString.h"
#include "nsILocaleService.h"
#include "nsXPIDLString.h"
#include "nsIDateTimeFormat.h"
#include "nsDateTimeFormatCID.h"
#include "nsILocaleService.h"
#include "pk11func.h"
#include "certdb.h"
#include "cert.h"
#include "secerr.h"
#include "nssb64.h"
#include "secasn1.h"
#include "secder.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gPIPNSSLog;
@ -609,7 +614,7 @@ nsNSSCertificate::GetOrganizationalUnit(PRUnichar **aOrganizationalUnit)
* nsIEnumerator getChain();
*/
NS_IMETHODIMP
nsNSSCertificate::GetChain(nsIEnumerator **_rvChain)
nsNSSCertificate::GetChain(nsISupportsArray **_rvChain)
{
nsresult rv;
CERTCertListNode *node;
@ -632,7 +637,9 @@ nsNSSCertificate::GetChain(nsIEnumerator **_rvChain)
nsCOMPtr<nsIX509Cert> cert = new nsNSSCertificate(node->cert);
array->AppendElement(cert);
}
rv = array->Enumerate(_rvChain);
*_rvChain = array;
NS_IF_ADDREF(*_rvChain);
rv = NS_OK;
done:
if (nssChain)
CERT_DestroyCertList(nssChain);
@ -1002,6 +1009,477 @@ verify_failed:
return NS_OK;
}
static nsresult
GetIntValue(SECItem *versionItem,
unsigned long *version)
{
SECStatus srv;
srv = SEC_ASN1DecodeInteger(versionItem,version);
if (srv != SECSuccess) {
NS_ASSERTION(0,"Could not decode version of cert");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
static nsresult
ProcessVersion(SECItem *versionItem,
nsINSSComponent *nssComponent,
nsIASN1PrintableItem **retItem)
{
nsresult rv;
nsString text;
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpVersion").get(),
text);
rv = printableItem->SetDisplayName(text.get());
if (NS_FAILED(rv))
return rv;
// Now to figure out what version this certificate is.
unsigned long version;
rv = GetIntValue(versionItem, &version);
if (NS_FAILED(rv))
return rv;
switch (version){
case 0:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpVersion1").get(),
text);
break;
case 1:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpVersion2").get(),
text);
break;
case 2:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpVersion3").get(),
text);
break;
default:
NS_ASSERTION(0,"Bad value for cert version");
rv = NS_ERROR_FAILURE;
}
if (NS_FAILED(rv))
return rv;
rv = printableItem->SetDisplayValue(text.get());
if (NS_FAILED(rv))
return rv;
*retItem = printableItem;
NS_ADDREF(*retItem);
return NS_OK;
}
nsresult
ProcessSerialNumber(SECItem *serialItem,
nsINSSComponent *nssComponent,
nsIASN1PrintableItem **retItem)
{
nsresult rv;
nsString text;
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSerialNo").get(),
text);
if (NS_FAILED(rv))
return rv;
rv = printableItem->SetDisplayName(text.get());
if (NS_FAILED(rv))
return rv;
nsXPIDLCString serialNumber;
serialNumber = CERT_Hexify(serialItem, 1);
if (serialNumber == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = printableItem->SetDisplayValue(NS_ConvertASCIItoUCS2(serialNumber).get());
*retItem = printableItem;
NS_ADDREF(*retItem);
return rv;
}
static nsresult
GetDefaultOIDFormat(SECItem *oid,
nsString &outString)
{
char buf[300];
int len, written;
unsigned long val = oid->data[0];
unsigned int i = val % 40;
val /= 40;
written = PR_snprintf(buf, 300, "%lu %u ", val, i);
if (written < 0)
return NS_ERROR_FAILURE;
len = written;
val = 0;
for (i = 1; i < oid->len; ++i) {
// In this loop, we have to parse a DER formatted
// If the first bit is a 1, then the integer is
// represented by more than one byte. If the
// first bit is set then we continue on and add
// the values of the later bytes until we get
// a byte without the first bit set.
unsigned long j;
j = oid->data[i];
val = (val << 7) | (j & 0x7f);
if (j & 0x80)
continue;
written = PR_snprintf(&buf[len], sizeof(buf)-len, "%lu ", val);
if (written < 0)
return NS_ERROR_FAILURE;
len += written;
NS_ASSERTION(len < sizeof(buf), "OID data to big to display in 300 chars.");
val = 0;
}
outString = NS_ConvertASCIItoUCS2(buf).get();
return NS_OK;
}
static nsresult
GetOIDText(SECItem *oid, nsINSSComponent *nssComponent, nsString &text)
{
nsresult rv;
SECOidTag oidTag = SECOID_FindOIDTag(oid);
switch (oidTag) {
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpMD2WithRSA").get(),
text);
break;
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpMD5WithRSA").get(),
text);
break;
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSHA1WithRSA").get(),
text);
break;
case SEC_OID_AVA_COUNTRY_NAME:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVACountry").get(),
text);
break;
case SEC_OID_AVA_COMMON_NAME:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVACN").get(),
text);
break;
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVAOU").get(),
text);
break;
case SEC_OID_AVA_ORGANIZATION_NAME:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVAOrg").get(),
text);
break;
case SEC_OID_AVA_LOCALITY:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVALocality").get(),
text);
break;
case SEC_OID_AVA_DN_QUALIFIER:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVADN").get(),
text);
break;
case SEC_OID_AVA_DC:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVADC").get(),
text);
break;
case SEC_OID_AVA_STATE_OR_PROVINCE:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAVAState").get(),
text);
break;
case SEC_OID_PKCS1_RSA_ENCRYPTION:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpRSAEncr").get(),
text);
break;
case SEC_OID_X509_KEY_USAGE:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKeyUsage").get(),
text);
break;
case SEC_OID_NS_CERT_EXT_CERT_TYPE:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpCertType").get(),
text);
break;
case SEC_OID_X509_AUTH_KEY_ID:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAuthKeyID").get(),
text);
break;
case SEC_OID_RFC1274_UID:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpUserID").get(),
text);
break;
case SEC_OID_PKCS9_EMAIL_ADDRESS:
rv = nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpPK9Email").get(),
text);
break;
default:
rv = GetDefaultOIDFormat(oid, text);
if (NS_FAILED(rv))
return rv;
const PRUnichar *params[1] = {text.get()};
nsXPIDLString text2;
rv = nssComponent->PIPBundleFormatStringFromName(NS_LITERAL_STRING("CertDumpDefOID").get(),
params, 1,
getter_Copies(text2));
text = text2;
break;
}
return rv;
}
#define SEPARATOR "\n"
static nsresult
ProcessRawBytes(SECItem *data, nsString &text)
{
// This function is used to display some DER bytes
// that we have not added support for decoding.
// It prints the value of the byte out into a
// string that can later be displayed as a byte
// string. We place a new line after 24 bytes
// to break up extermaly long sequence of bytes.
PRUint32 i;
char buffer[5];
for (i=0; i<data->len; i++) {
PR_snprintf(buffer, 5, "%02x ", data->data[i]);
text.Append(NS_ConvertASCIItoUCS2(buffer).get());
if ((i+1)%24 == 0) {
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
}
return NS_OK;
}
static nsresult
ProcessNSCertTypeExtensions(SECItem *extData,
nsString &text,
nsINSSComponent *nssComponent)
{
SECItem decoded;
decoded.data = nsnull;
decoded.len = 0;
SEC_ASN1DecodeItem(nsnull, &decoded, SEC_BitStringTemplate, extData);
unsigned char nsCertType = decoded.data[0];
nsString local;
nsMemory::Free(decoded.data);
if (nsCertType & NS_CERT_TYPE_SSL_CLIENT) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("VerifySSLClient").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (nsCertType & NS_CERT_TYPE_SSL_SERVER) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("VerifySSLServer").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (nsCertType & NS_CERT_TYPE_EMAIL) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpCertTypeEmail").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (nsCertType & NS_CERT_TYPE_OBJECT_SIGNING) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("VerifyObjSign").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (nsCertType & NS_CERT_TYPE_SSL_CA) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("VerifySSLCA").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (nsCertType & NS_CERT_TYPE_EMAIL_CA) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpEmailCA").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (nsCertType & NS_CERT_TYPE_OBJECT_SIGNING_CA) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("VerifyObjSign").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
return NS_OK;
}
static nsresult
ProcessKeyUsageExtension(SECItem *extData, nsString &text,
nsINSSComponent *nssComponent)
{
SECItem decoded;
decoded.data = nsnull;
decoded.len = 0;
SEC_ASN1DecodeItem(nsnull, &decoded, SEC_BitStringTemplate, extData);
unsigned char keyUsage = decoded.data[0];
nsString local;
nsMemory::Free(decoded.data);
if (keyUsage & KU_DIGITAL_SIGNATURE) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUSign").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (keyUsage & KU_NON_REPUDIATION) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUNonRep").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (keyUsage & KU_KEY_ENCIPHERMENT) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUEnc").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (keyUsage & KU_DATA_ENCIPHERMENT) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUDEnc").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (keyUsage & KU_KEY_AGREEMENT) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUKA").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (keyUsage & KU_KEY_CERT_SIGN) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUCertSign").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
if (keyUsage & KU_CRL_SIGN) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpKUCRLSign").get(),
local);
text.Append(local.get());
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
}
return NS_OK;
}
static nsresult
ProcessExtensionData(SECOidTag oidTag, SECItem *extData,
nsString &text, nsINSSComponent *nssComponent)
{
nsresult rv;
switch (oidTag) {
case SEC_OID_NS_CERT_EXT_CERT_TYPE:
rv = ProcessNSCertTypeExtensions(extData, text, nssComponent);
break;
case SEC_OID_X509_KEY_USAGE:
rv = ProcessKeyUsageExtension(extData, text, nssComponent);
break;
default:
rv = ProcessRawBytes(extData, text);
break;
}
return rv;
}
static nsresult
ProcessSingleExtension(CERTCertExtension *extension,
nsINSSComponent *nssComponent,
nsIASN1PrintableItem **retExtension)
{
nsString text;
GetOIDText(&extension->id, nssComponent, text);
nsCOMPtr<nsIASN1PrintableItem>extensionItem = new nsNSSASN1PrintableItem();
if (extensionItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
extensionItem->SetDisplayName(text.get());
SECOidTag oidTag = SECOID_FindOIDTag(&extension->id);
text.Truncate();
if (extension->critical.data != nsnull) {
if (extension->critical.data[0]) {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpCritical").get(),
text);
} else {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpNonCritical").get(),
text);
}
} else {
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpNonCritical").get(),
text);
}
text.Append(NS_LITERAL_STRING(SEPARATOR).get());
nsresult rv = ProcessExtensionData(oidTag, &extension->value, text,
nssComponent);
if (NS_FAILED(rv))
return rv;
extensionItem->SetDisplayValue(text.get());
*retExtension = extensionItem;
NS_ADDREF(*retExtension);
return NS_OK;
}
#ifdef DEBUG_javi
void
DumpASN1Object(nsIASN1Object *object, unsigned int level)
{
PRUnichar *dispNameU, *dispValU;
unsigned int i;
nsCOMPtr<nsISupportsArray> asn1Objects;
nsCOMPtr<nsISupports> isupports;
nsCOMPtr<nsIASN1Object> currObject;
PRBool processObjects;
PRUint32 numObjects;
for (i=0; i<level; i++)
printf (" ");
object->GetDisplayName(&dispNameU);
nsCOMPtr<nsIASN1Sequence> sequence(do_QueryInterface(object));
if (sequence) {
printf ("%s ", NS_ConvertUCS2toUTF8(dispNameU).get());
sequence->GetProcessObjects(&processObjects);
if (processObjects) {
printf("\n");
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
asn1Objects->Count(&numObjects);
for (i=0; i<numObjects;i++) {
isupports = dont_AddRef(asn1Objects->ElementAt(i));
currObject = do_QueryInterface(isupports);
DumpASN1Object(currObject, level+1);
}
} else {
object->GetDisplayValue(&dispValU);
printf("= %s\n", NS_ConvertUCS2toUTF8(dispValU).get());
PR_Free(dispValU);
}
} else {
object->GetDisplayValue(&dispValU);
printf("%s = %s\n",NS_ConvertUCS2toUTF8(dispNameU).get(),
NS_ConvertUCS2toUTF8(dispValU).get());
PR_Free(dispValU);
}
PR_Free(dispNameU);
}
#endif
/*
* void getUsages(out PRUint32 verified,
* out PRUint32 count,
@ -1064,6 +1542,398 @@ nsNSSCertificate::View()
return certDialogs->ViewCert(this);
}
static nsresult
ProcessSECAlgorithmID(SECAlgorithmID *algID,
nsINSSComponent *nssComponent,
nsIASN1Sequence **retSequence)
{
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
if (sequence == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
*retSequence = nsnull;
nsString text;
GetOIDText(&algID->algorithm, nssComponent, text);
if (algID->parameters.data[0] == nsIASN1Object::ASN1_NULL) {
sequence->SetDisplayValue(text.get());
sequence->SetProcessObjects(PR_FALSE);
} else {
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
printableItem->SetDisplayValue(text.get());
nsCOMPtr<nsISupportsArray>asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
asn1Objects->AppendElement(printableItem);
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpAlgID").get(),
text);
printableItem->SetDisplayName(text.get());
printableItem = new nsNSSASN1PrintableItem();
asn1Objects->AppendElement(printableItem);
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpParams").get(),
text);
printableItem->SetDisplayName(text.get());
ProcessRawBytes(&algID->parameters,text);
printableItem->SetDisplayValue(text.get());
}
*retSequence = sequence;
NS_ADDREF(*retSequence);
return NS_OK;
}
static nsresult
ProcessTime(PRTime dispTime, const PRUnichar *displayName,
nsIASN1Sequence *parentSequence)
{
nsresult rv;
nsCOMPtr<nsIDateTimeFormat> dateFormatter =
do_CreateInstance(kDateTimeFormatCID, &rv);
if (NS_FAILED(rv))
return rv;
nsString text;
dateFormatter->FormatPRTime(nsnull, kDateFormatShort, kTimeFormatNone,
dispTime, text);
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
printableItem->SetDisplayValue(text.get());
printableItem->SetDisplayName(displayName);
nsCOMPtr<nsISupportsArray> asn1Objects;
parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
asn1Objects->AppendElement(printableItem);
return NS_OK;
}
static nsresult
ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki,
nsIASN1Sequence *parentSequence,
nsINSSComponent *nssComponent)
{
nsCOMPtr<nsIASN1Sequence> spkiSequence = new nsNSSASN1Sequence();
if (spkiSequence == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsString text;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSPKI").get(),
text);
spkiSequence->SetDisplayName(text.get());
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSPKIAlg").get(),
text);
nsCOMPtr<nsIASN1Sequence> sequenceItem;
nsresult rv = ProcessSECAlgorithmID(&spki->algorithm, nssComponent,
getter_AddRefs(sequenceItem));
if (NS_FAILED(rv))
return rv;
sequenceItem->SetDisplayName(text.get());
nsCOMPtr<nsISupportsArray> asn1Objects;
spkiSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
asn1Objects->AppendElement(sequenceItem);
// The subjectPublicKey field is encoded as a bit string.
// ProcessRawBytes expects the lenght to be in bytes, so
// let's convert the lenght into a temporary SECItem.
SECItem data;
data.data = spki->subjectPublicKey.data;
data.len = spki->subjectPublicKey.len / 8;
text.Truncate();
ProcessRawBytes(&data, text);
nsCOMPtr<nsIASN1PrintableItem> printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
printableItem->SetDisplayValue(text.get());
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSubjPubKey").get(),
text);
printableItem->SetDisplayName(text.get());
asn1Objects->AppendElement(printableItem);
parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
asn1Objects->AppendElement(spkiSequence);
return NS_OK;
}
static nsresult
ProcessExtensions(CERTCertExtension **extensions,
nsIASN1Sequence *parentSequence,
nsINSSComponent *nssComponent)
{
nsCOMPtr<nsIASN1Sequence> extensionSequence = new nsNSSASN1Sequence;
if (extensionSequence == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsString text;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpExtensions").get(),
text);
extensionSequence->SetDisplayName(text.get());
PRInt32 i;
nsresult rv;
nsCOMPtr<nsIASN1PrintableItem> newExtension;
nsCOMPtr<nsISupportsArray> asn1Objects;
extensionSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
for (i=0; extensions[i] != nsnull; i++) {
rv = ProcessSingleExtension(extensions[i], nssComponent,
getter_AddRefs(newExtension));
if (NS_FAILED(rv))
return rv;
asn1Objects->AppendElement(newExtension);
}
parentSequence->GetASN1Objects(getter_AddRefs(asn1Objects));
asn1Objects->AppendElement(extensionSequence);
return NS_OK;
}
nsresult
nsNSSCertificate::CreateTBSCertificateASN1Struct(nsIASN1Sequence **retSequence,
nsINSSComponent *nssComponent)
{
//
// TBSCertificate ::= SEQUENCE {
// version [0] EXPLICIT Version DEFAULT v1,
// serialNumber CertificateSerialNumber,
// signature AlgorithmIdentifier,
// issuer Name,
// validity Validity,
// subject Name,
// subjectPublicKeyInfo SubjectPublicKeyInfo,
// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
// -- If present, version shall be v2 or v3
// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
// -- If present, version shall be v2 or v3
// extensions [3] EXPLICIT Extensions OPTIONAL
// -- If present, version shall be v3
// }
//
// This is the ASN1 structure we should be dealing with at this point.
// The code in this method will assert this is the structure we're dealing
// and then add more user friendly text for that field.
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
if (sequence == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsString text;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpCertificate").get(),
text);
sequence->SetDisplayName(text.get());
nsCOMPtr<nsIASN1PrintableItem> printableItem;
nsCOMPtr<nsISupportsArray> asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
nsresult rv = ProcessVersion(&mCert->version, nssComponent,
getter_AddRefs(printableItem));
if (NS_FAILED(rv))
return rv;
asn1Objects->AppendElement(printableItem);
rv = ProcessSerialNumber(&mCert->serialNumber, nssComponent,
getter_AddRefs(printableItem));
if (NS_FAILED(rv))
return rv;
asn1Objects->AppendElement(printableItem);
nsCOMPtr<nsIASN1Sequence> algID;
rv = ProcessSECAlgorithmID(&mCert->signature,
nssComponent, getter_AddRefs(algID));
if (NS_FAILED(rv))
return rv;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSigAlg").get(),
text);
algID->SetDisplayName(text.get());
asn1Objects->AppendElement(algID);
nsXPIDLString value;
GetIssuerName(getter_Copies(value));
printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
printableItem->SetDisplayValue(value);
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpIssuer").get(),
text);
printableItem->SetDisplayName(text.get());
asn1Objects->AppendElement(printableItem);
nsCOMPtr<nsIASN1Sequence> validitySequence = new nsNSSASN1Sequence();
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpValidity").get(),
text);
validitySequence->SetDisplayName(text.get());
asn1Objects->AppendElement(validitySequence);
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpNotBefore").get(),
text);
nsCOMPtr<nsIX509CertValidity> validityData;
GetValidity(getter_AddRefs(validityData));
PRTime notBefore, notAfter;
validityData->GetNotBefore(&notBefore);
validityData->GetNotAfter(&notAfter);
validityData = 0;
rv = ProcessTime(notBefore, text.get(), validitySequence);
if (NS_FAILED(rv))
return rv;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpNotAfter").get(),
text);
rv = ProcessTime(notAfter, text.get(), validitySequence);
if (NS_FAILED(rv))
return rv;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSubject").get(),
text);
printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
printableItem->SetDisplayName(text.get());
GetSubjectName(getter_Copies(value));
printableItem->SetDisplayValue(value);
asn1Objects->AppendElement(printableItem);
rv = ProcessSubjectPublicKeyInfo(&mCert->subjectPublicKeyInfo, sequence,
nssComponent);
if (NS_FAILED(rv))
return rv;
SECItem data;
// Is there an issuerUniqueID?
if (mCert->issuerID.data != nsnull) {
// The issuerID is encoded as a bit string.
// The function ProcessRawBytes expects the
// length to be in bytes, so let's convert the
// length in a temporary SECItem
data.data = mCert->issuerID.data;
data.len = mCert->issuerID.len / 8;
ProcessRawBytes(&data, text);
printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
printableItem->SetDisplayValue(text.get());
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpIssuerUniqueID").get(),
text);
printableItem->SetDisplayName(text.get());
asn1Objects->AppendElement(printableItem);
}
if (mCert->subjectID.data) {
// The subjectID is encoded as a bit string.
// The function ProcessRawBytes expects the
// length to be in bytes, so let's convert the
// length in a temporary SECItem
data.data = mCert->issuerID.data;
data.len = mCert->issuerID.len / 8;
ProcessRawBytes(&data, text);
printableItem = new nsNSSASN1PrintableItem();
if (printableItem == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
printableItem->SetDisplayValue(text.get());
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSubjectUniqueID").get(),
text);
printableItem->SetDisplayName(text.get());
asn1Objects->AppendElement(printableItem);
}
if (mCert->extensions) {
rv = ProcessExtensions(mCert->extensions, sequence, nssComponent);
if (NS_FAILED(rv))
return rv;
}
*retSequence = sequence;
NS_ADDREF(*retSequence);
return NS_OK;
}
nsresult
nsNSSCertificate::CreateASN1Struct()
{
nsCOMPtr<nsIASN1Sequence> sequence = new nsNSSASN1Sequence();
mASN1Structure = sequence;
if (mASN1Structure == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsCOMPtr<nsISupportsArray> asn1Objects;
sequence->GetASN1Objects(getter_AddRefs(asn1Objects));
nsXPIDLCString title;
GetWindowTitle(getter_Copies(title));
mASN1Structure->SetDisplayName(NS_ConvertASCIItoUCS2(title).get());
// This sequence will be contain the tbsCertificate, signatureAlgorithm,
// and signatureValue.
nsresult rv;
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
if (NS_FAILED(rv))
return rv;
rv = CreateTBSCertificateASN1Struct(getter_AddRefs(sequence),
nssComponent);
if (NS_FAILED(rv))
return rv;
asn1Objects->AppendElement(sequence);
nsCOMPtr<nsIASN1Sequence> algID;
rv = ProcessSECAlgorithmID(&mCert->signatureWrap.signatureAlgorithm,
nssComponent, getter_AddRefs(algID));
if (NS_FAILED(rv))
return rv;
nsString text;
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpSigAlg").get(),
text);
algID->SetDisplayName(text.get());
asn1Objects->AppendElement(algID);
nsCOMPtr<nsIASN1PrintableItem>printableItem = new nsNSSASN1PrintableItem();
nssComponent->GetPIPNSSBundleString(NS_LITERAL_STRING("CertDumpCertSig").get(),
text);
printableItem->SetDisplayName(text.get());
// The signatureWrap is encoded as a bit string.
// The function ProcessRawBytes expects the
// length to be in bytes, so let's convert the
// length in a temporary SECItem
SECItem temp;
temp.data = mCert->signatureWrap.signature.data;
temp.len = mCert->signatureWrap.signature.len / 8;
text.Truncate();
ProcessRawBytes(&temp,text);
printableItem->SetDisplayValue(text.get());
asn1Objects->AppendElement(printableItem);
return NS_OK;
}
/* readonly attribute nsIASN1Object ASN1Structure; */
NS_IMETHODIMP
nsNSSCertificate::GetASN1Structure(nsIASN1Object * *aASN1Structure)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(aASN1Structure);
if (mASN1Structure == nsnull) {
// First create the recursive structure os ASN1Objects
// which tells us the layout of the cert.
rv = CreateASN1Struct();
if (NS_FAILED(rv)) {
return rv;
}
#ifdef DEBUG_javi
DumpASN1Object(mASN1Structure, 0);
#endif
}
*aASN1Structure = mASN1Structure;
NS_IF_ADDREF(*aASN1Structure);
return rv;
}
/* nsNSSCertificateDB */
NS_IMPL_ISUPPORTS1(nsNSSCertificateDB, nsIX509CertDB)

Просмотреть файл

@ -44,6 +44,8 @@
#include "cert.h"
#include "secitem.h"
class nsINSSComponent;
/* Certificate */
class nsNSSCertificate : public nsIX509Cert
{
@ -59,6 +61,10 @@ public:
private:
CERTCertificate *mCert;
nsCOMPtr<nsIASN1Object> mASN1Structure;
nsresult CreateASN1Struct();
nsresult CreateTBSCertificateASN1Struct(nsIASN1Sequence **retSequence,
nsINSSComponent *nssComponent);
PRBool verifyFailed(PRUint32 *_verified);

Просмотреть файл

@ -161,6 +161,9 @@ nsNSSComponent::GetPIPNSSBundleString(const PRUnichar *name,
} else {
outString.SetLength(0);
}
if (ptrv)
nsMemory::Free(ptrv);
return NS_ERROR_FAILURE;
}
@ -179,6 +182,7 @@ nsNSSComponent::InstallLoadableRoots()
break;
}
}
PK11_FreeSlotList(slotList);
}
if (!hasRoot) {
nsresult rv;