<!ENTITY menu_securitySMIMEReceiptRequest.label "Demander un accusé de réception signé">
<!ENTITY menu_securitySMIMEReceiptRequest.accesskey "D">
+
+<!ENTITY menu_securityLabel.label "Libellé de sécurité...">
+<!ENTITY menu_securityLabel.accesskey "L">
<!ENTITY subject.plaintextWarning "Note : Le champ « Sujet » d'un message n'est jamais chiffré.">
<!ENTITY status.heading "Le contenu du message sera envoyé de la façon suivante :">
<!ENTITY status.signed "Signé numériquement :">
+<!ENTITY status.securityLabel "Libellé de sécurité :">
<!ENTITY status.encrypted "Chiffré :">
<!ENTITY status.certificates "Certificats :">
<!ENTITY view.label "Voir">
--- /dev/null
+<!--LOCALIZATION NOTE msgCompSecurityLabelDialog.dtd UI for selecting security label properties when composing a message -->
+
+<!ENTITY securityLabelDialog.name "Libellé de sécurité">
+<!ENTITY securityLabelDialog.securityPolicyIdentifier.name "Politique de sécurité :">
+<!ENTITY securityLabelDialog.securityClassification.name "Classification de sécurité :">
+<!ENTITY securityLabelDialog.privacyMark.name "Marque de confidentialité :">
+<!ENTITY securityLabelDialog.securityCategories.name "Catégories de sécurité :">
+<!ENTITY securityLabelDialog.securityCategories.button.add.name "Ajouter">
+<!ENTITY securityLabelDialog.securityCategories.button.remove.name "Supprimer">
<!ENTITY menu_securityStatus.label "Infos de sécurité des messages">
<!ENTITY menu_securityStatus.accesskey "I">
+<!ENTITY securityLabelSecurityClassificationColumn.label "Classification de sécurité">
+<!ENTITY securityLabelSecurityClassificationColumn.tooltip "Cliquez pour trier par classification de sécurité">
<!ENTITY recipient.name "Chiffré pour :">
<!ENTITY email.address "Adresse électronique :">
<!ENTITY issuer.name "Certificat fourni par :">
+
+<!ENTITY securityLabel.name "Libellé de sécurité">
+<!ENTITY securityLabel.securityPolicyIdentifier.name "Politique de sécurité :">
+<!ENTITY securityLabel.securityClassification.name "Classification de sécurité :">
+<!ENTITY securityLabel.privacyMark.name "Marque de confidentialité :">
+<!ENTITY securityLabel.securityCategories.name "Catégories de sécurité :">
--- /dev/null
+# msgSecurityLabel.js
+unknownSecurityPolicyIdentifier=inconnue
+unknownSecurityClassification=inconnue
+unknownSecurityCategory=inconnue
+
+# msgCompSecurityLabelDialog.js
+noSecurityPolicyIdentifier=aucune
+noSecurityClassification=aucune
<rdf:Description>
<!-- Thunderbird (only with Trustedbird) -->
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
- <em:minVersion>3.1.4+0.1.0</em:minVersion>
- <em:maxVersion>3.1.4+0.1.*</em:maxVersion>
+ <em:minVersion>3.1.4+0.2.0</em:minVersion>
+ <em:maxVersion>3.1.4+0.2.*</em:maxVersion>
</rdf:Description>
</em:targetApplication>
<rdf:Description>
<!-- Thunderbird (only with Trustedbird) -->
<em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
- <em:minVersion>3.1.4-0.1.0</em:minVersion>
- <em:maxVersion>3.1.4-0.1.*</em:maxVersion>
+ <em:minVersion>3.1.4-0.2.0</em:minVersion>
+ <em:maxVersion>3.1.4-0.2.*</em:maxVersion>
<em:updateLink>__XPI_URL__</em:updateLink>
<em:updateHash>__UPDATE_HASH__</em:updateHash>
</rdf:Description>
-3.1.1122.2+0.1.0
+3.1.1122.3+0.2.0
+trustedbird (3.1.4+0.2.0)
+ * Add S/MIME security labels (RFC 2634)
+-- 20 Sep 2010
+
trustedbird (3.1.4+0.1.0)
* Upgrade to Thunderbird 3.1.4
-- 17 Sep 2010
This software is an email client based on Mozilla Thunderbird 3.1 with additional features:
* S/MIME signed receipts (RFC 2634)
+* S/MIME security labels (RFC 2634)
Trustedbird/Milimail project
FILES := \
mimeTypes.rdf \
localstore.rdf \
+ securityLabelPolicy-sample.xml \
$(NULL)
libs:: $(FILES)
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ESS Security Label policy definition example -->
+<securityLabel>
+
+ <!--
+ Security Policy Identifier
+ value (attribute) [OID]
+ label (attribute) [string]: displayed name of the policy
+ -->
+ <securityPolicyIdentifier value="1.2.840.113549.1.9.16.7.1" label="default" />
+
+
+ <!--
+ Security Classification
+ valueDisplayed (attribute) [boolean]: decide if value is displayed or only label
+ item (element):
+ value (attribute) [integer]: must be in 0 - 256 range
+ label (attribute) [string]: displayed name
+ -->
+ <securityClassification valueDisplayed="true">
+ <item value="0" label="unmarked" />
+ <item value="1" label="unclassified" />
+ <item value="2" label="restricted" />
+ <item value="3" label="confidential" />
+ <item value="4" label="secret" />
+ <item value="5" label="top-secret" />
+ </securityClassification>
+
+
+ <!--
+ Privacy Mark
+ freeText (attribute) [boolean]: define if free text if allowed
+ item (element): add a predefined privacy mark
+ value (attribute) [string]: displayed text and value of the privacy mark
+ -->
+ <privacyMark freeText="true">
+ <item value="NOCONTRACTOR" />
+ <item value="NOFORN" />
+ <item value="保密" />
+ <item value="प्रतिबंधित/सीमित" />
+ </privacyMark>
+
+
+ <!--
+ Security Categories
+ securityClassificationValue (attribute) [integer]: specify that these categories apply only to this classification
+ item (element): category
+ oid (attribute) [OID]: type of the category
+ type (attribute) [integer]: data type of value attribute (1 for UTF-8 string, 2 for integer)
+ value (attribute) [string]: text of the category
+ label (attribute) [string]: displayed name of the category
+ -->
+
+ <!-- For all Security Classification -->
+ <securityCategories>
+ <item oid="1.2.66.1.5" type="1" value="private" label="Private" />
+ <item oid="1.2.66.1.89.4" type="1" value="EU Protected Information" label="Protected Information" />
+ </securityCategories>
+
+ <!-- Only for Security Classification 4 -->
+ <securityCategories securityClassificationValue="4">
+ <item oid="1.2.3.8" type="1" value="EYES ONLY" label="EYES ONLY" />
+ <item oid="1.2.398.5" type="1" value="EU do not print" label="DO NOT PRINT" />
+ <item oid="1.2.398.5" type="1" value="FR do not print" label="Ne pas imprimer" />
+ </securityCategories>
+
+ <!-- Only for Security Classification 5 -->
+ <securityCategories securityClassificationValue="5">
+ <item oid="1.2.324.74" type="1" value="NATO CONFIDENTIAL" label="NATO CONFIDENTIAL" />
+ <item oid="1.2.324.75" type="1" value="NATO RESTRICTED" label="NATO RESTRICTED" />
+ <item oid="1.2.99.2" type="1" value="高度機密" label="top-secret" />
+ <item oid="1.2.99.3" type="2" value="57" label="a" />
+ <item oid="1.2.99.4" type="2" value="6000" label="b" />
+ <item oid="1.2.99.5" type="1" value="6000" label="c" />
+ </securityCategories>
+
+</securityLabel>
var gEncryptOptionChanged;
var gSignOptionChanged;
+var gSecurityLabelConf = null;
+
function onComposerClose()
{
gSMFields = null;
setNoEncryptionUI();
setNoSignatureUI();
+ setSecurityLabelStatusBarUI();
if (!gMsgCompose || !gMsgCompose.compFields)
return;
if (gSMFields.signMessage)
gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+
+ setSecurityLabelStatusBarUI();
}
addEventListener("load", smimeComposeOnLoad, false);
{
gSMFields.SMIMEReceiptRequest = false;
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
setNoSignatureUI();
}
toggleSMIMEReceiptRequest();
break;
+ case "securityLabelDialog":
+ showSecurityLabelDialog();
+ break;
+
case "show":
default:
showMessageComposeSecurityStatus();
gSMFields.SMIMEReceiptRequest = false;
setNoSignatureUI();
}
+
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+}
+
+/**
+ * Show a dialog to define Security Label settings
+ */
+function showSecurityLabelDialog() {
+ window.openDialog('chrome://messenger-smime/content/msgCompSecurityLabelDialog.xul', '', 'chrome,resizable=yes,titlebar,modal,width=500,height=350');
+
+ /* make sure we have a cert name for signing */
+ if (gSMFields.securityPolicyIdentifier != "")
+ {
+ var signingCertName = gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+ if (!signingCertName)
+ {
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+ showNeedSetupInfo();
+ return;
+ }
+
+ // Enable signing if disabled
+ if (!gSMFields.signMessage)
+ toggleSignMessage();
+ }
+
+ setSecurityLabelStatusBarUI();
+}
+
+/**
+ * Display Security Label info in status bar of compose window
+ */
+function setSecurityLabelStatusBarUI() {
+ if (!gSMFields || gSMFields.securityPolicyIdentifier == "") {
+ top.document.getElementById("securityLabel-status").label = "";
+ top.document.getElementById("securityLabel-status").collapsed = true;
+ return;
+ }
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
+
+ var securityLabelValue = "";
+
+ if (gSMFields.securityClassification != -1)
+ securityLabelValue = gSecurityLabelConf.getSecurityClassificationName(gSMFields.securityPolicyIdentifier, gSMFields.securityClassification) + " ";
+
+ securityLabelValue += "[" + gSecurityLabelConf.getSecurityPolicyIdentifierName(gSMFields.securityPolicyIdentifier) + "]";
+ top.document.getElementById("securityLabel-status").label = securityLabelValue;
+ top.document.getElementById("securityLabel-status").collapsed = false;
}
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://messenger-smime/content/msgCompSMIMEOverlay.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
<window id="msgcomposeWindow">
<broadcaster id="securityStatus" crypto="" signing=""/>
label="&menu_securitySMIMEReceiptRequest.label;"
accesskey="&menu_securitySMIMEReceiptRequest.accesskey;"
oncommand="toggleSMIMEReceiptRequest()"/>
+
+ <menuseparator id="menu_securityLabelDialogSeparator1"/>
+ <menuitem id="menu_securityLabelDialog1"
+ label="&menu_securityLabel.label;"
+ accesskey="&menu_securityLabel.accesskey;"
+ oncommand="showSecurityLabelDialog();"/>
</menupopup>
<toolbarpalette id="MsgComposeToolbarPalette">
label="&menu_securitySMIMEReceiptRequest.label;"
accesskey="&menu_securitySMIMEReceiptRequest.accesskey;"
oncommand="setNextCommand('SMIMEReceiptRequest');"/>
+ <menuseparator id="menu_securityLabelDialogSeparator2"/>
+ <menuitem id="menu_securityLabelDialog2"
+ label="&menu_securityLabel.label;"
+ accesskey="&menu_securityLabel.accesskey;"
+ oncommand="setNextCommand('securityLabelDialog');"/>
<menuseparator id="smimeToolbarButtonSeparator"/>
<menuitem id="menu_securityStatus2"
label="&menu_securityStatus.label;"
<statusbar id="status-bar">
<statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
id="signing-status" oncommand="showMessageComposeSecurityStatus();"/>
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-text" collapsed="true"
+ id="securityLabel-status" onclick="showSecurityLabelDialog();"/>
<statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
id="encryption-status" oncommand="showMessageComposeSecurityStatus();"/>
</statusbar>
<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/msgCompSecurityInfo.dtd">
<dialog id="msgCompSecurityInfo" title="&title.label;"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="width: 50em;"
persist="width height"
buttons="accept"
onload="onLoad();">
<script type="application/javascript" src="chrome://messenger-smime/content/msgCompSecurityInfo.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
- <stringbundle id="bundle_smime_comp_info" src="chrome://messenger-smime/locale/msgCompSecurityInfo.properties"/>
+ <stringbundle id="bundle_smime_comp_info" src="chrome://messenger-smime/locale/msgCompSecurityInfo.properties"/>
<description>&subject.plaintextWarning;</description>
<separator class="thin"/>
<label value="&status.signed;"/>
<label id="signed"/>
</row>
+ <row>
+ <label value="&status.securityLabel;"/>
+ <label id="securityLabel"/>
+ </row>
<row>
<label value="&status.encrypted;"/>
<label id="encrypted"/>
gMessageNotificationBar.setSMIMEReceiptMsg(requestMsgHdr);
},
+ securityLabelStatus: function(aSecurityPolicyIdentifier, aSecurityClassification, aPrivacyMark, aSecurityCategories)
+ {
+ gSecurityPolicyIdentifier = aSecurityPolicyIdentifier;
+ gSecurityClassification = aSecurityClassification;
+ gPrivacyMark = aPrivacyMark;
+ gSecurityCategories = aSecurityCategories;
+
+ /* Add Security Label info in message database so as to be displayed in a column */
+ var msgHdr = gMessageDisplay.displayedMessage;
+ if (msgHdr && gSecurityPolicyIdentifier != "") {
+ /* Write Security Label in message database */
+ msgHdr.setStringProperty("securityLabelSecurityPolicyIdentifier", gSecurityPolicyIdentifier);
+ msgHdr.setStringProperty("securityLabelSecurityClassification", gSecurityClassification);
+ msgHdr.setStringProperty("securityLabelPrivacyMark", gPrivacyMark);
+ msgHdr.setStringProperty("securityLabelSecurityCategories", gSecurityCategories);
+ }
+ },
+
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgSMIMEHeaderSink) || iid.equals(Components.interfaces.nsISupports))
{
gEncryptionStatus = -1;
gSignatureStatus = -1;
-
+
+ gSecurityPolicyIdentifier = null;
+ gSecurityClassification = -1;
+ gPrivacyMark = null;
+ gSecurityCategories = null;
+
gSignerCert = null;
gEncryptionCert = null;
-
+
gSMIMEContainer.collapsed = true;
gSignedUINode.collapsed = true;
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://messenger-smime/content/msgReadSMIMEOverlay.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_read_smime" src="chrome://messenger-smime/locale/msgReadSMIMEOverlay.properties"/>
observes="cmd_viewSecurityStatus"/>
</menupopup>
+ <tree id="threadTree">
+ <treecols id="threadCols">
+ <splitter class="tree-splitter"/>
+ <treecol id="securityLabelSecurityClassificationColumn" persist="hidden ordinal width" hidden="true"
+ currentView="unthreaded" label="&securityLabelSecurityClassificationColumn.label;"
+ tooltiptext="&securityLabelSecurityClassificationColumn.tooltip;"/>
+ </treecols>
+ </tree>
+
</overlay>
content/messenger-smime/msgReadSecurityInfo.js (/mailnews/extensions/smime/content/msgReadSecurityInfo.js)
content/messenger-smime/certFetchingStatus.xul (/mailnews/extensions/smime/content/certFetchingStatus.xul)
content/messenger-smime/certFetchingStatus.js (/mailnews/extensions/smime/content/certFetchingStatus.js)
+ content/messenger-smime/msgSecurityLabel.js (/mailnews/extensions/smime/content/msgSecurityLabel.js)
+ content/messenger-smime/msgCompSecurityLabelDialog.xul (/mailnews/extensions/smime/content/msgCompSecurityLabelDialog.xul)
+ content/messenger-smime/msgCompSecurityLabelDialog.js (/mailnews/extensions/smime/content/msgCompSecurityLabelDialog.js)
@BINPATH@/defaults/profile/localstore.rdf
@BINPATH@/defaults/profile/prefs.js
@BINPATH@/defaults/profile/mimeTypes.rdf
+@BINPATH@/defaults/profile/securityLabelPolicy-sample.xml
@BINPATH@/isp/*
<!ENTITY menu_securitySMIMEReceiptRequest.label "Request a Signed Receipt">
<!ENTITY menu_securitySMIMEReceiptRequest.accesskey "R">
+
+<!ENTITY menu_securityLabel.label "Security Label...">
+<!ENTITY menu_securityLabel.accesskey "L">
<!ENTITY subject.plaintextWarning "Please note: Subject lines of email messages are never encrypted.">
<!ENTITY status.heading "The contents of your message will be sent as follows:">
<!ENTITY status.signed "Digitally signed:">
+<!ENTITY status.securityLabel "Security Label:">
<!ENTITY status.encrypted "Encrypted:">
<!ENTITY status.certificates "Certificates:">
<!ENTITY view.label "View">
--- /dev/null
+<!--LOCALIZATION NOTE msgCompSecurityLabelDialog.dtd UI for selecting security label properties when composing a message -->
+
+<!ENTITY securityLabelDialog.name "Security Label">
+<!ENTITY securityLabelDialog.securityPolicyIdentifier.name "Security Policy:">
+<!ENTITY securityLabelDialog.securityClassification.name "Security Classification:">
+<!ENTITY securityLabelDialog.privacyMark.name "Privacy Mark:">
+<!ENTITY securityLabelDialog.securityCategories.name "Security Categories:">
+<!ENTITY securityLabelDialog.securityCategories.button.add.name "Add">
+<!ENTITY securityLabelDialog.securityCategories.button.remove.name "Remove selected">
<!ENTITY menu_securityStatus.label "Message Security Info">
<!ENTITY menu_securityStatus.accesskey "I">
+<!ENTITY securityLabelSecurityClassificationColumn.label "Security Classification">
+<!ENTITY securityLabelSecurityClassificationColumn.tooltip "Click to sort by Security Classification">
<!ENTITY recipient.name "Encrypted for:">
<!ENTITY email.address "Email address:">
<!ENTITY issuer.name "Certificate issued by:">
+
+<!ENTITY securityLabel.name "Security Label">
+<!ENTITY securityLabel.securityPolicyIdentifier.name "Security Policy:">
+<!ENTITY securityLabel.securityClassification.name "Security Classification:">
+<!ENTITY securityLabel.privacyMark.name "Privacy Mark:">
+<!ENTITY securityLabel.securityCategories.name "Security Categories:">
--- /dev/null
+# msgSecurityLabel.js
+unknownSecurityPolicyIdentifier=unknown
+unknownSecurityClassification=unknown
+unknownSecurityCategory=unknown
+
+# msgCompSecurityLabelDialog.js
+noSecurityPolicyIdentifier=none
+noSecurityClassification=none
locale/@AB_CD@/messenger-smime/certFetchingStatus.dtd (%chrome/messenger-smime/certFetchingStatus.dtd)
locale/@AB_CD@/messenger-smime/msgSecurityInfo.properties (%chrome/messenger-smime/msgSecurityInfo.properties)
locale/@AB_CD@/messenger-smime/msgSMIMEReceiptGenerator.properties (%chrome/messenger-smime/msgSMIMEReceiptGenerator.properties)
+ locale/@AB_CD@/messenger-smime/msgSecurityLabel.properties (%chrome/messenger-smime/msgSecurityLabel.properties)
+ locale/@AB_CD@/messenger-smime/msgCompSecurityLabelDialog.dtd (%chrome/messenger-smime/msgCompSecurityLabelDialog.dtd)
% locale messenger-region @AB_CD@ %locale/@AB_CD@/messenger-region/
locale/@AB_CD@/messenger-region/region.properties (%chrome/messenger-region/region.properties)
% locale mozldap @AB_CD@ %locale/@AB_CD@/mozldap/
#encryptionCert {
margin: 5px;
}
+
+#securityLabel {
+ font-weight: bold;
+}
+
+#securityLabelContent {
+ margin: 5px;
+}
#encryptionCert {
margin: 5px;
}
+
+#securityLabel {
+ font-weight: bold;
+}
+
+#securityLabelContent {
+ margin: 5px;
+}
#encryptionCert {
margin: 5px;
}
+
+#securityLabel {
+ font-weight: bold;
+}
+
+#securityLabelContent {
+ margin: 5px;
+}
var signed_element = document.getElementById("signed");
var encrypted_element = document.getElementById("encrypted");
-
+ var securityLabel_element = document.getElementById("securityLabel");
+
if (params.smFields.requireEncryptMessage)
{
if (params.isEncryptionCertAvailable && canEncrypt.value)
{
signed_element.value = no_string;
}
+
+ /* Security Label */
+ if (params.smFields.securityPolicyIdentifier != "")
+ {
+ var tSecurityLabelConf = new securityLabelConf();;
+ var securityLabelValue = "";
+ if (params.smFields.securityClassification != -1)
+ securityLabelValue = tSecurityLabelConf.getSecurityClassificationName(params.smFields.securityPolicyIdentifier, params.smFields.securityClassification) + " ";
+
+ securityLabelValue += "[" + tSecurityLabelConf.getSecurityPolicyIdentifierName(params.smFields.securityPolicyIdentifier) + "]";
+ securityLabel_element.value = securityLabelValue;
+ }
+ else
+ securityLabel_element.value = no_string;
+
}
var imax = gCount.value;
--- /dev/null
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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
+ * BT Global Services / Etat francais - Ministere de la Defense.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var gSMFields;
+var gSecurityLabelDialogStringBundle;
+var currentSecurityPolicyIdentifier;
+var currentSecurityClassification;
+var currentPrivacyMark;
+var currentSecurityCategories;
+
+var gSecurityLabelConf;
+
+function securityLabelDialogOnLoad() {
+ gSMFields = window.opener.gMsgCompose.compFields.securityInfo;
+ if (gSMFields == null)
+ return;
+
+ gSecurityLabelDialogStringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService)
+ .createBundle("chrome://messenger-smime/locale/msgSecurityLabel.properties");
+
+ /* Read Security Label profiles */
+ gSecurityLabelConf = new securityLabelConf();
+
+ /* Get current values */
+ currentSecurityPolicyIdentifier = gSMFields.securityPolicyIdentifier;
+ currentSecurityClassification = gSMFields.securityClassification;
+ currentPrivacyMark = gSMFields.privacyMark;
+ currentSecurityCategories = gSMFields.securityCategories;
+
+ /* Build Security Policy menulist */
+ var securityPolicyIdentifierMenuList = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList");
+
+ /* Clear list */
+ while (securityPolicyIdentifierMenuList.menupopup.firstChild)
+ securityPolicyIdentifierMenuList.menupopup.removeChild(securityPolicyIdentifierMenuList.menupopup.firstChild);
+
+ /* Construct list */
+ securityLabelDialogCreateMenuItem(securityPolicyIdentifierMenuList, gSecurityLabelDialogStringBundle.GetStringFromName("noSecurityPolicyIdentifier"), "", "");
+ for (policyName in gSecurityLabelConf.mSecurityPolicyList)
+ securityLabelDialogCreateMenuItem(securityPolicyIdentifierMenuList, policyName, gSecurityLabelConf.mSecurityPolicyList[policyName], currentSecurityPolicyIdentifier);
+
+ /* Init UI */
+ securityLabelDialogInitUI();
+}
+
+function securityLabelDialogOnSecurityPolicyIdentifier() {
+ currentSecurityClassification = -1;
+ currentPrivacyMark = "";
+ currentSecurityCategories = "";
+
+ securityLabelDialogInitUI();
+}
+
+function securityLabelDialogInitUI() {
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+
+ /* Build Security Classification menulist */
+ var securityClassificationMenuList = document.getElementById("securityLabelSecurityClassificationMenuList");
+
+ /* Clear list */
+ while (securityClassificationMenuList.menupopup.firstChild)
+ securityClassificationMenuList.menupopup.removeChild(securityClassificationMenuList.menupopup.firstChild);
+
+ /* Construct list */
+ securityLabelDialogCreateMenuItem(securityClassificationMenuList, gSecurityLabelDialogStringBundle.GetStringFromName("noSecurityClassification"), "-1", "-1");
+ for (classificationName in gSecurityLabelConf.mSecurityClassificationList[selectedPolicyIdentifier])
+ securityLabelDialogCreateMenuItem(securityClassificationMenuList, classificationName, gSecurityLabelConf.mSecurityClassificationList[selectedPolicyIdentifier][classificationName], currentSecurityClassification);
+
+ /* Build Privacy Mark menulist */
+ var privacyMarkMenuList = document.getElementById("securityLabelPrivacyMarkMenuList");
+
+ /* Clear list */
+ while (privacyMarkMenuList.menupopup.firstChild)
+ privacyMarkMenuList.menupopup.removeChild(privacyMarkMenuList.menupopup.firstChild);
+ privacyMarkMenuList.removeAttribute("editable");
+
+ /* Construct list */
+ securityLabelDialogCreateMenuItem(privacyMarkMenuList, "", "", "");
+ for (privacyMarkName in gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier])
+ if (privacyMarkName != "freeText")
+ securityLabelDialogCreateMenuItem(privacyMarkMenuList, gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier][privacyMarkName], gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier][privacyMarkName], currentPrivacyMark);
+
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier]["freeText"])
+ privacyMarkMenuList.setAttribute("editable", true);
+
+ document.getElementById("securityLabelPrivacyMarkTextBox").value = currentPrivacyMark;
+ document.getElementById("securityLabelPrivacyMarkMenuList").value = currentPrivacyMark;
+
+ /* Security Categories */
+ securityLabelDialogSecurityCategoriesClearList();
+ if (currentSecurityCategories != "") {
+ var s = currentSecurityCategories.split("|");
+ if (s.length % 3 == 0) {
+ for (var i = 0; i < s.length; i += 3)
+ securityLabelDialogSecurityCategoriesAddItem(s[i] + "|" + s[i + 1] + "|" + s[i + 2]);
+
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+ securityLabelSecurityCategoriesListBox.selectedItem = securityLabelSecurityCategoriesListBox.firstChild;
+ }
+ }
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogOnSecurityClassification() {
+ securityLabelDialogSecurityCategoriesClearList();
+}
+
+function securityLabelDialogCreateMenuItem(menulist, label, value, selectedValue) {
+ var menuitem = menulist.appendItem(label, value);
+ if (value == selectedValue)
+ menulist.selectedItem = menuitem;
+}
+
+function securityLabelDialogSecurityCategoriesOnButtonAdd() {
+ securityLabelDialogSecurityCategoriesAddItem("");
+}
+
+function securityLabelDialogSecurityCategoriesAddItem(selectedValue) {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+ var n = 0;
+ while (document.getElementById("securityLabelSecurityCategoriesMenuList" + n) != null)
+ n++;
+
+ var menulist = document.createElement("menulist");
+ menulist.setAttribute("id", "securityLabelSecurityCategoriesMenuList" + n);
+ menulist.setAttribute("flex", "1");
+
+ var listitem = document.createElement("listitem");
+ listitem.setAttribute("id", "securityLabelSecurityCategoriesListitem" + n);
+ listitem.setAttribute("allowevents", true);
+ listitem.appendChild(menulist);
+ securityLabelSecurityCategoriesListBox.appendChild(listitem);
+ securityLabelSecurityCategoriesListBox.ensureIndexIsVisible(securityLabelSecurityCategoriesListBox.getRowCount() - 1);
+ securityLabelSecurityCategoriesListBox.selectedItem = listitem;
+
+ /* Construct menulist */
+ securityLabelDialogCreateMenuItem(menulist, "", "", selectedValue);
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+ for (var i = 0; i < 2; i++) {
+ if (gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier]) {
+ var list;
+ /* Security Categories for all classifications */
+ if (i == 0)
+ list = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier]["all"];
+ /* Security Categories for selected classification */
+ if (i == 1)
+ list = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier][document.getElementById("securityLabelSecurityClassificationMenuList").value];
+
+ for (securityCategoryName in list)
+ securityLabelDialogCreateMenuItem(menulist, securityCategoryName, list[securityCategoryName][0] + "|" + list[securityCategoryName][1] + "|" + list[securityCategoryName][2], selectedValue);
+ }
+ }
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogSecurityCategoriesOnButtonRemove() {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+
+ if (securityLabelSecurityCategoriesListBox.selectedItem != null) {
+ var nextNode = securityLabelSecurityCategoriesListBox.selectedItem.nextSibling;
+ if (nextNode == null)
+ nextNode = securityLabelSecurityCategoriesListBox.selectedItem.previousSibling;
+ securityLabelSecurityCategoriesListBox.removeChild(securityLabelSecurityCategoriesListBox.selectedItem);
+ securityLabelSecurityCategoriesListBox.selectedItem = nextNode;
+ }
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogSecurityCategoriesClearList() {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+
+ while (securityLabelSecurityCategoriesListBox.hasChildNodes())
+ securityLabelSecurityCategoriesListBox.removeChild(securityLabelSecurityCategoriesListBox.firstChild);
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogOnAccept() {
+ /* Security Policy Identifier */
+ gSMFields.securityPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").value;
+ if (gSMFields.securityPolicyIdentifier != "") {
+
+ /* Security Classification */
+ gSMFields.securityClassification = document.getElementById("securityLabelSecurityClassificationMenuList").value;
+
+ /* Privacy Mark */
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier].length > 0)
+ gSMFields.privacyMark = document.getElementById("securityLabelPrivacyMarkMenuList").value;
+ else
+ gSMFields.privacyMark = document.getElementById("securityLabelPrivacyMarkTextBox").value;
+
+ /* Security Categories */
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+ var securityCategories = "";
+ if (securityLabelSecurityCategoriesListBox.hasChildNodes()) {
+ for (var i = 0; i < securityLabelSecurityCategoriesListBox.childNodes.length; i++) {
+ var value = securityLabelSecurityCategoriesListBox.childNodes[i].firstChild.value;
+
+ if (value != undefined && value != "") {
+ if (securityCategories != "")
+ securityCategories += "|";
+ securityCategories += value;
+ }
+ }
+ }
+ gSMFields.securityCategories = securityCategories;
+
+ } else {
+ gSMFields.securityClassification = -1;
+ gSMFields.privacyMark = "";
+ gSMFields.securityCategories = "";
+ }
+}
+
+function securityLabelDialogSetControls() {
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier].length > 0) {
+ document.getElementById("securityLabelPrivacyMarkTextBox").hidden = true;
+ document.getElementById("securityLabelPrivacyMarkMenuList").hidden = false;
+ } else {
+ document.getElementById("securityLabelPrivacyMarkTextBox").hidden = false;
+ document.getElementById("securityLabelPrivacyMarkMenuList").hidden = true;
+ }
+
+ if (document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").value != "") {
+ document.getElementById("securityLabelSecurityClassificationMenuList").disabled = false;
+
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier]["freeText"])
+ document.getElementById("securityLabelPrivacyMarkTextBox").disabled = false;
+ else
+ document.getElementById("securityLabelPrivacyMarkTextBox").disabled = true;
+
+ document.getElementById("securityLabelPrivacyMarkMenuList").disabled = false;
+ document.getElementById("securityLabelSecurityCategoriesListBox").disabled = false;
+
+ /* Security Categories for all classifications */
+ var list1;
+ if (gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier])
+ list1 = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier]["all"];
+
+ /* Security Categories for selected classification */
+ var list2;
+ if (gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier])
+ list2 = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier][document.getElementById("securityLabelSecurityClassificationMenuList").value];
+
+ if (list1 != undefined || list2 != undefined)
+ document.getElementById("securityLabelSecurityCategoriesButtonAdd").disabled = false;
+ else
+ document.getElementById("securityLabelSecurityCategoriesButtonAdd").disabled = true;
+
+ if (document.getElementById("securityLabelSecurityCategoriesListBox").getRowCount() > 0 && document.getElementById("securityLabelSecurityCategoriesListBox").getRowCount() < 64)
+ document.getElementById("securityLabelSecurityCategoriesButtonRemove").disabled = false;
+ else
+ document.getElementById("securityLabelSecurityCategoriesButtonRemove").disabled = true;
+
+ } else {
+ document.getElementById("securityLabelSecurityClassificationMenuList").disabled = true;
+ document.getElementById("securityLabelPrivacyMarkTextBox").disabled = true;
+ document.getElementById("securityLabelPrivacyMarkMenuList").disabled = true;
+ document.getElementById("securityLabelSecurityCategoriesListBox").disabled = true;
+ document.getElementById("securityLabelSecurityCategoriesButtonAdd").disabled = true;
+ document.getElementById("securityLabelSecurityCategoriesButtonRemove").disabled = true;
+ }
+}
--- /dev/null
+<?xml version="1.0"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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
+ * BT Global Services / Etat francais - Ministere de la Defense.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/msgCompSecurityLabelDialog.dtd">
+
+<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ id="securityLabelDialog"
+ buttons="accept,cancel"
+ defaultButton="accept"
+ title="&securityLabelDialog.name;"
+ onload="securityLabelDialogOnLoad();"
+ ondialogaccept="securityLabelDialogOnAccept();">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSecurityLabelDialog.js"/>
+
+ <dialogheader title="&securityLabelDialog.name;" />
+
+ <grid flex="1">
+
+ <columns>
+ <column />
+ <column flex="1"/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <label control="securityLabelSecurityPolicyIdentifierTextBox" value="&securityLabelDialog.securityPolicyIdentifier.name;" />
+ <menulist id="securityLabelSecurityPolicyIdentifierMenuList" oncommand="securityLabelDialogOnSecurityPolicyIdentifier();">
+ <menupopup />
+ </menulist>
+ </row>
+ <row align="center">
+ <label control="securityLabelPrivacyMarkTextBox" value="&securityLabelDialog.privacyMark.name;" />
+ <vbox>
+ <textbox id="securityLabelPrivacyMarkTextBox" />
+ <menulist id="securityLabelPrivacyMarkMenuList">
+ <menupopup />
+ </menulist>
+ </vbox>
+ </row>
+ <row align="center">
+ <label value="&securityLabelDialog.securityClassification.name;" />
+ <menulist id="securityLabelSecurityClassificationMenuList" oncommand="securityLabelDialogOnSecurityClassification();">
+ <menupopup />
+ </menulist>
+ </row>
+ <row flex="1">
+ <label value="&securityLabelDialog.securityCategories.name;" />
+ <vbox flex="1">
+ <listbox id="securityLabelSecurityCategoriesListBox" flex="1" />
+ <hbox>
+ <button id="securityLabelSecurityCategoriesButtonAdd" label="&securityLabelDialog.securityCategories.button.add.name;" oncommand="securityLabelDialogSecurityCategoriesOnButtonAdd();" />
+ <button id="securityLabelSecurityCategoriesButtonRemove" label="&securityLabelDialog.securityCategories.button.remove.name;" oncommand="securityLabelDialogSecurityCategoriesOnButtonRemove();" />
+ </hbox>
+ <separator />
+ </vbox>
+ </row>
+ </rows>
+
+ </grid>
+
+</dialog>
var gSignatureStatus = -1;
var gSignerCert = null;
var gEncryptionCert = null;
+var gSecurityPolicyIdentifier = null;
+var gSecurityClassification = -1;
+var gPrivacyMark = null;
+var gSecurityCategories = null;
+var gSecurityLabelConf = null;
addEventListener("load", smimeReadOnLoad, false);
top.controllers.appendController(SecurityController);
addEventListener("unload", smimeReadOnUnload, false);
+
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService)
+ .addObserver(securityLabelCreateDbObserver, "MsgCreateDBView", false);
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
}
function smimeReadOnUnload()
removeEventListener("unload", smimeReadOnUnload, false);
top.controllers.removeController(SecurityController);
+
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService)
+ .removeObserver(securityLabelCreateDbObserver, "MsgCreateDBView");
}
function showImapSignatureUnknown()
// int array starts with index 0, but that is used for window exit status
params.SetInt(1, gSignatureStatus);
params.SetInt(2, gEncryptionStatus);
+ params.SetInt(3, gSecurityClassification);
+
+ params.SetString(0, gSecurityPolicyIdentifier);
+ params.SetString(1, gPrivacyMark);
+ params.SetString(2, gSecurityCategories);
window.openDialog("chrome://messenger-smime/content/msgReadSecurityInfo.xul",
"", "chrome,resizable=1,modal=1,dialog=1", pkiParams);
}
}
};
+
+/* Add Security Label column */
+var securityLabelCreateDbObserver = {
+ observe: function(aMsgFolder, aTopic, aData) {
+ try {
+ if (gDBView != undefined && gDBView.addColumnHandler)
+ gDBView.addColumnHandler("securityLabelSecurityClassificationColumn", securityLabelSecurityClassificationColumnHandler);
+ } catch(e) {}
+ }
+}
+
+var securityLabelSecurityClassificationColumnHandler = {
+ getCellText: function(row, column) {
+ var key = gDBView.getKeyAt(row);
+ var hdr = gDBView.db.GetMsgHdrForKey(key);
+ var securityLabelSecurityPolicyIdentifier = hdr.getStringProperty("securityLabelSecurityPolicyIdentifier");
+ var securityLabelSecurityClassification = hdr.getStringProperty("securityLabelSecurityClassification");
+
+ if (securityLabelSecurityPolicyIdentifier != "" && securityLabelSecurityClassification != "" && securityLabelSecurityClassification != "-1")
+ return gSecurityLabelConf.getSecurityClassificationName(securityLabelSecurityPolicyIdentifier, securityLabelSecurityClassification);
+
+ return "";
+ },
+ getSortStringForRow: function(hdr) {
+ var securityLabelSecurityPolicyIdentifier = hdr.getStringProperty("securityLabelSecurityPolicyIdentifier");
+ var securityLabelSecurityClassification = hdr.getStringProperty("securityLabelSecurityClassification");
+
+ if (securityLabelSecurityPolicyIdentifier != "") {
+ if (securityLabelSecurityClassification != "" && securityLabelSecurityClassification != "-1") {
+ if (securityLabelSecurityClassification < 10)
+ return "00" + securityLabelSecurityClassification;
+ else if (securityLabelSecurityClassification < 100)
+ return "0" + securityLabelSecurityClassification;
+ else
+ return securityLabelSecurityClassification;
+ }
+ }
+ return "";
+ },
+ isString: function() {return true;},
+ getCellProperties: function(row, col, props){ },
+ getRowProperties: function(row, props){ },
+ getImageSrc: function(row, col) {return null;},
+ getSortLongForRow: function(hdr) {return 0;}
+}
var gSignatureStatus = -1;
var gEncryptionStatus = -1;
+var gSecurityPolicyIdentifier = null;
+var gSecurityClassification = -1;
+var gPrivacyMark = null;
+var gSecurityCategories = null;
+
+var gSecurityLabelConf = null;
var params = null;
gSignatureStatus = params.GetInt(1);
gEncryptionStatus = params.GetInt(2);
-
+ gSecurityClassification = params.GetInt(3);
+
+ gSecurityPolicyIdentifier = params.GetString(0);
+ gPrivacyMark = params.GetString(1);
+ gSecurityCategories = params.GetString(2);
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
+
var bundle = document.getElementById("bundle_smime_read_info");
if (bundle) {
document.getElementById("encCertIssuedBy").value = gEncryptionCert.issuerCommonName;
}
}
+
+ if (gSecurityPolicyIdentifier != "") {
+ document.getElementById("securityLabelBox").collapsed = false;
+ document.getElementById("securityLabelSecurityPolicyIdentifierValue").value = gSecurityLabelConf.getSecurityPolicyIdentifierName(gSecurityPolicyIdentifier);
+ if (gSecurityClassification != -1) {
+ document.getElementById("securityLabelSecurityClassificationValue").value = gSecurityLabelConf.getSecurityClassificationName(gSecurityPolicyIdentifier, gSecurityClassification);
+ document.getElementById("securityLabelSecurityClassificationRow").collapsed = false;
+ }
+ if (gPrivacyMark != "") {
+ document.getElementById("securityLabelPrivacyMarkValue").value = gPrivacyMark;
+ document.getElementById("securityLabelPrivacyMarkRow").collapsed = false;
+ }
+ if (gSecurityCategories != "") {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+
+ securityCategoriesArray = gSecurityCategories.split("|");
+ var listboxSize = securityCategoriesArray.length / 3;
+ if (listboxSize > 5) listboxSize = 5;
+ securityLabelSecurityCategoriesListBox.setAttribute("rows", listboxSize);
+
+ for (var i = 0; i < securityCategoriesArray.length; i += 3) {
+ var listitem = document.createElement("listitem");
+ listitem.setAttribute("label", gSecurityLabelConf.getSecurityCategoryName(gSecurityPolicyIdentifier, gSecurityClassification, securityCategoriesArray[i], securityCategoriesArray[i + 1], securityCategoriesArray[i + 2]));
+ securityLabelSecurityCategoriesListBox.appendChild(listitem);
+ }
+ document.getElementById("securityLabelSecurityCategoriesRow").collapsed = false;
+ }
+ }
}
function viewCertHelper(parent, cert) {
<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/msgReadSecurityInfo.dtd">
<dialog id="msgReadSecurityInfo" title="&status.label;"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="width: 40em;"
buttons="accept"
onload="onLoad();">
<script type="application/javascript" src="chrome://messenger-smime/content/msgReadSecurityInfo.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
<stringbundle id="bundle_smime_read_info" src="chrome://messenger-smime/locale/msgSecurityInfo.properties"/>
oncommand="viewEncryptionCert()"/>
</hbox>
</vbox>
+
+ <vbox id="securityLabelBox" collapsed="true">
+ <separator/>
+ <label id="securityLabel">&securityLabel.name;</label>
+ <grid id="securityLabelContent" flex="1">
+ <columns>
+ <column />
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label id="securityLabelSecurityPolicyIdentifierLabel" value="&securityLabel.securityPolicyIdentifier.name;"/>
+ <description id="securityLabelSecurityPolicyIdentifierValue"/>
+ </row>
+ <row align="center" id="securityLabelPrivacyMarkRow" collapsed="true">
+ <label id="securityLabelPrivacyMarkLabel" value="&securityLabel.privacyMark.name;"/>
+ <description id="securityLabelPrivacyMarkValue"/>
+ </row>
+ <row align="center" id="securityLabelSecurityClassificationRow" collapsed="true">
+ <label id="securityLabelSecurityClassificationLabel" value="&securityLabel.securityClassification.name;"/>
+ <description id="securityLabelSecurityClassificationValue"/>
+ </row>
+ <row align="center" id="securityLabelSecurityCategoriesRow" collapsed="true">
+ <label id="securityLabelSecurityCategoriesLabel" value="&securityLabel.securityCategories.name;"/>
+ <listbox id="securityLabelSecurityCategoriesListBox" flex="1"/>
+ </row>
+ </rows>
+ </grid>
+ </vbox>
+
</vbox>
</dialog>
--- /dev/null
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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
+ * BT Global Services / Etat francais - Ministere de la Defense.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+function securityLabelConf() {
+ this.readProfiles();
+}
+
+securityLabelConf.prototype = {
+
+ mSecurityPolicyList: [],
+ mSecurityClassificationList: [],
+ mPrivacyMarkList: [],
+ mSecurityCategoriesList: [],
+
+ stringBundle: Components.classes["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService)
+ .createBundle("chrome://messenger-smime/locale/msgSecurityLabel.properties"),
+
+ /**
+ * Read Security Label profiles in %profile%/securityLabel/ directory
+ */
+ readProfiles: function() {
+
+ /* Reset lists */
+ this.mSecurityPolicyList = [];
+ this.mSecurityClassificationList = [];
+ this.mPrivacyMarkList = [];
+ this.mSecurityCategoriesList = [];
+
+ /* Get profile directory */
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .createInstance(Components.interfaces.nsIProperties)
+ .get("ProfD", Components.interfaces.nsIFile);
+ dir.append("securityLabel");
+
+ /* Copy a default profile if needed */
+ if (!dir.exists()) {
+ dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+ var defaultFile = Components.classes["@mozilla.org/file/directory_service;1"]
+ .createInstance(Components.interfaces.nsIProperties)
+ .get("ProfDefNoLoc", Components.interfaces.nsIFile);
+ defaultFile.append("securityLabelPolicy-sample.xml");
+ if (defaultFile.exists())
+ defaultFile.copyTo(dir, "default.xml");
+ }
+
+ if (dir.isDirectory()) {
+ /* Read directory contents */
+ var entries = dir.directoryEntries;
+ var dirList = [];
+ while (entries.hasMoreElements()) {
+ var entry = entries.getNext();
+ entry.QueryInterface(Components.interfaces.nsIFile);
+ dirList.push(entry);
+ }
+
+ for (var i in dirList) {
+ try {
+ if (dirList[i].isFile() && dirList[i].leafName.match(/\.xml$/) != null) {
+
+ /* Read file */
+ var fiStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ var siStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Components.interfaces.nsIScriptableInputStream);
+ fiStream.init(dirList[i], 1, 0, false);
+ siStream.init(fiStream);
+ var data = new String();
+ data += siStream.read(-1);
+ siStream.close();
+ fiStream.close();
+ var uniConv = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
+ .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+ uniConv.charset = "UTF-8";
+ var fileContents = uniConv.ConvertToUnicode(data);
+
+ if (fileContents != false) {
+ /* Parse file contents */
+ var domParser = new DOMParser();
+ var dom = domParser.parseFromString(fileContents, "text/xml");
+ if (dom.documentElement.nodeName == "securityLabel") {
+ var policy = this.parseSecurityPolicyIdentifier(dom);
+ if (policy) {
+ this.mSecurityPolicyList[policy[0]] = policy[1];
+ this.mSecurityClassificationList[policy[0]] = this.parseSecurityClassification(dom);
+ this.mPrivacyMarkList[policy[0]] = this.parsePrivacyMark(dom);
+ this.mSecurityCategoriesList[policy[0]] = this.parseSecurityCategories(dom);
+ }
+ }
+ }
+ }
+ } catch (e) {
+ dump("S/MIME Security Label: error while reading " + dirList[i].leafName + "\n");
+ }
+ }
+ }
+ },
+
+ parseSecurityPolicyIdentifier: function(aDom) {
+ var nodeList = aDom.getElementsByTagName("securityPolicyIdentifier");
+ if (nodeList.length == 1) {
+ var node = nodeList.item(0);
+ var label = node.getAttribute("label").trim();
+ var value = node.getAttribute("value").trim();
+ if (label != "" && value != "")
+ return [label, value];
+ }
+
+ return false;
+ },
+
+ parseSecurityClassification: function(aDom) {
+ var list = [];
+
+ var nodeList1 = aDom.getElementsByTagName("securityClassification");
+ if (nodeList1.length == 1) {
+ var node = nodeList1.item(0);
+ var displayValue = node.getAttribute("valueDisplayed");
+ if (node.hasChildNodes()) {
+ var nodeList2 = node.childNodes;
+ for (var i = 0; i < nodeList2.length; i++) {
+ var itemNode = nodeList2.item(i);
+ if (itemNode.nodeName == "item") {
+ var label = itemNode.getAttribute("label").trim();
+ var value = itemNode.getAttribute("value").trim();
+ value = parseInt(value);
+ if (label != "" && value >= 0 && value <= 256) {
+ if (displayValue != "false" && displayValue != "0")
+ label += " (" + value + ")";
+ list[label] = value;
+ }
+ }
+ }
+ }
+ }
+
+ return list;
+ },
+
+ parsePrivacyMark: function(aDom) {
+ var list = [];
+
+ var nodeList1 = aDom.getElementsByTagName("privacyMark");
+ if (nodeList1.length == 1) {
+ var node = nodeList1.item(0);
+ var freeText = node.getAttribute("freeText");
+ if (freeText != "false" && freeText != "0")
+ list["freeText"] = true;
+ else
+ list["freeText"] = false;
+ if (node.hasChildNodes()) {
+ var nodeList2 = node.childNodes;
+ for (var i = 0; i < nodeList2.length; i++) {
+ var itemNode = nodeList2.item(i);
+ if (itemNode.nodeName == "item") {
+ var value = itemNode.getAttribute("value").trim();
+ list.push(value);
+ }
+ }
+ }
+ }
+
+ return list;
+ },
+
+ parseSecurityCategories: function(aDom) {
+ var list = [];
+
+ var nodeList1 = aDom.getElementsByTagName("securityCategories");
+ for (var k = 0; k < nodeList1.length; k++) {
+ var node = nodeList1.item(k);
+ var securityClassificationValue = "all";
+ if (node.hasAttribute("securityClassificationValue"))
+ securityClassificationValue = node.getAttribute("securityClassificationValue").trim();
+
+ if (node.hasChildNodes()) {
+ var nodeList2 = node.childNodes;
+ for (var i = 0; i < nodeList2.length; i++) {
+ var itemNode = nodeList2.item(i);
+ if (itemNode.nodeName == "item") {
+ var label = itemNode.getAttribute("label").trim();
+ var oid = itemNode.getAttribute("oid").replace(/\|/g, "").trim();
+ var type = itemNode.getAttribute("type").replace(/\|/g, "").trim();
+ var value = itemNode.getAttribute("value").replace(/\|/g, "").trim();
+ if (label != "" && oid != "" && type != "" && value != "") {
+ if (list[securityClassificationValue] == undefined)
+ list[securityClassificationValue] = new Array();
+ list[securityClassificationValue][label] = [oid, type, value];
+ }
+ }
+ }
+ }
+ }
+
+ return list;
+ },
+
+ /**
+ * Get Human-readable Security Policy Identifier
+ * @param aSecurityPolicyIdentifier String with Policy Identifier OID
+ * @return String with the name of the Policy Identifier
+ */
+ getSecurityPolicyIdentifierName: function(aSecurityPolicyIdentifier) {
+ if (aSecurityPolicyIdentifier == undefined || aSecurityPolicyIdentifier == "")
+ return "";
+
+ for (policyName in this.mSecurityPolicyList)
+ if (this.mSecurityPolicyList[policyName] == aSecurityPolicyIdentifier)
+ return policyName;
+
+ return this.stringBundle.GetStringFromName("unknownSecurityPolicyIdentifier") +" (" + aSecurityPolicyIdentifier + ")";
+ },
+
+ /**
+ * Get Human-readable Security Classification value
+ * @param aSecurityPolicyIdentifier String with Policy Identifier OID
+ * @param aSecurityClassification Classification value
+ * @return String with the name and value of the Security Classification
+ */
+ getSecurityClassificationName: function(aSecurityPolicyIdentifier, aSecurityClassification) {
+ if (aSecurityPolicyIdentifier == undefined || aSecurityClassification == undefined)
+ return "";
+
+ var securityPolicyIdentifierName = this.getSecurityPolicyIdentifierName(aSecurityPolicyIdentifier);
+
+ if (this.mSecurityClassificationList[securityPolicyIdentifierName] != undefined)
+ for (classificationName in this.mSecurityClassificationList[securityPolicyIdentifierName])
+ if (this.mSecurityClassificationList[securityPolicyIdentifierName][classificationName] == aSecurityClassification)
+ return classificationName;
+
+ return this.stringBundle.GetStringFromName("unknownSecurityClassification") + " (" + aSecurityClassification + ")";
+ },
+
+ /**
+ * Get Human-readable Security Category value
+ * @param aSecurityPolicyIdentifier String with Policy Identifier OID
+ * @param aSecurityClassification Classification value
+ * @param aSecurityCategoryOid Category OID
+ * @param aSecurityCategoryType Category type
+ * @param aSecurityCategoryValue Category value
+ * @return String with the name of the Security Category
+ */
+ getSecurityCategoryName: function(aSecurityPolicyIdentifier, aSecurityClassification, aSecurityCategoryOid, aSecurityCategoryType, aSecurityCategoryValue) {
+ if (aSecurityPolicyIdentifier == undefined || aSecurityClassification == undefined || aSecurityCategoryOid == undefined || aSecurityCategoryType == undefined || aSecurityCategoryValue == undefined)
+ return "";
+
+ var securityPolicyIdentifierName = this.getSecurityPolicyIdentifierName(aSecurityPolicyIdentifier);
+
+ if (this.mSecurityCategoriesList[securityPolicyIdentifierName] != undefined) {
+ for (var i = 0; i < 2; i++) {
+ var list;
+ /* Security Categories for all classifications */
+ if (i == 0)
+ list = this.mSecurityCategoriesList[securityPolicyIdentifierName]["all"];
+ /* Security Categories for selected classification */
+ if (i == 1)
+ list = this.mSecurityCategoriesList[securityPolicyIdentifierName][aSecurityClassification.toString()];
+
+ for (securityCategoryName in list)
+ if (list[securityCategoryName][0] == aSecurityCategoryOid && list[securityCategoryName][1] == aSecurityCategoryType && list[securityCategoryName][2] == aSecurityCategoryValue)
+ return securityCategoryName;
+ }
+ }
+
+ return this.stringBundle.GetStringFromName("unknownSecurityCategory") + " (" + aSecurityCategoryOid + " | " + aSecurityCategoryValue + ")";
+ }
+}
content/messenger-smime/msgReadSecurityInfo.js (content/msgReadSecurityInfo.js)
content/messenger-smime/certFetchingStatus.xul (content/certFetchingStatus.xul)
content/messenger-smime/certFetchingStatus.js (content/certFetchingStatus.js)
+ content/messenger-smime/msgSecurityLabel.js (content/msgSecurityLabel.js)
+ content/messenger-smime/msgCompSecurityLabelDialog.xul (content/msgCompSecurityLabelDialog.xul)
+ content/messenger-smime/msgCompSecurityLabelDialog.js (content/msgCompSecurityLabelDialog.js)
#endif
attribute PRUint32 SMIMEReceiptOriginatorContentTypeLen;
[noscript] attribute PRUint8Ptr SMIMEReceiptMsgSigDigest;
attribute PRUint32 SMIMEReceiptMsgSigDigestLen;
+
+ attribute AString securityPolicyIdentifier;
+ attribute PRInt32 securityClassification;
+ attribute AString privacyMark;
+ attribute AString securityCategories;
};
in PRUint32 aOriginatorContentTypeLen,
[const,array,size_is(aMsgSigDigestLen)] in PRUint8 aMsgSigDigest,
in PRUint32 aMsgSigDigestLen);
+ void securityLabelStatus(in AString aSecurityPolicyIdentifier,
+ in PRInt32 aSecurityClassification,
+ in AString aPrivacyMark,
+ in AString aSecurityCategories);
long maxWantedNesting(); // 1 == only info on outermost nesting level wanted
};
mSMIMEReceiptSignedContentIdentifierLen(0),
mSMIMEReceiptOriginatorSignatureValueLen(0),
mSMIMEReceiptOriginatorContentTypeLen(0),
-mSMIMEReceiptMsgSigDigestLen(0)
+mSMIMEReceiptMsgSigDigestLen(0),
+mSecurityClassification(-1)
{
}
return NS_OK;
}
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSecurityPolicyIdentifier(const nsAString &value)
+{
+ mSecurityPolicyIdentifier = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecurityPolicyIdentifier(nsAString &_retval)
+{
+ _retval = mSecurityPolicyIdentifier;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSecurityClassification(PRInt32 value)
+{
+ mSecurityClassification = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecurityClassification(PRInt32 *_retval)
+{
+ *_retval = mSecurityClassification;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetPrivacyMark(const nsAString &value)
+{
+ mPrivacyMark = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetPrivacyMark(nsAString &_retval)
+{
+ _retval = mPrivacyMark;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSecurityCategories(const nsAString &value)
+{
+ mSecurityCategories = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecurityCategories(nsAString &_retval)
+{
+ _retval = mSecurityCategories;
+ return NS_OK;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// Implementation of nsMsgComposeSecure
/////////////////////////////////////////////////////////////////////////////////////////
mCryptoEncoderData = 0;
mBuffer = 0;
mBufferedBytes = 0;
+ mHasSecuritylabel = PR_FALSE;
+ mSecurityClassification = -1;
}
nsMsgComposeSecure::~nsMsgComposeSecure()
return NS_OK;
}
+nsresult nsMsgComposeSecure::ExtractSecurityLabelState(nsIMsgCompFields * aComposeFields, PRBool * aHasSecuritylabel, nsAString& aSecurityPolicyIdentifier, PRInt32 * aSecurityClassification, nsAString& aPrivacyMark, nsAString& aSecurityCategories)
+{
+ if (!aComposeFields)
+ return NS_ERROR_FAILURE; // kick out...invalid args....
+
+ NS_ENSURE_ARG_POINTER(aHasSecuritylabel);
+ NS_ENSURE_ARG_POINTER(aSecurityClassification);
+
+ nsCOMPtr<nsISupports> securityInfo;
+ if (aComposeFields)
+ {
+ aComposeFields->GetSecurityInfo(getter_AddRefs(securityInfo));
+
+ if (securityInfo) // if we were given security comp fields, use them.....
+ {
+ nsCOMPtr<nsIMsgSMIMECompFields> smimeCompFields = do_QueryInterface(securityInfo);
+ if (smimeCompFields)
+ {
+ smimeCompFields->GetSecurityPolicyIdentifier(aSecurityPolicyIdentifier);
+ smimeCompFields->GetSecurityClassification(aSecurityClassification);
+ smimeCompFields->GetPrivacyMark(aPrivacyMark);
+ smimeCompFields->GetSecurityCategories(aSecurityCategories);
+ if (!aSecurityPolicyIdentifier.IsEmpty())
+ *aHasSecuritylabel = PR_TRUE;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
/* void beginCryptoEncapsulation (in nsOutputFileStream aStream, in boolean aEncrypt, in boolean aSign, in string aRecipeints, in boolean aIsDraft); */
NS_IMETHODIMP nsMsgComposeSecure::BeginCryptoEncapsulation(nsIOutputStream * aStream,
const char * aRecipients,
signMessage = PR_TRUE;
}
+ ExtractSecurityLabelState(aCompFields, &mHasSecuritylabel, mSecurityPolicyIdentifier, &mSecurityClassification, mPrivacyMark, mSecurityCategories);
+
mStream = aStream;
mIsDraft = aIsDraft;
if (mSMIMEReceiptRequest && !mSMIMEReceiptRequestReceiptsTo.IsEmpty())
cinfo->SetReceiptRequest(mSMIMEReceiptRequestSignedContentIdentifier, mSMIMEReceiptRequestReceiptsTo);
+ /* Store Security Label
+ */
+ if (mHasSecuritylabel)
+ rv = cinfo->SetSecurityLabel(NS_ConvertUTF16toUTF8(mSecurityPolicyIdentifier), mSecurityClassification, NS_ConvertUTF16toUTF8(mPrivacyMark), NS_ConvertUTF16toUTF8(mSecurityCategories));
+
/* Create the signature...
*/
PRUint32 mSMIMEReceiptOriginatorContentTypeLen;
PRUint8 *mSMIMEReceiptMsgSigDigest;
PRUint32 mSMIMEReceiptMsgSigDigestLen;
+ nsString mSecurityPolicyIdentifier;
+ PRInt32 mSecurityClassification;
+ nsString mPrivacyMark;
+ nsString mSecurityCategories;
};
typedef enum {
PRUint32 *aSMIMEReceiptOriginatorContentTypeLen,
PRUint8 **aSMIMEReceiptMsgSigDigest,
PRUint32 *aSMIMEReceiptMsgSigDigestLen);
+ nsresult ExtractSecurityLabelState(nsIMsgCompFields *aComposeFields, PRBool *aHasSecuritylabel, nsAString& aSecurityPolicyIdentifier, PRInt32 *aSecurityClassification, nsAString& aPrivacyMark, nsAString& aSecurityCategories);
mimeDeliveryCryptoState mCryptoState;
nsCOMPtr<nsIOutputStream> mStream;
PRUint32 mSMIMEReceiptOriginatorContentTypeLen;
PRUint8 *mSMIMEReceiptMsgSigDigest;
PRUint32 mSMIMEReceiptMsgSigDigestLen;
+
+ PRBool mHasSecuritylabel;
+ nsString mSecurityPolicyIdentifier;
+ PRInt32 mSecurityClassification;
+ nsString mPrivacyMark;
+ nsString mSecurityCategories;
};
#endif
if (msgSigDigest)
PR_Free(msgSigDigest);
}
+
+ if (signature_status == nsICMSMessageErrors::SUCCESS)
+ {
+ // Handle Security Label
+ PRBool hasSecurityLabel = PR_FALSE;
+ nsCString securityPolicyIdentifier;
+ PRInt32 securityClassification = -1;
+ nsCString privacyMark;
+ nsCString securityCategories;
+ msg->GetSecurityLabel(&hasSecurityLabel,
+ securityPolicyIdentifier,
+ &securityClassification,
+ privacyMark,
+ securityCategories);
+
+ if (hasSecurityLabel)
+ proxySink->SecurityLabelStatus(NS_ConvertUTF8toUTF16(securityPolicyIdentifier),
+ securityClassification,
+ NS_ConvertUTF8toUTF16(privacyMark),
+ NS_ConvertUTF8toUTF16(securityCategories));
+ }
}
return NS_OK;
out PRUint32 aOriginatorContentTypeLen,
[const,array,size_is(aMsgSigDigestLen)] out PRUint8 aMsgSigDigest,
out PRUint32 aMsgSigDigestLen);
+ void setSecurityLabel(in ACString aSecurityPolicyIdentifier,
+ in PRInt32 aSecurityClassification,
+ in ACString aPrivacyMark,
+ in ACString aSecurityCategories);
+ void getSecurityLabel(out boolean aHasSecurityLabel,
+ out ACString aSecurityPolicyIdentifier,
+ out PRInt32 aSecurityClassification,
+ out ACString aPrivacyMark,
+ out ACString aSecurityCategories);
void verifySignature();
void verifyDetachedSignature(in UnsignedCharPtr aDigestData, in unsigned long aDigestDataLen);
void CreateEncrypted(in nsIArray aRecipientCerts);
m_cmsMsg = nsnull;
mHasReceiptRequest = PR_FALSE;
mHasReceipt = PR_FALSE;
+ mHasSecurityLabel = PR_FALSE;
}
nsCMSMessage::nsCMSMessage(NSSCMSMessage *aCMSMsg)
return NS_OK;
}
+NS_IMETHODIMP nsCMSMessage::SetSecurityLabel(const nsACString& aSecurityPolicyIdentifier,
+ PRInt32 aSecurityClassification,
+ const nsACString& aPrivacyMark,
+ const nsACString& aSecurityCategories)
+{
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::SetSecurityLabel\n"));
+
+ mHasSecurityLabel = PR_TRUE;
+ mSecurityPolicyIdentifier = aSecurityPolicyIdentifier;
+ mSecurityClassification = aSecurityClassification;
+ mPrivacyMark = aPrivacyMark;
+ mSecurityCategories = aSecurityCategories;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetSecurityLabel(PRBool *aHasSecurityLabel,
+ nsACString& aSecurityPolicyIdentifier,
+ PRInt32 *aSecurityClassification,
+ nsACString& aPrivacyMark,
+ nsACString& aSecurityCategories)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSecurityLabel\n"));
+ NS_ENSURE_ARG_POINTER(aHasSecurityLabel);
+ NS_ENSURE_ARG_POINTER(aSecurityClassification);
+
+ NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+ NSS_CMSSignerInfo_GetSecurityLabel(si,
+ aHasSecurityLabel,
+ getter_Copies(aSecurityPolicyIdentifier),
+ aSecurityClassification,
+ getter_Copies(aPrivacyMark),
+ getter_Copies(aSecurityCategories));
+
+ return NS_OK;
+}
+
NS_IMETHODIMP nsCMSMessage::VerifyDetachedSignature(unsigned char* aDigestData, PRUint32 aDigestDataLen)
{
if (!aDigestData || !aDigestDataLen)
}
}
+ /* Add Security Label */
+ if (mHasSecurityLabel) {
+ if (NSS_CMSSignerInfo_AddSecurityLabel(signerinfo,
+ (char*)(mSecurityPolicyIdentifier.get()),
+ mSecurityClassification,
+ (char*)(mPrivacyMark.get()),
+ (char*)(mSecurityCategories.get())) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add security label\n"));
+ goto loser;
+ }
+ }
+
if (ecert) {
if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, ecert,
CERT_GetDefaultCertDB())
PRUint8 *mReceiptMsgSigDigest;
PRUint32 mReceiptMsgSigDigestLen;
+ PRBool mHasSecurityLabel;
+ nsCString mSecurityPolicyIdentifier;
+ PRInt32 mSecurityClassification;
+ nsCString mPrivacyMark;
+ nsCString mSecurityCategories;
+
NSSCMSSignerInfo* GetTopLevelSignerInfo();
nsresult CommonVerifySignature(unsigned char* aDigestData, PRUint32 aDigestDataLen);
extern PRBool
NSS_CMSSignerInfo_HasReceipt(NSSCMSSignerInfo *signerinfo);
+/*
+ * NSS_CMSSignerInfo_AddSecurityLabel - add a SecurityLabel attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ char *aSecurityPolicyIdentifier,
+ PRInt32 aSecurityClassification,
+ char *aPrivacyMark,
+ char *aSecurityCategories);
+
+/*
+ * NSS_CMSSignerInfo_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+extern SECStatus
+NSS_CMSSignerInfo_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ PRInt32 *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories);
+
/************************************************************************
* cmsenvdata.c - CMS envelopedData methods
************************************************************************/
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
- * ESS Signed Receipts: Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
- * ESS Signed Receipts: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * ESS Signed Receipts/Security Labels: Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
+ * ESS Signed Receipts/Security Labels: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
return PR_TRUE;
}
+
+/*
+ * NSS_CMSSignerInfo_AddSecurityLabel - add a SecurityLabel attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSecurityLabel(NSSCMSSignerInfo *signerinfo,
+ char *securityPolicyIdentifier,
+ PRInt32 securityClassification,
+ char *privacyMark,
+ char *securityCategories)
+{
+ NSSCMSAttribute *attr;
+ SECItem *securityLabel = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ securityLabel = SECITEM_AllocItem(poolp, NULL, 0);
+ if (securityLabel == NULL)
+ goto loser;
+
+ /* create new SecurityLabel attribute */
+ if (NSS_SMIMEUtil_CreateSecurityLabel(poolp, securityLabel, securityPolicyIdentifier, securityClassification, privacyMark, securityCategories) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_SECURITY_LABEL, securityLabel, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+SECStatus
+NSS_CMSSignerInfo_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ PRInt32 *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories)
+{
+ return NSS_SMIMEUtil_GetSecurityLabel(aSignerinfo,
+ aHasSecurityLabel,
+ aSecurityPolicyIdentifier,
+ aSecurityClassification,
+ aPrivacyMark,
+ aSecurityCategories);
+}
typedef struct NSSCMSReceiptRequestGeneralNamesStr NSSCMSReceiptRequestGeneralNames;
typedef struct NSSCMSReceiptStr NSSCMSReceipt;
+typedef struct NSSCMSSecurityLabelStr NSSCMSSecurityLabel;
+typedef struct NSSCMSSecurityLabelElementStr NSSCMSSecurityLabelElement;
+typedef struct NSSCMSSecurityLabelSecurityCategoryStr NSSCMSSecurityLabelSecurityCategory;
+
/*
* Type of function passed to NSSCMSDecode or NSSCMSDecoderStart.
* If specified, this is where the content bytes (only) will be "sent"
SECItem originatorSignatureValue;
};
+/* ESS Security Label */
+typedef enum {
+ NSSCMSSecurityLabelElement_securityPolicyIdentifier = 0,
+ NSSCMSSecurityLabelElement_securityClassification = 1,
+ NSSCMSSecurityLabelElement_privacyMarkPrintableString = 2,
+ NSSCMSSecurityLabelElement_privacyMarkUTF8 = 3,
+ NSSCMSSecurityLabelElement_securityCategories = 4
+} NSSCMSSecurityLabelElementSelector;
+
+struct NSSCMSSecurityLabelElementStr {
+ NSSCMSSecurityLabelElementSelector selector;
+ union {
+ SECItem securityPolicyIdentifier;
+ SECItem securityClassification;
+ SECItem privacyMarkPrintableString;
+ SECItem privacyMarkUTF8;
+ NSSCMSSecurityLabelSecurityCategory **securityCategories;
+ } id;
+};
+
+struct NSSCMSSecurityLabelStr {
+ NSSCMSSecurityLabelElement **element;
+};
+
+struct NSSCMSSecurityLabelSecurityCategoryStr {
+ SECItem securityCategoryIdentifier;
+ SECItem securityCategoryValue;
+};
+
+enum {
+ SECURITY_CATEGORY_VALUE_TYPE_UNKNOWN = 0,
+ SECURITY_CATEGORY_VALUE_TYPE_UTF8 = 1,
+ SECURITY_CATEGORY_VALUE_TYPE_INTEGER = 2
+};
+
/* =============================================================================
* ENVELOPED DATA
*/
NSS_CMSSignerInfo_HasReceipt;
NSS_SMIMEUtil_CreateReceipt;
NSS_SMIMEUtil_GetReceipt;
+NSS_CMSSignerInfo_AddSecurityLabel;
+NSS_CMSSignerInfo_GetSecurityLabel;
;+ local:
;+ *;
;+};
PRUint8 **aOriginatorContentType,
PRUint32 *aOriginatorContentTypeLen);
+/*
+ * NSS_SMIMEUtil_CreateSecurityLabel - create S/MIME SecurityLabel attr value
+ */
+extern SECStatus NSS_SMIMEUtil_CreateSecurityLabel(PLArenaPool *aPoolp,
+ SECItem *aDest,
+ char *aSecurityPolicyIdentifier,
+ PRInt32 aSecurityClassification,
+ char *aPrivacyMark,
+ char *aSecurityCategories);
+
+/*
+ * NSS_SMIMEUtil_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+extern SECStatus NSS_SMIMEUtil_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ PRInt32 *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories);
+
/************************************************************************/
SEC_END_PROTOS
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
- * ESS Signed Receipts: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * ESS Signed Receipts/Security Labels: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * ESS Security Labels: Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
#include "nss.h"
#include "cmslocal.h"
#include "sechash.h"
+#include "prprf.h"
SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
{ 0 }
};
+/*
+ * ESS Security Label
+ *
+ * Implemented as a SET OF CHOICE because SET decoding is not implemented in NSS
+ */
+static const SEC_ASN1Template securityCategoryIdentifierTemplate[] = {
+ { SEC_ASN1_OBJECT_ID, 0, NULL },
+};
+
+static const SEC_ASN1Template securityCategoryValueTemplate[] = {
+ { SEC_ASN1_ANY, 0, NULL },
+};
+
+static const SEC_ASN1Template securityCategoryValueUTF8Template[] = {
+ { SEC_ASN1_UTF8_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) },
+};
+
+static const SEC_ASN1Template securityCategoryValueIntegerTemplate[] = {
+ { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) },
+};
+
+static const SEC_ASN1Template NSSCMSSecurityLabelSecurityCategoryTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSCMSSecurityLabelSecurityCategory) },
+ { SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(NSSCMSSecurityLabelSecurityCategory, securityCategoryIdentifier), securityCategoryIdentifierTemplate },
+ { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | 1, offsetof(NSSCMSSecurityLabelSecurityCategory, securityCategoryValue), securityCategoryValueTemplate },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSSecurityLabelElementTemplate[] = {
+ { SEC_ASN1_CHOICE, offsetof(NSSCMSSecurityLabelElement, selector), NULL, sizeof(NSSCMSSecurityLabelElement) },
+ { SEC_ASN1_OBJECT_ID, offsetof(NSSCMSSecurityLabelElement, id.securityPolicyIdentifier), NULL, NSSCMSSecurityLabelElement_securityPolicyIdentifier },
+ { SEC_ASN1_INTEGER, offsetof(NSSCMSSecurityLabelElement, id.securityClassification), NULL, NSSCMSSecurityLabelElement_securityClassification },
+ { SEC_ASN1_PRINTABLE_STRING, offsetof(NSSCMSSecurityLabelElement, id.privacyMarkPrintableString), NULL, NSSCMSSecurityLabelElement_privacyMarkPrintableString },
+ { SEC_ASN1_UTF8_STRING, offsetof(NSSCMSSecurityLabelElement, id.privacyMarkUTF8), NULL, NSSCMSSecurityLabelElement_privacyMarkUTF8 },
+ { SEC_ASN1_SET_OF, offsetof(NSSCMSSecurityLabelElement, id.securityCategories), NSSCMSSecurityLabelSecurityCategoryTemplate, NSSCMSSecurityLabelElement_securityCategories },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSSecurityLabelTemplate[] = {
+ { SEC_ASN1_SET_OF, 0, NSSCMSSecurityLabelElementTemplate },
+};
+
/* smime_cipher_map - map of SMIME symmetric "ciphers" to algtag & parameters */
typedef struct {
unsigned long cipher;
PORT_ArenaUnmark(aPoolp, mark);
return rv;
}
+/**
+ * DER-encode a dot-separated string of integers
+ * @param in data Dot-separated string of integers
+ * @param in len Length of data
+ * @param out output Pointer to a DER-encoded string which will be allocated - caller will have to PORT_Free() it
+ * @param out outputLen Length of returned output buffer
+ * @return *output or NULL if encoding failed
+ */
+void *
+NSS_SMIMEUtil_EncodeOid(const char *data, const unsigned int len, unsigned char **output, unsigned int *outputLen)
+{
+ unsigned int i;
+ unsigned int k;
+ unsigned int dotCount;
+ unsigned int *oid;
+ unsigned int n;
+ unsigned int itemCount;
+ unsigned char tempDER[5];
+
+ *outputLen = 0;
+
+ /* Count number of dot in the string */
+ dotCount = 0;
+ for (i = 0; i < len; i++)
+ if (data[i] == '.')
+ dotCount++;
+
+ if (dotCount == 0)
+ return NULL;
+
+ /* Allocate OID array of integers */
+ oid = PORT_Alloc((dotCount + 1) * sizeof(unsigned int));
+ if (oid == NULL)
+ return NULL;
+
+ /* Convert decimal, dot-separated OID string to an array of integers */
+ n = 0;
+ itemCount = 0;
+ for (i = 0; i <= len; i++) { /* Analyze all characters + 1 loop at the end */
+ if (i == len || data[i] == '.') {
+ /* Store number */
+ oid[itemCount++] = n;
+ n = 0;
+ } else if (data[i] >= '0' && data[i] <= '9') {
+ /* Add digit to number */
+ n *= 10;
+ n += data[i] - '0';
+ } else {
+ /* Unknown character */
+ PORT_Free(oid);
+ return NULL;
+ }
+ }
+
+ /* Error if less than 2 items */
+ if (itemCount < 2) {
+ PORT_Free(oid);
+ return NULL;
+ }
+
+ /* Check range of first 2 items */
+ if ((oid[0] < 2 && oid[1] > 39) ||
+ (oid[0] == 2 && oid[1] > 47) ||
+ (oid[0] > 2)) {
+ PORT_Free(oid);
+ return NULL;
+ }
+
+ /* Allocate DER-encoded buffer: 5 bytes by item maximum */
+ *output = PORT_Alloc((itemCount * 5) * sizeof(unsigned char));
+ if (*output == NULL) {
+ PORT_Free(oid);
+ return NULL;
+ }
+
+ /* DER encode the array of integers */
+ /* First byte contains first and second items */
+ (*output)[(*outputLen)++] = oid[0] * 40 + oid[1];
+ /* Next bytes */
+ for (i = 2; i < itemCount; i++) {
+ n = 0;
+ do {
+ if (n == 5) {/* 5 bytes by item maximum */
+ PORT_Free(oid);
+ return NULL;
+ }
+ tempDER[n] = oid[i] & 0x7F;
+ if (n != 0)
+ tempDER[n] |= 0x80;
+ oid[i] >>= 7;
+ n++;
+ } while (oid[i] > 0);
+ for (k = 0; k < n; k++)
+ (*output)[(*outputLen)++] = tempDER[n - 1 - k];
+ }
+
+ PORT_Free(oid);
+
+ return *output;
+}
+
+/**
+ * Decode a DER encoded OID to a dot-separated string of integers
+ * @param in data DER encoded buffer
+ * @param in len Length of data
+ * @param out output Pointer to a string which will be allocated - caller will have to PORT_Free() it
+ * @return SECSuccess or SECFailure if decoding failed
+ */
+SECStatus
+NSS_SMIMEUtil_DecodeOid(const unsigned char *data, const unsigned int len, char **output)
+{
+ unsigned int itemCount;
+ unsigned int outputCount;
+ unsigned int i;
+ unsigned int n;
+ unsigned int *oid;
+ int ret;
+
+ if (len == 0 || data[0] >= 128)
+ return SECFailure;
+
+ /* Convert DER encoded OID to an array of integers (number of values is less than 'len + 1') */
+ oid = PORT_Alloc((len + 1) * sizeof(unsigned int));
+ if (oid == NULL)
+ return SECFailure;
+
+ itemCount = 0;
+ /* Range of second item is 0-39 if first item is 0 or 1
+ * and 0-47 if first item is 2 */
+ if (data[0] < 120) {
+ oid[itemCount++] = data[0] / 40;
+ oid[itemCount++] = data[0] % 40;
+ } else {
+ oid[itemCount++] = 2;
+ oid[itemCount++] = data[0] - (2 * 40);
+ }
+
+ n = 0;
+ for (i = 1; i < len; i++) {
+ n = n * 128 + (data[i] & 0x7F);
+ if ((data[i] & 0x80) != 0x80) {
+ oid[itemCount++] = n;
+ n = 0;
+ }
+ }
+
+ /* Allocate output string: max 10 characters by number + '.' */
+ /* TODO: find a better way to compute max size of integers */
+ *output = PORT_Alloc(itemCount * (10 + 1) * sizeof(char));
+ if (*output == NULL) {
+ PORT_Free(oid);
+ return SECFailure;
+ }
+
+ outputCount = 0;
+ for (i = 0; i < itemCount; i++) {
+ if (i != 0) {
+ (*output)[outputCount] = '.';
+ outputCount++;
+ }
+ ret = PR_snprintf(&((*output)[outputCount]), 11, "%lu", oid[i]);
+ if (ret > 0 && ret < 11)
+ outputCount += ret;
+ else {
+ PORT_Free(oid);
+ return SECFailure;
+ }
+ }
+ (*output)[outputCount] = '\0';
+
+ PORT_Free(oid);
+
+ return SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_CreateSecurityLabel - create S/MIME SecurityLabel attr value
+ */
+SECStatus
+NSS_SMIMEUtil_CreateSecurityLabel(PLArenaPool *aPoolp,
+ SECItem *aDest,
+ char *aSecurityPolicyIdentifier,
+ PRInt32 aSecurityClassification,
+ char *aPrivacyMark,
+ char *aSecurityCategories)
+{
+ NSSCMSSecurityLabelElement **securityLabel;
+ SECItem *dummy = NULL;
+ unsigned int len;
+ unsigned int i;
+ unsigned int k;
+ unsigned int separatorCount;
+ unsigned int categoryCount;
+ unsigned int startPosition;
+ unsigned int fieldLen;
+ const char securityCategoriesSeparator = '|';
+ unsigned int securityLabelItem;
+ SECItem tempSecurityCategoryValue;
+ unsigned int tempSecurityCategoryValueType;
+ unsigned long tempSecurityCategoryValueInteger;
+ char valueChar;
+
+ /* Array of 4 elements max + 1 NULL at the end = 5 elements */
+ securityLabel = PORT_Alloc(5 * sizeof(NSSCMSSecurityLabelElement*));
+ for (i = 0; i < 5; i++)
+ securityLabel[i] = NULL;
+
+ securityLabelItem = 0;
+
+ /*
+ * securityPolicyIdentifier
+ */
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_securityPolicyIdentifier;
+ if (NSS_SMIMEUtil_EncodeOid(aSecurityPolicyIdentifier, PORT_Strlen(aSecurityPolicyIdentifier), &(securityLabel[securityLabelItem]->id.securityPolicyIdentifier.data), &(securityLabel[securityLabelItem]->id.securityPolicyIdentifier.len)) == NULL)
+ goto loser;
+ securityLabelItem++;
+
+ /*
+ * securityClassification
+ */
+ if (aSecurityClassification >= 0 && aSecurityClassification <= 256) {
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_securityClassification;
+
+ if (SEC_ASN1EncodeUnsignedInteger(aPoolp, &(securityLabel[securityLabelItem]->id.securityClassification), (PRUint32)aSecurityClassification) == NULL)
+ goto loser;
+ securityLabelItem++;
+ }
+
+ /*
+ * privacyMark
+ */
+ len = PORT_Strlen(aPrivacyMark);
+ if (len > 0) {
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_privacyMarkUTF8;
+
+ securityLabel[securityLabelItem]->id.privacyMarkUTF8.len = 0;
+ securityLabel[securityLabelItem]->id.privacyMarkUTF8.data = PORT_Alloc(len * sizeof(unsigned char));
+ if (securityLabel[securityLabelItem]->id.privacyMarkUTF8.data == NULL)
+ goto loser;
+ PORT_Memcpy(securityLabel[securityLabelItem]->id.privacyMarkUTF8.data, aPrivacyMark, len);
+ securityLabel[securityLabelItem]->id.privacyMarkUTF8.len = len;
+ securityLabelItem++;
+ }
+
+ /*
+ * securityCategories
+ * format: cat1_OID|cat1_type|cat1_value|cat2_OID|cat2_type|cat2_value|cat3_OID|cat3_type|cat3_value
+ *
+ * catX_type: 1 (UTF-8)
+ * 2 (integer)
+ */
+ len = PORT_Strlen(aSecurityCategories);
+ if (len > 0) {
+ separatorCount = 0;
+
+ /* Count number of separator character */
+ for (i = 0; i < len; i++)
+ if (aSecurityCategories[i] == securityCategoriesSeparator)
+ separatorCount++;
+
+ /* Separator count must be correct */
+ if (separatorCount < 2 || (((separatorCount - 2 ) % 3) != 0))
+ goto loser;
+ categoryCount = ((separatorCount - 2 ) / 3) + 1;
+
+ /* Create object */
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_securityCategories;
+
+ /* Allocate categoryCount + 1 NULL securityCategories */
+ securityLabel[securityLabelItem]->id.securityCategories = PORT_Alloc((categoryCount + 1) * sizeof(NSSCMSSecurityLabelSecurityCategory*));
+ if (securityLabel[securityLabelItem]->id.securityCategories == NULL)
+ goto loser;
+ for (i = 0; i < categoryCount; i++) {
+ securityLabel[securityLabelItem]->id.securityCategories[i] = PORT_Alloc(sizeof(NSSCMSSecurityLabelSecurityCategory));
+ if (securityLabel[securityLabelItem]->id.securityCategories[i] == NULL)
+ goto loser;
+ securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryIdentifier.len = 0;
+ securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryValue.len = 0;
+ }
+ /* Last one is NULL */
+ securityLabel[securityLabelItem]->id.securityCategories[categoryCount] = NULL;
+
+ startPosition = 0;
+
+ for (i = 0; i < categoryCount; i++) {
+ /* Search and copy securityCategoryIdentifier */
+ fieldLen = 0;
+ for (k = startPosition; k < len; k++) {
+ if (aSecurityCategories[k] == securityCategoriesSeparator) {
+ fieldLen = k - startPosition;
+ break;
+ }
+ }
+
+ if (fieldLen > 0) {
+ if (NSS_SMIMEUtil_EncodeOid(aSecurityCategories + startPosition, fieldLen, &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryIdentifier.data), &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryIdentifier.len)) == NULL)
+ goto loser;
+ startPosition += fieldLen + 1;
+ } else
+ goto loser;
+
+ /* Search type */
+ fieldLen = 0;
+ for (k = startPosition; k < len; k++) {
+ if (aSecurityCategories[k] == securityCategoriesSeparator) {
+ fieldLen = k - startPosition;
+ break;
+ }
+ }
+
+ if (fieldLen == 1) {
+ tempSecurityCategoryValueType = 0;
+ if (aSecurityCategories[startPosition] >= '0' && aSecurityCategories[startPosition] <= '9')
+ tempSecurityCategoryValueType = aSecurityCategories[startPosition] - '0';
+
+ startPosition += fieldLen + 1;
+ } else
+ goto loser;
+
+ /* Search and copy securityCategoryValue */
+ fieldLen = 0;
+ for (k = startPosition; k < len; k++) {
+ if (aSecurityCategories[k] == securityCategoriesSeparator) {
+ fieldLen = k - startPosition;
+ break;
+ }
+ if (k == len - 1) { /* Last character */
+ fieldLen = k - startPosition + 1;
+ break;
+ }
+ }
+
+ if (fieldLen > 0) {
+ switch (tempSecurityCategoryValueType) {
+ case SECURITY_CATEGORY_VALUE_TYPE_UTF8:
+ tempSecurityCategoryValue.data = (unsigned char*)aSecurityCategories + startPosition;
+ tempSecurityCategoryValue.len = fieldLen;
+ if (SEC_ASN1EncodeItem(aPoolp, &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryValue), &tempSecurityCategoryValue, securityCategoryValueUTF8Template) == NULL)
+ goto loser;
+ break;
+ case SECURITY_CATEGORY_VALUE_TYPE_INTEGER:
+ if (fieldLen > 10)
+ goto loser;
+ /* TODO: find a better way to compute max size of integers */
+
+ tempSecurityCategoryValueInteger = 0;
+ for (k = 0; k < fieldLen; k++) {
+ valueChar = aSecurityCategories[startPosition + k];
+ if (valueChar >= '0' && valueChar <= '9') {
+ tempSecurityCategoryValueInteger *= 10;
+ tempSecurityCategoryValueInteger += valueChar - '0';
+ } else
+ goto loser;
+ }
+
+ if (SEC_ASN1EncodeUnsignedInteger(aPoolp, &tempSecurityCategoryValue, tempSecurityCategoryValueInteger) == NULL)
+ goto loser;
+
+ if (SEC_ASN1EncodeItem(aPoolp, &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryValue), &tempSecurityCategoryValue, securityCategoryValueIntegerTemplate) == NULL)
+ goto loser;
+ break;
+ default:
+ goto loser;
+ break;
+ }
+
+ startPosition += fieldLen + 1;
+ } else
+ goto loser;
+
+ }
+ securityLabelItem++;
+ }
+
+ /* Encode Security Label */
+ dummy = SEC_ASN1EncodeItem(aPoolp, aDest, &securityLabel, NSSCMSSecurityLabelTemplate);
+
+loser:
+ for (i = 0; securityLabel[i] != NULL; i++) {
+ switch (securityLabel[i]->selector) {
+ case NSSCMSSecurityLabelElement_securityPolicyIdentifier:
+ if (securityLabel[i]->id.securityPolicyIdentifier.len > 0)
+ PORT_Free(securityLabel[i]->id.securityPolicyIdentifier.data);
+ break;
+ case NSSCMSSecurityLabelElement_securityClassification:
+ break;
+ case NSSCMSSecurityLabelElement_privacyMarkPrintableString:
+ if (securityLabel[i]->id.privacyMarkPrintableString.len > 0)
+ PORT_Free(securityLabel[i]->id.privacyMarkPrintableString.data);
+ break;
+ case NSSCMSSecurityLabelElement_privacyMarkUTF8:
+ if (securityLabel[i]->id.privacyMarkUTF8.len > 0)
+ PORT_Free(securityLabel[i]->id.privacyMarkUTF8.data);
+ break;
+ case NSSCMSSecurityLabelElement_securityCategories:
+ if (securityLabel[i]->id.securityCategories != NULL) {
+ for (k = 0; securityLabel[i]->id.securityCategories[k] != NULL; k++) {
+ if (securityLabel[i]->id.securityCategories[k]->securityCategoryIdentifier.len > 0)
+ PORT_Free(securityLabel[i]->id.securityCategories[k]->securityCategoryIdentifier.data);
+ PORT_Free(securityLabel[i]->id.securityCategories[k]);
+ }
+ PORT_Free(securityLabel[i]->id.securityCategories);
+ }
+ break;
+ }
+
+ PORT_Free(securityLabel[i]);
+ }
+ PORT_Free(securityLabel);
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+SECStatus
+NSS_SMIMEUtil_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ PRInt32 *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories)
+{
+ NSSCMSAttribute *attr;
+ SECStatus rv = SECSuccess;
+
+ PLArenaPool *poolp;
+ void *mark;
+
+ NSSCMSSecurityLabel securityLabel;
+ NSSCMSSecurityLabelElement *securityLabelElement;
+ unsigned int elementId;
+ unsigned int len;
+ char *tempBuffer;
+ const char securityCategoriesSeparator = '|';
+ unsigned int i;
+ char *oid;
+ char *tempSecurityCategories;
+ unsigned long tempLongValue;
+ SECItem tempSECItemValue;
+ int ret;
+
+ /* We have to check uniqueness of each element as we use a SET_OF CHOICE instead of a SET */
+ PRBool securityPolicyIdentifierFound = PR_FALSE;
+ PRBool securityClassificationFound = PR_FALSE;
+ PRBool privacyMarkFound = PR_FALSE;
+ PRBool securityCategoriesFound = PR_FALSE;
+
+ poolp = aSignerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(aSignerinfo->authAttr, SEC_OID_SMIME_SECURITY_LABEL, PR_TRUE);
+
+ if (attr == NULL || attr->values == NULL || attr->values[0] == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ if ((rv = SEC_ASN1DecodeItem(poolp, &securityLabel, NSSCMSSecurityLabelTemplate, attr->values[0])) != SECSuccess)
+ goto loser;
+
+ for (elementId = 0; securityLabel.element[elementId] != NULL; elementId++) {
+
+ securityLabelElement = securityLabel.element[elementId];
+
+ switch (securityLabelElement->selector) {
+
+ case NSSCMSSecurityLabelElement_securityPolicyIdentifier:
+ /*
+ * securityPolicyIdentifier
+ */
+ if (securityPolicyIdentifierFound) {
+ rv = SECFailure;
+ break;
+ }
+ securityPolicyIdentifierFound = PR_TRUE;
+
+ if (securityLabelElement->id.securityPolicyIdentifier.len > 0 && securityLabelElement->id.securityPolicyIdentifier.data[0] < 128) {
+ tempBuffer = NULL;
+
+ if ((rv = NSS_SMIMEUtil_DecodeOid(securityLabelElement->id.securityPolicyIdentifier.data, securityLabelElement->id.securityPolicyIdentifier.len, &tempBuffer)) != SECSuccess)
+ break;
+
+ if (tempBuffer != NULL) {
+ len = PORT_Strlen(tempBuffer);
+ *aSecurityPolicyIdentifier = PORT_Alloc((len + 1) * sizeof(char));
+ PORT_Memcpy(*aSecurityPolicyIdentifier, tempBuffer, len + 1);
+ PORT_Free(tempBuffer);
+
+ *aHasSecurityLabel = PR_TRUE;
+ }
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_securityClassification:
+ /*
+ * securityClassification
+ */
+ if (securityClassificationFound) {
+ rv = SECFailure;
+ break;
+ }
+ securityClassificationFound = PR_TRUE;
+
+ if ((rv = SEC_ASN1DecodeInteger(&(securityLabelElement->id.securityClassification), &tempLongValue)) != SECSuccess)
+ break;
+
+ if (tempLongValue <= 256)
+ *aSecurityClassification = tempLongValue;
+ else {
+ rv = SECFailure;
+ break;
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_privacyMarkPrintableString:
+ /*
+ * privacyMark (PrintableString)
+ */
+ if (privacyMarkFound) {
+ rv = SECFailure;
+ break;
+ }
+ privacyMarkFound = PR_TRUE;
+
+ len = securityLabelElement->id.privacyMarkPrintableString.len;
+
+ if (len > 0) {
+ tempBuffer = PORT_Alloc((len + 1) * sizeof(char));
+ if (tempBuffer == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ PORT_Memcpy(tempBuffer, securityLabelElement->id.privacyMarkPrintableString.data, len);
+ tempBuffer[len] = '\0';
+
+ *aPrivacyMark = tempBuffer;
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_privacyMarkUTF8:
+ /*
+ * privacyMark (UTF8)
+ */
+ if (privacyMarkFound) {
+ rv = SECFailure;
+ break;
+ }
+ privacyMarkFound = PR_TRUE;
+
+ len = securityLabelElement->id.privacyMarkUTF8.len;
+
+ if (len > 0) {
+ tempBuffer = PORT_Alloc((len + 1) * sizeof(char));
+ if (tempBuffer == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ PORT_Memcpy(tempBuffer, securityLabelElement->id.privacyMarkUTF8.data, len);
+ tempBuffer[len] = '\0';
+
+ *aPrivacyMark = tempBuffer;
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_securityCategories:
+ /*
+ * securityCategories
+ */
+ if (securityCategoriesFound) {
+ rv = SECFailure;
+ break;
+ }
+ securityCategoriesFound = PR_TRUE;
+
+ if (securityLabelElement->id.securityCategories == NULL) {
+ rv = SECFailure;
+ break;
+ }
+
+ /* Compute size of output string buffer */
+ len = 0;
+ for (i = 0; securityLabelElement->id.securityCategories[i] != NULL; i++) {
+ oid = NULL;
+ if ((rv = NSS_SMIMEUtil_DecodeOid(securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.data, securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.len, &oid)) != SECSuccess)
+ break;
+
+ if (oid != NULL) {
+ /* Add size of securityCategoryIdentifier */
+ len += PORT_Strlen(oid);
+ PORT_Free(oid);
+
+ /* Add size of type field */
+ len += 1;
+
+ /* Add size of securityCategoryValue */
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.len > 2) {
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.data[0] == SEC_ASN1_INTEGER) /* Integer */
+ len += 10;
+ /* 10 characters max for an integer */
+ /* TODO: find a better way to compute max size of integers */
+ else /* UTF-8 and other types */
+ len += securityLabelElement->id.securityCategories[i]->securityCategoryValue.len;
+ }
+
+ /* Add size of 3 separators */
+ len += 3;
+ }
+ }
+
+ if (len > 0) {
+ /* Create buffer */
+ tempSecurityCategories = PORT_Alloc(len * sizeof(char));
+ if (tempSecurityCategories == NULL) {
+ rv = SECFailure;
+ break;
+ }
+
+ /* Fill buffer */
+ len = 0;
+ for (i = 0; securityLabelElement->id.securityCategories[i] != NULL; i++) {
+ oid = NULL;
+ if ((rv = NSS_SMIMEUtil_DecodeOid(securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.data, securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.len, &oid)) != SECSuccess)
+ break;
+
+ if (oid != NULL) {
+ /* Add securityCategoryIdentifier OID */
+ PORT_Memcpy(tempSecurityCategories + len, oid, PORT_Strlen(oid));
+ len += PORT_Strlen(oid);
+ PORT_Free(oid);
+
+ /* Add separator */
+ tempSecurityCategories[len++] = securityCategoriesSeparator;
+
+ /* Add type field */
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.len > 0) {
+ switch (securityLabelElement->id.securityCategories[i]->securityCategoryValue.data[0]) {
+ case SEC_ASN1_UTF8_STRING: /* UTF-8 */
+ tempSecurityCategories[len++] = '0' + SECURITY_CATEGORY_VALUE_TYPE_UTF8;
+ break;
+ case SEC_ASN1_INTEGER: /* Integer */
+ tempSecurityCategories[len++] = '0' + SECURITY_CATEGORY_VALUE_TYPE_INTEGER;
+ break;
+ default: /* Other type */
+ tempSecurityCategories[len++] = '0' + SECURITY_CATEGORY_VALUE_TYPE_UNKNOWN;
+ break;
+ }
+ }
+
+ /* Add separator */
+ tempSecurityCategories[len++] = securityCategoriesSeparator;
+
+ /* Add securityCategoryValue */
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.len > 2) {
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.data[0] == SEC_ASN1_INTEGER) { /* Integer: decode */
+
+ if ((rv = SEC_ASN1DecodeItem(poolp, &tempSECItemValue, securityCategoryValueIntegerTemplate, &(securityLabelElement->id.securityCategories[i]->securityCategoryValue))) != SECSuccess)
+ break;
+
+ if ((rv = SEC_ASN1DecodeInteger(&tempSECItemValue, &tempLongValue)) != SECSuccess)
+ break;
+
+ ret = PR_snprintf(tempSecurityCategories + len, 11, "%lu", tempLongValue);
+ /* TODO: find a better way to compute max size of integers */
+ if (ret > 0 && ret < 11)
+ len += ret;
+ else {
+ rv = SECFailure;
+ break;
+ }
+ } else { /* UTF-8 and other types: direct copy */
+ PORT_Memcpy(tempSecurityCategories + len, securityLabelElement->id.securityCategories[i]->securityCategoryValue.data + 2, securityLabelElement->id.securityCategories[i]->securityCategoryValue.len - 2);
+ len += securityLabelElement->id.securityCategories[i]->securityCategoryValue.len - 2;
+ }
+ }
+
+ /* Add separator */
+ tempSecurityCategories[len++] = securityCategoriesSeparator;
+ }
+ }
+
+ /* Overwrite last separator with \0 */
+ tempSecurityCategories[len - 1] = '\0';
+
+ *aSecurityCategories = tempSecurityCategories;
+ }
+ break;
+ }
+
+ if (rv != SECSuccess)
+ break;
+ }
+
+loser:
+ /* If something failed, forget Security Label */
+ if (rv != SECSuccess)
+ *aHasSecurityLabel = PR_FALSE;
+
+ PORT_ArenaUnmark (poolp, mark);
+ return rv;
+}
CONST_OID smimeReceiptRequest[] = { PKCS9_SMIME_ATTRS, 1 };
CONST_OID smimeReceipt[] = { PKCS9_SMIME_IDS, 1, 1 };
CONST_OID smimeReceiptMsgSigDigest[] = { PKCS9_SMIME_ATTRS, 5 };
+CONST_OID smimeSecurityLabel[] = { PKCS9_SMIME_ATTRS, 2 };
CONST_OID x520CommonName[] = { X520_ATTRIBUTE_TYPE, 3 };
CONST_OID x520SurName[] = { X520_ATTRIBUTE_TYPE, 4 };
OD( smimeReceiptMsgSigDigest, SEC_OID_SMIME_RECEIPT_MSGSIGDIGEST,
"S/MIME Receipt MsgSigDigest",
CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( smimeSecurityLabel, SEC_OID_SMIME_SECURITY_LABEL,
+ "S/MIME Security Label",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
};
/* PRIVATE EXTENDED SECOID Table
SEC_OID_SMIME_RECEIPT = 310,
SEC_OID_SMIME_RECEIPT_MSGSIGDIGEST = 311,
+ SEC_OID_SMIME_SECURITY_LABEL = 312,
+
SEC_OID_TOTAL
} SECOidTag;