Merge mozilla-central and mozilla-inbound

This commit is contained in:
Marco Bonardo 2011-10-08 09:41:37 +02:00
commit dce4bad08f
114 changed files with 5670 additions and 1956 deletions

View File

@ -19,6 +19,7 @@ export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug-symbols="-gdwarf-2"
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Needed to enable breakpad in application.ini

View File

@ -19,6 +19,7 @@ export MOZ_DEBUG_SYMBOLS=1
ac_add_options --enable-debug-symbols="-gdwarf-2"
# PGO
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
# Needed to enable breakpad in application.ini

View File

@ -1,4 +1,5 @@
# for pgo
mk_add_options MOZ_PGO=1
mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) $(MOZ_OBJDIR)/_profile/pgo/profileserver.py'
ac_add_options --enable-application=browser

View File

@ -7070,7 +7070,7 @@ dnl We need to wrap dlopen and related functions on Android because we use
dnl our own linker.
if test "$OS_TARGET" = Android; then
WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozutils"
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
fi
dnl ========================================================

View File

@ -130,7 +130,6 @@
let Ci = Components.interfaces, Cc = Components.classes, Cu = Components.utils;
let gChromeWin = null;
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
function openLink(aElement) {
@ -326,7 +325,7 @@
return file;
},
_loadAddons: function(aAddons, aAddonCount, aTotalResults) {
_loadAddons: function(aAddons) {
let list = document.getElementById("newAddons");
let loading = document.getElementById("loadingAddons");
@ -381,23 +380,11 @@
_readFile(file, function(aContent) {
let json = JSON.parse(aContent);
if (!json || json.addons.length == 0) {
self._loadAddons([], 0, 0);
self._loadAddons([]);
return;
}
// Ignore addons already installed
let addonsCache = json.addons;
AddonManager.getAllAddons(function(aAddons) {
let addons = addonsCache.filter(function(addon) {
for (let i =0; i < aAddons.length; i++)
if (addon.id == aAddons[i].id)
return false;
return true;
});
self._loadAddons(addons, addons.length, json.totalResults);
});
self._loadAddons(json.addons);
});
} else {
setTimeout(function() {

View File

@ -69,8 +69,10 @@
#ifdef MOZ_PLATFORM_MAEMO
sizemode="fullscreen"
#else
#ifndef ANDROID
width="480"
height="800"
#endif
#endif
onkeypress="onDebugKeyPress(event);"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"

View File

@ -949,7 +949,6 @@ function AddonInstallListener() {
}
AddonInstallListener.prototype = {
onInstallEnded: function(aInstall, aAddon) {
let needsRestart = false;
let mode = "";
@ -961,6 +960,8 @@ AddonInstallListener.prototype = {
mode = "normal";
}
this._clearRecommendedCache();
// if we already have a mode, then we need to show a restart notification
// otherwise, we are likely a bootstrapped addon
if (needsRestart)
@ -1101,4 +1102,12 @@ AddonInstallListener.prototype = {
ExtensionsView.showAlert(strings.GetStringFromName(stringName), !aNeedsRestart);
},
_clearRecommendedCache: function xpidm_clearRecommendedCache() {
let dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
let file = dirService.get("ProfD", Ci.nsILocalFile);
file.append("recommended-addons.json");
if (file.exists())
file.remove(false);
}
};

View File

@ -186,19 +186,37 @@ var RecommendedSearchResults = {
},
searchSucceeded: function(aAddons, aAddonCount, aTotalResults) {
let json = {
addons: aAddons,
addonCount: aAddonCount,
totalResults: aTotalResults
};
let self = this;
// Avoid any NSS costs. Convert https to http.
json.addons.forEach(function(aAddon){
aAddon.iconURL = aAddon.iconURL.replace(/^https/, "http");
// Filter addons already installed
AddonManager.getAllAddons(function(aAllAddons) {
let addons = aAddons.filter(function(addon) {
for (let i = 0; i < aAllAddons.length; i++)
if (addon.id == aAllAddons[i].id)
return false;
return true;
});
let json = {
addons: []
};
// Avoid any NSS costs. Convert https to http.
addons.forEach(function(aAddon){
json.addons.push({
id: aAddon.id,
name: aAddon.name,
version: aAddon.version,
description: aAddon.description,
averageRating: aAddon.averageRating,
iconURL: aAddon.iconURL.replace(/^https/, "http")
})
});
let file = self._getFile();
self._writeFile(file, JSON.stringify(json));
});
let file = this._getFile();
this._writeFile(file, JSON.stringify(json));
},
searchFailed: function searchFailed() { },

View File

@ -64,7 +64,6 @@ XPIDL_MODULE = browsercomps
XPIDLSRCS = nsIShellService.idl
CPPSRCS = \
nsSSLCertErrorDialog.cpp \
nsBrowserModule.cpp \
nsShellService.cpp \
$(NULL)

View File

@ -40,23 +40,17 @@
#include "mozilla/ModuleUtils.h"
#include "nsShellService.h"
#include "nsSSLCertErrorDialog.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsShellService)
NS_DEFINE_NAMED_CID(nsShellService_CID);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSSLCertErrorDialog)
NS_DEFINE_NAMED_CID(nsSSLCertErrorDialog_CID);
static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
{ &knsShellService_CID, false, NULL, nsShellServiceConstructor },
{ &knsSSLCertErrorDialog_CID, false, NULL, nsSSLCertErrorDialogConstructor },
{ NULL }
};
static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ nsShellService_ContractID, &knsShellService_CID },
{ nsSSLCertErrorDialog_ContractID, &knsSSLCertErrorDialog_CID },
{ NULL }
};

View File

@ -1,58 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* ***** 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 Mobile Browser SSL Cert Dialog Override.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation <http://www.mozilla.org/>.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Finkle <mfinkle@mozilla.com>
*
* 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 ***** */
#include "nsSSLCertErrorDialog.h"
NS_IMPL_THREADSAFE_ISUPPORTS1(nsSSLCertErrorDialog, nsISSLCertErrorDialog)
NS_IMETHODIMP
nsSSLCertErrorDialog::ShowCertError(nsIInterfaceRequestor *ctx,
nsISSLStatus *status,
nsIX509Cert *cert,
const nsAString & textErrorMessage,
const nsAString & htmlErrorMessage,
const nsACString & hostName,
PRUint32 portNumber)
{
/* Returning NS_OK here does not mean that this connection will continue
* successfully. The connection has been or will be aborted regardless of
* what we do here.
*/
return NS_OK;
}

View File

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* ***** 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 Mobile Browser SSL Cert Dialog Override.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation <http://www.mozilla.org/>.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Finkle <mfinkle@mozilla.com>
*
* 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 ***** */
#ifndef __NS_SSLCERTERRORDIALOG_H__
#define __NS_SSLCERTERRORDIALOG_H__
#include "nsISSLCertErrorDialog.h"
class nsSSLCertErrorDialog : public nsISSLCertErrorDialog
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISSLCERTERRORDIALOG
nsSSLCertErrorDialog() {};
~nsSSLCertErrorDialog() {};
};
#define nsSSLCertErrorDialog_CID \
{ 0xb13f1121, 0xfa10, 0x4a7d, \
{0x82, 0xe5, 0x31, 0x59, 0x9b, 0x89, 0x60, 0xb8} }
#define nsSSLCertErrorDialog_ContractID "@mozilla.org/nsSSLCertErrorDialog;1"
#endif

View File

@ -24,6 +24,9 @@ var tests = [
var gCertErrorDialogShown = 0;
// We used to show a dialog box by default when we encountered an SSL
// certificate error. Now we treat these errors just like other
// networking errors; the dialog is no longer shown.
function test_asyncFetchBadCert() {
let listener = new WindowListener("chrome://pippki/content/certerror.xul", function (domwindow) {
gCertErrorDialogShown++;
@ -39,7 +42,7 @@ function test_asyncFetchBadCert() {
ok(!Components.isSuccessCode(aStatusCode), "request failed");
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
is(gCertErrorDialogShown, 0, "cert error was suppressed");
is(gCertErrorDialogShown, 0, "cert error dialog was not shown");
// Now try again with a channel whose notificationCallbacks doesn't suprress errors
let channel = NetUtil.newChannel("https://untrusted.example.com");
@ -54,7 +57,7 @@ function test_asyncFetchBadCert() {
ok(!Components.isSuccessCode(aStatusCode), "request failed");
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
is(gCertErrorDialogShown, 1, "cert error was not suppressed");
is(gCertErrorDialogShown, 0, "cert error dialog was not shown");
// Now try a valid request
NetUtil.asyncFetch("https://example.com", function (aInputStream, aStatusCode, aRequest) {
@ -62,7 +65,7 @@ function test_asyncFetchBadCert() {
ok(aRequest instanceof Ci.nsIHttpChannel, "request is an nsIHttpChannel");
ok(aRequest.requestSucceeded, "HTTP request succeeded");
is(gCertErrorDialogShown, 1, "cert error was not shown");
is(gCertErrorDialogShown, 0, "cert error dialog was not shown");
Services.wm.removeListener(listener);
nextTest();

View File

@ -0,0 +1,209 @@
diff --git a/other-licenses/android/getaddrinfo.c b/other-licenses/android/getaddrinfo.c
--- a/other-licenses/android/getaddrinfo.c
+++ b/other-licenses/android/getaddrinfo.c
@@ -398,191 +398,6 @@ _have_ipv4() {
return _test_connect(PF_INET, &addr.generic, sizeof(addr.in));
}
-// Returns 0 on success, else returns non-zero on error (in which case
-// getaddrinfo should continue as normal)
-static int
-android_getaddrinfo_proxy(
- const char *hostname, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res)
-{
- int sock;
- const int one = 1;
- struct sockaddr_un proxy_addr;
- const char* cache_mode = getenv("ANDROID_DNS_MODE");
- FILE* proxy = NULL;
- int success = 0;
-
- // Clear this at start, as we use its non-NULLness later (in the
- // error path) to decide if we have to free up any memory we
- // allocated in the process (before failing).
- *res = NULL;
-
- if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
- // Don't use the proxy in local mode. This is used by the
- // proxy itself.
- return -1;
- }
-
- // Temporary cautious hack to disable the DNS proxy for processes
- // requesting special treatment. Ideally the DNS proxy should
- // accomodate these apps, though.
- char propname[PROP_NAME_MAX];
- char propvalue[PROP_VALUE_MAX];
- snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
- if (__system_property_get(propname, propvalue) > 0) {
- return -1;
- }
-
- // Bogus things we can't serialize. Don't use the proxy.
- if ((hostname != NULL &&
- strcspn(hostname, " \n\r\t^'\"") != strlen(hostname)) ||
- (servname != NULL &&
- strcspn(servname, " \n\r\t^'\"") != strlen(servname))) {
- return -1;
- }
-
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- return -1;
- }
-
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
- memset(&proxy_addr, 0, sizeof(proxy_addr));
- proxy_addr.sun_family = AF_UNIX;
- strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
- sizeof(proxy_addr.sun_path));
- if (TEMP_FAILURE_RETRY(connect(sock,
- (const struct sockaddr*) &proxy_addr,
- sizeof(proxy_addr))) != 0) {
- close(sock);
- return -1;
- }
-
- // Send the request.
- proxy = fdopen(sock, "r+");
- if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d",
- hostname == NULL ? "^" : hostname,
- servname == NULL ? "^" : servname,
- hints == NULL ? -1 : hints->ai_flags,
- hints == NULL ? -1 : hints->ai_family,
- hints == NULL ? -1 : hints->ai_socktype,
- hints == NULL ? -1 : hints->ai_protocol) < 0) {
- goto exit;
- }
- // literal NULL byte at end, required by FrameworkListener
- if (fputc(0, proxy) == EOF ||
- fflush(proxy) != 0) {
- goto exit;
- }
-
- int remote_rv;
- if (fread(&remote_rv, sizeof(int), 1, proxy) != 1) {
- goto exit;
- }
-
- if (remote_rv != 0) {
- goto exit;
- }
-
- struct addrinfo* ai = NULL;
- struct addrinfo** nextres = res;
- while (1) {
- uint32_t addrinfo_len;
- if (fread(&addrinfo_len, sizeof(addrinfo_len),
- 1, proxy) != 1) {
- break;
- }
- addrinfo_len = ntohl(addrinfo_len);
- if (addrinfo_len == 0) {
- success = 1;
- break;
- }
-
- if (addrinfo_len < sizeof(struct addrinfo)) {
- break;
- }
- struct addrinfo* ai = calloc(1, addrinfo_len +
- sizeof(struct sockaddr_storage));
- if (ai == NULL) {
- break;
- }
-
- if (fread(ai, addrinfo_len, 1, proxy) != 1) {
- // Error; fall through.
- break;
- }
-
- // Zero out the pointer fields we copied which aren't
- // valid in this address space.
- ai->ai_addr = NULL;
- ai->ai_canonname = NULL;
- ai->ai_next = NULL;
-
- // struct sockaddr
- uint32_t addr_len;
- if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
- break;
- }
- addr_len = ntohl(addr_len);
- if (addr_len != 0) {
- if (addr_len > sizeof(struct sockaddr_storage)) {
- // Bogus; too big.
- break;
- }
- struct sockaddr* addr = (struct sockaddr*)(ai + 1);
- if (fread(addr, addr_len, 1, proxy) != 1) {
- break;
- }
- ai->ai_addr = addr;
- }
-
- // cannonname
- uint32_t name_len;
- if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
- break;
- }
- name_len = ntohl(name_len);
- if (name_len != 0) {
- ai->ai_canonname = (char*) malloc(name_len);
- if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
- break;
- }
- if (ai->ai_canonname[name_len - 1] != '\0') {
- // The proxy should be returning this
- // NULL-terminated.
- break;
- }
- }
-
- *nextres = ai;
- nextres = &ai->ai_next;
- ai = NULL;
- }
-
- if (ai != NULL) {
- // Clean up partially-built addrinfo that we never ended up
- // attaching to the response.
- freeaddrinfo(ai);
- }
-exit:
- if (proxy != NULL) {
- fclose(proxy);
- }
-
- if (success) {
- return 0;
- }
-
- // Proxy failed; fall through to local
- // resolver case. But first clean up any
- // memory we might've allocated.
- if (*res) {
- freeaddrinfo(*res);
- *res = NULL;
- }
- return -1;
-}
-
int
getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
@@ -729,13 +544,6 @@ getaddrinfo(const char *hostname, const
if (pai->ai_flags & AI_NUMERICHOST)
ERR(EAI_NONAME);
- /*
- * BEGIN ANDROID CHANGES; proxying to the cache
- */
- if (android_getaddrinfo_proxy(hostname, servname, hints, res) == 0) {
- return 0;
- }
-
/*
* hostname as alphabetical name.
* we would like to prefer AF_INET6 than AF_INET, so we'll make a

View File

@ -0,0 +1,357 @@
diff --git a/other-licenses/android/getaddrinfo.c b/other-licenses/android/getaddrinfo.c
--- a/other-licenses/android/getaddrinfo.c
+++ b/other-licenses/android/getaddrinfo.c
@@ -31,6 +31,16 @@
*/
/*
+ * This version of getaddrinfo.c is derived from Android 2.3 "Gingerbread",
+ * which contains uncredited changes by Android/Google developers. It has
+ * been modified in 2011 for use in the Android build of Mozilla Firefox by
+ * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>).
+ * These changes are offered under the same license as the original NetBSD
+ * file, whose copyright and license are unchanged above.
+ */
+#define ANDROID_CHANGES 1
+
+/*
* Issues to be discussed:
* - Thread safe-ness must be checked.
* - Return values. There are nonstandard return values defined and used
@@ -84,6 +94,7 @@
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <sys/mman.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -94,7 +105,6 @@
#include <netdb.h>
#include "resolv_private.h"
#include <stddef.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -103,10 +113,95 @@
#include <stdarg.h>
#include "nsswitch.h"
+#ifdef MOZ_GETADDRINFO_LOG_VERBOSE
+#include <android/log.h>
+#endif
+
#ifdef ANDROID_CHANGES
#include <sys/system_properties.h>
#endif /* ANDROID_CHANGES */
+typedef struct _pseudo_FILE {
+ int fd;
+ off_t maplen;
+ void* mapping;
+ off_t offset;
+} _pseudo_FILE;
+
+#define _PSEUDO_FILE_INITIALIZER { -1, 0, MAP_FAILED, 0 }
+
+static void
+_pseudo_fclose(_pseudo_FILE * __restrict__ fp)
+{
+ assert(fp);
+ fp->offset = 0;
+ if (fp->mapping != MAP_FAILED) {
+ (void) munmap(fp->mapping, fp->maplen);
+ fp->mapping = MAP_FAILED;
+ }
+ fp->maplen = 0;
+ if (fp->fd != -1) {
+ (void) close(fp->fd);
+ fp->fd = -1;
+ }
+}
+
+static _pseudo_FILE *
+_pseudo_fopen_r(_pseudo_FILE * __restrict__ fp, const char* fname)
+{
+ struct stat statbuf;
+ assert(fp);
+ fp->fd = open(fname, O_RDONLY);
+ if (fp->fd < 0) {
+ fp->fd = -1;
+ return NULL;
+ }
+ if ((0 != fstat(fp->fd, &statbuf)) || (statbuf.st_size <= 0)) {
+ close(fp->fd);
+ fp->fd = -1;
+ return NULL;
+ }
+ fp->maplen = statbuf.st_size;
+ fp->mapping = mmap(NULL, fp->maplen, PROT_READ, MAP_PRIVATE, fp->fd, 0);
+ if (fp->mapping == MAP_FAILED) {
+ close(fp->fd);
+ fp->fd = -1;
+ return NULL;
+ }
+ fp->offset = 0;
+ return fp;
+}
+
+static void
+_pseudo_rewind(_pseudo_FILE * __restrict__ fp)
+{
+ assert(fp);
+ fp->offset = 0;
+}
+
+static char*
+_pseudo_fgets(char* buf, int bufsize, _pseudo_FILE * __restrict__ fp)
+{
+ char* current;
+ char* endp;
+ int maxcopy;
+ assert(fp);
+ maxcopy = fp->maplen - fp->offset;
+ if (fp->mapping == MAP_FAILED)
+ return NULL;
+ if (maxcopy > bufsize - 1)
+ maxcopy = bufsize - 1;
+ if (maxcopy <= 0)
+ return NULL;
+ current = ((char*) fp->mapping) + fp->offset;
+ endp = memccpy(buf, current, '\n', maxcopy);
+ if (endp)
+ maxcopy = endp - buf;
+ buf[maxcopy] = '\0';
+ fp->offset += maxcopy;
+ return buf;
+}
+
typedef union sockaddr_union {
struct sockaddr generic;
struct sockaddr_in in;
@@ -231,9 +326,9 @@ static int ip6_str2scopeid(char *, struc
static struct addrinfo *getanswer(const querybuf *, int, const char *, int,
const struct addrinfo *);
static int _dns_getaddrinfo(void *, void *, va_list);
-static void _sethtent(FILE **);
-static void _endhtent(FILE **);
-static struct addrinfo *_gethtent(FILE **, const char *,
+static void _sethtent(_pseudo_FILE * __restrict__);
+static void _endhtent(_pseudo_FILE * __restrict__);
+static struct addrinfo *_gethtent(_pseudo_FILE * __restrict__, const char *,
const struct addrinfo *);
static int _files_getaddrinfo(void *, void *, va_list);
@@ -303,19 +398,52 @@ do { \
#define MATCH(x, y, w) \
((x) == (y) || (/*CONSTCOND*/(w) && ((x) == ANY || (y) == ANY)))
+#pragma GCC visibility push(default)
+
+extern const char *
+__wrap_gai_strerror(int ecode);
+extern void
+__wrap_freeaddrinfo(struct addrinfo *ai);
+extern int
+__wrap_getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res);
+
+int android_sdk_version;
+
+#pragma GCC visibility pop
+
+int android_sdk_version = -1;
+
+static int honeycomb_or_later()
+{
+#ifdef MOZ_GETADDRINFO_LOG_VERBOSE
+ __android_log_print(ANDROID_LOG_INFO, "getaddrinfo",
+ "I am%s Honeycomb\n",
+ (android_sdk_version >= 11) ? "" : " not");
+#endif
+ return android_sdk_version >= 11;
+}
+
const char *
-gai_strerror(int ecode)
+__wrap_gai_strerror(int ecode)
{
+ if (honeycomb_or_later())
+ return gai_strerror(ecode);
if (ecode < 0 || ecode > EAI_MAX)
ecode = EAI_MAX;
return ai_errlist[ecode];
}
void
-freeaddrinfo(struct addrinfo *ai)
+__wrap_freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *next;
+ if (honeycomb_or_later()) {
+ freeaddrinfo(ai);
+ return;
+ }
+
assert(ai != NULL);
do {
@@ -399,7 +527,7 @@ _have_ipv4() {
}
int
-getaddrinfo(const char *hostname, const char *servname,
+__wrap_getaddrinfo(const char *hostname, const char *servname,
const struct addrinfo *hints, struct addrinfo **res)
{
struct addrinfo sentinel;
@@ -410,6 +538,9 @@ getaddrinfo(const char *hostname, const
struct addrinfo *pai;
const struct explore *ex;
+ if (honeycomb_or_later())
+ return getaddrinfo(hostname, servname, hints, res);
+
/* hostname is allowed to be NULL */
/* servname is allowed to be NULL */
/* hints is allowed to be NULL */
@@ -594,7 +725,7 @@ getaddrinfo(const char *hostname, const
free:
bad:
if (sentinel.ai_next)
- freeaddrinfo(sentinel.ai_next);
+ __wrap_freeaddrinfo(sentinel.ai_next);
*res = NULL;
return error;
}
@@ -655,7 +786,7 @@ explore_fqdn(const struct addrinfo *pai,
free:
if (result)
- freeaddrinfo(result);
+ __wrap_freeaddrinfo(result);
return error;
}
@@ -723,7 +854,7 @@ explore_null(const struct addrinfo *pai,
free:
if (sentinel.ai_next)
- freeaddrinfo(sentinel.ai_next);
+ __wrap_freeaddrinfo(sentinel.ai_next);
return error;
}
@@ -810,7 +941,7 @@ explore_numeric(const struct addrinfo *p
free:
bad:
if (sentinel.ai_next)
- freeaddrinfo(sentinel.ai_next);
+ __wrap_freeaddrinfo(sentinel.ai_next);
return error;
}
@@ -1373,8 +1504,6 @@ _get_label(const struct sockaddr *addr)
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
return 0;
- } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
- return 1;
} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
return 3;
} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
@@ -1414,8 +1543,6 @@ _get_precedence(const struct sockaddr *a
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
return 60;
- } else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
- return 50;
} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
return 30;
} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
@@ -1804,27 +1931,24 @@ _dns_getaddrinfo(void *rv, void *cb_data
}
static void
-_sethtent(FILE **hostf)
+_sethtent(_pseudo_FILE * __restrict__ hostf)
{
-
- if (!*hostf)
- *hostf = fopen(_PATH_HOSTS, "r" );
+ assert(hostf);
+ if (hostf->mapping == MAP_FAILED)
+ (void) _pseudo_fopen_r(hostf, _PATH_HOSTS);
else
- rewind(*hostf);
+ _pseudo_rewind(hostf);
}
static void
-_endhtent(FILE **hostf)
+_endhtent(_pseudo_FILE * __restrict__ hostf)
{
-
- if (*hostf) {
- (void) fclose(*hostf);
- *hostf = NULL;
- }
+ assert(hostf);
+ (void) _pseudo_fclose(hostf);
}
static struct addrinfo *
-_gethtent(FILE **hostf, const char *name, const struct addrinfo *pai)
+_gethtent(_pseudo_FILE * __restrict__ hostf, const char *name, const struct addrinfo *pai)
{
char *p;
char *cp, *tname, *cname;
@@ -1833,14 +1957,17 @@ _gethtent(FILE **hostf, const char *name
const char *addr;
char hostbuf[8*1024];
+ assert(hostf);
// fprintf(stderr, "_gethtent() name = '%s'\n", name);
assert(name != NULL);
assert(pai != NULL);
- if (!*hostf && !(*hostf = fopen(_PATH_HOSTS, "r" )))
+ if (hostf->mapping == MAP_FAILED)
+ (void) _pseudo_fopen_r(hostf, _PATH_HOSTS);
+ if (hostf->mapping == MAP_FAILED)
return (NULL);
again:
- if (!(p = fgets(hostbuf, sizeof hostbuf, *hostf)))
+ if (!(p = _pseudo_fgets(hostbuf, sizeof hostbuf, hostf)))
return (NULL);
if (*p == '#')
goto again;
@@ -1872,7 +1999,7 @@ _gethtent(FILE **hostf, const char *name
found:
hints = *pai;
hints.ai_flags = AI_NUMERICHOST;
- error = getaddrinfo(addr, NULL, &hints, &res0);
+ error = __wrap_getaddrinfo(addr, NULL, &hints, &res0);
if (error)
goto again;
for (res = res0; res; res = res->ai_next) {
@@ -1881,7 +2008,7 @@ found:
if (pai->ai_flags & AI_CANONNAME) {
if (get_canonname(pai, res, cname) != 0) {
- freeaddrinfo(res0);
+ __wrap_freeaddrinfo(res0);
goto again;
}
}
@@ -1897,7 +2024,7 @@ _files_getaddrinfo(void *rv, void *cb_da
const struct addrinfo *pai;
struct addrinfo sentinel, *cur;
struct addrinfo *p;
- FILE *hostf = NULL;
+ _pseudo_FILE hostf = _PSEUDO_FILE_INITIALIZER;
name = va_arg(ap, char *);
pai = va_arg(ap, struct addrinfo *);

View File

@ -71,6 +71,7 @@ CSRCS = \
ba.c \
debugger.c \
dlfcn.c \
getaddrinfo.c \
linker.c \
linker_format.c \
rt.c \

View File

@ -0,0 +1,577 @@
/* $NetBSD: nameser.h,v 1.19 2005/12/26 19:01:47 perry Exp $ */
/*
* Copyright (c) 1983, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Id: nameser.h,v 1.2.2.4.4.1 2004/03/09 08:33:30 marka Exp
*/
#ifndef _ARPA_NAMESER_H_
#define _ARPA_NAMESER_H_
#define BIND_4_COMPAT
#include <sys/types.h>
#include <sys/cdefs.h>
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not
* compare for equality; rather, use it to determine whether your libbind.a
* contains a new enough lib/nameser/ to support the feature you need.
*/
#define __NAMESER 19991006 /* New interface version stamp. */
/*
* Define constants based on RFC 883, RFC 1034, RFC 1035
*/
#define NS_PACKETSZ 512 /* default UDP packet size */
#define NS_MAXDNAME 1025 /* maximum domain name */
#define NS_MAXMSG 65535 /* maximum message size */
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
#define NS_MAXLABEL 63 /* maximum length of domain label */
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
#define NS_INT32SZ 4 /* #/bytes of data in a uint32_t */
#define NS_INT16SZ 2 /* #/bytes of data in a uint16_t */
#define NS_INT8SZ 1 /* #/bytes of data in a uint8_t */
#define NS_INADDRSZ 4 /* IPv4 T_A */
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
/*
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
* in synch with it.
*/
typedef enum __ns_sect {
ns_s_qd = 0, /* Query: Question. */
ns_s_zn = 0, /* Update: Zone. */
ns_s_an = 1, /* Query: Answer. */
ns_s_pr = 1, /* Update: Prerequisites. */
ns_s_ns = 2, /* Query: Name servers. */
ns_s_ud = 2, /* Update: Update. */
ns_s_ar = 3, /* Query|Update: Additional records. */
ns_s_max = 4
} ns_sect;
/*
* This is a message handle. It is caller allocated and has no dynamic data.
* This structure is intended to be opaque to all but ns_parse.c, thus the
* leading _'s on the member names. Use the accessor functions, not the _'s.
*/
typedef struct __ns_msg {
const u_char *_msg, *_eom;
uint16_t _id, _flags, _counts[ns_s_max];
const u_char *_sections[ns_s_max];
ns_sect _sect;
int _rrnum;
const u_char *_msg_ptr;
} ns_msg;
/* Private data structure - do not use from outside library. */
struct _ns_flagdata { int mask, shift; };
extern const struct _ns_flagdata _ns_flagdata[];
/* Accessor macros - this is part of the public interface. */
#define ns_msg_id(handle) ((handle)._id + 0)
#define ns_msg_base(handle) ((handle)._msg + 0)
#define ns_msg_end(handle) ((handle)._eom + 0)
#define ns_msg_size(handle) ((size_t)((handle)._eom - (handle)._msg))
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
/*
* This is a parsed record. It is caller allocated and has no dynamic data.
*/
typedef struct __ns_rr {
char name[NS_MAXDNAME];
uint16_t type;
uint16_t rr_class;
uint32_t ttl;
uint16_t rdlength;
const u_char * rdata;
} ns_rr;
/* Accessor macros - this is part of the public interface. */
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
#define ns_rr_type(rr) ((ns_type)((rr).type + 0))
#define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0))
#define ns_rr_ttl(rr) ((u_long)(rr).ttl + 0)
#define ns_rr_rdlen(rr) ((size_t)(rr).rdlength + 0)
#define ns_rr_rdata(rr) ((rr).rdata + 0)
/*
* These don't have to be in the same order as in the packet flags word,
* and they can even overlap in some cases, but they will need to be kept
* in synch with ns_parse.c:ns_flagdata[].
*/
typedef enum __ns_flag {
ns_f_qr, /* Question/Response. */
ns_f_opcode, /* Operation code. */
ns_f_aa, /* Authoritative Answer. */
ns_f_tc, /* Truncation occurred. */
ns_f_rd, /* Recursion Desired. */
ns_f_ra, /* Recursion Available. */
ns_f_z, /* MBZ. */
ns_f_ad, /* Authentic Data (DNSSEC). */
ns_f_cd, /* Checking Disabled (DNSSEC). */
ns_f_rcode, /* Response code. */
ns_f_max
} ns_flag;
/*
* Currently defined opcodes.
*/
typedef enum __ns_opcode {
ns_o_query = 0, /* Standard query. */
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
ns_o_status = 2, /* Name server status query (unsupported). */
/* Opcode 3 is undefined/reserved. */
ns_o_notify = 4, /* Zone change notification. */
ns_o_update = 5, /* Zone update message. */
ns_o_max = 6
} ns_opcode;
/*
* Currently defined response codes.
*/
typedef enum __ns_rcode {
ns_r_noerror = 0, /* No error occurred. */
ns_r_formerr = 1, /* Format error. */
ns_r_servfail = 2, /* Server failure. */
ns_r_nxdomain = 3, /* Name error. */
ns_r_notimpl = 4, /* Unimplemented. */
ns_r_refused = 5, /* Operation refused. */
/* these are for BIND_UPDATE */
ns_r_yxdomain = 6, /* Name exists */
ns_r_yxrrset = 7, /* RRset exists */
ns_r_nxrrset = 8, /* RRset does not exist */
ns_r_notauth = 9, /* Not authoritative for zone */
ns_r_notzone = 10, /* Zone of record different from zone section */
ns_r_max = 11,
/* The following are EDNS extended rcodes */
ns_r_badvers = 16,
/* The following are TSIG errors */
ns_r_badsig = 16,
ns_r_badkey = 17,
ns_r_badtime = 18
} ns_rcode;
/* BIND_UPDATE */
typedef enum __ns_update_operation {
ns_uop_delete = 0,
ns_uop_add = 1,
ns_uop_max = 2
} ns_update_operation;
/*
* This structure is used for TSIG authenticated messages
*/
struct ns_tsig_key {
char name[NS_MAXDNAME], alg[NS_MAXDNAME];
unsigned char *data;
int len;
};
typedef struct ns_tsig_key ns_tsig_key;
/*
* This structure is used for TSIG authenticated TCP messages
*/
struct ns_tcp_tsig_state {
int counter;
struct dst_key *key;
void *ctx;
unsigned char sig[NS_PACKETSZ];
int siglen;
};
typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
#define NS_TSIG_FUDGE 300
#define NS_TSIG_TCP_COUNT 100
#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
#define NS_TSIG_ERROR_NO_TSIG -10
#define NS_TSIG_ERROR_NO_SPACE -11
#define NS_TSIG_ERROR_FORMERR -12
/*
* Currently defined type values for resources and queries.
*/
typedef enum __ns_type {
ns_t_invalid = 0, /* Cookie. */
ns_t_a = 1, /* Host address. */
ns_t_ns = 2, /* Authoritative server. */
ns_t_md = 3, /* Mail destination. */
ns_t_mf = 4, /* Mail forwarder. */
ns_t_cname = 5, /* Canonical name. */
ns_t_soa = 6, /* Start of authority zone. */
ns_t_mb = 7, /* Mailbox domain name. */
ns_t_mg = 8, /* Mail group member. */
ns_t_mr = 9, /* Mail rename name. */
ns_t_null = 10, /* Null resource record. */
ns_t_wks = 11, /* Well known service. */
ns_t_ptr = 12, /* Domain name pointer. */
ns_t_hinfo = 13, /* Host information. */
ns_t_minfo = 14, /* Mailbox information. */
ns_t_mx = 15, /* Mail routing information. */
ns_t_txt = 16, /* Text strings. */
ns_t_rp = 17, /* Responsible person. */
ns_t_afsdb = 18, /* AFS cell database. */
ns_t_x25 = 19, /* X_25 calling address. */
ns_t_isdn = 20, /* ISDN calling address. */
ns_t_rt = 21, /* Router. */
ns_t_nsap = 22, /* NSAP address. */
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
ns_t_sig = 24, /* Security signature. */
ns_t_key = 25, /* Security key. */
ns_t_px = 26, /* X.400 mail mapping. */
ns_t_gpos = 27, /* Geographical position (withdrawn). */
ns_t_aaaa = 28, /* Ip6 Address. */
ns_t_loc = 29, /* Location Information. */
ns_t_nxt = 30, /* Next domain (security). */
ns_t_eid = 31, /* Endpoint identifier. */
ns_t_nimloc = 32, /* Nimrod Locator. */
ns_t_srv = 33, /* Server Selection. */
ns_t_atma = 34, /* ATM Address */
ns_t_naptr = 35, /* Naming Authority PoinTeR */
ns_t_kx = 36, /* Key Exchange */
ns_t_cert = 37, /* Certification record */
ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
ns_t_sink = 40, /* Kitchen sink (experimentatl) */
ns_t_opt = 41, /* EDNS0 option (meta-RR) */
ns_t_apl = 42, /* Address prefix list (RFC 3123) */
ns_t_tkey = 249, /* Transaction key */
ns_t_tsig = 250, /* Transaction signature. */
ns_t_ixfr = 251, /* Incremental zone transfer. */
ns_t_axfr = 252, /* Transfer zone of authority. */
ns_t_mailb = 253, /* Transfer mailbox records. */
ns_t_maila = 254, /* Transfer mail agent records. */
ns_t_any = 255, /* Wildcard match. */
ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
ns_t_max = 65536
} ns_type;
/* Exclusively a QTYPE? (not also an RTYPE) */
#define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
(t) == ns_t_mailb || (t) == ns_t_maila)
/* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */
#define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
/* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */
#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
(t) == ns_t_zxfr)
/*
* Values for class field
*/
typedef enum __ns_class {
ns_c_invalid = 0, /* Cookie. */
ns_c_in = 1, /* Internet. */
ns_c_2 = 2, /* unallocated/unsupported. */
ns_c_chaos = 3, /* MIT Chaos-net. */
ns_c_hs = 4, /* MIT Hesiod. */
/* Query class values which do not appear in resource records */
ns_c_none = 254, /* for prereq. sections in update requests */
ns_c_any = 255, /* Wildcard match. */
ns_c_max = 65536
} ns_class;
/* DNSSEC constants. */
typedef enum __ns_key_types {
ns_kt_rsa = 1, /* key type RSA/MD5 */
ns_kt_dh = 2, /* Diffie Hellman */
ns_kt_dsa = 3, /* Digital Signature Standard (MANDATORY) */
ns_kt_private = 254 /* Private key type starts with OID */
} ns_key_types;
typedef enum __ns_cert_types {
cert_t_pkix = 1, /* PKIX (X.509v3) */
cert_t_spki = 2, /* SPKI */
cert_t_pgp = 3, /* PGP */
cert_t_url = 253, /* URL private type */
cert_t_oid = 254 /* OID private type */
} ns_cert_types;
/* Flags field of the KEY RR rdata. */
#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
/* The type bits can also be interpreted independently, as single bits: */
#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
#define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */
#define NS_KEY_EXTENDED_FLAGS 0x1000 /* reserved - must be zero */
#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
#define NS_KEY_RESERVED5 0x0400 /* reserved - must be zero */
#define NS_KEY_NAME_TYPE 0x0300 /* these bits determine the type */
#define NS_KEY_NAME_USER 0x0000 /* key is assoc. with user */
#define NS_KEY_NAME_ENTITY 0x0200 /* key is assoc. with entity eg host */
#define NS_KEY_NAME_ZONE 0x0100 /* key is zone key */
#define NS_KEY_NAME_RESERVED 0x0300 /* reserved meaning */
#define NS_KEY_RESERVED8 0x0080 /* reserved - must be zero */
#define NS_KEY_RESERVED9 0x0040 /* reserved - must be zero */
#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
NS_KEY_RESERVED4 | \
NS_KEY_RESERVED5 | \
NS_KEY_RESERVED8 | \
NS_KEY_RESERVED9 | \
NS_KEY_RESERVED10 | \
NS_KEY_RESERVED11 )
#define NS_KEY_RESERVED_BITMASK2 0xFFFF /* no bits defined here */
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
#define NS_ALG_DH 2 /* Diffie Hellman KEY */
#define NS_ALG_DSA 3 /* DSA KEY */
#define NS_ALG_DSS NS_ALG_DSA
#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
/* Protocol values */
/* value 0 is reserved */
#define NS_KEY_PROT_TLS 1
#define NS_KEY_PROT_EMAIL 2
#define NS_KEY_PROT_DNSSEC 3
#define NS_KEY_PROT_IPSEC 4
#define NS_KEY_PROT_ANY 255
/* Signatures */
#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
#define NS_MD5RSA_MAX_BITS 4096
/* Total of binary mod and exp */
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
/* Max length of text sig block */
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
#define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8)
#define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8)
#define NS_DSA_SIG_SIZE 41
#define NS_DSA_MIN_SIZE 213
#define NS_DSA_MAX_BYTES 405
/* Offsets into SIG record rdata to find various values */
#define NS_SIG_TYPE 0 /* Type flags */
#define NS_SIG_ALG 2 /* Algorithm */
#define NS_SIG_LABELS 3 /* How many labels in name */
#define NS_SIG_OTTL 4 /* Original TTL */
#define NS_SIG_EXPIR 8 /* Expiration time */
#define NS_SIG_SIGNED 12 /* Signature time */
#define NS_SIG_FOOT 16 /* Key footprint */
#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
/* How RR types are represented as bit-flags in NXT records */
#define NS_NXT_BITS 8
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
#define NS_NXT_MAX 127
/*
* EDNS0 extended flags, host order.
*/
#define NS_OPT_DNSSEC_OK 0x8000U
/*
* Inline versions of get/put short/long. Pointer is advanced.
*/
#define NS_GET16(s, cp) do { \
const u_char *t_cp = (const u_char *)(cp); \
(s) = ((uint16_t)t_cp[0] << 8) \
| ((uint16_t)t_cp[1]) \
; \
(cp) += NS_INT16SZ; \
} while (/*CONSTCOND*/0)
#define NS_GET32(l, cp) do { \
const u_char *t_cp = (const u_char *)(cp); \
(l) = ((uint32_t)t_cp[0] << 24) \
| ((uint32_t)t_cp[1] << 16) \
| ((uint32_t)t_cp[2] << 8) \
| ((uint32_t)t_cp[3]) \
; \
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
#define NS_PUT16(s, cp) do { \
uint32_t t_s = (uint32_t)(s); \
u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_s >> 8; \
*t_cp = t_s; \
(cp) += NS_INT16SZ; \
} while (/*CONSTCOND*/0)
#define NS_PUT32(l, cp) do { \
uint32_t t_l = (uint32_t)(l); \
u_char *t_cp = (u_char *)(cp); \
*t_cp++ = t_l >> 24; \
*t_cp++ = t_l >> 16; \
*t_cp++ = t_l >> 8; \
*t_cp = t_l; \
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
/*
* ANSI C identifier hiding for bind's lib/nameser.
*/
#define ns_msg_getflag __ns_msg_getflag
#define ns_get16 __ns_get16
#define ns_get32 __ns_get32
#define ns_put16 __ns_put16
#define ns_put32 __ns_put32
#define ns_initparse __ns_initparse
#define ns_skiprr __ns_skiprr
#define ns_parserr __ns_parserr
#define ns_sprintrr __ns_sprintrr
#define ns_sprintrrf __ns_sprintrrf
#define ns_format_ttl __ns_format_ttl
#define ns_parse_ttl __ns_parse_ttl
#define ns_datetosecs __ns_datetosecs
#define ns_name_ntol __ns_name_ntol
#define ns_name_ntop __ns_name_ntop
#define ns_name_pton __ns_name_pton
#define ns_name_unpack __ns_name_unpack
#define ns_name_pack __ns_name_pack
#define ns_name_compress __ns_name_compress
#define ns_name_uncompress __ns_name_uncompress
#define ns_name_skip __ns_name_skip
#define ns_name_rollback __ns_name_rollback
#define ns_sign __ns_sign
#define ns_sign2 __ns_sign2
#define ns_sign_tcp __ns_sign_tcp
#define ns_sign_tcp2 __ns_sign_tcp2
#define ns_sign_tcp_init __ns_sign_tcp_init
#define ns_find_tsig __ns_find_tsig
#define ns_verify __ns_verify
#define ns_verify_tcp __ns_verify_tcp
#define ns_verify_tcp_init __ns_verify_tcp_init
#define ns_samedomain __ns_samedomain
#define ns_subdomain __ns_subdomain
#define ns_makecanon __ns_makecanon
#define ns_samename __ns_samename
__BEGIN_DECLS
int ns_msg_getflag(ns_msg, int);
uint16_t ns_get16(const u_char *);
uint32_t ns_get32(const u_char *);
void ns_put16(uint16_t, u_char *);
void ns_put32(uint32_t, u_char *);
int ns_initparse(const u_char *, int, ns_msg *);
int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
int ns_sprintrr(const ns_msg *, const ns_rr *,
const char *, const char *, char *, size_t);
int ns_sprintrrf(const u_char *, size_t, const char *,
ns_class, ns_type, u_long, const u_char *,
size_t, const char *, const char *,
char *, size_t);
int ns_format_ttl(u_long, char *, size_t);
int ns_parse_ttl(const char *, u_long *);
uint32_t ns_datetosecs(const char *cp, int *errp);
int ns_name_ntol(const u_char *, u_char *, size_t);
int ns_name_ntop(const u_char *, char *, size_t);
int ns_name_pton(const char *, u_char *, size_t);
int ns_name_unpack(const u_char *, const u_char *,
const u_char *, u_char *, size_t);
int ns_name_pack(const u_char *, u_char *, int,
const u_char **, const u_char **);
int ns_name_uncompress(const u_char *, const u_char *,
const u_char *, char *, size_t);
int ns_name_compress(const char *, u_char *, size_t,
const u_char **, const u_char **);
int ns_name_skip(const u_char **, const u_char *);
void ns_name_rollback(const u_char *, const u_char **,
const u_char **);
int ns_sign(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t);
int ns_sign2(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t,
u_char **, u_char **);
int ns_sign_tcp(u_char *, int *, int, int,
ns_tcp_tsig_state *, int);
int ns_sign_tcp2(u_char *, int *, int, int,
ns_tcp_tsig_state *, int,
u_char **, u_char **);
int ns_sign_tcp_init(void *, const u_char *, int,
ns_tcp_tsig_state *);
u_char *ns_find_tsig(u_char *, u_char *);
int ns_verify(u_char *, int *, void *,
const u_char *, int, u_char *, int *,
time_t *, int);
int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
int ns_verify_tcp_init(void *, const u_char *, int,
ns_tcp_tsig_state *);
int ns_samedomain(const char *, const char *);
int ns_subdomain(const char *, const char *);
int ns_makecanon(const char *, char *, size_t);
int ns_samename(const char *, const char *);
__END_DECLS
#ifdef BIND_4_COMPAT
#include "arpa_nameser_compat.h"
#endif
#if 0
# include <logd.h>
# define XLOG(...) \
__libc_android_log_print(ANDROID_LOG_DEBUG,"libc",__VA_ARGS__)
#else
#define XLOG(...) do {} while (0)
#endif
#endif /* !_ARPA_NAMESER_H_ */

View File

@ -0,0 +1,236 @@
/* $NetBSD: nameser_compat.h,v 1.1.1.2 2004/11/07 01:28:27 christos Exp $ */
/* Copyright (c) 1983, 1989
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* from nameser.h 8.1 (Berkeley) 6/2/93
* Id: nameser_compat.h,v 1.1.2.3.4.2 2004/07/01 04:43:41 marka Exp
*/
#ifndef _ARPA_NAMESER_COMPAT_
#define _ARPA_NAMESER_COMPAT_
#define __BIND 19950621 /* (DEAD) interface version stamp. */
#include <endian.h>
#ifndef BYTE_ORDER
#if (BSD >= 199103)
# include <machine/endian.h>
#else
#ifdef __linux
# include <endian.h>
#else
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
defined(__alpha__) || defined(__alpha) || \
(defined(__Lynx__) && defined(__x86__))
#define BYTE_ORDER LITTLE_ENDIAN
#endif
#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
defined(apollo) || defined(__convex__) || defined(_CRAY) || \
defined(__hppa) || defined(__hp9000) || \
defined(__hp9000s300) || defined(__hp9000s700) || \
defined(__hp3000s900) || defined(__hpux) || defined(MPE) || \
defined (BIT_ZERO_ON_LEFT) || defined(m68k) || defined(__sparc) || \
(defined(__Lynx__) && \
(defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
#define BYTE_ORDER BIG_ENDIAN
#endif
#endif /* __linux */
#endif /* BSD */
#endif /* BYTE_ORDER */
#if !defined(BYTE_ORDER) || \
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
BYTE_ORDER != PDP_ENDIAN)
/* you must determine what the correct bit order is for
* your compiler - the next line is an intentional error
* which will force your compiles to bomb until you fix
* the above macros.
*/
#error "Undefined or invalid BYTE_ORDER";
#endif
/*
* Structure for query header. The order of the fields is machine- and
* compiler-dependent, depending on the byte/bit order and the layout
* of bit fields. We use bit fields only in int variables, as this
* is all ANSI requires. This requires a somewhat confusing rearrangement.
*/
typedef struct {
unsigned id :16; /* query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /* response flag */
unsigned opcode: 4; /* purpose of message */
unsigned aa: 1; /* authoritive answer */
unsigned tc: 1; /* truncated message */
unsigned rd: 1; /* recursion desired */
/* fields in fourth byte */
unsigned ra: 1; /* recursion available */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ad: 1; /* authentic data from named */
unsigned cd: 1; /* checking disabled by resolver */
unsigned rcode :4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields in third byte */
unsigned rd :1; /* recursion desired */
unsigned tc :1; /* truncated message */
unsigned aa :1; /* authoritive answer */
unsigned opcode :4; /* purpose of message */
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
unsigned cd: 1; /* checking disabled by resolver */
unsigned ad: 1; /* authentic data from named */
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
unsigned ra :1; /* recursion available */
#endif
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
} HEADER;
#define PACKETSZ NS_PACKETSZ
#define MAXDNAME NS_MAXDNAME
#define MAXCDNAME NS_MAXCDNAME
#define MAXLABEL NS_MAXLABEL
#define HFIXEDSZ NS_HFIXEDSZ
#define QFIXEDSZ NS_QFIXEDSZ
#define RRFIXEDSZ NS_RRFIXEDSZ
#define INT32SZ NS_INT32SZ
#define INT16SZ NS_INT16SZ
#define INT8SZ NS_INT8SZ
#define INADDRSZ NS_INADDRSZ
#define IN6ADDRSZ NS_IN6ADDRSZ
#define INDIR_MASK NS_CMPRSFLGS
#define NAMESERVER_PORT NS_DEFAULTPORT
#define S_ZONE ns_s_zn
#define S_PREREQ ns_s_pr
#define S_UPDATE ns_s_ud
#define S_ADDT ns_s_ar
#define QUERY ns_o_query
#define IQUERY ns_o_iquery
#define STATUS ns_o_status
#define NS_NOTIFY_OP ns_o_notify
#define NS_UPDATE_OP ns_o_update
#define NOERROR ns_r_noerror
#define FORMERR ns_r_formerr
#define SERVFAIL ns_r_servfail
#define NXDOMAIN ns_r_nxdomain
#define NOTIMP ns_r_notimpl
#define REFUSED ns_r_refused
#define YXDOMAIN ns_r_yxdomain
#define YXRRSET ns_r_yxrrset
#define NXRRSET ns_r_nxrrset
#define NOTAUTH ns_r_notauth
#define NOTZONE ns_r_notzone
/*#define BADSIG ns_r_badsig*/
/*#define BADKEY ns_r_badkey*/
/*#define BADTIME ns_r_badtime*/
#define DELETE ns_uop_delete
#define ADD ns_uop_add
#define T_A ns_t_a
#define T_NS ns_t_ns
#define T_MD ns_t_md
#define T_MF ns_t_mf
#define T_CNAME ns_t_cname
#define T_SOA ns_t_soa
#define T_MB ns_t_mb
#define T_MG ns_t_mg
#define T_MR ns_t_mr
#define T_NULL ns_t_null
#define T_WKS ns_t_wks
#define T_PTR ns_t_ptr
#define T_HINFO ns_t_hinfo
#define T_MINFO ns_t_minfo
#define T_MX ns_t_mx
#define T_TXT ns_t_txt
#define T_RP ns_t_rp
#define T_AFSDB ns_t_afsdb
#define T_X25 ns_t_x25
#define T_ISDN ns_t_isdn
#define T_RT ns_t_rt
#define T_NSAP ns_t_nsap
#define T_NSAP_PTR ns_t_nsap_ptr
#define T_SIG ns_t_sig
#define T_KEY ns_t_key
#define T_PX ns_t_px
#define T_GPOS ns_t_gpos
#define T_AAAA ns_t_aaaa
#define T_LOC ns_t_loc
#define T_NXT ns_t_nxt
#define T_EID ns_t_eid
#define T_NIMLOC ns_t_nimloc
#define T_SRV ns_t_srv
#define T_ATMA ns_t_atma
#define T_NAPTR ns_t_naptr
#define T_A6 ns_t_a6
#define T_TSIG ns_t_tsig
#define T_IXFR ns_t_ixfr
#define T_AXFR ns_t_axfr
#define T_MAILB ns_t_mailb
#define T_MAILA ns_t_maila
#define T_ANY ns_t_any
#define C_IN ns_c_in
#define C_CHAOS ns_c_chaos
#define C_HS ns_c_hs
/* BIND_UPDATE */
#define C_NONE ns_c_none
#define C_ANY ns_c_any
#define GETSHORT NS_GET16
#define GETLONG NS_GET32
#define PUTSHORT NS_PUT16
#define PUTLONG NS_PUT32
#endif /* _ARPA_NAMESER_COMPAT_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,499 @@
/* $NetBSD: resolv.h,v 1.31 2005/12/26 19:01:47 perry Exp $ */
/*
* Copyright (c) 1983, 1987, 1989
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* @(#)resolv.h 8.1 (Berkeley) 6/2/93
* Id: resolv.h,v 1.7.2.11.4.2 2004/06/25 00:41:05 marka Exp
*/
#ifndef _RESOLV_PRIVATE_H_
#define _RESOLV_PRIVATE_H_
#include <resolv.h>
#include "resolv_static.h"
/*
* Revision information. This is the release date in YYYYMMDD format.
* It can change every day so the right thing to do with it is use it
* in preprocessor commands such as "#if (__RES > 19931104)". Do not
* compare for equality; rather, use it to determine whether your resolver
* is new enough to contain a certain feature.
*/
#define __RES 20030124
/*
* This used to be defined in res_query.c, now it's in herror.c.
* [XXX no it's not. It's in irs/irs_data.c]
* It was
* never extern'd by any *.h file before it was placed here. For thread
* aware programs, the last h_errno value set is stored in res->h_errno.
*
* XXX: There doesn't seem to be a good reason for exposing RES_SET_H_ERRNO
* (and __h_errno_set) to the public via <resolv.h>.
* XXX: __h_errno_set is really part of IRS, not part of the resolver.
* If somebody wants to build and use a resolver that doesn't use IRS,
* what do they do? Perhaps something like
* #ifdef WANT_IRS
* # define RES_SET_H_ERRNO(r,x) __h_errno_set(r,x)
* #else
* # define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
* #endif
*/
#define RES_SET_H_ERRNO(r,x) (h_errno = (r)->res_h_errno = (x))
struct __res_state; /* forward */
/*
* Resolver configuration file.
* Normally not present, but may contain the address of the
* initial name server(s) to query and the domain search list.
*/
#ifndef _PATH_RESCONF
#ifdef ANDROID_CHANGES
#define _PATH_RESCONF "/etc/ppp/resolv.conf"
#else
#define _PATH_RESCONF "/etc/resolv.conf"
#endif
#endif
typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
res_sendhookact;
typedef res_sendhookact (*res_send_qhook)(struct sockaddr * const *,
const u_char **, int *,
u_char *, int, int *);
typedef res_sendhookact (*res_send_rhook)(const struct sockaddr *,
const u_char *, int, u_char *,
int, int *);
struct res_sym {
int number; /* Identifying number, like T_MX */
const char * name; /* Its symbolic name, like "MX" */
const char * humanname; /* Its fun name, like "mail exchanger" */
};
/*
* Global defines and variables for resolver stub.
*/
#define MAXNS 3 /* max # name servers we'll track */
#define MAXDFLSRCH 3 /* # default domain levels to try */
#define MAXDNSRCH 6 /* max # domains in search path */
#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
#define RES_TIMEOUT 5 /* min. seconds between retries */
#define MAXRESOLVSORT 10 /* number of net to sort on */
#define RES_MAXNDOTS 15 /* should reflect bit field size */
#define RES_MAXRETRANS 30 /* only for resolv.conf/RES_OPTIONS */
#define RES_MAXRETRY 5 /* only for resolv.conf/RES_OPTIONS */
#define RES_DFLRETRY 2 /* Default #/tries. */
#define RES_MAXTIME 65535 /* Infinity, in milliseconds. */
struct __res_state_ext;
struct __res_state {
int retrans; /* retransmission time interval */
int retry; /* number of times to retransmit */
#ifdef sun
u_int options; /* option flags - see below. */
#else
u_long options; /* option flags - see below. */
#endif
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
#define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
#ifdef sun
u_int pfcode; /* RES_PRF_ flags - see below. */
#else
u_long pfcode; /* RES_PRF_ flags - see below. */
#endif
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
char unused[3];
struct {
struct in_addr addr;
uint32_t mask;
} sort_list[MAXRESOLVSORT];
#ifdef __OLD_RES_STATE
char lookups[4];
#else
res_send_qhook qhook; /* query hook */
res_send_rhook rhook; /* response hook */
int res_h_errno; /* last one set for this context */
int _vcsock; /* PRIVATE: for res_send VC i/o */
u_int _flags; /* PRIVATE: see below */
u_int _pad; /* make _u 64 bit aligned */
union {
/* On an 32-bit arch this means 512b total. */
char pad[72 - 4*sizeof (int) - 2*sizeof (void *)];
struct {
uint16_t nscount;
uint16_t nstimes[MAXNS]; /* ms. */
int nssocks[MAXNS];
struct __res_state_ext *ext; /* extention for IPv6 */
} _ext;
} _u;
#endif
struct res_static rstatic[1];
};
typedef struct __res_state *res_state;
union res_sockaddr_union {
struct sockaddr_in sin;
#ifdef IN6ADDR_ANY_INIT
struct sockaddr_in6 sin6;
#endif
#ifdef ISC_ALIGN64
int64_t __align64; /* 64bit alignment */
#else
int32_t __align32; /* 32bit alignment */
#endif
char __space[128]; /* max size */
};
/*
* Resolver flags (used to be discrete per-module statics ints).
*/
#define RES_F_VC 0x00000001 /* socket is TCP */
#define RES_F_CONN 0x00000002 /* socket is connected */
#define RES_F_EDNS0ERR 0x00000004 /* EDNS0 caused errors */
#define RES_F__UNUSED 0x00000008 /* (unused) */
#define RES_F_LASTMASK 0x000000F0 /* ordinal server of last res_nsend */
#define RES_F_LASTSHIFT 4 /* bit position of LASTMASK "flag" */
#define RES_GETLAST(res) (((res)._flags & RES_F_LASTMASK) >> RES_F_LASTSHIFT)
/* res_findzonecut2() options */
#define RES_EXHAUSTIVE 0x00000001 /* always do all queries */
#define RES_IPV4ONLY 0x00000002 /* IPv4 only */
#define RES_IPV6ONLY 0x00000004 /* IPv6 only */
/*
* Resolver options (keep these in synch with res_debug.c, please)
*/
#define RES_INIT 0x00000001 /* address initialized */
#define RES_DEBUG 0x00000002 /* print debug messages */
#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
#define RES_USEVC 0x00000008 /* use virtual circuit */
#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
#define RES_IGNTC 0x00000020 /* ignore trucation errors */
#define RES_RECURSE 0x00000040 /* recursion desired */
#define RES_DEFNAMES 0x00000080 /* use default domain name */
#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
#define RES_DNSRCH 0x00000200 /* search up local domain tree */
#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
#define RES_ROTATE 0x00004000 /* rotate ns list after each query */
#define RES_NOCHECKNAME 0x00008000 /* do not check names for sanity. */
#define RES_KEEPTSIG 0x00010000 /* do not strip TSIG records */
#define RES_BLAST 0x00020000 /* blast all recursive servers */
#define RES_NOTLDQUERY 0x00100000 /* don't unqualified name as a tld */
#define RES_USE_DNSSEC 0x00200000 /* use DNSSEC using OK bit in OPT */
/* #define RES_DEBUG2 0x00400000 */ /* nslookup internal */
/* KAME extensions: use higher bit to avoid conflict with ISC use */
#define RES_USE_DNAME 0x10000000 /* use DNAME */
#define RES_USE_EDNS0 0x40000000 /* use EDNS0 if configured */
#define RES_NO_NIBBLE2 0x80000000 /* disable alternate nibble lookup */
#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | \
RES_DNSRCH | RES_NO_NIBBLE2)
/*
* Resolver "pfcode" values. Used by dig.
*/
#define RES_PRF_STATS 0x00000001
#define RES_PRF_UPDATE 0x00000002
#define RES_PRF_CLASS 0x00000004
#define RES_PRF_CMD 0x00000008
#define RES_PRF_QUES 0x00000010
#define RES_PRF_ANS 0x00000020
#define RES_PRF_AUTH 0x00000040
#define RES_PRF_ADD 0x00000080
#define RES_PRF_HEAD1 0x00000100
#define RES_PRF_HEAD2 0x00000200
#define RES_PRF_TTLID 0x00000400
#define RES_PRF_HEADX 0x00000800
#define RES_PRF_QUERY 0x00001000
#define RES_PRF_REPLY 0x00002000
#define RES_PRF_INIT 0x00004000
#define RES_PRF_TRUNC 0x00008000
/* 0x00010000 */
/* Things involving an internal (static) resolver context. */
__BEGIN_DECLS
extern struct __res_state *__res_get_state(void);
extern void __res_put_state(struct __res_state *);
#ifndef ANDROID_CHANGES
/*
* Source and Binary compatibility; _res will not work properly
* with multi-threaded programs.
*/
extern struct __res_state *__res_state(void);
#define _res (*__res_state())
#endif
__END_DECLS
#ifndef __BIND_NOSTATIC
#define fp_nquery __fp_nquery
#define fp_query __fp_query
#define hostalias __hostalias
#define p_query __p_query
#define res_close __res_close
#define res_opt __res_opt
#define res_isourserver __res_isourserver
#define res_querydomain __res_querydomain
#define res_send __res_send
#define res_sendsigned __res_sendsigned
#ifdef BIND_RES_POSIX3
#define dn_expand __dn_expand
#define res_init __res_init
#define res_query __res_query
#define res_search __res_search
#define res_mkquery __res_mkquery
#endif
__BEGIN_DECLS
void fp_nquery(const u_char *, int, FILE *);
void fp_query(const u_char *, FILE *);
const char * hostalias(const char *);
void p_query(const u_char *);
void res_close(void);
int res_init(void);
int res_opt(int, u_char *, int, int);
int res_isourserver(const struct sockaddr_in *);
int res_mkquery(int, const char *, int, int, const u_char *, int, const u_char *, u_char *, int);
int res_query(const char *, int, int, u_char *, int);
int res_querydomain(const char *, const char *, int, int, u_char *, int);
int res_search(const char *, int, int, u_char *, int);
int res_send(const u_char *, int, u_char *, int);
int res_sendsigned(const u_char *, int, ns_tsig_key *, u_char *, int);
__END_DECLS
#endif
#if !defined(SHARED_LIBBIND) || defined(LIB)
/*
* If libbind is a shared object (well, DLL anyway)
* these externs break the linker when resolv.h is
* included by a lib client (like named)
* Make them go away if a client is including this
*
*/
extern const struct res_sym __p_key_syms[];
extern const struct res_sym __p_cert_syms[];
extern const struct res_sym __p_class_syms[];
extern const struct res_sym __p_type_syms[];
extern const struct res_sym __p_rcode_syms[];
#endif /* SHARED_LIBBIND */
#ifndef ADNROID_CHANGES
#define b64_ntop __b64_ntop
#define b64_pton __b64_pton
#endif
#define dn_comp __dn_comp
#define dn_count_labels __dn_count_labels
#define dn_skipname __dn_skipname
#define fp_resstat __fp_resstat
#define loc_aton __loc_aton
#define loc_ntoa __loc_ntoa
#define p_cdname __p_cdname
#define p_cdnname __p_cdnname
#define p_class __p_class
#define p_fqname __p_fqname
#define p_fqnname __p_fqnname
#define p_option __p_option
#define p_secstodate __p_secstodate
#define p_section __p_section
#define p_time __p_time
#define p_type __p_type
#define p_rcode __p_rcode
#define p_sockun __p_sockun
#define putlong __putlong
#define putshort __putshort
#define res_dnok __res_dnok
#define res_findzonecut __res_findzonecut
#define res_findzonecut2 __res_findzonecut2
#define res_hnok __res_hnok
#define res_hostalias __res_hostalias
#define res_mailok __res_mailok
#define res_nameinquery __res_nameinquery
#define res_nclose __res_nclose
#define res_ninit __res_ninit
#define res_nmkquery __res_nmkquery
#define res_pquery __res_pquery
#define res_nquery __res_nquery
#define res_nquerydomain __res_nquerydomain
#define res_nsearch __res_nsearch
#define res_nsend __res_nsend
#define res_nsendsigned __res_nsendsigned
#define res_nisourserver __res_nisourserver
#define res_ownok __res_ownok
#define res_queriesmatch __res_queriesmatch
#define res_randomid __res_randomid
#define sym_ntop __sym_ntop
#define sym_ntos __sym_ntos
#define sym_ston __sym_ston
#define res_nopt __res_nopt
#define res_ndestroy __res_ndestroy
#define res_nametoclass __res_nametoclass
#define res_nametotype __res_nametotype
#define res_setservers __res_setservers
#define res_getservers __res_getservers
#define res_buildprotolist __res_buildprotolist
#define res_destroyprotolist __res_destroyprotolist
#define res_destroyservicelist __res_destroyservicelist
#define res_get_nibblesuffix __res_get_nibblesuffix
#define res_get_nibblesuffix2 __res_get_nibblesuffix2
#define res_ourserver_p __res_ourserver_p
#define res_protocolname __res_protocolname
#define res_protocolnumber __res_protocolnumber
#define res_send_setqhook __res_send_setqhook
#define res_send_setrhook __res_send_setrhook
#define res_servicename __res_servicename
#define res_servicenumber __res_servicenumber
__BEGIN_DECLS
int res_hnok(const char *);
int res_ownok(const char *);
int res_mailok(const char *);
int res_dnok(const char *);
int sym_ston(const struct res_sym *, const char *, int *);
const char * sym_ntos(const struct res_sym *, int, int *);
const char * sym_ntop(const struct res_sym *, int, int *);
#ifndef ANDROID_CHANGES
int b64_ntop(u_char const *, size_t, char *, size_t);
int b64_pton(char const *, u_char *, size_t);
#endif
int loc_aton(const char *, u_char *);
const char * loc_ntoa(const u_char *, char *);
int dn_skipname(const u_char *, const u_char *);
void putlong(uint32_t, u_char *);
void putshort(uint16_t, u_char *);
#ifndef __ultrix__
uint16_t _getshort(const u_char *);
uint32_t _getlong(const u_char *);
#endif
const char * p_class(int);
const char * p_time(uint32_t);
const char * p_type(int);
const char * p_rcode(int);
const char * p_sockun(union res_sockaddr_union, char *, size_t);
const u_char * p_cdnname(const u_char *, const u_char *, int, FILE *);
const u_char * p_cdname(const u_char *, const u_char *, FILE *);
const u_char * p_fqnname(const u_char *, const u_char *,
int, char *, int);
const u_char * p_fqname(const u_char *, const u_char *, FILE *);
const char * p_option(u_long);
char * p_secstodate(u_long);
int dn_count_labels(const char *);
int dn_comp(const char *, u_char *, int, u_char **, u_char **);
int dn_expand(const u_char *, const u_char *, const u_char *,
char *, int);
u_int res_randomid(void);
int res_nameinquery(const char *, int, int, const u_char *,
const u_char *);
int res_queriesmatch(const u_char *, const u_char *,
const u_char *, const u_char *);
const char * p_section(int, int);
/* Things involving a resolver context. */
int res_ninit(res_state);
int res_nisourserver(const res_state, const struct sockaddr_in *);
void fp_resstat(const res_state, FILE *);
void res_pquery(const res_state, const u_char *, int, FILE *);
const char * res_hostalias(const res_state, const char *, char *, size_t);
int res_nquery(res_state, const char *, int, int, u_char *, int);
int res_nsearch(res_state, const char *, int, int, u_char *, int);
int res_nquerydomain(res_state, const char *, const char *,
int, int, u_char *, int);
int res_nmkquery(res_state, int, const char *, int, int,
const u_char *, int, const u_char *,
u_char *, int);
int res_nsend(res_state, const u_char *, int, u_char *, int);
int res_nsendsigned(res_state, const u_char *, int,
ns_tsig_key *, u_char *, int);
int res_findzonecut(res_state, const char *, ns_class, int,
char *, size_t, struct in_addr *, int);
int res_findzonecut2(res_state, const char *, ns_class, int,
char *, size_t,
union res_sockaddr_union *, int);
void res_nclose(res_state);
int res_nopt(res_state, int, u_char *, int, int);
void res_send_setqhook(res_send_qhook);
void res_send_setrhook(res_send_rhook);
int __res_vinit(res_state, int);
void res_destroyservicelist(void);
const char * res_servicename(uint16_t, const char *);
const char * res_protocolname(int);
void res_destroyprotolist(void);
void res_buildprotolist(void);
const char * res_get_nibblesuffix(res_state);
const char * res_get_nibblesuffix2(res_state);
void res_ndestroy(res_state);
uint16_t res_nametoclass(const char *, int *);
uint16_t res_nametotype(const char *, int *);
void res_setservers(res_state,
const union res_sockaddr_union *, int);
int res_getservers(res_state,
union res_sockaddr_union *, int);
int res_get_dns_changed();
u_int res_randomid(void);
__END_DECLS
#endif /* !_RESOLV_PRIVATE_H_ */

View File

@ -0,0 +1,32 @@
#ifndef _RESOLV_STATIC_H
#define _RESOLV_STATIC_H
#include <netdb.h>
/* this structure contains all the variables that were declared
* 'static' in the original NetBSD resolver code.
*
* this caused vast amounts of crashes and memory corruptions
* when the resolver was being used by multiple threads.
*
* (note: the OpenBSD/FreeBSD resolver has similar 'issues')
*/
#define MAXALIASES 35
#define MAXADDRS 35
typedef struct res_static {
char* h_addr_ptrs[MAXADDRS + 1];
char* host_aliases[MAXALIASES];
char hostbuf[8*1024];
u_int32_t host_addr[16 / sizeof(u_int32_t)]; /* IPv4 or IPv6 */
FILE* hostf;
int stayopen;
const char* servent_ptr;
struct servent servent;
struct hostent host;
} *res_static;
extern res_static __res_get_static(void);
#endif /* _RESOLV_STATIC_H */

View File

@ -59,9 +59,13 @@ CC += -arch i386
override CPU_ARCH = x86
endif
else
ifeq (arm,$(CPU_ARCH))
# Nothing set for arm currently.
else
OS_REL_CFLAGS = -Dppc
CC += -arch ppc
endif
endif
ifneq (,$(MACOS_SDK_DIR))
GCC_VERSION_FULL := $(shell $(CC) -dumpversion)

View File

@ -124,9 +124,9 @@ ifdef NS_USE_GCC
# The -mnop-fun-dllimport flag allows us to avoid a drawback of
# the dllimport attribute that a pointer to a function marked as
# dllimport cannot be used as as a constant address.
OS_CFLAGS += -mno-cygwin -mms-bitfields -mnop-fun-dllimport
OS_CFLAGS += -mwindows -mms-bitfields -mnop-fun-dllimport
_GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
DLLFLAGS += -mno-cygwin -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
ifdef BUILD_OPT
ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
OPTIMIZER += -Os

View File

@ -43,4 +43,3 @@
#error "Do not include this header file."

View File

@ -354,7 +354,6 @@ certErrorTrust_Untrusted=The certificate does not come from a trusted source.
certErrorMismatch=The certificate is not valid for the name %S.
# LOCALIZATION NOTE (certErrorMismatchSingle2): Do not translate <a id="cert_domain_link" title="%1$S">%1$S</a>
certErrorMismatchSingle2=The certificate is only valid for <a id="cert_domain_link" title="%1$S">%1$S</a>
certErrorMismatchSinglePlain=The certificate is only valid for %S
certErrorMismatchMultiple=The certificate is only valid for the following names:
certErrorMismatchNoNames=The certificate is not valid for any server names.

View File

@ -103,6 +103,7 @@ CPPSRCS = \
nsRandomGenerator.cpp \
NSSErrorsService.cpp \
nsNSSCertificateFakeTransport.cpp \
PSMRunnable.cpp \
$(NULL)
ifdef MOZ_XUL

View File

@ -0,0 +1,68 @@
/* ***** 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 Firefox.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation <http://www.mozilla.org/>.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#include "PSMRunnable.h"
namespace mozilla { namespace psm {
SyncRunnableBase::SyncRunnableBase()
: monitor("SyncRunnableBase::monitor")
{
}
nsresult
SyncRunnableBase::DispatchToMainThreadAndWait()
{
NS_ASSERTION(!NS_IsMainThread(),
"DispatchToMainThreadAndWait called on the main thread.");
mozilla::MonitorAutoLock lock(monitor);
nsresult rv = NS_DispatchToMainThread(this);
if (NS_SUCCEEDED(rv)) {
lock.Wait();
}
return rv;
}
NS_IMETHODIMP
SyncRunnableBase::Run()
{
RunOnTargetThread();
mozilla::MonitorAutoLock(monitor).Notify();
return NS_OK;
}
} } // namespace mozilla::psm

View File

@ -0,0 +1,62 @@
/* ***** 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 Firefox.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation <http://www.mozilla.org/>.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#ifndef PSMRunnable_h
#define PSMRunnable_h
#include "mozilla/Monitor.h"
#include "nsThreadUtils.h"
namespace mozilla { namespace psm {
// Wait for the event to run on the target thread without spinning the event
// loop on the calling thread. (Dispatching events to a thread using
// NS_DISPATCH_SYNC would cause the event loop on the calling thread to spin.)
class SyncRunnableBase : public nsRunnable
{
public:
NS_DECL_NSIRUNNABLE
nsresult DispatchToMainThreadAndWait();
protected:
SyncRunnableBase();
virtual void RunOnTargetThread() = 0;
private:
mozilla::Monitor monitor;
};
} } // namespace mozilla::psm
#endif

View File

@ -50,7 +50,7 @@
#include "nsIObserverService.h"
#include "nsISupportsPrimitives.h"
#include "nsPromiseFlatString.h"
#include "nsProxiedService.h"
#include "nsThreadUtils.h"
#include "nsStringBuffer.h"
#include "nsAutoPtr.h"
#include "nspr.h"
@ -131,6 +131,11 @@ nsCertOverrideService::~nsCertOverrideService()
nsresult
nsCertOverrideService::Init()
{
if (!NS_IsMainThread()) {
NS_NOTREACHED("nsCertOverrideService initialized off main thread");
return NS_ERROR_NOT_SAME_THREAD;
}
if (!mSettingsTable.Init())
return NS_ERROR_OUT_OF_MEMORY;
@ -147,30 +152,24 @@ nsCertOverrideService::Init()
mDottedOidForStoringNewHashes = dotted_oid;
PR_smprintf_free(dotted_oid);
// cache mSettingsFile
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mSettingsFile));
if (mSettingsFile) {
mSettingsFile->AppendNative(NS_LITERAL_CSTRING(kCertOverrideFileName));
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
Read();
nsresult rv;
NS_WITH_ALWAYS_PROXIED_SERVICE(nsIObserverService, mObserverService,
"@mozilla.org/observer-service;1",
NS_PROXY_TO_MAIN_THREAD, &rv);
if (mObserverService) {
mObserverService->AddObserver(this, "profile-before-change", PR_TRUE);
mObserverService->AddObserver(this, "profile-do-change", PR_TRUE);
mObserverService->AddObserver(this, "shutdown-cleanse", PR_TRUE);
// If we cannot add ourselves as a profile change observer, then we will not
// attempt to read/write any settings file. Otherwise, we would end up
// reading/writing the wrong settings file after a profile change.
if (observerService) {
observerService->AddObserver(this, "profile-before-change", true);
observerService->AddObserver(this, "profile-do-change", true);
// simulate a profile change so we read the current profile's settings file
Observe(nsnull, "profile-do-change", nsnull);
}
return NS_OK;
}
NS_IMETHODIMP
nsCertOverrideService::Observe(nsISupports *aSubject,
nsCertOverrideService::Observe(nsISupports *,
const char *aTopic,
const PRUnichar *aData)
{
@ -201,6 +200,8 @@ nsCertOverrideService::Observe(nsISupports *aSubject,
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mSettingsFile));
if (NS_SUCCEEDED(rv)) {
mSettingsFile->AppendNative(NS_LITERAL_CSTRING(kCertOverrideFileName));
} else {
mSettingsFile = nsnull;
}
Read();
@ -243,6 +244,10 @@ nsCertOverrideService::Read()
{
ReentrantMonitorAutoEnter lock(monitor);
// If we don't have a profile, then we won't try to read any settings file.
if (!mSettingsFile)
return NS_OK;
nsresult rv;
nsCOMPtr<nsIInputStream> fileInputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), mSettingsFile);
@ -362,8 +367,9 @@ nsCertOverrideService::Write()
{
ReentrantMonitorAutoEnter lock(monitor);
// If we don't have any profile, then we won't try to write any file
if (!mSettingsFile) {
return NS_ERROR_NULL_POINTER;
return NS_OK;
}
nsresult rv;

View File

@ -1694,15 +1694,6 @@ nsNSSComponent::InitializeNSS(bool showWarningBox)
}
}
{
nsCOMPtr<nsICertOverrideService> icos =
do_GetService("@mozilla.org/security/certoverride;1", &rv);
if (NS_FAILED(rv)) {
nsPSMInitPanic::SetPanic();
return rv;
}
}
hashTableCerts = PL_NewHashTable( 0, certHashtable_keyHash, certHashtable_keyCompare,
certHashtable_valueCompare, 0, 0 );

View File

@ -45,7 +45,6 @@
#include "prlog.h"
#include "prnetdb.h"
#include "nsIPrompt.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIServiceManager.h"
@ -65,7 +64,6 @@
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsRecentBadCerts.h"
#include "nsISSLCertErrorDialog.h"
#include "nsIStrictTransportSecurityService.h"
#include "nsXPIDLString.h"
@ -88,6 +86,7 @@
#include "nsIProgrammingLanguage.h"
#include "nsIArray.h"
#include "nsCharSeparatedTokenizer.h"
#include "PSMRunnable.h"
#include "ssl.h"
#include "secerr.h"
@ -100,6 +99,7 @@
#include "secport.h"
using namespace mozilla;
using namespace mozilla::psm;
//#define DEBUG_SSL_VERBOSE //Enable this define to get minimal
//reports when doing SSL read/write
@ -441,20 +441,11 @@ nsNSSSocketInfo::EnsureDocShellDependentStuffKnown()
return NS_OK;
}
nsresult
nsNSSSocketInfo::GetExternalErrorReporting(bool* state)
bool
nsNSSSocketInfo::GetExternalErrorReporting()
{
nsresult rv = EnsureDocShellDependentStuffKnown();
NS_ENSURE_SUCCESS(rv, rv);
*state = mExternalErrorReporting;
return NS_OK;
}
nsresult
nsNSSSocketInfo::SetExternalErrorReporting(bool aState)
{
mExternalErrorReporting = aState;
return NS_OK;
return NS_SUCCEEDED(rv) && mExternalErrorReporting;
}
NS_IMETHODIMP
@ -551,10 +542,9 @@ nsNSSSocketInfo::GetErrorMessage(PRUnichar** aText) {
return NS_OK;
}
nsresult
void
nsNSSSocketInfo::SetErrorMessage(const PRUnichar* aText) {
mErrorMessage.Assign(aText);
return NS_OK;
}
/* void getInterface (in nsIIDRef uuid, [iid_is (uuid), retval] out nsQIResult result); */
@ -951,7 +941,6 @@ static nsresult
getErrorMessage(PRInt32 err,
const nsString &host,
PRInt32 port,
bool externalErrorReporting,
nsINSSComponent *component,
nsString &returnedMessage)
{
@ -964,14 +953,14 @@ getErrorMessage(PRInt32 err,
{
nsString hostWithPort;
// For now, hide port when it's 443 and we're reporting the error using
// external reporting. In the future a better mechanism should be used
// For now, hide port when it's 443 and we're reporting the error.
// In the future a better mechanism should be used
// to make a decision about showing the port number, possibly by requiring
// the context object to implement a specific interface.
// The motivation is that Mozilla browser would like to hide the port number
// in error pages in the common case.
if (externalErrorReporting && port == 443) {
if (port == 443) {
params[0] = host.get();
}
else {
@ -1148,7 +1137,6 @@ static void
AppendErrorTextMismatch(const nsString &host,
nsIX509Cert* ix509,
nsINSSComponent *component,
bool wantsHtml,
nsString &returnedMessage)
{
const PRUnichar *params[1];
@ -1212,14 +1200,8 @@ AppendErrorTextMismatch(const nsString &host,
const PRUnichar *params[1];
params[0] = allNames.get();
const char *stringID;
if (wantsHtml)
stringID = "certErrorMismatchSingle2";
else
stringID = "certErrorMismatchSinglePlain";
nsString formattedString;
rv = component->PIPBundleFormatStringFromName(stringID,
rv = component->PIPBundleFormatStringFromName("certErrorMismatchSingle2",
params, 1,
formattedString);
if (NS_SUCCEEDED(rv)) {
@ -1345,7 +1327,7 @@ AppendErrorTextCode(PRErrorCode errorCodeToReport,
}
}
static nsresult
static void
getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
PRErrorCode errorCodeToReport,
PRErrorCode errTrust,
@ -1355,31 +1337,29 @@ getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
const nsString &hostWithPort,
PRInt32 port,
nsIX509Cert* ix509,
bool externalErrorReporting,
bool wantsHtml,
nsINSSComponent *component,
nsString &returnedMessage)
{
NS_ENSURE_ARG_POINTER(component);
const PRUnichar *params[1];
nsresult rv;
// For now, hide port when it's 443 and we're reporting the error using
// external reporting. In the future a better mechanism should be used
// For now, hide port when it's 443 and we're reporting the error.
// In the future a better mechanism should be used
// to make a decision about showing the port number, possibly by requiring
// the context object to implement a specific interface.
// The motivation is that Mozilla browser would like to hide the port number
// in error pages in the common case.
if (externalErrorReporting && port == 443)
if (port == 443)
params[0] = host.get();
else
params[0] = hostWithPort.get();
nsCOMPtr<nsINSSComponent> component = do_GetService(kNSSComponentCID, &rv);
if (NS_FAILED(rv))
return;
nsString formattedString;
rv = component->PIPBundleFormatStringFromName("certErrorIntro",
params, 1,
rv = component->PIPBundleFormatStringFromName("certErrorIntro", params, 1,
formattedString);
if (NS_SUCCEEDED(rv))
{
@ -1395,7 +1375,7 @@ getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
if (multipleCollectedErrors & nsICertOverrideService::ERROR_MISMATCH)
{
AppendErrorTextMismatch(host, ix509, component, wantsHtml, returnedMessage);
AppendErrorTextMismatch(host, ix509, component, returnedMessage);
}
if (multipleCollectedErrors & nsICertOverrideService::ERROR_TIME)
@ -1404,199 +1384,66 @@ getInvalidCertErrorMessage(PRUint32 multipleCollectedErrors,
}
AppendErrorTextCode(errorCodeToReport, component, returnedMessage);
return NS_OK;
}
static nsresult
displayAlert(nsAFlatString &formattedString, nsNSSSocketInfo *infoObject)
{
// The interface requestor object may not be safe, so proxy the call to get
// the nsIPrompt.
if (nsSSLThread::stoppedOrStopping())
return NS_ERROR_FAILURE;
nsCOMPtr<nsIInterfaceRequestor> proxiedCallbacks;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIInterfaceRequestor),
static_cast<nsIInterfaceRequestor*>(infoObject),
NS_PROXY_SYNC,
getter_AddRefs(proxiedCallbacks));
nsCOMPtr<nsIPrompt> prompt (do_GetInterface(proxiedCallbacks));
if (!prompt)
return NS_ERROR_NO_INTERFACE;
// Finally, get a proxy for the nsIPrompt
nsCOMPtr<nsIPrompt> proxyPrompt;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIPrompt),
prompt,
NS_PROXY_SYNC,
getter_AddRefs(proxyPrompt));
proxyPrompt->Alert(nsnull, formattedString.get());
return NS_OK;
}
static nsresult
static void
nsHandleSSLError(nsNSSSocketInfo *socketInfo, PRInt32 err)
{
if (!NS_IsMainThread()) {
NS_ERROR("nsHandleSSLError called off the main thread");
return;
}
// SetCanceled is only called by the main thread or the SSL thread. Whenever
// this function is called, the SSL thread is waiting on this thread (the
// main thread). So, no mutex is necessary for SetCanceled()/GetCanceled().
if (socketInfo->GetCanceled()) {
// If the socket has been flagged as canceled,
// the code who did was responsible for showing
// an error message (if desired).
return NS_OK;
return;
}
if (nsSSLThread::stoppedOrStopping()) {
return NS_ERROR_FAILURE;
return;
}
nsresult rv;
NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID);
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv));
if (NS_FAILED(rv))
return rv;
return;
nsXPIDLCString hostName;
socketInfo->GetHostName(getter_Copies(hostName));
NS_ConvertASCIItoUTF16 hostNameU(hostName);
PRInt32 port;
socketInfo->GetPort(&port);
bool suppressMessage = false;
// Try to get a nsISSLErrorListener implementation from the socket consumer.
nsCOMPtr<nsIInterfaceRequestor> cb;
socketInfo->GetNotificationCallbacks(getter_AddRefs(cb));
if (cb) {
nsCOMPtr<nsIInterfaceRequestor> callbacks;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIInterfaceRequestor),
cb,
NS_PROXY_SYNC,
getter_AddRefs(callbacks));
nsCOMPtr<nsISSLErrorListener> sel = do_GetInterface(callbacks);
nsCOMPtr<nsISSLErrorListener> sel = do_GetInterface(cb);
if (sel) {
nsISSLErrorListener *proxy_sel = nsnull;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsISSLErrorListener),
sel,
NS_PROXY_SYNC,
(void**)&proxy_sel);
if (proxy_sel) {
nsIInterfaceRequestor *csi = static_cast<nsIInterfaceRequestor*>(socketInfo);
bool suppressMessage = false;
nsCString hostWithPortString = hostName;
hostWithPortString.AppendLiteral(":");
hostWithPortString.AppendInt(port);
rv = proxy_sel->NotifySSLError(csi, err, hostWithPortString,
&suppressMessage);
if (NS_SUCCEEDED(rv) && suppressMessage)
return NS_OK;
}
nsIInterfaceRequestor *csi = static_cast<nsIInterfaceRequestor*>(socketInfo);
nsCString hostWithPortString = hostName;
hostWithPortString.AppendLiteral(":");
hostWithPortString.AppendInt(port);
rv = sel->NotifySSLError(csi, err, hostWithPortString, &suppressMessage);
if (NS_SUCCEEDED(rv) && suppressMessage)
return;
}
}
bool external = false;
socketInfo->GetExternalErrorReporting(&external);
nsString formattedString;
rv = getErrorMessage(err, hostNameU, port, external, nssComponent, formattedString);
if (external)
{
if (socketInfo->GetExternalErrorReporting()) {
NS_ConvertASCIItoUTF16 hostNameU(hostName);
nsString formattedString;
(void) getErrorMessage(err, hostNameU, port, nssComponent, formattedString);
socketInfo->SetErrorMessage(formattedString.get());
}
else
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
rv = displayAlert(formattedString, socketInfo);
}
}
return rv;
}
static nsresult
nsHandleInvalidCertError(nsNSSSocketInfo *socketInfo,
PRUint32 multipleCollectedErrors,
const nsACString &host,
const nsACString &hostWithPort,
PRInt32 port,
PRErrorCode errorCodeToReport,
PRErrorCode errTrust,
PRErrorCode errMismatch,
PRErrorCode errExpired,
bool wantsHtml,
nsIX509Cert* ix509)
{
nsresult rv;
NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID);
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv));
if (NS_FAILED(rv))
return rv;
NS_ConvertASCIItoUTF16 hostU(host);
NS_ConvertASCIItoUTF16 hostWithPortU(hostWithPort);
// What mechanism is used to inform the user?
// The highest priority has the "external error reporting" feature,
// if set, we'll provide the strings to be used by the nsINSSErrorsService
bool external = false;
socketInfo->GetExternalErrorReporting(&external);
nsString formattedString;
rv = getInvalidCertErrorMessage(multipleCollectedErrors, errorCodeToReport,
errTrust, errMismatch, errExpired,
hostU, hostWithPortU, port,
ix509, external, wantsHtml,
nssComponent, formattedString);
if (external)
{
socketInfo->SetErrorMessage(formattedString.get());
}
else
{
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
nsISSLCertErrorDialog *dialogs = nsnull;
rv = getNSSDialogs((void**)&dialogs,
NS_GET_IID(nsISSLCertErrorDialog),
NS_SSLCERTERRORDIALOG_CONTRACTID);
if (NS_SUCCEEDED(rv)) {
nsPSMUITracker tracker;
if (tracker.isUIForbidden()) {
rv = NS_ERROR_NOT_AVAILABLE;
}
else {
nsCOMPtr<nsISSLStatus> status;
socketInfo->GetSSLStatus(getter_AddRefs(status));
nsString empty;
rv = dialogs->ShowCertError(nsnull, status, ix509,
formattedString,
empty, host, port);
}
NS_RELEASE(dialogs);
}
}
}
return rv;
}
static PRStatus PR_CALLBACK
@ -1948,6 +1795,23 @@ isTLSIntoleranceError(PRInt32 err, bool withInitialCleartext)
return PR_FALSE;
}
class SSLErrorRunnable : public SyncRunnableBase
{
public:
SSLErrorRunnable(nsNSSSocketInfo * infoObject, PRErrorCode errorCode)
: mInfoObject(infoObject), mErrorCode(errorCode)
{
}
virtual void RunOnTargetThread()
{
nsHandleSSLError(mInfoObject, mErrorCode);
}
nsRefPtr<nsNSSSocketInfo> mInfoObject;
const PRErrorCode mErrorCode;
};
PRInt32
nsSSLThread::checkHandshake(PRInt32 bytesTransfered,
bool wasReading,
@ -2009,7 +1873,9 @@ nsSSLThread::checkHandshake(PRInt32 bytesTransfered,
// This is the common place where we trigger an error message on a SSL socket.
// This might be reached at any time of the connection.
if (!wantRetry && (IS_SSL_ERROR(err) || IS_SEC_ERROR(err))) {
nsHandleSSLError(socketInfo, err);
nsRefPtr<SyncRunnableBase> runnable = new SSLErrorRunnable(socketInfo,
err);
(void) runnable->DispatchToMainThreadAndWait();
}
}
else if (wasReading && 0 == bytesTransfered) // zero bytes on reading, socket closed
@ -3331,6 +3197,35 @@ done:
return ret;
}
class CertErrorRunnable : public SyncRunnableBase
{
public:
CertErrorRunnable(const void * fdForLogging,
nsIX509Cert * cert,
nsNSSSocketInfo * infoObject,
const CERTVerifyLog * verify_log,
bool hasCertNameMismatch,
PRErrorCode defaultErrorCodeToReport)
: mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject),
mVerifyLog(verify_log), mHasCertNameMismatch(hasCertNameMismatch),
mRv(SECFailure), mErrorCodeToReport(defaultErrorCodeToReport)
{
}
virtual void RunOnTargetThread();
// in
const void * const mFdForLogging;
nsCOMPtr<nsIX509Cert> mCert;
nsNSSSocketInfo * const mInfoObject;
const CERTVerifyLog * const mVerifyLog;
const bool mHasCertNameMismatch;
nsXPIDLCString mHostname;
SECStatus mRv; // out
PRErrorCode mErrorCodeToReport; // in/out
};
static SECStatus
cancel_and_failure(nsNSSSocketInfo* infoObject)
{
@ -3345,9 +3240,15 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
// Calling cancel_and_failure is not necessary, and would be wrong,
// [for errors other than the ones explicitly handled below,]
// because it suppresses error reporting.
if (PR_GetError() == SEC_ERROR_REVOKED_CERTIFICATE)
PRErrorCode defaultErrorCodeToReport = PR_GetError();
if (defaultErrorCodeToReport == SEC_ERROR_REVOKED_CERTIFICATE)
return SECFailure;
if (defaultErrorCodeToReport == 0) {
NS_ERROR("No error code set during certificate validation failure.");
defaultErrorCodeToReport = SEC_ERROR_CERT_NOT_VALID;
}
nsNSSShutDownPreventionLock locker;
nsNSSSocketInfo* infoObject = (nsNSSSocketInfo *)arg;
if (!infoObject)
@ -3367,16 +3268,8 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
if (!nssCert)
return cancel_and_failure(infoObject);
nsCOMPtr<nsIX509Cert> ix509 = static_cast<nsIX509Cert*>(nssCert.get());
SECStatus srv;
nsresult nsrv;
PRUint32 collected_errors = 0;
PRUint32 remaining_display_errors = 0;
PRErrorCode errorCodeTrust = SECSuccess;
PRErrorCode errorCodeMismatch = SECSuccess;
PRErrorCode errorCodeExpired = SECSuccess;
nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
@ -3391,23 +3284,10 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
return cancel_and_failure(infoObject);
charCleaner hostnameCleaner(hostname);
nsDependentCString hostString(hostname);
PRInt32 port;
infoObject->GetPort(&port);
nsCString hostWithPortString = hostString;
hostWithPortString.AppendLiteral(":");
hostWithPortString.AppendInt(port);
NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString);
// Check the name field against the desired hostname.
if (hostname[0] &&
CERT_VerifyCertName(peerCert, hostname) != SECSuccess) {
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
bool hasCertNameMismatch =
hostname[0] && CERT_VerifyCertName(peerCert, hostname) != SECSuccess;
{
PRArenaPool *log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@ -3426,7 +3306,7 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
srv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), peerCert,
PR_TRUE, certificateUsageSSLServer,
true, certificateUsageSSLServer,
PR_Now(), (void*)infoObject,
verify_log, NULL);
}
@ -3441,18 +3321,79 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
cvout, (void*)infoObject);
}
if (infoObject->IsCertIssuerBlacklisted()) {
collected_errors |= nsICertOverrideService::ERROR_UNTRUSTED;
}
// We ignore the result code of the cert verification.
// Either it is a failure, which is expected, and we'll process the
// verify log below.
// Or it is a success, then a domain mismatch is the only
// possible failure.
nsRefPtr<CertErrorRunnable> runnable =
new CertErrorRunnable(static_cast<void*>(sslSocket),
static_cast<nsIX509Cert*>(nssCert.get()),
infoObject, verify_log, hasCertNameMismatch,
defaultErrorCodeToReport);
// now grab the host name to pass to the STS Service
nsrv = infoObject->GetHostName(getter_Copies(runnable->mHostname));
if (NS_FAILED(nsrv)) {
PR_SetError(defaultErrorCodeToReport, 0);
return SECFailure;
}
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p][%p] Before dispatching CertErrorRunnable\n",
sslSocket, runnable.get()));
// Dispatch SYNC since the result is used below
(void) runnable->DispatchToMainThreadAndWait();
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p][%p] After dispatching CertErrorRunnable\n",
sslSocket, runnable.get()));
if (runnable->mRv == SECSuccess)
return SECSuccess;
NS_ASSERTION(runnable->mErrorCodeToReport != 0,
"CertErrorRunnable did not set error code.");
PR_SetError(runnable->mErrorCodeToReport ? runnable->mErrorCodeToReport
: defaultErrorCodeToReport, 0);
return SECFailure;
}
}
void CertErrorRunnable::RunOnTargetThread()
{
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p][%p] top of CertErrorRunnable::Run\n",
mFdForLogging, this));
if (!NS_IsMainThread()) {
NS_ERROR("CertErrorRunnable::RunOnTargetThread called off main thread");
return;
}
if (nsSSLThread::stoppedOrStopping())
return;
PRErrorCode errorCodeMismatch = 0;
PRErrorCode errorCodeTrust = 0;
PRErrorCode errorCodeExpired = 0;
PRUint32 collected_errors = 0;
if (mInfoObject->IsCertIssuerBlacklisted()) {
collected_errors |= nsICertOverrideService::ERROR_UNTRUSTED;
errorCodeTrust = mErrorCodeToReport;
}
if (mHasCertNameMismatch) {
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
{
CERTVerifyLogNode *i_node;
for (i_node = verify_log->head; i_node; i_node = i_node->next)
for (i_node = mVerifyLog->head; i_node; i_node = i_node->next)
{
switch (i_node->error)
{
@ -3482,11 +3423,12 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
break;
default:
// we are not willing to continue on any other error
nsHandleSSLError(infoObject, i_node->error);
nsHandleSSLError(mInfoObject, i_node->error);
// this error is our stop condition, so let's make sure
// this error code will be reported to the external world.
PR_SetError(i_node->error, 0);
return cancel_and_failure(infoObject);
mErrorCodeToReport = i_node->error;
mInfoObject->SetCanceled(true);
return;
}
}
}
@ -3494,53 +3436,57 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
if (!collected_errors)
{
NS_NOTREACHED("why did NSS call our bad cert handler if all looks good? Let's cancel the connection");
return SECFailure;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p][%p] !collected_errors\n",
mFdForLogging, this));
return;
}
nsRefPtr<nsSSLStatus> status = infoObject->SSLStatus();
nsRefPtr<nsSSLStatus> status = mInfoObject->SSLStatus();
if (!status) {
status = new nsSSLStatus();
infoObject->SetSSLStatus(status);
mInfoObject->SetSSLStatus(status);
}
if (status) {
if (!status->mServerCert) {
status->mServerCert = nssCert;
status->mServerCert = mCert;
}
status->mHaveCertErrorBits = PR_TRUE;
status->mHaveCertErrorBits = true;
status->mIsDomainMismatch = collected_errors & nsICertOverrideService::ERROR_MISMATCH;
status->mIsNotValidAtThisTime = collected_errors & nsICertOverrideService::ERROR_TIME;
status->mIsUntrusted = collected_errors & nsICertOverrideService::ERROR_UNTRUSTED;
nsSSLIOLayerHelpers::mHostsWithCertErrors->RememberCertHasError(
infoObject, status, SECFailure);
mInfoObject, status, SECFailure);
}
remaining_display_errors = collected_errors;
nsDependentCString hostString(mHostname);
PRInt32 port;
mInfoObject->GetPort(&port);
nsCString hostWithPortString = hostString;
hostWithPortString.AppendLiteral(":");
hostWithPortString.AppendInt(port);
NS_ConvertUTF8toUTF16 hostWithPortStringUTF16(hostWithPortString);
PRUint32 remaining_display_errors = collected_errors;
nsresult nsrv;
// Enforce Strict-Transport-Security for hosts that are "STS" hosts:
// connections must be dropped when there are any certificate errors
// (STS Spec section 7.3).
bool strictTransportSecurityEnabled = false;
nsCOMPtr<nsIStrictTransportSecurityService> stss
= do_GetService(NS_STSSERVICE_CONTRACTID);
nsCOMPtr<nsIStrictTransportSecurityService> proxied_stss;
nsrv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIStrictTransportSecurityService),
stss, NS_PROXY_SYNC,
getter_AddRefs(proxied_stss));
NS_ENSURE_SUCCESS(nsrv, SECFailure);
// now grab the host name to pass to the STS Service
nsXPIDLCString hostName;
nsrv = infoObject->GetHostName(getter_Copies(hostName));
NS_ENSURE_SUCCESS(nsrv, SECFailure);
bool strictTransportSecurityEnabled;
nsrv = proxied_stss->IsStsHost(hostName, &strictTransportSecurityEnabled);
NS_ENSURE_SUCCESS(nsrv, SECFailure);
= do_GetService(NS_STSSERVICE_CONTRACTID, &nsrv);
if (NS_SUCCEEDED(nsrv)) {
nsrv = stss->IsStsHost(mHostname, &strictTransportSecurityEnabled);
}
if (NS_FAILED(nsrv))
return; // use default rv and errorCodeToReport
if (!strictTransportSecurityEnabled) {
nsCOMPtr<nsICertOverrideService> overrideService =
@ -3555,7 +3501,7 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
bool isTemporaryOverride; // we don't care
nsrv = overrideService->HasMatchingOverride(hostString, port,
ix509,
mCert,
&overrideBits,
&isTemporaryOverride,
&haveOverride);
@ -3568,43 +3514,36 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
if (!remaining_display_errors) {
// all errors are covered by override rules, so let's accept the cert
return SECSuccess;
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p][%p] All errors covered by override rules\n",
mFdForLogging, this));
mRv = SECSuccess;
return;
}
} else {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Strict-Transport-Security is violated: untrusted transport layer\n"));
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p][%p] Strict-Transport-Security is violated: untrusted "
"transport layer\n", mFdForLogging, this));
}
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("[%p][%p] Certificate error was not overridden\n",
mFdForLogging, this));
// Ok, this is a full stop.
// First, deliver the technical details of the broken SSL status,
// giving the caller a chance to suppress the error messages.
bool suppressMessage = false;
nsresult rv;
// Try to get a nsIBadCertListener2 implementation from the socket consumer.
nsCOMPtr<nsIInterfaceRequestor> cb;
infoObject->GetNotificationCallbacks(getter_AddRefs(cb));
mInfoObject->GetNotificationCallbacks(getter_AddRefs(cb));
if (cb) {
nsCOMPtr<nsIInterfaceRequestor> callbacks;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIInterfaceRequestor),
cb,
NS_PROXY_SYNC,
getter_AddRefs(callbacks));
nsCOMPtr<nsIBadCertListener2> bcl = do_GetInterface(callbacks);
nsCOMPtr<nsIBadCertListener2> bcl = do_GetInterface(cb);
if (bcl) {
nsCOMPtr<nsIBadCertListener2> proxy_bcl;
NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
NS_GET_IID(nsIBadCertListener2),
bcl,
NS_PROXY_SYNC,
getter_AddRefs(proxy_bcl));
if (proxy_bcl) {
nsIInterfaceRequestor *csi = static_cast<nsIInterfaceRequestor*>(infoObject);
rv = proxy_bcl->NotifyCertProblem(csi, status, hostWithPortString,
&suppressMessage);
}
nsIInterfaceRequestor *csi = static_cast<nsIInterfaceRequestor*>(mInfoObject);
nsrv = bcl->NotifyCertProblem(csi, status, hostWithPortString, &suppressMessage);
}
}
@ -3616,33 +3555,26 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
}
// pick the error code to report by priority
PRErrorCode errorCodeToReport = SECSuccess;
mErrorCodeToReport = 0;
if (remaining_display_errors & nsICertOverrideService::ERROR_UNTRUSTED)
errorCodeToReport = errorCodeTrust;
mErrorCodeToReport = errorCodeTrust;
else if (remaining_display_errors & nsICertOverrideService::ERROR_MISMATCH)
errorCodeToReport = errorCodeMismatch;
mErrorCodeToReport = errorCodeMismatch;
else if (remaining_display_errors & nsICertOverrideService::ERROR_TIME)
errorCodeToReport = errorCodeExpired;
mErrorCodeToReport = errorCodeExpired;
if (!suppressMessage) {
bool external = false;
infoObject->GetExternalErrorReporting(&external);
nsHandleInvalidCertError(infoObject,
remaining_display_errors,
hostString,
hostWithPortString,
port,
errorCodeToReport,
errorCodeTrust,
errorCodeMismatch,
errorCodeExpired,
external, // wantsHtml
ix509);
if (!suppressMessage && mInfoObject->GetExternalErrorReporting()) {
NS_ConvertASCIItoUTF16 hostU(hostString);
NS_ConvertASCIItoUTF16 hostWithPortU(hostWithPortString);
nsString formattedString;
getInvalidCertErrorMessage(remaining_display_errors, mErrorCodeToReport,
errorCodeTrust, errorCodeMismatch,
errorCodeExpired, hostU, hostWithPortU, port,
mCert, formattedString);
mInfoObject->SetErrorMessage(formattedString.get());
}
PR_SetError(errorCodeToReport, 0);
return cancel_and_failure(infoObject);
mInfoObject->SetCanceled(true);
}
static PRFileDesc*

View File

@ -156,7 +156,7 @@ public:
nsresult SetSecurityState(PRUint32 aState);
nsresult SetShortSecurityDescription(const PRUnichar *aText);
nsresult SetErrorMessage(const PRUnichar *aText);
void SetErrorMessage(const PRUnichar *aText);
nsresult SetForSTARTTLS(bool aForSTARTTLS);
nsresult GetForSTARTTLS(bool *aForSTARTTLS);
@ -190,8 +190,7 @@ public:
void SetAllowTLSIntoleranceTimeout(bool aAllow);
nsresult GetExternalErrorReporting(bool* state);
nsresult SetExternalErrorReporting(bool aState);
bool GetExternalErrorReporting();
nsresult RememberCAChain(CERTCertList *aCertList);

View File

@ -1 +1 @@
NSS_3_13_BETA1
NSS_3_13_RC0

View File

@ -50,7 +50,7 @@
#include "plgetopt.h"
#include "softoken.h"
#include "nspr.h"
#include "nssutil.h"
#include "secport.h"
#include "secoid.h"
#ifdef NSS_ENABLE_ECC
@ -78,7 +78,7 @@ char *testdir = NULL;
if (rv) { \
PRErrorCode prerror = PR_GetError(); \
PR_fprintf(PR_STDERR, "%s: ERR %d (%s) at line %d.\n", progName, \
prerror, NSS_Strerror(prerror,formatSimple), ln); \
prerror, PORT_ErrorToString(prerror), ln); \
exit(-1); \
}
@ -271,7 +271,7 @@ atob(SECItem *ascii, SECItem *binary, PRArenaPool *arena)
binary->len = 0;
it.item = binary;
it.arena = arena;
len = (strncmp(&ascii->data[ascii->len-2],"\r\n",2)) ?
len = (strncmp((const char *)&ascii->data[ascii->len-2],"\r\n",2)) ?
ascii->len : ascii->len-2;
cx = NSSBase64Decoder_Create(get_binary, &it);
status = NSSBase64Decoder_Update(cx, (const char *)ascii->data, len);
@ -296,9 +296,6 @@ btoa_file(SECItem *binary, PRFileDesc *outfile)
{
SECStatus status;
NSSBase64Encoder *cx;
SECItem ascii;
ascii.data = NULL;
ascii.len = 0;
if (binary->len == 0)
return SECSuccess;
cx = NSSBase64Encoder_Create(output_ascii, outfile);
@ -354,9 +351,6 @@ serialize_key(SECItem *it, int ni, PRFileDesc *file)
int i;
SECStatus status;
NSSBase64Encoder *cx;
SECItem ascii;
ascii.data = NULL;
ascii.len = 0;
cx = NSSBase64Encoder_Create(output_ascii, file);
for (i=0; i<ni; i++, it++) {
len[0] = (it->len >> 24) & 0xff;

View File

@ -1106,7 +1106,7 @@ static void luCommonDetailsAE()
" -t trustargs");
FPS "%-25s trustargs is of the form x,y,z where x is for SSL, y is for S/MIME,\n", "");
FPS "%-25s and z is for code signing. Use ,, for no explicit trust.\n", "");
FPS "%-25s p \t prohibited\n", "");
FPS "%-25s p \t prohibited (explicitly distrusted)\n", "");
FPS "%-25s P \t trusted peer\n", "");
FPS "%-25s c \t valid CA\n", "");
FPS "%-25s T \t trusted CA to issue client certs (implies c)\n", "");

View File

@ -248,7 +248,8 @@ static SECStatus DeleteCRL (CERTCertDBHandle *certHandle, char *name, int type)
}
SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type,
PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions)
PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions,
secuPWData *pwdata)
{
CERTSignedCrl *crl = NULL;
SECItem crlDER;
@ -272,6 +273,12 @@ SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type,
decodeOptions |= CRL_DECODE_DONT_COPY_DER;
slot = PK11_GetInternalKeySlot();
if (PK11_NeedLogin(slot)) {
rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
if (rv != SECSuccess)
goto loser;
}
#if defined(DEBUG_jp96085)
starttime = PR_IntervalNow();
@ -299,6 +306,7 @@ SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type,
} else {
SEC_DestroyCrl (crl);
}
loser:
if (slot) {
PK11_FreeSlot(slot);
}
@ -1050,7 +1058,7 @@ int main(int argc, char **argv)
}
else if (importCRL) {
rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
decodeOptions);
decodeOptions, &pwdata);
} else if (generateCRL || modifyCRL) {
if (!inCrlInitFile)
inCrlInitFile = PR_STDIN;
@ -1072,7 +1080,7 @@ int main(int argc, char **argv)
ListCRLNames (certHandle, crlType, PR_FALSE);
/* import CRL as a blob */
rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
decodeOptions);
decodeOptions, &pwdata);
/* list CRLs */
ListCRLNames (certHandle, crlType, PR_FALSE);
}

View File

@ -40,11 +40,11 @@
#include "secitem.h"
#include "blapi.h"
#include "nss.h"
#include "nssutil.h"
#include "secerr.h"
#include "secder.h"
#include "secdig.h"
#include "keythi.h"
#include "secoid.h"
#include "ec.h"
#include "hasht.h"
#include "lowkeyi.h"
@ -1972,10 +1972,10 @@ static CurveNameTagPair nameTagPair[] =
{ "sect131r2", SEC_OID_SECG_EC_SECT131R2},
};
static SECKEYECParams *
static SECItem *
getECParams(const char *curve)
{
SECKEYECParams *ecparams;
SECItem *ecparams;
SECOidData *oidData = NULL;
SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
int i, numCurves;
@ -2046,7 +2046,7 @@ ecdsa_keypair_test(char *reqfn)
if (buf[0] == '[') {
const char *src;
char *dst;
SECKEYECParams *encodedparams;
SECItem *encodedparams;
src = &buf[1];
dst = &curve[4];
@ -2152,7 +2152,7 @@ ecdsa_pkv_test(char *reqfn)
if (buf[0] == '[') {
const char *src;
char *dst;
SECKEYECParams *encodedparams;
SECItem *encodedparams;
src = &buf[1];
dst = &curve[4];
@ -2273,7 +2273,7 @@ ecdsa_siggen_test(char *reqfn)
if (buf[0] == '[') {
const char *src;
char *dst;
SECKEYECParams *encodedparams;
SECItem *encodedparams;
src = &buf[1];
dst = &curve[4];
@ -2416,7 +2416,7 @@ ecdsa_sigver_test(char *reqfn)
if (buf[0] == '[') {
const char *src;
char *dst;
SECKEYECParams *encodedparams;
SECItem *encodedparams;
ECParams *ecparams;
src = &buf[1];
@ -4235,7 +4235,7 @@ loser:
PQG_DestroyVerify(vfy);
vfy = NULL;
}
if (dsaKey) {
if (dsakey) {
PORT_FreeArena(dsakey->params.arena, PR_TRUE);
dsakey = NULL;
}
@ -4940,7 +4940,7 @@ loser:
int main(int argc, char **argv)
{
if (argc < 2) exit (-1);
NSS_NoDB_Init(NULL);
/*************/
/* TDEA */
/*************/

View File

@ -52,7 +52,6 @@ CSRCS = secutil.c \
derprint.c \
moreoids.c \
pppolicy.c \
secerror.c \
ffs.c \
pk11table.c \
$(NULL)

View File

@ -1,45 +0,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 the Netscape security libraries.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
#include "prtypes.h"
#include "nssutil.h"
/* Returns a UTF-8 encoded constant error string for "errNum".
* Returns NULL if errNum is unknown.
*/
const char *
SECU_Strerror(PRErrorCode errNum) {
return NSS_Strerror(errNum, formatSimple);
}

View File

@ -3679,8 +3679,8 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
}
}
}
fprintf(outfile," ERROR %ld: %s\n", node->error,
SECU_Strerror(node->error));
fprintf(outfile, " ERROR %ld: %s\n", node->error,
SECU_Strerror(node->error));
errstr = NULL;
switch (node->error) {
case SEC_ERROR_INADEQUATE_KEY_USAGE:

View File

@ -38,6 +38,7 @@
#include "seccomon.h"
#include "secitem.h"
#include "secport.h"
#include "prerror.h"
#include "base64.h"
#include "key.h"
@ -63,6 +64,8 @@
#define NS_CRL_HEADER "-----BEGIN CRL-----"
#define NS_CRL_TRAILER "-----END CRL-----"
#define SECU_Strerror PORT_ErrorToString
#ifdef SECUTIL_NEW
typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item,
char *msg, int level);
@ -171,9 +174,6 @@ extern void SECU_PrintError(char *progName, char *msg, ...);
/* print out a system error message */
extern void SECU_PrintSystemError(char *progName, char *msg, ...);
/* Return informative error string */
extern const char * SECU_Strerror(PRErrorCode errNum);
/* revalidate the cert and print information about cert verification
* failure at time == now */
extern void

View File

@ -1190,7 +1190,11 @@ client_main(
errExit("SSL_OptionSet SSL_SECURITY");
}
/* disabling SSL2 compatible hellos also disables SSL2 */
rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, !disableSSL2);
if (rv != SECSuccess) {
errExit("error enabling SSLv2 ");
}
rv = SSL_OptionSet(model_sock, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
if (rv != SECSuccess) {
errExit("error enabling SSLv2 compatible hellos ");

View File

@ -833,10 +833,9 @@ int main(int argc, char **argv)
return 1;
}
/* disable ssl2 and ssl2-compatible client hellos. */
rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error disabling v2 compatibility");
SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
return 1;
}

View File

@ -36,7 +36,7 @@
/*
* certi.h - private data structures for the certificate library
*
* $Id: certi.h,v 1.35 2011/01/29 22:17:20 nelson%bolyard.com Exp $
* $Id: certi.h,v 1.36 2011/09/14 23:16:14 wtc%google.com Exp $
*/
#ifndef _CERTI_H_
#define _CERTI_H_
@ -397,5 +397,19 @@ cert_GetSubjectAltNameList(CERTCertificate *cert, PRArenaPool *arena);
PRUint32
cert_CountDNSPatterns(CERTGeneralName *firstName);
/*
* returns the trust status of the leaf certificate based on usage.
* If the leaf is explicitly untrusted, this function will fail and
* failedFlags will be set to the trust bit value that lead to the failure.
* If the leaf is trusted, isTrusted is set to true and the function returns
* SECSuccess. This function does not check if the cert is fit for a
* particular usage.
*/
SECStatus
cert_CheckLeafTrust(CERTCertificate *cert,
SECCertUsage usage,
unsigned int *failedFlags,
PRBool *isTrusted);
#endif /* _CERTI_H_ */

View File

@ -388,6 +388,15 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
&trustType) != SECSuccess ) {
PORT_Assert(0);
EXIT_IF_NOT_LOGGING(log);
/* XXX continuing with requiredFlags = 0 seems wrong. It'll
* cause the following test to be true incorrectly:
* flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
* if (( flags & requiredFlags ) == requiredFlags) {
* rv = rvFinal;
* goto done;
* }
* There are three other instances of this problem.
*/
requiredFlags = 0;
trustType = trustSSL;
}
@ -581,10 +590,10 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
}
/* is it explicitly distrusted? */
if ((flags & CERTDB_TERMINAL_RECORD) &&
((flags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
/* untrusted -- the cert is explicitly untrusted, not
* just that it doesn't chain to a trusted cert */
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags);
}
} else {
@ -609,10 +618,10 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
/* is it explicitly distrusted? */
if ((flags & CERTDB_TERMINAL_RECORD) &&
((flags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
/* untrusted -- the cert is explicitly untrusted, not
* just that it doesn't chain to a trusted cert */
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);
LOG_ERROR_OR_EXIT(log,issuerCert,count+1,flags);
}
}
@ -742,7 +751,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool validCAOverride = PR_FALSE;
SECStatus rv;
SECStatus rvFinal = SECSuccess;
int flags;
unsigned int flags;
unsigned int caCertType;
unsigned int requiredCAKeyUsage;
unsigned int requiredFlags;
@ -839,7 +848,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
}
/*
* check the trust parms of the issuer
* check the trust params of the issuer
*/
flags = SEC_GET_TRUST_FLAGS(cert->trust, trustType);
if ( ( flags & requiredFlags ) == requiredFlags) {
@ -852,7 +861,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
}
/* is it explicitly distrusted? */
if ((flags & CERTDB_TERMINAL_RECORD) &&
((flags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
/* untrusted -- the cert is explicitly untrusted, not
* just that it doesn't chain to a trusted cert */
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
@ -970,11 +979,9 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
break;
case certUsageSSLCA:
flags = cert->trust->sslFlags;
/* we probably should also not explicitly fail the cert
* if only the trusted DELEGATOR flag is set */
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if (( flags & CERTDB_TRUSTED_CA ) == 0) {
if (( flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA) ) == 0) {
/* don't trust this cert */
*failedFlags = flags;
return SECFailure;
@ -1041,7 +1048,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
flags = cert->trust->sslFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ((flags & CERTDB_TRUSTED_CA) == 0) {
if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
*failedFlags = flags;
return SECFailure;
}
@ -1049,16 +1056,17 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
flags = cert->trust->emailFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ((flags & CERTDB_TRUSTED_CA) == 0) {
if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
*failedFlags = flags;
return SECFailure;
}
}
/* fall through */
case certUsageProtectedObjectSigner:
flags = cert->trust->objectSigningFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ((flags & CERTDB_TRUSTED_CA) == 0) {
if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
*failedFlags = flags;
return SECFailure;
}
@ -1196,8 +1204,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
}
LOG_ERROR(log, cert, 0, flags);
INVALID_USAGE();
}
if (trusted) {
} else if (trusted) {
VALID_USAGE();
}
@ -1328,8 +1335,7 @@ CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
if (rv == SECFailure) {
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
LOG_ERROR_OR_EXIT(log,cert,0,flags);
}
if (trusted) {
} else if (trusted) {
goto winner;
}

View File

@ -35,7 +35,7 @@
*
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.75 $ $Date: 2011/08/01 06:33:47 $""; @(#) $RCSfile: certdata.perl,v $ $Revision: 1.13 $ $Date: 2010/03/26 22:06:47 $";
static const char CVS_ID[] = "@(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $";
#endif /* DEBUG */
#ifndef BUILTINS_H
@ -1083,7 +1083,7 @@ static const NSSItem nss_builtins_items_0 [] = {
{ (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
{ (void *)"CVS ID", (PRUint32)7 },
{ (void *)"NSS", (PRUint32)4 },
{ (void *)"@(#) $RCSfile: certdata.txt,v $ $Revision: 1.75 $ $Date: 2011/08/01 06:33:47 $""; @(#) $RCSfile: certdata.perl,v $ $Revision: 1.13 $ $Date: 2010/03/26 22:06:47 $", (PRUint32)160 }
{ (void *)"@(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $""; @(#) $RCSfile: certdata.c,v $ $Revision: 1.82 $ $Date: 2011/09/02 19:40:56 $", (PRUint32)160 }
};
#endif /* DEBUG */
static const NSSItem nss_builtins_items_1 [] = {

View File

@ -34,7 +34,7 @@
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
CVS_ID "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.75 $ $Date: 2011/08/01 06:33:47 $"
CVS_ID "@(#) $RCSfile: certdata.txt,v $ $Revision: 1.79 $ $Date: 2011/09/02 19:40:56 $"
#
# certdata.txt

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.41 $ $Date: 2011/04/13 00:10:25 $";
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.42 $ $Date: 2011/09/14 00:28:48 $";
#endif /* DEBUG */
#include "pkcs11.h"
@ -437,6 +437,7 @@ nssCryptokiTrust_GetAttributes (
CK_TRUST csTrust = CKT_NSS_TRUST_UNKNOWN;
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE trust_template[7];
CK_ATTRIBUTE_PTR sha1_hash_attr;
CK_ULONG trust_size;
/* Use the trust object to find the trust settings */
@ -447,6 +448,7 @@ nssCryptokiTrust_GetAttributes (
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp);
sha1_hash_attr = attr;
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, sha1_hash);
NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
@ -473,6 +475,11 @@ nssCryptokiTrust_GetAttributes (
}
}
if (sha1_hash_attr->ulValueLen == -1) {
/* The trust object does not have the CKA_CERT_SHA1_HASH attribute. */
sha1_hash_attr->ulValueLen = 0;
}
sha1_hash->size = sha1_hash_attr->ulValueLen;
*serverAuth = get_nss_trust(saTrust);
*clientAuth = get_nss_trust(caTrust);
*emailProtection = get_nss_trust(epTrust);

View File

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: blapi.h,v 1.41 2010/12/06 17:22:49 kaie%kuix.de Exp $ */
/* $Id: blapi.h,v 1.42 2011/10/04 22:05:53 wtc%google.com Exp $ */
#ifndef _BLAPI_H_
#define _BLAPI_H_
@ -1257,13 +1257,6 @@ PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
extern SECStatus
PRNGTEST_Uninstantiate(void);
/*
* Mask generation function MGF1
*/
extern SECStatus
MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
const unsigned char *mgfSeed, unsigned int mgfSeedLen);
/* Generate PQGParams and PQGVerify structs.
* Length of seed and length of h both equal length of P.
* All lengths are specified by "j", according to the table above.

View File

@ -713,6 +713,27 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
goto cleanup;
}
/*
** We do not want timing information to leak the length of k,
** so we compute k*G using an equivalent scalar of fixed
** bit-length.
** Fix based on patch for ECDSA timing attack in the paper
** by Billy Bob Brumley and Nicola Tuveri at
** http://eprint.iacr.org/2011/232
**
** How do we convert k to a value of a fixed bit-length?
** k starts off as an integer satisfying 0 <= k < n. Hence,
** n <= k+n < 2n, which means k+n has either the same number
** of bits as n or one more bit than n. If k+n has the same
** number of bits as n, the second addition ensures that the
** final value has exactly one more bit than n. Thus, we
** always end up with a value that exactly one more bit than n.
*/
CHECK_MPI_OK( mp_add(&k, &n, &k) );
if (mpl_significant_bits(&k) <= mpl_significant_bits(&n)) {
CHECK_MPI_OK( mp_add(&k, &n, &k) );
}
/*
** ANSI X9.62, Section 5.3.2, Step 2
**

View File

@ -53,7 +53,6 @@ GFMethod *
GFMethod_consGFp_mont(const mp_int *irr)
{
mp_err res = MP_OKAY;
int i;
GFMethod *meth = NULL;
mp_mont_modulus *mmm;

View File

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: ldvector.c,v 1.28 2010/12/06 17:22:49 kaie%kuix.de Exp $ */
/* $Id: ldvector.c,v 1.29 2011/10/04 22:05:53 wtc%google.com Exp $ */
#ifdef FREEBL_NO_DEPEND
extern int FREEBL_InitStubs(void);
@ -273,7 +273,6 @@ static const struct FREEBLVectorStr vector =
/* End of Version 3.012 */
MGF1,
TLS_P_hash,
SHA224_NewContext,
SHA224_DestroyContext,

View File

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: loader.c,v 1.53 2011/01/15 19:54:49 nelson%bolyard.com Exp $ */
/* $Id: loader.c,v 1.54 2011/10/04 22:05:53 wtc%google.com Exp $ */
#include "loader.h"
#include "prmem.h"
@ -1758,15 +1758,6 @@ JPAKE_Final(PLArenaPool * arena, const SECItem * p, const SECItem *q,
return (vector->p_JPAKE_Final)(arena, p, q, x2, gx4, x2s, B, K);
}
SECStatus
MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
const unsigned char *mgfSeed, unsigned int mgfSeedLen)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return (vector->p_MGF1)(hashAlg, mask, maskLen, mgfSeed, mgfSeedLen);
}
SECStatus
TLS_P_hash(HASH_HashType hashAlg, const SECItem *secret, const char *label,
SECItem *seed, SECItem *result, PRBool isFIPS)

View File

@ -37,7 +37,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: loader.h,v 1.34 2011/03/29 15:12:44 wtc%google.com Exp $ */
/* $Id: loader.h,v 1.35 2011/10/04 22:05:53 wtc%google.com Exp $ */
#ifndef _LOADER_H_
#define _LOADER_H_ 1
@ -570,10 +570,6 @@ struct FREEBLVectorStr {
/* Version 3.012 came to here */
SECStatus (* p_MGF1)(HASH_HashType hashAlg,
unsigned char *mask, unsigned int maskLen,
const unsigned char *mgfSeed, unsigned int mgfSeedLen);
SECStatus (* p_TLS_P_hash)(HASH_HashType hashAlg,
const SECItem *secret,
const char *label,

View File

@ -128,7 +128,6 @@ CSRCS = \
md5.c \
sha512.c \
alghmac.c \
mgf1.c \
rawhash.c \
alg2268.c \
arcfour.c \

View File

@ -1,91 +0,0 @@
/*
* mgf1.c - implementation of MGF1 as defined in PKCS #1 v2.1 / RFC 3447
*
* ***** 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 the Netscape security libraries.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Hanno Boeck <hanno@hboeck.de>
*
* 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 ***** */
/* $Id: mgf1.c,v 1.2 2010/07/22 23:09:46 wtc%google.com Exp $ */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
#include "blapi.h"
#include "hasht.h"
SECStatus
MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
const unsigned char *mgfSeed, unsigned int mgfSeedLen)
{
unsigned int digestLen;
PRUint32 counter, rounds;
unsigned char *tempHash, *temp;
const SECHashObject *hash;
void *hashContext;
unsigned char C[4];
hash = HASH_GetRawHashObject(hashAlg);
if (hash == NULL)
return SECFailure;
hashContext = (*hash->create)();
rounds = (maskLen + hash->length - 1) / hash->length;
for (counter = 0; counter < rounds; counter++) {
C[0] = (unsigned char)((counter >> 24) & 0xff);
C[1] = (unsigned char)((counter >> 16) & 0xff);
C[2] = (unsigned char)((counter >> 8) & 0xff);
C[3] = (unsigned char)(counter & 0xff);
/* This could be optimized when the clone functions in
* rawhash.c are implemented. */
(*hash->begin)(hashContext);
(*hash->update)(hashContext, mgfSeed, mgfSeedLen);
(*hash->update)(hashContext, C, sizeof C);
tempHash = mask + counter * hash->length;
if (counter != (rounds-1)) {
(*hash->end)(hashContext, tempHash, &digestLen, hash->length);
} else { /* we're in the last round and need to cut the hash */
temp = PORT_Alloc(hash->length);
(*hash->end)(hashContext, temp, &digestLen, hash->length);
PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
PORT_Free(temp);
}
}
(*hash->destroy)(hashContext, PR_TRUE);
return SECSuccess;
}

View File

@ -660,9 +660,13 @@ s_mpi_is_sse2()
return 0;
}
freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
/* string holds the CPU's manufacturer ID string - a twelve
* character ASCII string stored in ebx, edx, ecx, and
* the 32-bit extended feature flags are in edx, ecx.
*/
*(int *)string = ebx;
*(int *)&string[4] = edx;
*(int *)&string[8] = ecx;
*(int *)&string[4] = (int)edx;
*(int *)&string[8] = (int)ecx;
string[12] = 0;
/* has no SSE2 extensions */
@ -703,9 +707,13 @@ s_mpi_getProcessorLineSize()
/* Pentium, cpuid command is available */
freebl_cpuid(0, &eax, &ebx, &ecx, &edx);
cpuidLevel = eax;
/* string holds the CPU's manufacturer ID string - a twelve
* character ASCII string stored in ebx, edx, ecx, and
* the 32-bit extended feature flags are in edx, ecx.
*/
*(int *)string = ebx;
*(int *)&string[4] = edx;
*(int *)&string[8] = ecx;
*(int *)&string[4] = (int)edx;
*(int *)&string[8] = (int)ecx;
string[12] = 0;
manufacturer = MAN_UNKNOWN;

View File

@ -37,7 +37,7 @@
/*
* RSA key generation, public key op, private key op.
*
* $Id: rsa.c,v 1.42 2011/03/30 01:20:12 rrelyea%redhat.com Exp $
* $Id: rsa.c,v 1.43 2011/09/21 01:09:48 wtc%google.com Exp $
*/
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
@ -1096,8 +1096,6 @@ init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key,
mp_int *n, unsigned int modLen)
{
blindingParams * bp = rsabp->array;
SECStatus rv = SECSuccess;
mp_err err = MP_OKAY;
int i = 0;
/* Initialize the list pointer for the element */
@ -1217,7 +1215,7 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen,
PZ_Unlock(blindingParamsList.lock);
return SECSuccess;
}
/* We did not find a usable set of blinding params. Can we make one?
/* We did not find a usable set of blinding params. Can we make one? */
/* Find a free bp struct. */
prevbp = NULL;
if ((bp = rsabp->free) != NULL) {

View File

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: sha512.c,v 1.18 2011/03/30 22:35:43 wtc%google.com Exp $ */
/* $Id: sha512.c,v 1.19 2011/09/14 17:48:03 wtc%google.com Exp $ */
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
@ -571,12 +571,6 @@ SHA224_Begin(SHA224Context *ctx)
memcpy(H, H224, sizeof H224);
}
static void
SHA224_Compress(SHA224Context *ctx)
{
SHA256_Compress(ctx);
}
void
SHA224_Update(SHA224Context *ctx, const unsigned char *input,
unsigned int inputLen)

View File

@ -843,8 +843,11 @@ safe_pclose(FILE *fp)
}
#ifdef DARWIN
#include <TargetConditionals.h>
#if !TARGET_OS_IPHONE
#include <crt_externs.h>
#endif
#endif
/* Fork netstat to collect its output by default. Do not unset this unless
* another source of entropy is available
@ -859,7 +862,12 @@ void RNG_SystemInfoForRNG(void)
const char * const *cp;
char *randfile;
#ifdef DARWIN
#if TARGET_OS_IPHONE
/* iOS does not expose a way to access environ. */
char **environ = NULL;
#else
char **environ = *_NSGetEnviron();
#endif
#else
extern char **environ;
#endif

View File

@ -1535,6 +1535,9 @@ PKIX_PL_Cert_VerifySignature(
* If the Certificate is not intrinsically trustworthy, it still might end up a
* component in a successful chain.
*
* If the Certificate is intrinsically untrustworthy, this function will return
* an error.
*
* PARAMETERS
* "cert"
* Address of Cert whose trustworthiness is to be determined. Must be
@ -1559,6 +1562,43 @@ PKIX_PL_Cert_IsCertTrusted(
PKIX_Boolean *pTrusted,
void *plContext);
/*
* FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
* DESCRIPTION:
*
* Checks the Leaf Cert specified by "cert" to determine, in a manner that
* depends on the underlying platform, whether it is trusted, and stores the
* result in "pTrusted". If a certificate is trusted it means that this
* End Entify certificate has been marked as trusted for the requested usage,
* policy, validity, and other tests.
*
* If the Certificate is not intrinsically trustworthy, we can still try to
* build a successful chain.
*
* If the Certificate is intrinsically untrustworthy, this function will return
* an error.
*
* PARAMETERS
* "cert"
* Address of Cert whose trustworthiness is to be determined. Must be
* non-NULL.
* "pTrusted"
* Address where the Boolean value will be stored. Must be non-NULL.
* "plContext"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
* RETURNS:
* Returns NULL if the function succeeds.
* Returns a CERT Error if the function fails in a non-fatal way.
* Returns a Fatal Error if the function fails in an unrecoverable way.
*/
PKIX_Error *
PKIX_PL_Cert_IsLeafCertTrusted(
PKIX_PL_Cert *cert,
PKIX_Boolean *pTrusted,
void *plContext);
/* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
PKIX_Error*
PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert,

View File

@ -3235,6 +3235,7 @@ pkix_Build_InitiateBuildChain(
PKIX_ForwardBuilderState *state = NULL;
PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
PKIX_CertSelector_MatchCallback selectorCallback = NULL;
PKIX_Boolean trusted = PKIX_FALSE;
PKIX_PL_AIAMgr *aiaMgr = NULL;
PKIX_ENTER(BUILD, "pkix_Build_InitiateBuildChain");
@ -3340,6 +3341,15 @@ pkix_Build_InitiateBuildChain(
PKIX_ERROR(PKIX_NOTARGETCERTSUPPLIED);
}
PKIX_CHECK(PKIX_PL_Cert_IsLeafCertTrusted
(targetCert,
&trusted,
plContext),
PKIX_CERTISCERTTRUSTEDFAILED);
/* future: look at the |trusted| flag and force success. We only
* want to do this if we aren't validating against a policy (like
* EV). */
PKIX_CHECK(PKIX_PL_Cert_GetAllSubjectNames
(targetCert,
&targetSubjNames,

View File

@ -3241,6 +3241,82 @@ cleanup:
PKIX_RETURN(CERT);
}
/*
* Find out the state of the NSS trust bits for the requested usage.
* Returns SECFailure if the cert is explicitly distrusted.
* Returns SECSuccess if the cert can be used to form a chain (normal case),
* or it is explicitly trusted. The trusted bool is set to true if it is
* explicitly trusted.
*/
static SECStatus
pkix_pl_Cert_GetTrusted(void *plContext,
PKIX_PL_Cert *cert,
PKIX_Boolean *trusted,
PKIX_Boolean isCA)
{
SECStatus rv;
CERTCertificate *nssCert = NULL;
SECCertUsage certUsage = 0;
SECCertificateUsage certificateUsage;
SECTrustType trustType;
unsigned int trustFlags;
unsigned int requiredFlags;
CERTCertTrust trust;
*trusted = PKIX_FALSE;
/* no key usage information */
if (plContext == NULL) {
return SECSuccess;
}
certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
/* ensure we obtained a single usage bit only */
PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
/* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
nssCert = cert->nssCert;
if (!isCA) {
PRBool prTrusted;
unsigned int failedFlags;
rv = cert_CheckLeafTrust(nssCert, certUsage,
&failedFlags, &prTrusted);
*trusted = (PKIX_Boolean) prTrusted;
return rv;
}
rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,
&trustType);
if (rv != SECSuccess) {
return SECSuccess;
}
rv = CERT_GetCertTrust(nssCert, &trust);
if (rv != SECSuccess) {
return SECSuccess;
}
trustFlags = SEC_GET_TRUST_FLAGS(&trust, trustType);
/* normally trustTypeNone usages accept any of the given trust bits
* being on as acceptable. If any are distrusted (and none are trusted),
* then we will also distrust the cert */
if ((trustFlags == 0) && (trustType == trustTypeNone)) {
trustFlags = trust.sslFlags | trust.emailFlags |
trust.objectSigningFlags;
}
if ((trustFlags & requiredFlags) == requiredFlags) {
*trusted = PKIX_TRUE;
return SECSuccess;
}
if ((trustFlags & CERTDB_TERMINAL_RECORD) &&
((trustFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED)) == 0)) {
return SECFailure;
}
return SECSuccess;
}
/*
* FUNCTION: PKIX_PL_Cert_IsCertTrusted
* (see comments in pkix_pl_pki.h)
@ -3253,77 +3329,84 @@ PKIX_PL_Cert_IsCertTrusted(
void *plContext)
{
PKIX_CertStore_CheckTrustCallback trustCallback = NULL;
SECCertUsage certUsage = 0;
PKIX_Boolean trusted = PKIX_FALSE;
SECStatus rv = SECFailure;
unsigned int requiredFlags;
SECTrustType trustType;
CERTCertTrust trust;
CERTCertificate *nssCert = NULL;
SECCertificateUsage certificateUsage;
PKIX_ENTER(CERT, "pkix_pl_Cert_IsCertTrusted");
PKIX_ENTER(CERT, "PKIX_PL_Cert_IsCertTrusted");
PKIX_NULLCHECK_TWO(cert, pTrusted);
/* Call GetTrusted first to see if we are going to distrust the
* certificate */
rv = pkix_pl_Cert_GetTrusted(plContext, cert, &trusted, PKIX_TRUE);
if (rv != SECSuccess) {
/* Failure means the cert is explicitly distrusted,
* let the next level know not to use it. */
*pTrusted = PKIX_FALSE;
PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
}
if (trustOnlyUserAnchors) {
/* discard our |trusted| value since we are using the anchors */
*pTrusted = cert->isUserTrustAnchor;
goto cleanup;
}
/* no key usage information and store is not trusted */
/* no key usage information or store is not trusted */
if (plContext == NULL || cert->store == NULL) {
*pTrusted = PKIX_FALSE;
goto cleanup;
}
if (cert->store) {
PKIX_CHECK(PKIX_CertStore_GetTrustCallback
(cert->store, &trustCallback, plContext),
PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
PKIX_CHECK(PKIX_CertStore_GetTrustCallback
(cert->store, &trustCallback, plContext),
PKIX_CERTSTOREGETTRUSTCALLBACKFAILED);
PKIX_CHECK_ONLY_FATAL(trustCallback
(cert->store, cert, &trusted, plContext),
PKIX_CHECKTRUSTCALLBACKFAILED);
PKIX_CHECK_ONLY_FATAL(trustCallback
(cert->store, cert, &trusted, plContext),
PKIX_CHECKTRUSTCALLBACKFAILED);
if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
*pTrusted = PKIX_FALSE;
goto cleanup;
}
}
certificateUsage = ((PKIX_PL_NssContext*)plContext)->certificateUsage;
/* ensure we obtained a single usage bit only */
PORT_Assert(!(certificateUsage & (certificateUsage - 1)));
/* convert SECertificateUsage (bit mask) to SECCertUsage (enum) */
while (0 != (certificateUsage = certificateUsage >> 1)) { certUsage++; }
rv = CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, &trustType);
if (rv != SECSuccess) {
/* allow trust store to override if we can trust the trust
* bits */
if (PKIX_ERROR_RECEIVED || (trusted == PKIX_FALSE)) {
*pTrusted = PKIX_FALSE;
goto cleanup;
}
nssCert = cert->nssCert;
rv = CERT_GetCertTrust(nssCert, &trust);
if (rv == SECSuccess) {
unsigned int certFlags;
certFlags = SEC_GET_TRUST_FLAGS((&trust), trustType);
if ((certFlags & requiredFlags) == requiredFlags) {
trusted = PKIX_TRUE;
}
}
*pTrusted = trusted;
cleanup:
PKIX_RETURN(CERT);
}
/*
* FUNCTION: PKIX_PL_Cert_IsLeafCertTrusted
* (see comments in pkix_pl_pki.h)
*/
PKIX_Error *
PKIX_PL_Cert_IsLeafCertTrusted(
PKIX_PL_Cert *cert,
PKIX_Boolean *pTrusted,
void *plContext)
{
SECStatus rv;
PKIX_ENTER(CERT, "PKIX_PL_Cert_IsLeafCertTrusted");
PKIX_NULLCHECK_TWO(cert, pTrusted);
*pTrusted = PKIX_FALSE;
rv = pkix_pl_Cert_GetTrusted(plContext, cert, pTrusted, PKIX_FALSE);
if (rv != SECSuccess) {
/* Failure means the cert is explicitly distrusted,
* let the next level know not to use it. */
*pTrusted = PKIX_FALSE;
PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED);
}
cleanup:
PKIX_RETURN(CERT);
}
/* FUNCTION: PKIX_PL_Cert_SetAsTrustAnchor */
PKIX_Error*
PKIX_PL_Cert_SetAsTrustAnchor(PKIX_PL_Cert *cert,

View File

@ -632,7 +632,7 @@ pkix_pl_InfoAccess_ParseTokens(
separator = terminator;
if (endPos == '\0') {
if (*endPos == '\0') {
*startPos = endPos;
break;
} else {

View File

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: nss.h,v 1.83 2011/08/01 07:08:08 kaie%kuix.de Exp $ */
/* $Id: nss.h,v 1.84 2011/10/04 22:56:31 wtc%google.com Exp $ */
#ifndef __nss_h_
#define __nss_h_
@ -66,12 +66,12 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define NSS_VERSION "3.13.0.0" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
#define NSS_VERSION "3.13.0.0" _NSS_ECC_STRING _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
#define NSS_VMINOR 13
#define NSS_VPATCH 0
#define NSS_VBUILD 0
#define NSS_BETA PR_TRUE
#define NSS_BETA PR_FALSE
#ifndef RC_INVOKED

View File

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: nssinit.c,v 1.108 2011/08/17 14:40:49 emaldona%redhat.com Exp $ */
/* $Id: nssinit.c,v 1.112 2011/10/04 02:35:58 emaldona%redhat.com Exp $ */
#include <ctype.h>
#include <string.h>
@ -53,7 +53,6 @@
#include "nss.h"
#include "pk11func.h"
#include "secerr.h"
#include "errstrs.h"
#include "nssbase.h"
#include "nssutil.h"
#include "pkixt.h"
@ -381,7 +380,6 @@ nss_InitModules(const char *configdir, const char *certPrefix,
PRBool isContextInit)
{
SECStatus rv = SECFailure;
PRStatus status = PR_SUCCESS;
char *moduleSpec = NULL;
char *flags = NULL;
char *lconfigdir = NULL;
@ -394,10 +392,9 @@ nss_InitModules(const char *configdir, const char *certPrefix,
char *lupdateID = NULL;
char *lupdateName = NULL;
status = NSS_InitializePRErrorTable();
if (status != PR_SUCCESS) {
PORT_SetError(status);
return SECFailure;
if (NSS_InitializePRErrorTable() != SECSuccess) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return rv;
}
flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
@ -532,6 +529,27 @@ static SECStatus nss_InitShutdownList(void);
static CERTCertificate dummyCert;
#endif
/* All initialized to zero in BSS */
static PRCallOnceType nssInitOnce;
static PZLock *nssInitLock;
static PZCondVar *nssInitCondition;
static int nssIsInInit;
static PRStatus
nss_doLockInit(void)
{
nssInitLock = PZ_NewLock(nssILockOther);
if (nssInitLock == NULL) {
return (PRStatus) SECFailure;
}
nssInitCondition = PZ_NewCondVar(nssInitLock);
if (nssInitCondition == NULL) {
return (PRStatus) SECFailure;
}
return (PRStatus) SECSuccess;
}
static SECStatus
nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
const char *secmodName, const char *updateDir,
@ -558,26 +576,49 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
if (!initContextPtr && nssIsInitted) {
return SECSuccess;
}
/* make sure our locks are initialized one and only one time */
rv = PR_CallOnce(&nssInitOnce, nss_doLockInit);
if (rv != SECSuccess) {
return rv;
}
/*
* if we haven't done basic initialization, single thread the
* initializations.
*/
PZ_Lock(nssInitLock);
isReallyInitted = NSS_IsInitialized();
if (!isReallyInitted) {
while (!isReallyInitted && nssIsInInit) {
PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
isReallyInitted = NSS_IsInitialized();
}
/* once we've completed basic initialization, we can allow more than
* one process initialize NSS at a time. */
}
/* get the current value */
nssIsInInit++;
PZ_Unlock(nssInitLock);
/* this tells us whether or not some library has already initialized us.
* if so, we don't want to double call some of the basic initialization
* functions */
isReallyInitted = NSS_IsInitialized();
if (!isReallyInitted) {
/* New option bits must not change the size of CERTCertificate. */
PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
if (SECSuccess != cert_InitLocks()) {
return SECFailure;
goto loser;
}
if (SECSuccess != InitCRLCache()) {
return SECFailure;
goto loser;
}
if (SECSuccess != OCSP_InitGlobal()) {
return SECFailure;
goto loser;
}
}
@ -697,6 +738,7 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
* in, then return the new context pointer and add it to the
* nssInitContextList. Otherwise set the global nss_isInitted flag
*/
PZ_Lock(nssInitLock);
if (!initContextPtr) {
nssIsInitted = PR_TRUE;
} else {
@ -704,6 +746,10 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
(*initContextPtr)->next = nssInitContextList;
nssInitContextList = (*initContextPtr);
}
nssIsInInit--;
/* now that we are inited, all waiters can move forward */
PZ_NotifyAllCondVar(nssInitCondition);
PZ_Unlock(nssInitLock);
return SECSuccess;
@ -894,10 +940,13 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
{
int i;
PZ_Lock(nssInitLock);
if (!NSS_IsInitialized()) {
PZ_Unlock(nssInitLock);
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
PZ_Unlock(nssInitLock);
if (sFunc == NULL) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@ -948,10 +997,14 @@ SECStatus
NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
{
int i;
PZ_Lock(nssInitLock);
if (!NSS_IsInitialized()) {
PZ_Unlock(nssInitLock);
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
PZ_Unlock(nssInitLock);
PORT_Assert(nssShutdownList.lock);
PZ_Lock(nssShutdownList.lock);
@ -1082,12 +1135,23 @@ nss_Shutdown(void)
SECStatus
NSS_Shutdown(void)
{
SECStatus rv;
PZ_Lock(nssInitLock);
if (!nssIsInitted) {
PZ_Unlock(nssInitLock);
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
return nss_Shutdown();
/* If one or more threads are in the middle of init, wait for them
* to complete */
while (nssIsInInit) {
PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
}
rv = nss_Shutdown();
PZ_Unlock(nssInitLock);
return rv;
}
/*
@ -1122,32 +1186,49 @@ nss_RemoveList(NSSInitContext *context) {
SECStatus
NSS_ShutdownContext(NSSInitContext *context)
{
if (!context) {
SECStatus rv = SECSuccess;
PZ_Lock(nssInitLock);
/* If one or more threads are in the middle of init, wait for them
* to complete */
while (nssIsInInit) {
PZ_WaitCondVar(nssInitCondition,PR_INTERVAL_NO_TIMEOUT);
}
/* OK, we are the only thread now either initializing or shutting down */
if (!context) {
if (!nssIsInitted) {
PZ_Unlock(nssInitLock);
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
nssIsInitted = 0;
} else if (! nss_RemoveList(context)) {
PZ_Unlock(nssInitLock);
/* context was already freed or wasn't valid */
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
if ((nssIsInitted == 0) && (nssInitContextList == NULL)) {
return nss_Shutdown();
rv = nss_Shutdown();
}
return SECSuccess;
}
/* NOTE: we don't try to free the nssInitLocks to prevent races against
* the locks. There may be a thread, right now, waiting in NSS_Init for us
* to free the lock below. If we delete the locks, bad things would happen
* to that thread */
PZ_Unlock(nssInitLock);
return rv;
}
PRBool
NSS_IsInitialized(void)
{
return (nssIsInitted) || (nssInitContextList != NULL);
}
extern const char __nss_base_rcsid[];
extern const char __nss_base_sccsid[];

View File

@ -350,7 +350,7 @@ pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) {
char *ptr = (char *)attrib->pValue;
unsigned long len = attrib->ulValueLen;
while (len && (*ptr == 0)) {
while ((len > 1) && (*ptr == 0)) {
len--;
ptr++;
}

View File

@ -38,7 +38,7 @@
/*
* PKCS7 decoding, verification.
*
* $Id: p7decode.c,v 1.25 2008/03/10 00:01:26 wtc%google.com Exp $
* $Id: p7decode.c,v 1.26 2011/08/21 01:14:17 wtc%google.com Exp $
*/
#include "p7local.h"
@ -428,7 +428,6 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx,
* XXX Need comment explaining following helper function (which is used
* by sec_pkcs7_decoder_start_decrypt).
*/
extern const SEC_ASN1Template SEC_SMIMEKEAParamTemplateAllParams[];
static PK11SymKey *
sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
@ -460,7 +459,7 @@ sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
keyalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
encalgtag = SECOID_GetAlgorithmTag (&(ri->keyEncAlg));
if ((encalgtag != SEC_OID_NETSCAPE_SMIME_KEA) && (keyalgtag != encalgtag)) {
if (keyalgtag != encalgtag) {
p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH;
goto no_key_found;
}
@ -477,117 +476,6 @@ sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx,
goto no_key_found;
}
break;
/* ### mwelch -- KEA */
case SEC_OID_NETSCAPE_SMIME_KEA:
{
SECStatus err;
CK_MECHANISM_TYPE bulkType;
PK11SymKey *tek;
SECKEYPublicKey *senderPubKey;
SEC_PKCS7SMIMEKEAParameters keaParams;
(void) memset(&keaParams, 0, sizeof(keaParams));
/* Decode the KEA algorithm parameters. */
err = SEC_ASN1DecodeItem(NULL,
&keaParams,
SEC_SMIMEKEAParamTemplateAllParams,
&(ri->keyEncAlg.parameters));
if (err != SECSuccess)
{
p7dcx->error = err;
PORT_SetError(0);
goto no_key_found;
}
/* We just got key data, no key structure. So, we
create one. */
senderPubKey =
PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
keaParams.originatorKEAKey.len);
if (senderPubKey == NULL)
{
p7dcx->error = PORT_GetError();
PORT_SetError(0);
goto no_key_found;
}
/* Generate the TEK (token exchange key) which we use
to unwrap the bulk encryption key. */
tek = PK11_PubDerive(privkey, senderPubKey,
PR_FALSE,
&keaParams.originatorRA,
NULL,
CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
CKA_WRAP, 0, p7dcx->pwfn_arg);
SECKEY_DestroyPublicKey(senderPubKey);
if (tek == NULL)
{
p7dcx->error = PORT_GetError();
PORT_SetError(0);
goto no_key_found;
}
/* Now that we have the TEK, unwrap the bulk key
with which to decrypt the message. We have to
do one of two different things depending on
whether Skipjack was used for bulk encryption
of the message. */
bulkType = PK11_AlgtagToMechanism (bulkalgtag);
switch(bulkType)
{
case CKM_SKIPJACK_CBC64:
case CKM_SKIPJACK_ECB64:
case CKM_SKIPJACK_OFB64:
case CKM_SKIPJACK_CFB64:
case CKM_SKIPJACK_CFB32:
case CKM_SKIPJACK_CFB16:
case CKM_SKIPJACK_CFB8:
/* Skipjack is being used as the bulk encryption algorithm.*/
/* Unwrap the bulk key. */
bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP,
NULL, &ri->encKey,
CKM_SKIPJACK_CBC64,
CKA_DECRYPT, 0);
break;
default:
/* Skipjack was not used for bulk encryption of this
message. Use Skipjack CBC64, with the nonSkipjackIV
part of the KEA key parameters, to decrypt
the bulk key. If we got a parameter indicating that the
bulk key size is different than the encrypted key size,
pass in the real key size. */
/* Check for specified bulk key length (unspecified implies
that the bulk key length is the same as encrypted length) */
if (keaParams.bulkKeySize.len > 0)
{
p7dcx->error = SEC_ASN1DecodeItem(NULL, &bulkLength,
SEC_ASN1_GET(SEC_IntegerTemplate),
&keaParams.bulkKeySize);
}
if (p7dcx->error != SECSuccess)
goto no_key_found;
bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64,
&keaParams.nonSkipjackIV,
&ri->encKey,
bulkType,
CKA_DECRYPT, bulkLength);
}
if (bulkkey == NULL)
{
p7dcx->error = PORT_GetError();
PORT_SetError(0);
goto no_key_found;
}
break;
}
default:
p7dcx->error = SEC_ERROR_UNSUPPORTED_KEYALG;
break;

View File

@ -38,7 +38,7 @@
/*
* PKCS7 encoding.
*
* $Id: p7encode.c,v 1.13 2008/03/10 00:01:26 wtc%google.com Exp $
* $Id: p7encode.c,v 1.14 2011/08/21 01:14:17 wtc%google.com Exp $
*/
#include "p7local.h"
@ -91,7 +91,6 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
sec_PKCS7CipherObject *encryptobj;
SEC_PKCS7RecipientInfo **recipientinfos, *ri;
SEC_PKCS7EncryptedContentInfo *enccinfo;
SEC_PKCS7SMIMEKEAParameters keaParams;
SECKEYPublicKey *publickey = NULL;
SECKEYPrivateKey *ourPrivKey = NULL;
PK11SymKey *bulkkey;
@ -102,9 +101,6 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
/* Get the context in case we need it below. */
wincx = cinfo->pwfn_arg;
/* Clear keaParams, since cleanup code checks the lengths */
(void) memset(&keaParams, 0, sizeof(keaParams));
kind = SEC_PKCS7ContentType (cinfo);
switch (kind) {
default:
@ -197,8 +193,7 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
* down into the subjectPublicKeyInfo myself) and another which
* takes a public key and algorithm tag and data and encrypts
* the data. Or something like that. The point is that all
* of the following hardwired RSA and KEA stuff should be done
* elsewhere.
* of the following hardwired RSA stuff should be done elsewhere.
*/
certalgtag=SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
@ -223,149 +218,6 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo,
if (rv != SECSuccess) goto loser;
params = NULL; /* paranoia */
break;
/* ### mwelch -- KEA */
case SEC_OID_MISSI_KEA_DSS_OLD:
case SEC_OID_MISSI_KEA_DSS:
case SEC_OID_MISSI_KEA:
{
#define SMIME_FORTEZZA_RA_LENGTH 128
#define SMIME_FORTEZZA_IV_LENGTH 24
#define SMIME_FORTEZZA_MAX_KEY_SIZE 256
SECStatus err;
PK11SymKey *tek;
CERTCertificate *ourCert;
SECKEYPublicKey *ourPubKey;
SECKEATemplateSelector whichKEA = SECKEAInvalid;
/* We really want to show our KEA tag as the
key exchange algorithm tag. */
encalgtag = SEC_OID_NETSCAPE_SMIME_KEA;
/* Get the public key of the recipient. */
publickey = CERT_ExtractPublicKey(cert);
if (publickey == NULL) goto loser;
/* Find our own cert, and extract its keys. */
ourCert = PK11_FindBestKEAMatch(cert,wincx);
if (ourCert == NULL) goto loser;
arena = PORT_NewArena(1024);
if (arena == NULL) goto loser;
ourPubKey = CERT_ExtractPublicKey(ourCert);
if (ourPubKey == NULL)
{
CERT_DestroyCertificate(ourCert);
goto loser;
}
/* While we're here, copy the public key into the outgoing
* KEA parameters. */
SECITEM_CopyItem(arena, &(keaParams.originatorKEAKey),
&(ourPubKey->u.fortezza.KEAKey));
SECKEY_DestroyPublicKey(ourPubKey);
ourPubKey = NULL;
/* Extract our private key in order to derive the
* KEA key. */
ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx);
CERT_DestroyCertificate(ourCert); /* we're done with this */
if (!ourPrivKey) goto loser;
/* Prepare raItem with 128 bytes (filled with zeros). */
keaParams.originatorRA.data =
(unsigned char*)PORT_ArenaAlloc(arena,SMIME_FORTEZZA_RA_LENGTH);
keaParams.originatorRA.len = SMIME_FORTEZZA_RA_LENGTH;
/* Generate the TEK (token exchange key) which we use
* to wrap the bulk encryption key. (raItem) will be
* filled with a random seed which we need to send to
* the recipient. */
tek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
&keaParams.originatorRA, NULL,
CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
CKA_WRAP, 0, wincx);
SECKEY_DestroyPublicKey(publickey);
SECKEY_DestroyPrivateKey(ourPrivKey);
publickey = NULL;
ourPrivKey = NULL;
if (!tek)
goto loser;
ri->encKey.data = (unsigned char*)PORT_ArenaAlloc(cinfo->poolp,
SMIME_FORTEZZA_MAX_KEY_SIZE);
ri->encKey.len = SMIME_FORTEZZA_MAX_KEY_SIZE;
if (ri->encKey.data == NULL)
{
PK11_FreeSymKey(tek);
goto loser;
}
/* Wrap the bulk key. What we do with the resulting data
depends on whether we're using Skipjack to wrap the key. */
switch(PK11_AlgtagToMechanism(enccinfo->encalg))
{
case CKM_SKIPJACK_CBC64:
case CKM_SKIPJACK_ECB64:
case CKM_SKIPJACK_OFB64:
case CKM_SKIPJACK_CFB64:
case CKM_SKIPJACK_CFB32:
case CKM_SKIPJACK_CFB16:
case CKM_SKIPJACK_CFB8:
/* do SKIPJACK, we use the wrap mechanism */
err = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL,
tek, bulkkey, &ri->encKey);
whichKEA = SECKEAUsesSkipjack;
break;
default:
/* Not SKIPJACK, we encrypt the raw key data */
keaParams.nonSkipjackIV .data =
(unsigned char*)PORT_ArenaAlloc(arena,
SMIME_FORTEZZA_IV_LENGTH);
keaParams.nonSkipjackIV.len = SMIME_FORTEZZA_IV_LENGTH;
err = PK11_WrapSymKey(CKM_SKIPJACK_CBC64,
&keaParams.nonSkipjackIV,
tek, bulkkey, &ri->encKey);
if (err != SECSuccess)
goto loser;
if (ri->encKey.len != PK11_GetKeyLength(bulkkey))
{
/* The size of the encrypted key is not the same as
that of the original bulk key, presumably due to
padding. Encode and store the real size of the
bulk key. */
if (SEC_ASN1EncodeInteger(arena,
&keaParams.bulkKeySize,
PK11_GetKeyLength(bulkkey))
== NULL)
err = (SECStatus)PORT_GetError();
else
/* use full template for encoding */
whichKEA = SECKEAUsesNonSkipjackWithPaddedEncKey;
}
else
/* enc key length == bulk key length */
whichKEA = SECKEAUsesNonSkipjack;
break;
}
PK11_FreeSymKey(tek);
if (err != SECSuccess)
goto loser;
PORT_Assert( whichKEA != SECKEAInvalid);
/* Encode the KEA parameters into the recipient info. */
params = SEC_ASN1EncodeItem(arena,NULL, &keaParams,
sec_pkcs7_get_kea_template(whichKEA));
if (params == NULL) goto loser;
break;
}
default:
PORT_SetError (SEC_ERROR_INVALID_ALGORITHM);
goto loser;
@ -940,10 +792,6 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo,
*/
signalgtag = SECOID_GetAlgorithmTag (&(cert->subjectPublicKeyInfo.algorithm));
/* Fortezza MISSI have weird signature formats. Map them
* to standard DSA formats */
signalgtag = PK11_FortezzaMapSig(signalgtag);
if (signerinfo->authAttr != NULL) {
SEC_PKCS7Attribute *attr;
SECItem encoded_attrs;

View File

@ -40,7 +40,7 @@
* encoding/creation side *and* the decoding/decryption side. Anything
* else should be static routines in the appropriate file.
*
* $Id: p7local.c,v 1.14 2010/03/15 07:25:14 nelson%bolyard.com Exp $
* $Id: p7local.c,v 1.15 2011/08/21 01:14:17 wtc%google.com Exp $
*/
#include "p7local.h"
@ -1308,63 +1308,6 @@ static const SEC_ASN1Template SEC_PointerToPKCS7EncryptedDataTemplate[] = {
{ SEC_ASN1_POINTER, 0, SEC_PKCS7EncryptedDataTemplate }
};
const SEC_ASN1Template SEC_SMIMEKEAParamTemplateSkipjack[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },
{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },
{ SEC_ASN1_OCTET_STRING,
offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },
{ 0 }
};
const SEC_ASN1Template SEC_SMIMEKEAParamTemplateNoSkipjack[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },
{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },
{ SEC_ASN1_OCTET_STRING,
offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },
{ SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL ,
offsetof(SEC_PKCS7SMIMEKEAParameters,nonSkipjackIV) },
{ 0 }
};
const SEC_ASN1Template SEC_SMIMEKEAParamTemplateAllParams[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },
{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },
{ SEC_ASN1_OCTET_STRING,
offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },
{ SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL ,
offsetof(SEC_PKCS7SMIMEKEAParameters,nonSkipjackIV) },
{ SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL ,
offsetof(SEC_PKCS7SMIMEKEAParameters,bulkKeySize) },
{ 0 }
};
const SEC_ASN1Template*
sec_pkcs7_get_kea_template(SECKEATemplateSelector whichTemplate)
{
const SEC_ASN1Template *returnVal = NULL;
switch(whichTemplate)
{
case SECKEAUsesNonSkipjack:
returnVal = SEC_SMIMEKEAParamTemplateNoSkipjack;
break;
case SECKEAUsesSkipjack:
returnVal = SEC_SMIMEKEAParamTemplateSkipjack;
break;
case SECKEAUsesNonSkipjackWithPaddedEncKey:
default:
returnVal = SEC_SMIMEKEAParamTemplateAllParams;
break;
}
return returnVal;
}
static const SEC_ASN1Template *
sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding)
{

View File

@ -45,7 +45,7 @@
* you. If that has a problem, then just move out what you need, changing
* its name as appropriate!
*
* $Id: p7local.h,v 1.2 2004/04/25 15:03:13 gerv%gerv.net Exp $
* $Id: p7local.h,v 1.3 2011/08/21 01:14:17 wtc%google.com Exp $
*/
#ifndef _P7LOCAL_H_
@ -167,12 +167,6 @@ extern SECStatus sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj,
unsigned int input_len,
PRBool final);
/* return the correct kea template based on the template selector. skipjack
* does not have the extra IV.
*/
const SEC_ASN1Template *
sec_pkcs7_get_kea_template(SECKEATemplateSelector whichTemplate);
/************************************************************************/
SEC_END_PROTOS

View File

@ -37,7 +37,7 @@
/*
* Header for pkcs7 types.
*
* $Id: pkcs7t.h,v 1.6 2008/06/14 14:20:24 wtc%google.com Exp $
* $Id: pkcs7t.h,v 1.7 2011/08/21 01:14:17 wtc%google.com Exp $
*/
#ifndef _PKCS7T_H_
@ -98,7 +98,6 @@ typedef struct SEC_PKCS7SignerInfoStr SEC_PKCS7SignerInfo;
typedef struct SEC_PKCS7RecipientInfoStr SEC_PKCS7RecipientInfo;
typedef struct SEC_PKCS7DigestedDataStr SEC_PKCS7DigestedData;
typedef struct SEC_PKCS7EncryptedDataStr SEC_PKCS7EncryptedData;
typedef struct SEC_PKCS7SMIMEKEAParametersStr SEC_PKCS7SMIMEKEAParameters;
/*
* The following is not actually a PKCS7 type, but for now it is only
* used by PKCS7, so we have adopted it. If someone else *ever* needs
@ -223,35 +222,6 @@ struct SEC_PKCS7AttributeStr {
PRBool encoded; /* when true, values are encoded */
};
/* An enumerated type used to select templates based on the encryption
scenario and data specifics. */
typedef enum
{
SECKEAInvalid = -1,
SECKEAUsesSkipjack = 0,
SECKEAUsesNonSkipjack = 1,
SECKEAUsesNonSkipjackWithPaddedEncKey = 2
} SECKEATemplateSelector;
/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
but I cannot think of a more appropriate place at this time. */
struct SEC_PKCS7SMIMEKEAParametersStr {
SECItem originatorKEAKey; /* sender KEA key (encrypted?) */
SECItem originatorRA; /* random number generated by sender */
SECItem nonSkipjackIV; /* init'n vector for SkipjackCBC64
decryption of KEA key if Skipjack
is not the bulk algorithm used on
the message */
SECItem bulkKeySize; /* if Skipjack is not the bulk
algorithm used on the message,
and the size of the bulk encryption
key is not the same as that of
originatorKEAKey (due to padding
perhaps), this field will contain
the real size of the bulk encryption
key. */
};
/*
* Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart.
* If specified, this is where the content bytes (only) will be "sent"

View File

@ -38,7 +38,7 @@
* Stuff specific to S/MIME policy and interoperability.
* Depends on PKCS7, but there should be no dependency the other way around.
*
* $Id: secmime.c,v 1.4 2004/06/18 00:38:45 jpierre%netscape.com Exp $
* $Id: secmime.c,v 1.5 2011/08/21 01:14:17 wtc%google.com Exp $
*/
#include "secmime.h"
@ -87,8 +87,7 @@ static smime_cipher_map smime_cipher_maps[] = {
{ SMIME_RC5PAD_64_16_128, SEC_OID_RC5_CBC_PAD, &smime_rc5p128 },
#endif
{ SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL },
{ SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL },
{ SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL}
{ SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL }
};
/*
@ -252,8 +251,6 @@ smime_policy_algorithm (SECAlgorithmID *algid, PK11SymKey *key)
return SMIME_DES_CBC_56;
case SEC_OID_DES_EDE3_CBC:
return SMIME_DES_EDE3_168;
case SEC_OID_FORTEZZA_SKIPJACK:
return SMIME_FORTEZZA;
#ifdef SMIME_DOES_RC5
case SEC_OID_RC5_CBC_PAD:
PORT_Assert (0); /* XXX need to pull out parameters and match */
@ -403,8 +400,7 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
int *cipher_abilities;
int *cipher_votes;
int strong_mapi;
int rcount, mapi, max, i;
PRBool isFortezza = PK11_FortezzaHasKEA(scert);
int rcount, mapi, max;
if (smime_policy_bits == 0) {
PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
@ -429,23 +425,11 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
/*
* XXX Should have a #define somewhere which specifies default
* strong cipher. (Or better, a way to configure, which would
* take Fortezza into account as well.)
* strong cipher. (Or better, a way to configure.)
*/
/* If the user has the Fortezza preference turned on, make
* that the strong cipher. Otherwise, use triple-DES. */
strong_mapi = -1;
if (isFortezza) {
for(i=0;i < smime_current_pref_index && strong_mapi < 0;i++)
{
if (smime_prefs[i] == SMIME_FORTEZZA)
strong_mapi = smime_mapi_by_cipher(SMIME_FORTEZZA);
}
}
if (strong_mapi == -1)
strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
/* Make triple-DES the strong cipher. */
strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
PORT_Assert (strong_mapi >= 0);
@ -505,8 +489,6 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts)
continue;
if (! smime_cipher_allowed (smime_cipher_maps[mapi].cipher))
continue;
if (!isFortezza && (smime_cipher_maps[mapi].cipher == SMIME_FORTEZZA))
continue;
if (cipher_votes[mapi] > max) {
chosen_cipher = smime_cipher_maps[mapi].cipher;
max = cipher_votes[mapi];
@ -553,7 +535,6 @@ smime_keysize_by_cipher (unsigned long which)
#endif
case SMIME_DES_CBC_56:
case SMIME_DES_EDE3_168:
case SMIME_FORTEZZA:
/*
* These are special; since the key size is fixed, we actually
* want to *avoid* specifying a key size.
@ -642,21 +623,18 @@ SECMIME_CreateEncrypted(CERTCertificate *scert,
static smime_capability **smime_capabilities;
static SECItem *smime_encoded_caps;
static PRBool lastUsedFortezza;
static SECStatus
smime_init_caps (PRBool isFortezza)
smime_init_caps (void)
{
smime_capability *cap;
smime_cipher_map *map;
SECOidData *oiddata;
SECStatus rv;
int i, capIndex;
int i;
if (smime_encoded_caps != NULL
&& (! smime_prefs_changed)
&& lastUsedFortezza == isFortezza)
if (smime_encoded_caps != NULL && (! smime_prefs_changed))
return SECSuccess;
if (smime_encoded_caps != NULL) {
@ -690,17 +668,8 @@ smime_init_caps (PRBool isFortezza)
(In the process of performing (a), Lisa put in some optimizations
which allow us to avoid needlessly re-populating elements in
smime_capabilities as we walk through smime_prefs.)
We want to use separate loop variables for smime_prefs and
smime_capabilities because in the case where the Skipjack cipher
is turned on in the prefs, but where we don't want to include
Skipjack in the encoded capabilities (presumably due to using a
non-fortezza cert when sending a message), we want to avoid creating
an empty element in smime_capabilities. This would otherwise cause
the encoding step to produce an empty set, since Skipjack happens
to be the first cipher in smime_prefs, if it is turned on.
*/
for (i = 0, capIndex = 0; i < smime_current_pref_index; i++, capIndex++) {
for (i = 0; i < smime_current_pref_index; i++) {
int mapi;
/* Get the next cipher preference in smime_prefs. */
@ -712,26 +681,17 @@ smime_init_caps (PRBool isFortezza)
PORT_Assert (mapi < smime_symmetric_count);
map = &(smime_cipher_maps[mapi]);
/* If we're using a non-Fortezza cert, only advertise non-Fortezza
capabilities. (We advertise all capabilities if we have a
Fortezza cert.) */
if ((!isFortezza) && (map->cipher == SMIME_FORTEZZA))
{
capIndex--; /* we want to visit the same caps index entry next time */
continue;
}
/*
* Convert the next preference found in smime_prefs into an
* smime_capability.
*/
cap = smime_capabilities[capIndex];
cap = smime_capabilities[i];
if (cap == NULL) {
cap = (smime_capability*)PORT_ZAlloc (sizeof(smime_capability));
if (cap == NULL)
break;
smime_capabilities[capIndex] = cap;
smime_capabilities[i] = cap;
} else if (cap->cipher == smime_prefs[i]) {
continue; /* no change to this one */
}
@ -765,24 +725,22 @@ smime_init_caps (PRBool isFortezza)
if (i != smime_current_pref_index)
return rv;
while (capIndex < smime_symmetric_count) {
cap = smime_capabilities[capIndex];
while (i < smime_symmetric_count) {
cap = smime_capabilities[i];
if (cap != NULL) {
SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE);
PORT_Free (cap);
}
smime_capabilities[capIndex] = NULL;
capIndex++;
smime_capabilities[i] = NULL;
i++;
}
smime_capabilities[capIndex] = NULL;
smime_capabilities[i] = NULL;
smime_encoded_caps = SEC_ASN1EncodeItem (NULL, NULL, &smime_capabilities,
smime_capabilities_template);
if (smime_encoded_caps == NULL)
return SECFailure;
lastUsedFortezza = isFortezza;
return SECSuccess;
}
@ -790,22 +748,16 @@ smime_init_caps (PRBool isFortezza)
static SECStatus
smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
{
PRBool isFortezza = PR_FALSE;
PORT_Assert (smime_prefs_complete);
if (! smime_prefs_complete)
return SECFailure;
/* See if the sender's cert specifies Fortezza key exchange. */
if (cert != NULL)
isFortezza = PK11_FortezzaHasKEA(cert);
/* For that matter, if capabilities haven't been initialized yet,
do so now. */
if (isFortezza != lastUsedFortezza || smime_encoded_caps == NULL || smime_prefs_changed) {
if (smime_encoded_caps == NULL || smime_prefs_changed) {
SECStatus rv;
rv = smime_init_caps(isFortezza);
rv = smime_init_caps();
if (rv != SECSuccess)
return rv;

View File

@ -37,7 +37,7 @@
/*
* CMS ASN.1 templates
*
* $Id: cmsasn1.c,v 1.9 2011/01/31 23:56:30 rrelyea%redhat.com Exp $
* $Id: cmsasn1.c,v 1.10 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#include "cmslocal.h"
@ -493,66 +493,6 @@ const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = {
SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate);
/* -----------------------------------------------------------------------------
* FORTEZZA KEA
*/
const SEC_ASN1Template NSS_SMIMEKEAParamTemplateSkipjack[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSCMSSMIMEKEAParameters) },
{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) },
{ SEC_ASN1_OCTET_STRING,
offsetof(NSSCMSSMIMEKEAParameters,originatorRA) },
{ 0 }
};
const SEC_ASN1Template NSS_SMIMEKEAParamTemplateNoSkipjack[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSCMSSMIMEKEAParameters) },
{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) },
{ SEC_ASN1_OCTET_STRING,
offsetof(NSSCMSSMIMEKEAParameters,originatorRA) },
{ SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL ,
offsetof(NSSCMSSMIMEKEAParameters,nonSkipjackIV) },
{ 0 }
};
const SEC_ASN1Template NSS_SMIMEKEAParamTemplateAllParams[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSCMSSMIMEKEAParameters) },
{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,
offsetof(NSSCMSSMIMEKEAParameters,originatorKEAKey) },
{ SEC_ASN1_OCTET_STRING,
offsetof(NSSCMSSMIMEKEAParameters,originatorRA) },
{ SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL ,
offsetof(NSSCMSSMIMEKEAParameters,nonSkipjackIV) },
{ SEC_ASN1_OCTET_STRING | SEC_ASN1_OPTIONAL ,
offsetof(NSSCMSSMIMEKEAParameters,bulkKeySize) },
{ 0 }
};
const SEC_ASN1Template *
nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate)
{
const SEC_ASN1Template *returnVal = NULL;
switch(whichTemplate)
{
case NSSCMSKEAUsesNonSkipjack:
returnVal = NSS_SMIMEKEAParamTemplateNoSkipjack;
break;
case NSSCMSKEAUsesSkipjack:
returnVal = NSS_SMIMEKEAParamTemplateSkipjack;
break;
case NSSCMSKEAUsesNonSkipjackWithPaddedEncKey:
default:
returnVal = NSS_SMIMEKEAParamTemplateAllParams;
break;
}
return returnVal;
}
/* -----------------------------------------------------------------------------
*
*/

View File

@ -37,7 +37,7 @@
/*
* CMS decoding.
*
* $Id: cmsdecode.c,v 1.13 2011/03/15 17:45:21 emaldona%redhat.com Exp $
* $Id: cmsdecode.c,v 1.14 2011/09/30 22:10:13 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -60,6 +60,8 @@ struct NSSCMSDecoderContextStr {
int error;
NSSCMSContentCallback cb;
void * cb_arg;
PRBool first_decoded;
PRBool need_indefinite_finish;
};
struct NSSCMSDecoderDataStr {
@ -316,6 +318,11 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
*/
childp7dcx->cb = p7dcx->cb;
childp7dcx->cb_arg = p7dcx->cb_arg;
childp7dcx->first_decoded = PR_FALSE;
childp7dcx->need_indefinite_finish = PR_FALSE;
if (childtype == SEC_OID_PKCS7_SIGNED_DATA) {
childp7dcx->first_decoded = PR_TRUE;
}
/* now set up the parent to hand decoded data to the next level decoder */
p7dcx->cb = (NSSCMSContentCallback)NSS_CMSDecoder_Update;
@ -348,6 +355,13 @@ nss_cms_after_data(NSSCMSDecoderContext *p7dcx)
if (p7dcx->childp7dcx != NULL) {
childp7dcx = p7dcx->childp7dcx;
if (childp7dcx->dcx != NULL) {
/* we started and indefinite sequence somewhere, not complete it */
if (childp7dcx->need_indefinite_finish) {
static const char lbuf[2] = { 0, 0 };
NSS_CMSDecoder_Update(childp7dcx, lbuf, sizeof(lbuf));
childp7dcx->need_indefinite_finish = PR_FALSE;
}
if (SEC_ASN1DecoderFinish(childp7dcx->dcx) != SECSuccess) {
/* do what? free content? */
rv = SECFailure;
@ -647,7 +661,8 @@ NSS_CMSDecoder_Start(PRArenaPool *poolp,
p7dcx->cb = cb;
p7dcx->cb_arg = cb_arg;
p7dcx->first_decoded = PR_FALSE;
p7dcx->need_indefinite_finish = PR_FALSE;
return p7dcx;
}
@ -658,16 +673,37 @@ SECStatus
NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf,
unsigned long len)
{
SECStatus rv;
SECStatus rv = SECSuccess;
if (p7dcx->dcx != NULL && p7dcx->error == 0) {
/* if error is set already, don't bother */
rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
if (rv != SECSuccess) {
p7dcx->error = PORT_GetError();
PORT_Assert (p7dcx->error);
if (p7dcx->error == 0)
p7dcx->error = -1;
if ((p7dcx->type == SEC_OID_PKCS7_SIGNED_DATA)
&& (p7dcx->first_decoded==PR_TRUE)
&& (buf[0] == SEC_ASN1_INTEGER)) {
/* Microsoft Windows 2008 left out the Sequence wrapping in some
* of their kerberos replies. If we are here, we most likely are
* dealing with one of those replies. Supply the Sequence wrap
* as indefinite encoding (since we don't know the total length
* yet) */
static const char lbuf[2] =
{ SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED, 0x80 };
rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, lbuf, sizeof(lbuf));
if (rv != SECSuccess) {
goto loser;
}
/* ok, we're going to need the indefinite finish when we are done */
p7dcx->need_indefinite_finish = PR_TRUE;
}
rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
}
loser:
p7dcx->first_decoded = PR_FALSE;
if (rv != SECSuccess) {
p7dcx->error = PORT_GetError();
PORT_Assert (p7dcx->error);
if (p7dcx->error == 0)
p7dcx->error = -1;
}
if (p7dcx->error == 0)

View File

@ -37,7 +37,7 @@
/*
* CMS encoding.
*
* $Id: cmsencode.c,v 1.11 2011/02/11 01:53:17 emaldona%redhat.com Exp $
* $Id: cmsencode.c,v 1.12 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#include "cmslocal.h"
@ -726,7 +726,6 @@ NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
{
SECStatus rv = SECFailure;
NSSCMSContentInfo *cinfo;
SECOidTag childtype;
/*
* Finish any inner decoders before us so that all the encoded data is flushed

View File

@ -42,7 +42,7 @@
* you. If that has a problem, then just move out what you need, changing
* its name as appropriate!
*
* $Id: cmslocal.h,v 1.6 2011/01/28 23:03:59 rrelyea%redhat.com Exp $
* $Id: cmslocal.h,v 1.8 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
*/
#ifndef _CMSLOCAL_H_
@ -199,14 +199,6 @@ NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
extern PK11SymKey *
NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag);
extern SECStatus
NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg);
extern PK11SymKey *
NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey,
SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg);
extern SECStatus
NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
@ -356,6 +348,12 @@ NSS_CMSAttributeArray_SetAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, SECO
extern SECStatus
NSS_CMSSignedData_AddTempCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert);
/*
* local function to handle compatibility issues
* by mapping a signature algorithm back to a digest.
*/
SECOidTag NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg);
/************************************************************************/

View File

@ -37,7 +37,7 @@
/*
* CMS public key crypto
*
* $Id: cmspubkey.c,v 1.7 2004/04/25 15:03:16 gerv%gerv.net Exp $
* $Id: cmspubkey.c,v 1.8 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#include "cmslocal.h"
@ -141,252 +141,6 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid
return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0);
}
/* ====== MISSI (Fortezza) ========================================================== */
extern const SEC_ASN1Template NSS_SMIMEKEAParamTemplateAllParams[];
SECStatus
NSS_CMSUtil_EncryptSymKey_MISSI(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *bulkkey,
SECOidTag symalgtag, SECItem *encKey, SECItem **pparams, void *pwfn_arg)
{
SECOidTag certalgtag; /* the certificate's encryption algorithm */
SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */
SECStatus rv = SECFailure;
SECItem *params = NULL;
SECStatus err;
PK11SymKey *tek;
CERTCertificate *ourCert;
SECKEYPublicKey *ourPubKey, *publickey = NULL;
SECKEYPrivateKey *ourPrivKey = NULL;
NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid;
NSSCMSSMIMEKEAParameters keaParams;
PLArenaPool *arena = NULL;
extern const SEC_ASN1Template *nss_cms_get_kea_template(NSSCMSKEATemplateSelector whichTemplate);
/* Clear keaParams, since cleanup code checks the lengths */
(void) memset(&keaParams, 0, sizeof(keaParams));
certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
PORT_Assert(certalgtag == SEC_OID_MISSI_KEA_DSS_OLD ||
certalgtag == SEC_OID_MISSI_KEA_DSS ||
certalgtag == SEC_OID_MISSI_KEA);
#define SMIME_FORTEZZA_RA_LENGTH 128
#define SMIME_FORTEZZA_IV_LENGTH 24
#define SMIME_FORTEZZA_MAX_KEY_SIZE 256
/* We really want to show our KEA tag as the key exchange algorithm tag. */
encalgtag = SEC_OID_NETSCAPE_SMIME_KEA;
/* Get the public key of the recipient. */
publickey = CERT_ExtractPublicKey(cert);
if (publickey == NULL) goto loser;
/* Find our own cert, and extract its keys. */
ourCert = PK11_FindBestKEAMatch(cert, pwfn_arg);
if (ourCert == NULL) goto loser;
arena = PORT_NewArena(1024);
if (arena == NULL)
goto loser;
ourPubKey = CERT_ExtractPublicKey(ourCert);
if (ourPubKey == NULL) {
CERT_DestroyCertificate(ourCert);
goto loser;
}
/* While we're here, copy the public key into the outgoing
* KEA parameters. */
SECITEM_CopyItem(arena, &(keaParams.originatorKEAKey), &(ourPubKey->u.fortezza.KEAKey));
SECKEY_DestroyPublicKey(ourPubKey);
ourPubKey = NULL;
/* Extract our private key in order to derive the KEA key. */
ourPrivKey = PK11_FindKeyByAnyCert(ourCert, pwfn_arg);
CERT_DestroyCertificate(ourCert); /* we're done with this */
if (!ourPrivKey)
goto loser;
/* Prepare raItem with 128 bytes (filled with zeros). */
keaParams.originatorRA.data = (unsigned char *)PORT_ArenaAlloc(arena,SMIME_FORTEZZA_RA_LENGTH);
keaParams.originatorRA.len = SMIME_FORTEZZA_RA_LENGTH;
/* Generate the TEK (token exchange key) which we use
* to wrap the bulk encryption key. (keaparams.originatorRA) will be
* filled with a random seed which we need to send to
* the recipient. (user keying material in RFC2630/DSA speak) */
tek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
&keaParams.originatorRA, NULL,
CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
CKA_WRAP, 0, pwfn_arg);
SECKEY_DestroyPublicKey(publickey);
SECKEY_DestroyPrivateKey(ourPrivKey);
publickey = NULL;
ourPrivKey = NULL;
if (!tek)
goto loser;
/* allocate space for the wrapped key data */
encKey->data = (unsigned char *)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE;
if (encKey->data == NULL) {
PK11_FreeSymKey(tek);
goto loser;
}
/* Wrap the bulk key. What we do with the resulting data
depends on whether we're using Skipjack to wrap the key. */
switch (PK11_AlgtagToMechanism(symalgtag)) {
case CKM_SKIPJACK_CBC64:
case CKM_SKIPJACK_ECB64:
case CKM_SKIPJACK_OFB64:
case CKM_SKIPJACK_CFB64:
case CKM_SKIPJACK_CFB32:
case CKM_SKIPJACK_CFB16:
case CKM_SKIPJACK_CFB8:
/* SKIPJACK, we use the wrap mechanism because we can do it on the hardware */
err = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, bulkkey, encKey);
whichKEA = NSSCMSKEAUsesSkipjack;
break;
default:
/* Not SKIPJACK, we encrypt the raw key data */
keaParams.nonSkipjackIV.data =
(unsigned char *)PORT_ArenaAlloc(arena, SMIME_FORTEZZA_IV_LENGTH);
keaParams.nonSkipjackIV.len = SMIME_FORTEZZA_IV_LENGTH;
err = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV, tek, bulkkey, encKey);
if (err != SECSuccess)
goto loser;
if (encKey->len != PK11_GetKeyLength(bulkkey)) {
/* The size of the encrypted key is not the same as
that of the original bulk key, presumably due to
padding. Encode and store the real size of the
bulk key. */
if (SEC_ASN1EncodeInteger(arena, &keaParams.bulkKeySize, PK11_GetKeyLength(bulkkey)) == NULL)
err = (SECStatus)PORT_GetError();
else
/* use full template for encoding */
whichKEA = NSSCMSKEAUsesNonSkipjackWithPaddedEncKey;
}
else
/* enc key length == bulk key length */
whichKEA = NSSCMSKEAUsesNonSkipjack;
break;
}
PK11_FreeSymKey(tek);
if (err != SECSuccess)
goto loser;
PORT_Assert(whichKEA != NSSCMSKEAInvalid);
/* Encode the KEA parameters into the recipient info. */
params = SEC_ASN1EncodeItem(poolp, NULL, &keaParams, nss_cms_get_kea_template(whichKEA));
if (params == NULL)
goto loser;
/* pass back the algorithm params */
*pparams = params;
rv = SECSuccess;
loser:
if (arena)
PORT_FreeArena(arena, PR_FALSE);
if (publickey)
SECKEY_DestroyPublicKey(publickey);
if (ourPrivKey)
SECKEY_DestroyPrivateKey(ourPrivKey);
return rv;
}
PK11SymKey *
NSS_CMSUtil_DecryptSymKey_MISSI(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg)
{
/* fortezza: do a key exchange */
SECStatus err;
CK_MECHANISM_TYPE bulkType;
PK11SymKey *tek;
SECKEYPublicKey *originatorPubKey;
NSSCMSSMIMEKEAParameters keaParams;
PK11SymKey *bulkkey;
int bulkLength;
(void) memset(&keaParams, 0, sizeof(keaParams));
/* NOTE: this uses the SMIME v2 recipientinfo for compatibility.
All additional KEA parameters are DER-encoded in the encryption algorithm parameters */
/* Decode the KEA algorithm parameters. */
err = SEC_ASN1DecodeItem(NULL, &keaParams, NSS_SMIMEKEAParamTemplateAllParams,
&(keyEncAlg->parameters));
if (err != SECSuccess)
goto loser;
/* get originator's public key */
originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
keaParams.originatorKEAKey.len);
if (originatorPubKey == NULL)
goto loser;
/* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key.
The Derive function generates a shared secret and combines it with the originatorRA
data to come up with an unique session key */
tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE,
&keaParams.originatorRA, NULL,
CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
CKA_WRAP, 0, pwfn_arg);
SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */
if (tek == NULL)
goto loser;
/* Now that we have the TEK, unwrap the bulk key
with which to decrypt the message. We have to
do one of two different things depending on
whether Skipjack was used for *bulk* encryption
of the message. */
bulkType = PK11_AlgtagToMechanism(bulkalgtag);
switch (bulkType) {
case CKM_SKIPJACK_CBC64:
case CKM_SKIPJACK_ECB64:
case CKM_SKIPJACK_OFB64:
case CKM_SKIPJACK_CFB64:
case CKM_SKIPJACK_CFB32:
case CKM_SKIPJACK_CFB16:
case CKM_SKIPJACK_CFB8:
/* Skipjack is being used as the bulk encryption algorithm.*/
/* Unwrap the bulk key. */
bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL,
encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
break;
default:
/* Skipjack was not used for bulk encryption of this
message. Use Skipjack CBC64, with the nonSkipjackIV
part of the KEA key parameters, to decrypt
the bulk key. If the optional parameter bulkKeySize is present,
bulk key size is different than the encrypted key size */
if (keaParams.bulkKeySize.len > 0) {
err = SEC_ASN1DecodeItem(NULL, &bulkLength,
SEC_ASN1_GET(SEC_IntegerTemplate),
&keaParams.bulkKeySize);
if (err != SECSuccess)
goto loser;
}
bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &keaParams.nonSkipjackIV,
encKey, bulkType, CKA_DECRYPT, bulkLength);
break;
}
return bulkkey;
loser:
return NULL;
}
/* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */
SECStatus

View File

@ -37,7 +37,7 @@
/*
* CMS recipientInfo methods.
*
* $Id: cmsrecinfo.c,v 1.20 2008/06/06 01:16:18 wtc%google.com Exp $
* $Id: cmsrecinfo.c,v 1.21 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#include "cmslocal.h"
@ -579,11 +579,6 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
/* get the symmetric (bulk) key by unwrapping it using our private key */
bulkkey = NSS_CMSUtil_DecryptSymKey_RSA(privkey, enckey, bulkalgtag);
break;
case SEC_OID_NETSCAPE_SMIME_KEA:
/* FORTEZZA key exchange algorithm */
/* the supplemental data is in the parameters of encalg */
bulkkey = NSS_CMSUtil_DecryptSymKey_MISSI(privkey, enckey, encalg, bulkalgtag, ri->cmsg->pwfn_arg);
break;
default:
error = SEC_ERROR_UNSUPPORTED_KEYALG;
goto loser;
@ -604,6 +599,7 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
/* content encryption key using a Unwrap op */
/* the derive operation has to generate the key using the algorithm in RFC2631 */
error = SEC_ERROR_UNSUPPORTED_KEYALG;
goto loser;
break;
default:
error = SEC_ERROR_UNSUPPORTED_KEYALG;
@ -623,6 +619,7 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
return bulkkey;
loser:
PORT_SetError(error);
return NULL;
}

View File

@ -37,7 +37,7 @@
/*
* CMS signedData methods.
*
* $Id: cmssigdata.c,v 1.31 2011/02/11 01:53:17 emaldona%redhat.com Exp $
* $Id: cmssigdata.c,v 1.32 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -406,6 +406,25 @@ NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd)
if (rv != SECSuccess) {
return SECFailure;
}
/* handle issue with Windows 2003 servers and kerberos */
if (sigd->digestAlgorithms != NULL) {
int i;
for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
SECAlgorithmID *algid = sigd->digestAlgorithms[i];
SECOidTag senttag= SECOID_FindOIDTag(&algid->algorithm);
SECOidTag maptag = NSS_CMSUtil_MapSignAlgs(senttag);
if (maptag != senttag) {
SECOidData *hashoid = SECOID_FindOIDByTag(maptag);
rv = SECITEM_CopyItem(sigd->cmsg->poolp, &algid->algorithm
,&hashoid->oid);
if (rv != SECSuccess) {
return rv;
}
}
}
}
/* set up the digests */
if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
/* if digests are already there, do nothing */

View File

@ -38,7 +38,7 @@
/*
* CMS signerInfo methods.
*
* $Id: cmssiginfo.c,v 1.34 2011/02/07 18:32:19 nelson%bolyard.com Exp $
* $Id: cmssiginfo.c,v 1.36 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -215,11 +215,6 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
}
/* Fortezza MISSI have weird signature formats.
* Map them to standard DSA formats
*/
pubkAlgTag = PK11_FortezzaMapSig(pubkAlgTag);
if (signerinfo->authAttr != NULL) {
SECOidTag signAlgTag;
SECItem encoded_attrs;
@ -535,7 +530,28 @@ NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo)
SECOidData *
NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
{
return SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
SECOidData *algdata;
SECOidTag algtag;
algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
if (algdata == NULL) {
return algdata;
}
/* Windows may have given us a signer algorithm oid instead of a digest
* algorithm oid. This call will map to a signer oid to a digest one,
* otherwise it leaves the oid alone and let the chips fall as they may
* if it's not a digest oid.
*/
algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset);
if (algtag != algdata->offset) {
/* if the tags don't match, then we must have received a signer
* algorithID. Now we need to get the oid data for the digest
* oid, which the rest of the code is expecting */
algdata = SECOID_FindOIDByTag(algtag);
}
return algdata;
}
SECOidTag
@ -548,7 +564,7 @@ NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
return SEC_OID_UNKNOWN;
}
algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
if (algdata != NULL)
return algdata->offset;
else
@ -784,8 +800,7 @@ NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo)
goto loser;
/* create new signing time attribute */
if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps,
PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess)
if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess)
goto loser;
if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)

View File

@ -37,7 +37,7 @@
/*
* Header for CMS types.
*
* $Id: cmst.h,v 1.13 2011/02/11 01:53:17 emaldona%redhat.com Exp $
* $Id: cmst.h,v 1.14 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#ifndef _CMST_H_
@ -100,8 +100,6 @@ typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData;
typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData;
typedef struct NSSCMSSMIMEKEAParametersStr NSSCMSSMIMEKEAParameters;
typedef struct NSSCMSAttributeStr NSSCMSAttribute;
typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext;
@ -511,38 +509,6 @@ struct NSSCMSEncryptedDataStr {
#define NSS_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
#define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
/* =============================================================================
* FORTEZZA KEA
*/
/* An enumerated type used to select templates based on the encryption
scenario and data specifics. */
typedef enum {
NSSCMSKEAInvalid = -1,
NSSCMSKEAUsesSkipjack = 0,
NSSCMSKEAUsesNonSkipjack = 1,
NSSCMSKEAUsesNonSkipjackWithPaddedEncKey = 2
} NSSCMSKEATemplateSelector;
/* ### mwelch - S/MIME KEA parameters. These don't really fit here,
but I cannot think of a more appropriate place at this time. */
struct NSSCMSSMIMEKEAParametersStr {
SECItem originatorKEAKey; /* sender KEA key (encrypted?) */
SECItem originatorRA; /* random number generated by sender */
SECItem nonSkipjackIV; /* init'n vector for SkipjackCBC64
decryption of KEA key if Skipjack
is not the bulk algorithm used on
the message */
SECItem bulkKeySize; /* if Skipjack is not the bulk
algorithm used on the message,
and the size of the bulk encryption
key is not the same as that of
originatorKEAKey (due to padding
perhaps), this field will contain
the real size of the bulk encryption
key. */
};
/*
* *****************************************************************************
* *****************************************************************************

View File

@ -38,7 +38,7 @@
/*
* CMS miscellaneous utility functions.
*
* $Id: cmsutil.c,v 1.16 2011/01/28 23:03:59 rrelyea%redhat.com Exp $
* $Id: cmsutil.c,v 1.17 2011/09/30 19:42:09 rrelyea%redhat.com Exp $
*/
#include "cmslocal.h"
@ -211,6 +211,45 @@ NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray,
return i;
}
/*
* Map a sign algorithm to a digest algorithm.
* This is used to handle incorrectly formatted packages sent to us
* from Windows 2003.
*/
SECOidTag
NSS_CMSUtil_MapSignAlgs(SECOidTag signAlg)
{
switch (signAlg) {
case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
return SEC_OID_MD2;
break;
case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
return SEC_OID_MD5;
break;
case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
return SEC_OID_SHA1;
break;
case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
return SEC_OID_SHA256;
break;
case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
return SEC_OID_SHA384;
break;
case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
return SEC_OID_SHA512;
break;
default:
break;
}
/* not one of the algtags incorrectly sent to us*/
return signAlg;
}
const SECHashObject *
NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid)
{
@ -350,3 +389,4 @@ NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
}
return rv;
}

View File

@ -38,7 +38,7 @@
* Header file for routines specific to S/MIME. Keep things that are pure
* pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc.
*
* $Id: smime.h,v 1.10 2011/08/01 07:08:09 kaie%kuix.de Exp $
* $Id: smime.h,v 1.11 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#ifndef _SECMIME_H_
@ -126,7 +126,7 @@ extern PRBool NSS_SMIMEUtil_EncryptionPossible(void);
* scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
* S/MIME capabilities attribute value.
*/
extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers);
extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest);
/*
* NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value

View File

@ -37,7 +37,7 @@
/*
* Stuff specific to S/MIME policy and interoperability.
*
* $Id: smimeutil.c,v 1.21 2011/08/01 07:08:09 kaie%kuix.de Exp $
* $Id: smimeutil.c,v 1.22 2011/08/21 01:14:18 wtc%google.com Exp $
*/
#include "secmime.h"
@ -152,8 +152,7 @@ static smime_cipher_map_entry smime_cipher_map[] = {
{ SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &param_int64, PR_TRUE, PR_TRUE },
{ SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &param_int128, PR_TRUE, PR_TRUE },
{ SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE },
{ SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE },
{ SMIME_FORTEZZA, SEC_OID_FORTEZZA_SKIPJACK, NULL, PR_TRUE, PR_TRUE }
{ SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE }
};
static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);
@ -273,10 +272,8 @@ nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key, uns
case SEC_OID_AES_128_CBC:
c = SMIME_AES_CBC_128;
break;
case SEC_OID_FORTEZZA_SKIPJACK:
c = SMIME_FORTEZZA;
break;
default:
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
}
*cipher = c;
@ -393,7 +390,6 @@ smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
int weak_mapi;
int strong_mapi;
int rcount, mapi, max, i;
PRBool scert_is_fortezza = (scert == NULL) ? PR_FALSE : PK11_FortezzaHasKEA(scert);
chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
weak_mapi = smime_mapi_by_cipher(chosen_cipher);
@ -407,14 +403,8 @@ smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
if (cipher_votes == NULL || cipher_abilities == NULL)
goto done;
/* If the user has the Fortezza preference turned on, make
* that the strong cipher. Otherwise, use triple-DES. */
/* Make triple-DES the strong cipher. */
strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
if (scert_is_fortezza) {
mapi = smime_mapi_by_cipher(SMIME_FORTEZZA);
if (mapi >= 0 && smime_cipher_map[mapi].enabled)
strong_mapi = mapi;
}
/* walk all the recipient's certs */
for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
@ -498,9 +488,6 @@ smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
/* if cipher is not enabled or not allowed by policy, forget it */
if (!smime_cipher_map[mapi].enabled || !smime_cipher_map[mapi].allowed)
continue;
/* if we're not doing fortezza, but the cipher is fortezza, forget it */
if (!scert_is_fortezza && (smime_cipher_map[mapi].cipher == SMIME_FORTEZZA))
continue;
/* now see if this one has more votes than the last best one */
if (cipher_votes[mapi] >= max) {
/* if equal number of votes, prefer the ones further down in the list */
@ -541,7 +528,6 @@ smime_keysize_by_cipher (unsigned long which)
break;
case SMIME_DES_CBC_56:
case SMIME_DES_EDE3_168:
case SMIME_FORTEZZA:
/*
* These are special; since the key size is fixed, we actually
* want to *avoid* specifying a key size.
@ -588,10 +574,9 @@ NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulk
*
* "poolp" - arena pool to create the S/MIME capabilities data on
* "dest" - SECItem to put the data in
* "includeFortezzaCiphers" - PR_TRUE if fortezza ciphers should be included
*/
SECStatus
NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers)
NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
{
NSSSMIMECapability *cap;
NSSSMIMECapability **smime_capabilities;
@ -619,12 +604,6 @@ NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool
if (!map->enabled)
continue;
/* If we're using a non-Fortezza cert, only advertise non-Fortezza
capabilities. (We advertise all capabilities if we have a
Fortezza cert.) */
if ((!includeFortezzaCiphers) && (map->cipher == SMIME_FORTEZZA))
continue;
/* get next SMIME capability */
cap = (NSSSMIMECapability *)PORT_ZAlloc(sizeof(NSSSMIMECapability));
if (cap == NULL)

View File

@ -2320,7 +2320,6 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,
PORT_Memcpy(pSignature, context->macBuf, outlen );
}
terminate:
sftk_TerminateOp( session, SFTK_SIGN, context );
finish:
*pulSignatureLen = outlen;
@ -2751,7 +2750,6 @@ CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession,
crv = CKR_SIGNATURE_INVALID;
}
terminate:
sftk_TerminateOp( session, SFTK_VERIFY, context );
sftk_FreeSession(session);
return crv;

View File

@ -23,6 +23,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Hanno Boeck <hanno@hboeck.de>
*
* 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
@ -37,7 +38,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: rsawrapr.c,v 1.17 2010/08/07 18:10:35 wtc%google.com Exp $ */
/* $Id: rsawrapr.c,v 1.18 2011/10/04 22:05:53 wtc%google.com Exp $ */
#include "blapi.h"
#include "softoken.h"
@ -944,6 +945,53 @@ failure:
return SECFailure;
}
/*
* Mask generation function MGF1 as defined in PKCS #1 v2.1 / RFC 3447.
*/
static SECStatus
MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
const unsigned char *mgfSeed, unsigned int mgfSeedLen)
{
unsigned int digestLen;
PRUint32 counter, rounds;
unsigned char *tempHash, *temp;
const SECHashObject *hash;
void *hashContext;
unsigned char C[4];
hash = HASH_GetRawHashObject(hashAlg);
if (hash == NULL)
return SECFailure;
hashContext = (*hash->create)();
rounds = (maskLen + hash->length - 1) / hash->length;
for (counter = 0; counter < rounds; counter++) {
C[0] = (unsigned char)((counter >> 24) & 0xff);
C[1] = (unsigned char)((counter >> 16) & 0xff);
C[2] = (unsigned char)((counter >> 8) & 0xff);
C[3] = (unsigned char)(counter & 0xff);
/* This could be optimized when the clone functions in
* rawhash.c are implemented. */
(*hash->begin)(hashContext);
(*hash->update)(hashContext, mgfSeed, mgfSeedLen);
(*hash->update)(hashContext, C, sizeof C);
tempHash = mask + counter * hash->length;
if (counter != (rounds-1)) {
(*hash->end)(hashContext, tempHash, &digestLen, hash->length);
} else { /* we're in the last round and need to cut the hash */
temp = PORT_Alloc(hash->length);
(*hash->end)(hashContext, temp, &digestLen, hash->length);
PORT_Memcpy(tempHash, temp, maskLen - counter * hash->length);
PORT_Free(temp);
}
}
(*hash->destroy)(hashContext, PR_TRUE);
return SECSuccess;
}
/*
* Encode a RSA-PSS signature.
* Described in RFC 3447, section 9.1.1.

View File

@ -1495,6 +1495,9 @@ sftkdb_CloseDB(SFTKDBHandle *handle)
}
(*handle->db->sdb_Close)(handle->db);
}
if (handle->passwordKey.data) {
PORT_ZFree(handle->passwordKey.data, handle->passwordKey.len);
}
if (handle->passwordLock) {
SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
}

View File

@ -179,15 +179,18 @@ char *sftk_getOldSecmodName(const char *dbname,const char *filename)
char *sep;
sep = PORT_Strrchr(dirPath,*PATH_SEPARATOR);
#ifdef WINDOWS
#ifdef _WIN32
if (!sep) {
sep = PORT_Strrchr(dirPath,'/');
/* pkcs11i.h defines PATH_SEPARATOR as "/" for all platforms. */
sep = PORT_Strrchr(dirPath,'\\');
}
#endif
if (sep) {
*(sep)=0;
*sep = 0;
file = PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename);
} else {
file = PR_smprintf("%s", filename);
}
file= PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename);
PORT_Free(dirPath);
return file;
}
@ -242,13 +245,18 @@ sftkdb_ReadSecmodDB(SDBType dbType, const char *appName,
char *paramsValue=NULL;
PRBool failed = PR_TRUE;
if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
if ((dbname != NULL) &&
((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS))) {
return sftkdbCall_ReadSecmodDB(appName, filename, dbname, params, rw);
}
moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
if (moduleList == NULL) return NULL;
if (dbname == NULL) {
goto return_default;
}
/* do we really want to use streams here */
fd = fopen(dbname, "r");
if (fd == NULL) goto done;
@ -405,7 +413,11 @@ sftkdb_ReadSecmodDB(SDBType dbType, const char *appName,
moduleString = NULL;
}
done:
/* if we couldn't open a pkcs11 database, look for the old one */
/* If we couldn't open a pkcs11 database, look for the old one.
* This is necessary to maintain the semantics of the transition from
* old to new DB's. If there is an old DB and not new DB, we will
* automatically use the old DB. If the DB was opened read/write, we
* create a new db and upgrade it from the old one. */
if (fd == NULL) {
char *olddbname = sftk_getOldSecmodName(dbname,filename);
PRStatus status;
@ -462,6 +474,8 @@ bail:
PR_smprintf_free(olddbname);
}
}
return_default:
if (!moduleList[0]) {
char * newParams;
@ -515,7 +529,8 @@ sftkdb_ReleaseSecmodDBData(SDBType dbType, const char *appName,
const char *filename, const char *dbname,
char **moduleSpecList, PRBool rw)
{
if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
if ((dbname != NULL) &&
((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS))) {
return sftkdbCall_ReleaseSecmodDBData(appName, filename, dbname,
moduleSpecList, rw);
}
@ -546,6 +561,10 @@ sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName,
PRBool skip = PR_FALSE;
PRBool found = PR_FALSE;
if (dbname == NULL) {
return SECFailure;
}
if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw);
}
@ -669,6 +688,10 @@ sftkdb_AddSecmodDB(SDBType dbType, const char *appName,
char *block = NULL;
PRBool libFound = PR_FALSE;
if (dbname == NULL) {
return SECFailure;
}
if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
return sftkdbCall_AddSecmodDB(appName, filename, dbname, module, rw);
}

View File

@ -607,6 +607,7 @@ sftk_getSecmodName(char *param, SDBType *dbType, char **appName,
char *value = NULL;
char *save_params = param;
const char *lconfigdir;
PRBool noModDB = PR_FALSE;
param = sftk_argStrip(param);
@ -631,7 +632,10 @@ sftk_getSecmodName(char *param, SDBType *dbType, char **appName,
if (sftk_argHasFlag("flags","noModDB",save_params)) {
/* there isn't a module db, don't load the legacy support */
noModDB = PR_TRUE;
*dbType = SDB_SQL;
PORT_Free(*filename);
*filename = NULL;
*rw = PR_FALSE;
}
@ -640,7 +644,9 @@ sftk_getSecmodName(char *param, SDBType *dbType, char **appName,
secmodName="pkcs11.txt";
}
if (lconfigdir) {
if (noModDB) {
value = NULL;
} else if (lconfigdir && lconfigdir[0] != '\0') {
value = PR_smprintf("%s" PATH_SEPARATOR "%s",lconfigdir,secmodName);
} else {
value = PR_smprintf("%s",secmodName);

View File

@ -57,11 +57,11 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define SOFTOKEN_VERSION "3.13.0.0" SOFTOKEN_ECC_STRING " Beta"
#define SOFTOKEN_VERSION "3.13.0.0" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 13
#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_TRUE
#define SOFTOKEN_BETA PR_FALSE
#endif /* _SOFTKVER_H_ */

View File

@ -52,7 +52,8 @@ ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
"Unable to communicate securely with peer: peers's certificate was rejected.")
/* unused (SSL_ERROR_BASE + 5),*/
ER3(SSL_ERROR_UNUSED_5, SSL_ERROR_BASE + 5,
"Unrecognized SSL error code.")
ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
"The server has encountered bad data from the client.")
@ -66,7 +67,8 @@ ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
"Peer using unsupported version of security protocol.")
/* unused (SSL_ERROR_BASE + 10),*/
ER3(SSL_ERROR_UNUSED_10, SSL_ERROR_BASE + 10,
"Unrecognized SSL error code.")
ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
"Client authentication failed: private key in key database does not match public key in certificate database.")
@ -74,9 +76,8 @@ ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
defined in sslerr.h
*/
ER3(SSL_ERROR_POST_WARNING, SSL_ERROR_BASE + 13,
"Unrecognized SSL error code.")
ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
"Peer only supports SSL version 2, which is locally disabled.")
@ -103,7 +104,6 @@ ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
"Cannot connect: SSL peer is in another FORTEZZA domain.")
ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
"An unknown SSL cipher suite has been requested.")

View File

@ -46,11 +46,6 @@ EXPORTS = \
preenc.h \
$(NULL)
PRIVATE_EXPORTS = \
sslerrstrs.h \
SSLerrs.h \
$(NULL)
MODULE = nss
MAPFILE = $(OBJDIR)/ssl.def

View File

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: ssl.h,v 1.42 2011/08/01 07:08:09 kaie%kuix.de Exp $ */
/* $Id: ssl.h,v 1.44 2011/10/06 22:42:33 wtc%google.com Exp $ */
#ifndef __ssl_h_
#define __ssl_h_
@ -100,7 +100,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
/* (off by default) */
#define SSL_HANDSHAKE_AS_SERVER 6 /* force connect to hs as server */
/* (off by default) */
#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (on by default) */
#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (off by default) */
#define SSL_ENABLE_SSL3 8 /* enable ssl v3 (on by default) */
#define SSL_NO_CACHE 9 /* don't use the session cache */
/* (off by default) */
@ -109,7 +109,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
#define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */
/* (off by default) */
#define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */
/* (on by default) */
/* (off by default) */
#define SSL_ENABLE_TLS 13 /* enable TLS (on by default) */
#define SSL_ROLLBACK_DETECTION 14 /* for compatibility, default: on */
#define SSL_NO_STEP_DOWN 15 /* Disable export cipher suites */
@ -140,6 +140,34 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd);
/* bits. The advantage of False Start is that it saves a round trip for */
/* client-speaks-first protocols when performing a full handshake. */
/* For SSL 3.0 and TLS 1.0, by default we prevent chosen plaintext attacks
* on SSL CBC mode cipher suites (see RFC 4346 Section F.3) by splitting
* non-empty application_data records into two records; the first record has
* only the first byte of plaintext, and the second has the rest.
*
* This only prevents the attack in the sending direction; the connection may
* still be vulnerable to such attacks if the peer does not implement a similar
* countermeasure.
*
* This protection mechanism is on by default; the default can be overridden by
* setting NSS_SSL_CBC_RANDOM_IV=0 in the environment prior to execution,
* and/or by the application setting the option SSL_CBC_RANDOM_IV to PR_FALSE.
*
* The per-record IV in TLS 1.1 and later adds one block of overhead per
* record, whereas this hack will add at least two blocks of overhead per
* record, so TLS 1.1+ will always be more efficient.
*
* Other implementations (e.g. some versions of OpenSSL, in some
* configurations) prevent the same attack by prepending an empty
* application_data record to every application_data record they send; we do
* not do that because some implementations cannot handle empty
* application_data records. Also, we only split application_data records and
* not other types of records, because some implementations will not accept
* fragmented records of some other types (e.g. some versions of NSS do not
* accept fragmented alerts).
*/
#define SSL_CBC_RANDOM_IV 23
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);

View File

@ -39,7 +39,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: ssl3con.c,v 1.151 2011/07/26 02:13:37 wtc%google.com Exp $ */
/* $Id: ssl3con.c,v 1.152 2011/10/01 03:59:54 bsmith%mozilla.com Exp $ */
#include "cert.h"
#include "ssl.h"
@ -2037,24 +2037,22 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
return isPresent;
}
/* Caller must hold the spec read lock. */
static SECStatus
ssl3_CompressMACEncryptRecord(sslSocket * ss,
ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
PRBool isServer,
SSL3ContentType type,
const SSL3Opaque * pIn,
PRUint32 contentLen)
PRUint32 contentLen,
sslBuffer * wrBuf)
{
ssl3CipherSpec * cwSpec;
const ssl3BulkCipherDef * cipher_def;
sslBuffer * wrBuf = &ss->sec.writeBuf;
SECStatus rv;
PRUint32 macLen = 0;
PRUint32 fragLen;
PRUint32 p1Len, p2Len, oddLen = 0;
PRInt32 cipherBytes = 0;
ssl_GetSpecReadLock(ss); /********************************/
cwSpec = ss->ssl3.cwSpec;
cipher_def = cwSpec->cipher_def;
if (cwSpec->compressor) {
@ -2071,12 +2069,12 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
/*
* Add the MAC
*/
rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer),
rv = ssl3_ComputeRecordMAC( cwSpec, isServer,
type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
goto spec_locked_loser;
return SECFailure;
}
p1Len = contentLen;
p2Len = macLen;
@ -2129,7 +2127,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
PORT_Assert(rv == SECSuccess && cipherBytes == p1Len);
if (rv != SECSuccess || cipherBytes != p1Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
goto spec_locked_loser;
return SECFailure;
}
}
if (p2Len > 0) {
@ -2143,7 +2141,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
goto spec_locked_loser;
return SECFailure;
}
cipherBytes += cipherBytesPart2;
}
@ -2158,13 +2156,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
wrBuf->buf[3] = MSB(cipherBytes);
wrBuf->buf[4] = LSB(cipherBytes);
ssl_ReleaseSpecReadLock(ss); /************************************/
return SECSuccess;
spec_locked_loser:
ssl_ReleaseSpecReadLock(ss);
return SECFailure;
}
/* Process the plain text before sending it.
@ -2225,20 +2217,70 @@ ssl3_SendRecord( sslSocket * ss,
while (nIn > 0) {
PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
unsigned int spaceNeeded;
unsigned int numRecords;
if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen);
newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH);
newSpace += SSL3_BUFFER_FUDGE;
rv = sslBuffer_Grow(wrBuf, newSpace);
ssl_GetSpecReadLock(ss); /********************************/
if (nIn > 1 && ss->opt.cbcRandomIV &&
ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS &&
type == content_application_data &&
ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
/* We will split the first byte of the record into its own record,
* as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
*/
numRecords = 2;
} else {
numRecords = 1;
}
spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
if (spaceNeeded > wrBuf->space) {
rv = sslBuffer_Grow(wrBuf, spaceNeeded);
if (rv != SECSuccess) {
SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
SSL_GETPID(), ss->fd, newSpace));
return SECFailure; /* sslBuffer_Grow set a memory error code. */
SSL_GETPID(), ss->fd, spaceNeeded));
goto spec_locked_loser; /* sslBuffer_Grow set error code. */
}
}
rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen);
if (numRecords == 2) {
sslBuffer secondRecord;
rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
ss->sec.isServer, type, pIn, 1,
wrBuf);
if (rv != SECSuccess)
goto spec_locked_loser;
PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
wrBuf->buf, wrBuf->len));
secondRecord.buf = wrBuf->buf + wrBuf->len;
secondRecord.len = 0;
secondRecord.space = wrBuf->space - wrBuf->len;
rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
ss->sec.isServer, type, pIn + 1,
contentLen - 1, &secondRecord);
if (rv == SECSuccess) {
PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
secondRecord.buf, secondRecord.len));
wrBuf->len += secondRecord.len;
}
} else {
rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
ss->sec.isServer, type, pIn,
contentLen, wrBuf);
if (rv == SECSuccess) {
PRINT_BUF(50, (ss, "send (encrypted) record data:",
wrBuf->buf, wrBuf->len));
}
}
spec_locked_loser:
ssl_ReleaseSpecReadLock(ss); /************************************/
if (rv != SECSuccess)
return SECFailure;
@ -2246,8 +2288,6 @@ ssl3_SendRecord( sslSocket * ss,
nIn -= contentLen;
PORT_Assert( nIn >= 0 );
PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len));
/* If there's still some previously saved ciphertext,
* or the caller doesn't want us to send the data yet,
* then add all our new ciphertext to the amount previously saved.

View File

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: sslerr.h,v 1.13 2010/09/01 19:43:48 wtc%google.com Exp $ */
/* $Id: sslerr.h,v 1.14 2011/10/05 18:07:18 emaldona%redhat.com Exp $ */
#ifndef __SSL_ERR_H_
#define __SSL_ERR_H_
@ -57,11 +57,13 @@ SSL_ERROR_NO_CYPHER_OVERLAP = (SSL_ERROR_BASE + 2),
*/
SSL_ERROR_NO_CERTIFICATE /*_ALERT */ = (SSL_ERROR_BASE + 3),
SSL_ERROR_BAD_CERTIFICATE = (SSL_ERROR_BASE + 4),
SSL_ERROR_UNUSED_5 = (SSL_ERROR_BASE + 5),
/* error 5 is obsolete */
SSL_ERROR_BAD_CLIENT = (SSL_ERROR_BASE + 6),
SSL_ERROR_BAD_SERVER = (SSL_ERROR_BASE + 7),
SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE = (SSL_ERROR_BASE + 8),
SSL_ERROR_UNSUPPORTED_VERSION = (SSL_ERROR_BASE + 9),
SSL_ERROR_UNUSED_10 = (SSL_ERROR_BASE + 10),
/* error 10 is obsolete */
SSL_ERROR_WRONG_CERTIFICATE = (SSL_ERROR_BASE + 11),
SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12),

View File

@ -39,7 +39,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: sslimpl.h,v 1.82 2011/03/10 04:29:04 alexei.volkov.bugs%sun.com Exp $ */
/* $Id: sslimpl.h,v 1.83 2011/10/01 03:59:54 bsmith%mozilla.com Exp $ */
#ifndef __sslimpl_h_
#define __sslimpl_h_
@ -334,6 +334,7 @@ typedef struct sslOptionsStr {
unsigned int enableRenegotiation : 2; /* 20-21 */
unsigned int requireSafeNegotiation : 1; /* 22 */
unsigned int enableFalseStart : 1; /* 23 */
unsigned int cbcRandomIV : 1; /* 24 */
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,

View File

@ -33,7 +33,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: sslmutex.c,v 1.25 2010/04/03 18:27:33 nelson%bolyard.com Exp $ */
/* $Id: sslmutex.c,v 1.27 2011/10/01 00:11:02 wtc%google.com Exp $ */
#include "seccomon.h"
/* This ifdef should match the one in sslsnce.c */
@ -168,7 +168,7 @@ loser:
}
SECStatus
sslMutex_Destroy(sslMutex *pMutex)
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
if (PR_FALSE == pMutex->isMultiProcess) {
return single_process_sslMutex_Destroy(pMutex);
@ -180,6 +180,10 @@ sslMutex_Destroy(sslMutex *pMutex)
close(pMutex->u.pipeStr.mPipes[0]);
close(pMutex->u.pipeStr.mPipes[1]);
if (processLocal) {
return SECSuccess;
}
pMutex->u.pipeStr.mPipes[0] = -1;
pMutex->u.pipeStr.mPipes[1] = -1;
pMutex->u.pipeStr.mPipes[2] = -1;
@ -409,7 +413,7 @@ sslMutex_Init(sslMutex *pMutex, int shared)
}
SECStatus
sslMutex_Destroy(sslMutex *pMutex)
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
HANDLE hMutex;
int rv;
@ -435,9 +439,10 @@ sslMutex_Destroy(sslMutex *pMutex)
}
rv = CloseHandle(hMutex); /* ignore error */
if (rv) {
if (!processLocal && rv) {
pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE;
} else {
}
if (!rv) {
nss_MD_win32_map_default_error(GetLastError());
retvalue = SECFailure;
}
@ -557,12 +562,17 @@ sslMutex_Init(sslMutex *pMutex, int shared)
}
SECStatus
sslMutex_Destroy(sslMutex *pMutex)
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
int rv;
if (PR_FALSE == pMutex->isMultiProcess) {
return single_process_sslMutex_Destroy(pMutex);
}
/* semaphores are global resources. See SEM_DESTROY(3) man page */
if (processLocal) {
return SECSuccess;
}
do {
rv = sem_destroy(&pMutex->u.sem);
} while (rv < 0 && errno == EINTR);
@ -623,7 +633,7 @@ sslMutex_Init(sslMutex *pMutex, int shared)
}
SECStatus
sslMutex_Destroy(sslMutex *pMutex)
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
{
PR_ASSERT(pMutex);
if (PR_FALSE == pMutex->isMultiProcess) {

View File

@ -33,7 +33,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: sslmutex.h,v 1.12 2009/06/05 02:34:15 nelson%bolyard.com Exp $ */
/* $Id: sslmutex.h,v 1.13 2011/09/30 23:27:08 rrelyea%redhat.com Exp $ */
#ifndef __SSLMUTEX_H_
#define __SSLMUTEX_H_ 1
@ -138,7 +138,10 @@ SEC_BEGIN_PROTOS
extern SECStatus sslMutex_Init(sslMutex *sem, int shared);
extern SECStatus sslMutex_Destroy(sslMutex *sem);
/* If processLocal is set to true, then just free resources which are *only* associated
* with the current process. Leave any shared resources (including the state of
* shared memory) intact. */
extern SECStatus sslMutex_Destroy(sslMutex *sem, PRBool processLocal);
extern SECStatus sslMutex_Unlock(sslMutex *sem);

View File

@ -36,7 +36,7 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* $Id: sslsnce.c,v 1.56 2011/08/17 14:41:10 emaldona%redhat.com Exp $ */
/* $Id: sslsnce.c,v 1.58 2011/10/01 00:11:02 wtc%google.com Exp $ */
/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server
* cache sids!
@ -1027,15 +1027,16 @@ CloseCache(cacheDesc *cache)
int locks_initialized = cache->numSIDCacheLocksInitialized;
if (cache->cacheMem) {
/* If everInherited is true, this shared cache was (and may still
** be) in use by multiple processes. We do not wish to destroy
** the mutexes while they are still in use.
*/
if (cache->sharedCache &&
PR_FALSE == cache->sharedCache->everInherited) {
if (cache->sharedCache) {
sidCacheLock *pLock = cache->sidCacheLocks;
for (; locks_initialized > 0; --locks_initialized, ++pLock ) {
sslMutex_Destroy(&pLock->mutex);
/* If everInherited is true, this shared cache was (and may
** still be) in use by multiple processes. We do not wish to
** destroy the mutexes while they are still in use, but we do
** want to free mutex resources associated with this process.
*/
sslMutex_Destroy(&pLock->mutex,
cache->sharedCache->everInherited);
}
}
if (cache->shared) {

Some files were not shown because too many files have changed in this diff Show More