summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelsonb%netscape.com <devnull@localhost>2005-04-06 21:35:45 +0000
committernelsonb%netscape.com <devnull@localhost>2005-04-06 21:35:45 +0000
commit705baae0e4c5ab4186394bffcd910db0dfac8807 (patch)
tree455f2e5eef62e04761981731f71714252c9cc239
parentbacf6dd62bff2253687c3a993cbce138cb39a7d1 (diff)
downloadnss-hg-705baae0e4c5ab4186394bffcd910db0dfac8807.tar.gz
Back out the preceeding fortezza removal patch, which was accidentally
applied to the trunk, not to the intended branch.
-rw-r--r--security/nss/cmd/SSLsample/server.c3
-rw-r--r--security/nss/cmd/SSLsample/sslsample.c6
-rw-r--r--security/nss/cmd/manifest.mn3
-rw-r--r--security/nss/cmd/modutil/modutil.c5
-rw-r--r--security/nss/cmd/platlibs.mk2
-rw-r--r--security/nss/cmd/selfserv/selfserv.c11
-rw-r--r--security/nss/cmd/sslstrength/sslstrength.c7
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c8
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c11
-rw-r--r--security/nss/cmd/vfyserv/vfyserv.c2
-rw-r--r--security/nss/cmd/vfyserv/vfyutil.c6
-rw-r--r--security/nss/lib/manifest.mn4
-rw-r--r--security/nss/lib/ssl/nsskea.c6
-rw-r--r--security/nss/lib/ssl/preenc.h94
-rw-r--r--security/nss/lib/ssl/prelib.c197
-rw-r--r--security/nss/lib/ssl/ssl.h2
-rw-r--r--security/nss/lib/ssl/ssl3con.c1005
-rw-r--r--security/nss/lib/ssl/ssl3prot.h17
-rw-r--r--security/nss/lib/ssl/sslauth.c3
-rw-r--r--security/nss/lib/ssl/sslcon.c2
-rw-r--r--security/nss/lib/ssl/sslenum.c5
-rw-r--r--security/nss/lib/ssl/sslimpl.h16
-rw-r--r--security/nss/lib/ssl/sslinfo.c5
-rw-r--r--security/nss/lib/ssl/sslproto.h6
-rw-r--r--security/nss/lib/ssl/sslsecur.c7
-rw-r--r--security/nss/lib/ssl/sslsnce.c6
-rw-r--r--security/nss/lib/ssl/sslsock.c3
-rw-r--r--security/nss/lib/ssl/sslt.h6
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsd/prototype2
29 files changed, 1349 insertions, 101 deletions
diff --git a/security/nss/cmd/SSLsample/server.c b/security/nss/cmd/SSLsample/server.c
index 5965d4723..ced32d287 100644
--- a/security/nss/cmd/SSLsample/server.c
+++ b/security/nss/cmd/SSLsample/server.c
@@ -102,11 +102,14 @@ Usage(const char *progName)
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
"\n"
+"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
+"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
"f SSL3 RSA EXPORT WITH RC4 40 MD5\n"
"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
+"h SSL3 FORTEZZA DMS WITH NULL SHA\n"
"i SSL3 RSA WITH NULL MD5\n"
"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
"k SSL3 RSA FIPS WITH DES CBC SHA\n"
diff --git a/security/nss/cmd/SSLsample/sslsample.c b/security/nss/cmd/SSLsample/sslsample.c
index 422d453de..85f5d523b 100644
--- a/security/nss/cmd/SSLsample/sslsample.c
+++ b/security/nss/cmd/SSLsample/sslsample.c
@@ -50,14 +50,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA a */
- -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn
index 7066fa03e..de58f84c1 100644
--- a/security/nss/cmd/manifest.mn
+++ b/security/nss/cmd/manifest.mn
@@ -72,6 +72,7 @@ DIRS = lib \
SSLsample \
ssltap \
strsclnt \
+ swfort \
symkeyutil \
tstclnt \
vfychain \
@@ -80,7 +81,6 @@ DIRS = lib \
$(NULL)
TEMPORARILY_DONT_BUILD = \
- sha1test \
$(NULL)
# rsaperf \
@@ -92,6 +92,5 @@ TEMPORARILY_DONT_BUILD = \
# to build (requires allxpstr.h)
#
DONT_BULD = jar \
- swfort \
perror \
$(NULL)
diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c
index d277fea05..77c91a31e 100644
--- a/security/nss/cmd/modutil/modutil.c
+++ b/security/nss/cmd/modutil/modutil.c
@@ -749,10 +749,11 @@ usage()
"---------------------------------------------------------------------------\n"
"\n"
"Mechanism lists are colon-separated. The following mechanisms are recognized:\n"
-"RSA, DSA, RC2, RC4, RC5, DES, DH, SHA1, MD5, MD2, SSL, TLS, RANDOM, FRIENDLY\n"
+"RSA, DSA, RC2, RC4, RC5, DES, DH, FORTEZZA, SHA1, MD5, MD2, SSL, TLS, RANDOM,\n"
+" FRIENDLY\n"
"\n"
"Cipher lists are colon-separated. The following ciphers are recognized:\n"
-"\n"
+"FORTEZZA\n"
"\nQuestions or bug reports should be sent to modutil-support@netscape.com.\n"
);
diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk
index b586c787e..92269a250 100644
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -66,6 +66,7 @@ EXTRA_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX) \
$(CRYPTOLIB) \
+ $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
@@ -115,6 +116,7 @@ EXTRA_LIBS += \
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
+ $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \
$(CRYPTOLIB) \
$(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) \
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index c936e71c8..d5469ebc1 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -133,14 +133,14 @@ const int ssl2CipherSuites[] = {
};
const int ssl3CipherSuites[] = {
- -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
- -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
@@ -253,11 +253,14 @@ Usage(const char *progName)
"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
#endif /* NSS_ENABLE_ECC */
"\n"
+"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
+"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
"f SSL3 RSA EXPORT WITH RC4 40 MD5\n"
"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
+"h SSL3 FORTEZZA DMS WITH NULL SHA\n"
"i SSL3 RSA WITH NULL MD5\n"
"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
"k SSL3 RSA FIPS WITH DES CBC SHA\n"
@@ -1892,7 +1895,7 @@ main(int argc, char **argv)
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher > 0) {
+ if (cipher) {
SECStatus status;
status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
if (status != SECSuccess)
diff --git a/security/nss/cmd/sslstrength/sslstrength.c b/security/nss/cmd/sslstrength/sslstrength.c
index 34ac5c0df..ee4c0a692 100644
--- a/security/nss/cmd/sslstrength/sslstrength.c
+++ b/security/nss/cmd/sslstrength/sslstrength.c
@@ -91,11 +91,18 @@ struct CipherPolicy ciphers[] = {
{ 'd',SSL_EN_DES_64_CBC_WITH_MD5, "SSL_EN_DES_64_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'e',SSL_EN_RC4_128_EXPORT40_WITH_MD5, "SSL_EN_RC4_128_EXPORT40_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_ALLOWED },
{ 'f',SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_ALLOWED },
+#ifdef FORTEZZA
+ { 'g',SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA",1,SSL_ALLOWED,SSL_NOT_ALLOWED },
+ { 'h',SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, "SSL_FORTEZZA_DMS_WITH_RC4_128_SHA",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
+#endif
{ 'i',SSL_RSA_WITH_RC4_128_MD5, "SSL_RSA_WITH_RC4_128_MD5 (ssl3)",1, SSL_ALLOWED,SSL_RESTRICTED },
{ 'j',SSL_RSA_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_WITH_3DES_EDE_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_RESTRICTED },
{ 'k',SSL_RSA_WITH_DES_CBC_SHA, "SSL_RSA_WITH_DES_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'l',SSL_RSA_EXPORT_WITH_RC4_40_MD5, "SSL_RSA_EXPORT_WITH_RC4_40_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED },
{ 'm',SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED },
+#ifdef FORTEZZA
+ { 'n',SSL_FORTEZZA_DMS_WITH_NULL_SHA, "SSL_FORTEZZA_DMS_WITH_NULL_SHA",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
+#endif
{ 'o',SSL_RSA_WITH_NULL_MD5, "SSL_RSA_WITH_NULL_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED },
{ 'p',SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED },
{ 'q',SSL_RSA_FIPS_WITH_DES_CBC_SHA, "SSL_RSA_FIPS_WITH_DES_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index e6111b4ad..2e1a930dd 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -111,14 +111,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
- -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA * h */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
@@ -1053,7 +1053,7 @@ client_main(
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher > 0) {
+ if (cipher) {
SECStatus rv;
rv = SSL_CipherPrefSetDefault(cipher, PR_TRUE);
if (rv != SECSuccess) {
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index b0980a6d0..fb658604d 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -108,14 +108,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
- -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
@@ -257,11 +257,14 @@ static void Usage(const char *progName)
"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
#endif /* NSS_ENABLE_ECC */
"\n"
+"a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA\n"
+"b SSL3 FORTEZZA DMS WITH RC4 128 SHA\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
"f SSL3 RSA EXPORT WITH RC4 40 MD5\n"
"g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5\n"
+"h SSL3 FORTEZZA DMS WITH NULL SHA\n"
"i SSL3 RSA WITH NULL MD5\n"
"j SSL3 RSA FIPS WITH 3DES EDE CBC SHA\n"
"k SSL3 RSA FIPS WITH DES CBC SHA\n"
@@ -667,7 +670,7 @@ int main(int argc, char **argv)
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher > 0) {
+ if (cipher) {
SECStatus status;
status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
if (status != SECSuccess)
diff --git a/security/nss/cmd/vfyserv/vfyserv.c b/security/nss/cmd/vfyserv/vfyserv.c
index 4c31e4c70..f1fd23825 100644
--- a/security/nss/cmd/vfyserv/vfyserv.c
+++ b/security/nss/cmd/vfyserv/vfyserv.c
@@ -444,7 +444,7 @@ main(int argc, char **argv)
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
- if (cipher > 0) {
+ if (cipher) {
SSL_CipherPrefSetDefault(cipher, PR_TRUE);
}
}
diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c
index 4741a22ad..b1d282f64 100644
--- a/security/nss/cmd/vfyserv/vfyutil.c
+++ b/security/nss/cmd/vfyserv/vfyutil.c
@@ -53,14 +53,14 @@ int ssl2CipherSuites[] = {
};
int ssl3CipherSuites[] = {
- -1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
- -1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
SSL_RSA_WITH_RC4_128_MD5, /* c */
SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
SSL_RSA_WITH_DES_CBC_SHA, /* e */
SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
- -1, /* SSL_FORTEZZA_DMS_WITH_NULL_SHA, * h */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
SSL_RSA_WITH_NULL_MD5, /* i */
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
diff --git a/security/nss/lib/manifest.mn b/security/nss/lib/manifest.mn
index 268ff0496..108f188f0 100644
--- a/security/nss/lib/manifest.mn
+++ b/security/nss/lib/manifest.mn
@@ -47,6 +47,7 @@ DEPTH = ../..
# smime
# ckfw (builtins module)
# crmf jar (not dll's)
+# fortcrypt
DIRS = util freebl softoken \
base asn1 dev pki pki1 \
certdb certhigh pk11wrap cryptohi nss \
@@ -54,10 +55,9 @@ DIRS = util freebl softoken \
pkcs12 pkcs7 smime \
crmf jar \
ckfw \
+ fortcrypt \
$(NULL)
-# fortcrypt is no longer built
-
# NSS 4.0 build - pure stan libraries
ifdef PURE_STAN_BUILD
DIRS = base asn1 dev pki pki1
diff --git a/security/nss/lib/ssl/nsskea.c b/security/nss/lib/ssl/nsskea.c
index beafc506e..b61ac71e4 100644
--- a/security/nss/lib/ssl/nsskea.c
+++ b/security/nss/lib/ssl/nsskea.c
@@ -58,6 +58,12 @@ NSS_FindCertKEAType(CERTCertificate * cert)
case SEC_OID_PKCS1_RSA_ENCRYPTION:
keaType = kt_rsa;
break;
+ case SEC_OID_MISSI_KEA_DSS_OLD:
+ case SEC_OID_MISSI_KEA_DSS:
+ case SEC_OID_MISSI_DSS_OLD:
+ case SEC_OID_MISSI_DSS:
+ keaType = kt_fortezza;
+ break;
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
keaType = kt_dh;
break;
diff --git a/security/nss/lib/ssl/preenc.h b/security/nss/lib/ssl/preenc.h
index f7c9093cb..9b6d3104a 100644
--- a/security/nss/lib/ssl/preenc.h
+++ b/security/nss/lib/ssl/preenc.h
@@ -1,7 +1,8 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
/*
- * Fortezza support is removed.
+ * Functions and types used by https servers to send (download) pre-encrypted
+ * files over SSL connections that use Fortezza ciphersuites.
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@@ -40,11 +41,6 @@
* ***** END LICENSE BLOCK ***** */
/* $Id$ */
-/* Fortezza support is removed.
- * This file remains so that old programs will continue to compile,
- * But this functionality is no longer supported or implemented.
- */
-
#include "seccomon.h"
#include "prio.h"
@@ -52,44 +48,53 @@ typedef struct PEHeaderStr PEHeader;
#define PE_MIME_TYPE "application/pre-encrypted"
+
+/*
+ * unencrypted header. The 'top' half of this header is generic. The union
+ * is type specific, and may include bulk cipher type information
+ * (Fortezza supports only Fortezza Bulk encryption). Only fortezza
+ * pre-encrypted is defined.
+ */
typedef struct PEFortezzaHeaderStr PEFortezzaHeader;
typedef struct PEFortezzaGeneratedHeaderStr PEFortezzaGeneratedHeader;
typedef struct PEFixedKeyHeaderStr PEFixedKeyHeader;
typedef struct PERSAKeyHeaderStr PERSAKeyHeader;
struct PEFortezzaHeaderStr {
- unsigned char key[12];
- unsigned char iv[24];
- unsigned char hash[20];
- unsigned char serial[8];
+ unsigned char key[12]; /* Ks wrapped MEK */
+ unsigned char iv[24]; /* iv for this MEK */
+ unsigned char hash[20]; /* SHA hash of file */
+ unsigned char serial[8]; /* serial number of the card that owns
+ * Ks */
};
struct PEFortezzaGeneratedHeaderStr {
- unsigned char key[12];
- unsigned char iv[24];
- unsigned char hash[20];
- unsigned char Ra[128];
- unsigned char Y[128];
+ unsigned char key[12]; /* TEK wrapped MEK */
+ unsigned char iv[24]; /* iv for this MEK */
+ unsigned char hash[20]; /* SHA hash of file */
+ unsigned char Ra[128]; /* RA to generate TEK */
+ unsigned char Y[128]; /* Y to generate TEK */
};
struct PEFixedKeyHeaderStr {
- unsigned char pkcs11Mech[4];
- unsigned char labelLen[2];
- unsigned char keyIDLen[2];
- unsigned char ivLen[2];
- unsigned char keyLen[2];
- unsigned char data[1];
+ unsigned char pkcs11Mech[4]; /* Symetric key operation */
+ unsigned char labelLen[2]; /* length of the token label */
+ unsigned char keyIDLen[2]; /* length of the token Key ID */
+ unsigned char ivLen[2]; /* length of IV */
+ unsigned char keyLen[2]; /* length of key (DES3_ECB encrypted) */
+ unsigned char data[1]; /* start of data */
};
struct PERSAKeyHeaderStr {
- unsigned char pkcs11Mech[4];
- unsigned char issuerLen[2];
- unsigned char serialLen[2];
- unsigned char ivLen[2];
- unsigned char keyLen[2];
- unsigned char data[1];
+ unsigned char pkcs11Mech[4]; /* Symetric key operation */
+ unsigned char issuerLen[2]; /* length of cert issuer */
+ unsigned char serialLen[2]; /* length of the cert serial */
+ unsigned char ivLen[2]; /* length of IV */
+ unsigned char keyLen[2]; /* length of key (RSA encrypted) */
+ unsigned char data[1]; /* start of data */
};
+/* macros to get at the variable length data fields */
#define PEFIXED_Label(header) (header->data)
#define PEFIXED_KeyID(header) (&header->data[GetInt2(header->labelLen)])
#define PEFIXED_IV(header) (&header->data[GetInt2(header->labelLen)\
@@ -103,10 +108,10 @@ struct PERSAKeyHeaderStr {
#define PERSA_Key(header) (&header->data[GetInt2(header->issuerLen)\
+GetInt2(header->serialLen)+GetInt2(header->keyLen)])
struct PEHeaderStr {
- unsigned char magic [2];
- unsigned char len [2];
- unsigned char type [2];
- unsigned char version[2];
+ unsigned char magic [2]; /* always 0xC0DE */
+ unsigned char len [2]; /* length of PEHeader */
+ unsigned char type [2]; /* FORTEZZA, DIFFIE-HELMAN, RSA */
+ unsigned char version[2]; /* version number: 1.0 */
union {
PEFortezzaHeader fortezza;
PEFortezzaGeneratedHeader g_fortezza;
@@ -119,9 +124,12 @@ struct PEHeaderStr {
#define PE_INTRO_LEN 4
#define PE_BASE_HEADER_LEN 8
-#define PRE_BLOCK_SIZE 8
+#define PRE_BLOCK_SIZE 8 /* for decryption blocks */
+/*
+ * Platform neutral encode/decode macros.
+ */
#define GetInt2(c) ((c[0] << 8) | c[1])
#define GetInt4(c) (((unsigned long)c[0] << 24)|((unsigned long)c[1] << 16)\
|((unsigned long)c[2] << 8)| ((unsigned long)c[3]))
@@ -129,18 +137,28 @@ struct PEHeaderStr {
#define PutInt4(c,i) ((c[0]=((i) >> 24) & 0xff),(c[1]=((i) >> 16) & 0xff),\
(c[2] = ((i) >> 8) & 0xff), (c[3] = (i) & 0xff))
+/*
+ * magic numbers.
+ */
#define PRE_MAGIC 0xc0de
#define PRE_VERSION 0x1010
-#define PRE_FORTEZZA_FILE 0x00ff
-#define PRE_FORTEZZA_STREAM 0x00f5
-#define PRE_FORTEZZA_GEN_STREAM 0x00f6
-#define PRE_FIXED_FILE 0x000f
-#define PRE_RSA_FILE 0x001f
-#define PRE_FIXED_STREAM 0x0005
+#define PRE_FORTEZZA_FILE 0x00ff /* pre-encrypted file on disk */
+#define PRE_FORTEZZA_STREAM 0x00f5 /* pre-encrypted file in stream */
+#define PRE_FORTEZZA_GEN_STREAM 0x00f6 /* Generated pre-encrypted file */
+#define PRE_FIXED_FILE 0x000f /* fixed key on disk */
+#define PRE_RSA_FILE 0x001f /* RSA in file */
+#define PRE_FIXED_STREAM 0x0005 /* fixed key in stream */
+
+/*
+ * internal implementation info
+ */
+
+/* convert an existing stream header to a version with local parameters */
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *,
int *headerSize);
+/* convert an existing file header to one suitable for streaming out */
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *,
int *headerSize);
diff --git a/security/nss/lib/ssl/prelib.c b/security/nss/lib/ssl/prelib.c
index c63483924..b24399b98 100644
--- a/security/nss/lib/ssl/prelib.c
+++ b/security/nss/lib/ssl/prelib.c
@@ -50,18 +50,205 @@
#include "preenc.h"
#include "pk11func.h"
+static unsigned char fromHex(char x) {
+ if ((x >= '0') && (x <= '9')) return x-'0';
+ if ((x >= 'a') && (x <= 'f')) return x-'a'+10;
+ return x-'A'+10;
+}
+
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
- int *headerSize)
+ int *headerSize)
{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
+ PK11SymKey *key, *tek, *Ks;
+ sslSocket *ss;
+ PK11SlotInfo *slot;
+ CK_TOKEN_INFO info;
+ int oldHeaderSize;
+ PEHeader *header;
+ SECStatus rv;
+ SECItem item;
+ int i;
+
+ if (fd == NULL) {
+ /* XXX set an error */
+ return NULL;
+ }
+
+ ss = ssl_FindSocket(fd);
+ if (ss == NULL) {
+ return NULL;
+ }
+
+ PORT_Assert(ss->ssl3 != NULL);
+ if (ss->ssl3 == NULL) {
+ return NULL;
+ }
+
+ if (GetInt2(inHeader->magic) != PRE_MAGIC) {
+ return NULL;
+ }
+
+ oldHeaderSize = GetInt2(inHeader->len);
+ header = (PEHeader *) PORT_ZAlloc(oldHeaderSize);
+ if (header == NULL) {
+ return NULL;
+ }
+
+ switch (GetInt2(inHeader->type)) {
+ case PRE_FORTEZZA_FILE:
+ case PRE_FORTEZZA_GEN_STREAM:
+ case PRE_FIXED_FILE:
+ case PRE_RSA_FILE:
+ default:
+ *headerSize = oldHeaderSize;
+ PORT_Memcpy(header,inHeader,oldHeaderSize);
+ return header;
+
+ case PRE_FORTEZZA_STREAM:
+ *headerSize = PE_BASE_HEADER_LEN + sizeof(PEFortezzaHeader);
+ PutInt2(header->magic,PRE_MAGIC);
+ PutInt2(header->len,*headerSize);
+ PutInt2(header->type, PRE_FORTEZZA_FILE);
+ PORT_Memcpy(header->version,inHeader->version,sizeof(header->version));
+ PORT_Memcpy(header->u.fortezza.hash,inHeader->u.fortezza.hash,
+ sizeof(header->u.fortezza.hash));
+ PORT_Memcpy(header->u.fortezza.iv,inHeader->u.fortezza.iv,
+ sizeof(header->u.fortezza.iv));
+
+ /* get the kea context from the session */
+ tek = ss->ssl3->fortezza.tek;
+ if (tek == NULL) {
+ PORT_Free(header);
+ return NULL;
+ }
+
+
+ /* get the slot and the serial number */
+ slot = PK11_GetSlotFromKey(tek);
+ if (slot == NULL) {
+ PORT_Free(header);
+ return NULL;
+ }
+ rv = PK11_GetTokenInfo(slot,&info);
+ if (rv != SECSuccess) {
+ PORT_Free(header);
+ PK11_FreeSlot(slot);
+ return NULL;
+ }
+
+ /* Look up the Token Fixed Key */
+ Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
+ PK11_FreeSlot(slot);
+ if (Ks == NULL) {
+ PORT_Free(header);
+ return NULL;
+ }
+
+ /* unwrap the key with the TEK */
+ item.data = inHeader->u.fortezza.key;
+ item.len = sizeof(inHeader->u.fortezza.key);
+ key = PK11_UnwrapSymKey(tek,CKM_SKIPJACK_WRAP,
+ NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
+ if (key == NULL) {
+ PORT_Free(header);
+ PK11_FreeSymKey(Ks);
+ return NULL;
+ }
+
+ /* rewrap with the local Ks */
+ item.data = header->u.fortezza.key;
+ item.len = sizeof(header->u.fortezza.key);
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks, key, &item);
+ PK11_FreeSymKey(Ks);
+ PK11_FreeSymKey(key);
+ if (rv != SECSuccess) {
+ PORT_Free(header);
+ return NULL;
+ }
+
+ /* copy our local serial number into header */
+ for (i=0; i < sizeof(header->u.fortezza.serial); i++) {
+ header->u.fortezza.serial[i] =
+ (fromHex(info.serialNumber[i*2]) << 4) |
+ fromHex(info.serialNumber[i*2 + 1]);
+ }
+ break;
+ case PRE_FIXED_STREAM:
+ /* not implemented yet */
+ PORT_Free(header);
+ return NULL;
+ }
+
+ return(header);
}
+/*
+ * this one needs to allocate space and work for RSA & FIXED key files as well
+ */
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
int *headerSize)
{
- PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
- return NULL;
+ PK11SymKey *key, *tek, *Ks;
+ sslSocket *ss;
+ PK11SlotInfo *slot;
+ SECStatus rv;
+ SECItem item;
+
+ *headerSize = 0; /* hack */
+
+ if (fd == NULL) {
+ /* XXX set an error */
+ return NULL;
+ }
+
+ ss = ssl_FindSocket(fd);
+ if (ss == NULL) {
+ return NULL;
+ }
+
+ PORT_Assert(ss->ssl3 != NULL);
+ if (ss->ssl3 == NULL) {
+ return NULL;
+ }
+
+ /* get the kea context from the session */
+ tek = ss->ssl3->fortezza.tek;
+ if (tek == NULL) {
+ return NULL;
+ }
+
+ slot = PK11_GetSlotFromKey(tek);
+ if (slot == NULL) return NULL;
+ Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, PK11_GetWindow(tek));
+ PK11_FreeSlot(slot);
+ if (Ks == NULL) return NULL;
+
+
+ /* unwrap with the local Ks */
+ item.data = header->u.fortezza.key;
+ item.len = sizeof(header->u.fortezza.key);
+ /* rewrap the key with the TEK */
+ key = PK11_UnwrapSymKey(Ks,CKM_SKIPJACK_WRAP,
+ NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
+ if (key == NULL) {
+ PK11_FreeSymKey(Ks);
+ return NULL;
+ }
+
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, key, &item);
+ PK11_FreeSymKey(Ks);
+ PK11_FreeSymKey(key);
+ if (rv != SECSuccess) {
+ return NULL;
+ }
+
+ /* copy over our local serial number */
+ PORT_Memset(header->u.fortezza.serial,0,sizeof(header->u.fortezza.serial));
+
+ /* change type to stream */
+ PutInt2(header->type, PRE_FORTEZZA_STREAM);
+
+ return(header);
}
diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h
index e22c70504..f6ab20af7 100644
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -190,7 +190,7 @@ SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
#define SSL_SECURITY_STATUS_OFF 0
#define SSL_SECURITY_STATUS_ON_HIGH 1
#define SSL_SECURITY_STATUS_ON_LOW 2
-#define SSL_SECURITY_STATUS_FORTEZZA 3 /* NO LONGER SUPPORTED */
+#define SSL_SECURITY_STATUS_FORTEZZA 3
/*
** Return the certificate for our SSL peer. If the client calls this
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 669060bc2..1e7f7411a 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -109,6 +109,7 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
#endif /* NSS_ENABLE_ECC */
{ TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
+ { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -135,6 +136,7 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
{ SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE},
@@ -150,6 +152,7 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
{ SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
{ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
+ { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE},
#ifdef NSS_ENABLE_ECC
{ TLS_ECDH_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
{ TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE},
@@ -174,6 +177,9 @@ static const /*SSL3ClientCertificateType */ uint8 certificate_types [] = {
#endif /* NSS_ENABLE_ECC */
};
+static const /*SSL3ClientCertificateType */ uint8 fortezza_certificate_types [] = {
+ ct_Fortezza,
+};
/*
* make sure there is room in the write buffer for padding and
@@ -211,13 +217,13 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = {
{cipher_3des, calg_3des, 24, 24, type_block, 8, 8, kg_strong},
{cipher_des40, calg_des, 8, 5, type_block, 8, 8, kg_export},
{cipher_idea, calg_idea, 16, 16, type_block, 8, 8, kg_strong},
+ {cipher_fortezza, calg_fortezza, 10, 10, type_block, 24, 8, kg_null},
{cipher_aes_128, calg_aes, 16, 16, type_block, 16,16, kg_strong},
{cipher_aes_256, calg_aes, 32, 32, type_block, 16,16, kg_strong},
{cipher_missing, calg_null, 0, 0, type_stream, 0, 0, kg_null},
};
-static const ssl3KEADef kea_defs[] =
-{ /* indexed by SSL3KeyExchangeAlgorithm */
+static const ssl3KEADef kea_defs[] = { /* indexed by SSL3KeyExchangeAlgorithm */
/* kea exchKeyType signKeyType is_limited limit tls_keygen */
{kea_null, kt_null, sign_null, PR_FALSE, 0, PR_FALSE},
{kea_rsa, kt_rsa, sign_rsa, PR_FALSE, 0, PR_FALSE},
@@ -233,6 +239,7 @@ static const ssl3KEADef kea_defs[] =
{kea_dhe_rsa_export, kt_dh, sign_rsa, PR_TRUE, 512, PR_FALSE},
{kea_dh_anon, kt_dh, sign_null, PR_FALSE, 0, PR_FALSE},
{kea_dh_anon_export, kt_dh, sign_null, PR_TRUE, 512, PR_FALSE},
+ {kea_fortezza, kt_fortezza, sign_dsa, PR_FALSE, 0, PR_FALSE},
{kea_rsa_fips, kt_rsa, sign_rsa, PR_FALSE, 0, PR_TRUE },
#ifdef NSS_ENABLE_ECC
{kea_ecdh_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE},
@@ -243,8 +250,7 @@ static const ssl3KEADef kea_defs[] =
};
/* must use ssl_LookupCipherSuiteDef to access */
-static const ssl3CipherSuiteDef cipher_suite_defs[] =
-{
+static const ssl3CipherSuiteDef cipher_suite_defs[] = {
/* cipher_suite bulk_cipher_alg mac_alg key_exchange_alg */
{SSL_NULL_WITH_NULL_NULL, cipher_null, mac_null, kea_null},
@@ -292,6 +298,10 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] =
{SSL_DH_ANON_3DES_CBC_SHA, cipher_3des, mac_sha, kea_dh_anon},
#endif
+ {SSL_FORTEZZA_DMS_WITH_NULL_SHA, cipher_null, mac_sha, kea_fortezza},
+ {SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
+ cipher_fortezza, mac_sha, kea_fortezza},
+ {SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_fortezza},
/* New TLS cipher suites */
{TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa},
@@ -352,16 +362,14 @@ typedef struct SSLCipher2MechStr {
CK_MECHANISM_TYPE cmech;
} SSLCipher2Mech;
-/* indexed by type SSLCipherAlgorithm */
static const SSLCipher2Mech alg2Mech[] = {
- /* calg, cmech */
{ calg_null , (CK_MECHANISM_TYPE)0x80000000L },
{ calg_rc4 , CKM_RC4 },
{ calg_rc2 , CKM_RC2_CBC },
{ calg_des , CKM_DES_CBC },
{ calg_3des , CKM_DES3_CBC },
{ calg_idea , CKM_IDEA_CBC },
- { calg_fortezza , CKM_SKIPJACK_CBC64 },
+ { calg_fortezza , CKM_SKIPJACK_CBC64 },
{ calg_aes , CKM_AES_CBC },
/* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */
};
@@ -393,6 +401,7 @@ const char * const ssl3_cipherName[] = {
"3DES-EDE-CBC",
"DES-CBC-40",
"IDEA-CBC",
+ "FORTEZZA",
"AES-128",
"AES-256",
"missing"
@@ -829,6 +838,7 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf,
hashItem.len = sizeof(SSL3Hashes);
break;
case dsaKey:
+ case fortezzaKey:
doDerEncode = isTLS;
hashItem.data = hash->sha;
hashItem.len = sizeof(hash->sha);
@@ -901,6 +911,7 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert,
hashItem.len = sizeof(SSL3Hashes);
break;
case dsaKey:
+ case fortezzaKey:
hashItem.data = hash->sha;
hashItem.len = sizeof(hash->sha);
if (isTLS) {
@@ -1201,6 +1212,30 @@ done:
}
#endif /* NSS_ENABLE_ECC */
+/* Caller must set hiLevel error code. */
+static SECStatus
+ssl3_ComputeFortezzaPublicKeyHash(SECItem publicValue, unsigned char * hash)
+{
+ PK11Context *sha = NULL;
+ SECStatus rv = SECFailure;
+ unsigned int outLen;
+
+ sha = PK11_CreateDigestContext(SEC_OID_SHA1);
+ if (sha == NULL) {
+ return rv; /* Caller must set hiLevel error code. */
+ }
+
+ rv = PK11_DigestBegin(sha);
+ rv |= PK11_DigestOp(sha, (unsigned char *)publicValue.data, publicValue.len);
+ rv |= PK11_DigestFinal(sha, hash, &outLen, SHA1_LENGTH);
+ PORT_Assert(rv != SECSuccess || outLen == SHA1_LENGTH);
+ if (rv != SECSuccess)
+ rv = SECFailure;
+ PK11_DestroyContext(sha, PR_TRUE);
+
+ return rv;
+}
+
static void
ssl3_BumpSequenceNumber(SSL3SequenceNumber *num)
@@ -1678,9 +1713,10 @@ ssl3_SendRecord( sslSocket * ss,
}
}
- /* This variable records the actual size of the buffer allocated above.
- * Some algorithms may expand the number of bytes needed to send data.
- * If we only supply the output buffer with the same number
+ /* This variable records
+ * the actual size of the buffer we allocated above. Some
+ * algorithms (FORTEZZA) will expand the number of bytes it needs to
+ * send data. If we only supply the output buffer with the same number
* of bytes as the input buffer, we will fail.
*/
bufSize = contentLen + SSL3_BUFFER_FUDGE;
@@ -1958,6 +1994,7 @@ ssl3_HandleNoCertificate(sslSocket *ss)
** ssl3_HandleClientHello <-
** ssl3_HandleV2ClientHello <-
** ssl3_HandleCertificateVerify <-
+** ssl3_HandleFortezzaClientKeyExchange <-
** ssl3_HandleClientKeyExchange <-
** ssl3_HandleCertificate <-
** ssl3_HandleFinished <-
@@ -2272,7 +2309,9 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
void * pwArg = ss->pkcs11PinArg;
PRBool isTLS = (PRBool)(kea_def->tls_keygen ||
(pwSpec->version > SSL_LIBRARY_VERSION_3_0));
- PRBool skipKeysAndIVs = (PRBool)(cipher_def->calg == calg_null);
+ PRBool skipKeysAndIVs = (PRBool)
+ ((cipher_def->calg == calg_fortezza) ||
+ (cipher_def->calg == calg_null));
/*
* Whenever isDH is true, we need to use CKM_TLS_MASTER_KEY_DERIVE_DH
* which, unlike CKM_TLS_MASTER_KEY_DERIVE, converts arbitrary size
@@ -2960,7 +2999,8 @@ ssl3_SendClientHello(sslSocket *ss)
* make sure the token that holds the master secret still exists ...
* If we previously did client-auth, make sure that the token that holds
* the private key still exists, is logged in, hasn't been removed, etc.
- */
+ * Also for fortezza, make sure that the card that holds the session keys
+ * exist as well... */
if (sid) {
PK11SlotInfo *slot;
PRBool sidOK = PR_TRUE;
@@ -2982,6 +3022,12 @@ ssl3_SendClientHello(sslSocket *ss)
PK11_FreeSlot(slot);
slot = NULL;
}
+ /* do sid-has-FORTEZZA-slot check */
+ if (sid->u.ssl3.hasFortezza) {
+ /* do has fortezza check */
+ if (!PK11_VerifyKeyOK(sid->u.ssl3.tek))
+ sidOK = PR_FALSE;
+ }
/* If we previously did client-auth, make sure that the token that
** holds the private key still exists, is logged in, hasn't been
@@ -3233,6 +3279,35 @@ ssl_UnwrapSymWrappingKey(
PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
switch (exchKeyType) {
+ PK11SymKey * Ks;
+ PK11SlotInfo * slot;
+ SECItem param;
+
+ case kt_fortezza:
+ /* get the slot that the fortezza server private key is in. */
+ slot = PK11_GetSlotFromPrivateKey(svrPrivKey);
+ if (slot == NULL) {
+ SET_ERROR_CODE
+ goto loser;
+ }
+
+ /* Look up the Token Fixed Key */
+ Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_CBC64, NULL, pwArg);
+ PK11_FreeSlot(slot);
+ if (Ks == NULL) {
+ SET_ERROR_CODE
+ goto loser;
+ }
+
+ /* unwrap client write key with the local Ks and IV */
+ param.type = siBuffer;
+ param.data = pWswk->wrapIV;
+ param.len = pWswk->wrapIVLen;
+ unwrappedWrappingKey =
+ PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_CBC64, &param, &wrappedKey,
+ masterWrapMech, CKA_UNWRAP, 0);
+ PK11_FreeSymKey(Ks);
+ break;
case kt_rsa:
unwrappedWrappingKey =
@@ -3391,6 +3466,36 @@ getWrappingKey( sslSocket * ss,
/* wrap symmetric wrapping key in server's public key. */
switch (exchKeyType) {
+ PK11SymKey * Ks;
+ PK11SlotInfo * fSlot;
+ SECItem param;
+
+ case kt_fortezza:
+ /* get the slot that the fortezza server private key is in. */
+ fSlot = PK11_GetSlotFromPrivateKey(svrPrivKey);
+ if (fSlot == NULL) {
+ SET_ERROR_CODE
+ goto loser;
+ }
+
+ /* Look up the Token Fixed Key */
+ Ks = PK11_FindFixedKey(fSlot, CKM_SKIPJACK_CBC64, NULL, pwArg);
+ PK11_FreeSlot(fSlot);
+ if (Ks == NULL) {
+ SET_ERROR_CODE
+ goto loser;
+ }
+
+ /* wrap symmetricWrapping key with the local Ks */
+ param.type = siBuffer;
+ param.data = wswk.wrapIV;
+ param.len = sizeof wswk.wrapIV;
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &param, Ks,
+ unwrappedWrappingKey, &wrappedKey);
+ wswk.wrapIVLen = param.len;
+ PK11_FreeSymKey(Ks);
+ asymWrapMechanism = CKM_SKIPJACK_CBC64;
+ break;
case kt_rsa:
asymWrapMechanism = CKM_RSA_PKCS;
@@ -3449,6 +3554,20 @@ done:
}
+static SECStatus
+ssl3_FortezzaAppendHandshake(sslSocket *ss, unsigned char * data, int len)
+{
+ SSL3FortezzaKeys *fortezza_CKE = NULL;
+ SECStatus rv = SECFailure;
+
+ rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange,
+ (sizeof(*fortezza_CKE)-sizeof(fortezza_CKE->y_c)) + 1 + len);
+ if (rv == SECSuccess) {
+ rv = ssl3_AppendHandshakeVariable(ss, data, len, 1);
+ }
+ return rv; /* err set by ssl3_AppendHandshake* */
+}
+
/* Called from ssl3_SendClientKeyExchange(). */
static SECStatus
sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
@@ -3695,8 +3814,433 @@ loser:
}
#endif /* NSS_ENABLE_ECC */
+/* fortezza client-auth portion of ClientKeyExchange message
+ * This function appends the KEA public key from the client's V3 cert
+ * (empty for a V1 cert) to the outgoing ClientKeyExchange message.
+ * For a V3 cert, it also computes the Fortezza public key hash of that key
+ * and signs that hash with the client's signing private key.
+ * It also finds and returns the client's KEA private key.
+ *
+ * Called from sendFortezzaClientKeyExchange <- ssl3_SendClientKeyExchange()
+ */
+static SECKEYPrivateKey *
+sendFortezzaCKXClientAuth(sslSocket *ss, SSL3FortezzaKeys * fortezza_CKE)
+{
+ SECKEYPublicKey * pubKey = NULL;
+ SECKEYPrivateKey * privKeaKey = NULL;
+ CERTCertificate * peerCert = ss->sec.peerCert;
+ void * pwArg = ss->pkcs11PinArg;
+ SECStatus rv = SECFailure;
+ SECItem sigItem;
+ SECItem hashItem;
+
+ /* extract our own local public key. */
+ pubKey = CERT_ExtractPublicKey(ss->ssl3->clientCertificate);
+ if (!pubKey) {
+ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ goto loser;
+ }
+
+ if (pubKey->keyType == fortezzaKey) {
+ /* fortezza clientauth with fortezza V1 certificate */
+ rv = ssl3_FortezzaAppendHandshake(ss, NULL, 0);
+ if (rv != SECSuccess) {
+ goto loser; /* err was set by AppendHandshake. */
+ }
+ privKeaKey = PK11_FindKeyByAnyCert(ss->ssl3->clientCertificate, pwArg);
+ if (!privKeaKey) {
+ ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
+ }
+
+ } else {
+ /* fortezza clientauth w/ V3 certificate or non fortezza cert*/
+ CERTCertificate * ccert = NULL;
+ SECKEYPublicKey * foundPubKey = NULL;
+ unsigned char hash[SHA1_LENGTH];
+
+ ccert = PK11_FindBestKEAMatch(peerCert, pwArg);
+ if (ccert == NULL) {
+ PORT_SetError(SSL_ERROR_FORTEZZA_PQG);
+ goto v3_loser;
+ }
+
+ foundPubKey = CERT_ExtractPublicKey(ccert);
+ if (foundPubKey == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ goto v3_loser;
+ }
+
+ if (foundPubKey->keyType == keaKey) {
+ rv = ssl3_FortezzaAppendHandshake(ss,
+ foundPubKey->u.kea.publicValue.data,
+ foundPubKey->u.kea.publicValue.len);
+ if (rv != SECSuccess) {
+ goto v3_loser; /* err was set by AppendHandshake. */
+ }
+
+ rv = ssl3_ComputeFortezzaPublicKeyHash(
+ foundPubKey->u.kea.publicValue, hash);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto v3_loser;
+ }
+ } else {
+ rv = ssl3_FortezzaAppendHandshake(ss,
+ foundPubKey->u.fortezza.KEAKey.data,
+ foundPubKey->u.fortezza.KEAKey.len);
+ if (rv != SECSuccess) {
+ goto v3_loser; /* err was set by AppendHandshake. */
+ }
+
+ rv = ssl3_ComputeFortezzaPublicKeyHash(
+ foundPubKey->u.fortezza.KEAKey, hash);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto v3_loser;
+ }
+ }
+
+ hashItem.data = (unsigned char *) hash;
+ hashItem.len = SHA1_LENGTH;
+
+ sigItem.data = fortezza_CKE->y_signature;
+ sigItem.len = sizeof fortezza_CKE->y_signature;
+
+ rv = PK11_Sign(ss->ssl3->clientPrivateKey, &sigItem, &hashItem);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto v3_loser;
+ }
+
+ privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
+ if (!privKeaKey) {
+ ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
+ }
+
+v3_loser:
+ if (foundPubKey)
+ SECKEY_DestroyPublicKey(foundPubKey);
+ if (ccert)
+ CERT_DestroyCertificate(ccert);
+ } /* fortezza clientauth w/ V3 certificate or non fortezza cert*/
+
+loser:
+
+ if (pubKey)
+ SECKEY_DestroyPublicKey(pubKey);
+ return privKeaKey;
+} /* End of fortezza client-auth. */
+
+
+/* fortezza without client-auth */
+/* fortezza client-auth portion of ClientKeyExchange message
+ * This function appends the public KEA key from the client's cert
+ * to the outgoing ClientKeyExchange message.
+ * It also finds and returns the client's KEA private key.
+ *
+ * Called from sendFortezzaClientKeyExchange <- ssl3_SendClientKeyExchange()
+ */
+static SECKEYPrivateKey *
+sendFortezzaCKXNoClientAuth(sslSocket *ss)
+{
+ SECKEYPublicKey * foundPubKey = NULL;
+ SECKEYPrivateKey * privKeaKey = NULL;
+ CERTCertificate * ccert = NULL;
+ CERTCertificate * peerCert = ss->sec.peerCert;
+ void * pwArg = ss->pkcs11PinArg;
+ SECStatus rv = SECFailure;
+
+ ccert = PK11_FindBestKEAMatch(peerCert, pwArg);
+ if (ccert == NULL) {
+ PORT_SetError(SSL_ERROR_FORTEZZA_PQG);
+ goto loser;
+ }
+
+ foundPubKey = CERT_ExtractPublicKey(ccert);
+ if (foundPubKey == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ goto loser;
+ }
+
+ if (foundPubKey->keyType == fortezzaKey) {
+ /* fortezza V1 cert */
+ rv = ssl3_FortezzaAppendHandshake(ss,
+ foundPubKey->u.fortezza.KEAKey.data,
+ foundPubKey->u.fortezza.KEAKey.len);
+ if (rv != SECSuccess) {
+ goto loser; /* err was set by AppendHandshake. */
+ }
+ privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
+ if (!privKeaKey) {
+ ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
+ }
+ } else {
+ /* fortezza V3 cert */
+ rv = ssl3_FortezzaAppendHandshake(ss,
+ foundPubKey->u.kea.publicValue.data,
+ foundPubKey->u.kea.publicValue.len);
+ if (rv != SECSuccess) {
+ goto loser; /* err was set by AppendHandshake. */
+ }
+ privKeaKey = PK11_FindKeyByAnyCert(ccert, pwArg);
+ if (!privKeaKey) {
+ ssl_MapLowLevelError(SEC_ERROR_NO_KEY);
+ }
+ }
+
+loser:
+ if (foundPubKey)
+ SECKEY_DestroyPublicKey(foundPubKey);
+ if (ccert)
+ CERT_DestroyCertificate(ccert);
+ return privKeaKey;
+}
+
+/* Called from ssl3_SendClientKeyExchange(). */
+static SECStatus
+sendFortezzaClientKeyExchange(sslSocket * ss, SECKEYPublicKey * serverKey)
+{
+ ssl3CipherSpec * pwSpec = NULL;
+ sslSessionID * sid = ss->sec.ci.sid;
+ PK11SlotInfo * slot = NULL;
+ PK11SymKey * pms = NULL;
+ PK11SymKey * tek = NULL;
+ PK11SymKey * client_write_key = NULL;
+ PK11SymKey * server_write_key = NULL;
+ SECKEYPrivateKey * privKeaKey = NULL;
+ void * pwArg = ss->pkcs11PinArg;
+ SECStatus rv = SECFailure;
+ CK_VERSION version;
+ SECItem param;
+ SECItem raItem;
+ SECItem rbItem;
+ SECItem enc_pms;
+ SECItem item;
+ SSL3FortezzaKeys fortezza_CKE;
+ PRBool releaseSpecWriteLock = PR_FALSE;
+
+ PORT_Assert( ssl_HaveXmitBufLock(ss));
+ PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+
+ /* first get an appropriate slot for doing MACing.
+ * Note: This slot will NOT be a Fortezza slot because Fortezza
+ * cannot generate an SSL3 pre-master-secret.
+ */
+ slot = PK11_GetBestSlot(CKM_SSL3_PRE_MASTER_KEY_GEN, pwArg);
+ if (slot == NULL) {
+ PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND);
+ goto loser;
+ }
+
+ /* create a pre-Master secret */
+ version.major = MSB(ss->version);
+ version.minor = LSB(ss->version);
+
+ param.data = (unsigned char *)&version;
+ param.len = sizeof version;
+
+ pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN,
+ &param, 0, pwArg);
+ PK11_FreeSlot(slot);
+ slot = NULL;
+ if (pms == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ /* If we don't have a certificate, we need to read out your public key.
+ * This changes a bit when we need to deal with the PQG stuff
+ */
+ PORT_Memset(fortezza_CKE.y_signature, 0, sizeof fortezza_CKE.y_signature);
+
+ /* Send the KEA public key and get the KEA private key. */
+ if (ss->ssl3->clientCertificate != NULL) {
+ /* with client-auth */
+ privKeaKey = sendFortezzaCKXClientAuth(ss, &fortezza_CKE);
+ } else {
+ /* without client-auth */
+ privKeaKey = sendFortezzaCKXNoClientAuth(ss);
+ }
+ if (privKeaKey == NULL) {
+ rv = SECFailure;
+ goto loser; /* error was already set. */
+ }
+
+ /* Now we derive the TEK, and generate r_c the client's "random" public key.
+ * r_c is generated and filled in by the PubDerive call below.
+ */
+ raItem.data = fortezza_CKE.r_c;
+ raItem.len = sizeof fortezza_CKE.r_c;
+
+ /* R_s == server's "random" public key, sent in the Server Key Exchange */
+ rbItem.data = ss->ssl3->fortezza.R_s;
+ rbItem.len = sizeof ss->ssl3->fortezza.R_s;
+
+ tek = PK11_PubDerive(privKeaKey, serverKey, PR_TRUE, /* generate r_c */
+ &raItem, &rbItem, CKM_KEA_KEY_DERIVE,
+ CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwArg);
+ SECKEY_DestroyPrivateKey(privKeaKey);
+ privKeaKey = NULL;
+ if (tek == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(tek); /* can't fail. */
+
+ /* encrypt the pms with the TEK.
+ * NB: PK11_WrapSymKey will generate and output the encrypted PMS
+ * AND the IV for decrypting the PMS.
+ */
+ param.data = fortezza_CKE.master_secret_iv;
+ param.len = sizeof fortezza_CKE.master_secret_iv;
+
+ enc_pms.data = fortezza_CKE.encrypted_preMasterSecret;
+ enc_pms.len = sizeof fortezza_CKE.encrypted_preMasterSecret;
+
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_CBC64, &param, tek, pms, &enc_pms);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ rv = SECFailure; /* not there yet. */
+
+ slot = PK11_GetSlotFromKey(tek);
+
+ ssl_GetSpecWriteLock(ss); releaseSpecWriteLock = PR_TRUE;
+
+ pwSpec = ss->ssl3->pwSpec;
+ pwSpec->client.write_key = client_write_key =
+ PK11_KeyGen(slot, CKM_SKIPJACK_CBC64, NULL, 0, pwArg);
+ if (client_write_key == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ /* the -1 is a hack. It's supposed to be key size, but we use it
+ * to tell the wrapper that we're doing a weird PKCS #11 key gen.
+ * Usually the result of key gen is an encrypt key. This is not
+ * the case with SSL, where this key is a decrypt key.
+ */
+ pwSpec->server.write_key = server_write_key =
+ PK11_KeyGen(slot, CKM_SKIPJACK_CBC64, NULL, -1, pwArg);
+ if (server_write_key == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms); pms = NULL;
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ /* copy the keys and IVs out now */
+ item.data = fortezza_CKE.wrapped_client_write_key;
+ item.len = sizeof fortezza_CKE.wrapped_client_write_key;
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, client_write_key, &item);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ item.data = fortezza_CKE.wrapped_server_write_key;
+ item.len = sizeof fortezza_CKE.wrapped_server_write_key;
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, server_write_key, &item);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ /* we only get the generated IV's if we're doing skipjack. */
+ if (pwSpec->cipher_def->calg == calg_fortezza) {
+ PORT_Memcpy(fortezza_CKE.client_write_iv, pwSpec->client.write_iv,
+ sizeof fortezza_CKE.client_write_iv);
+ PORT_Memcpy(fortezza_CKE.server_write_iv, pwSpec->server.write_iv,
+ sizeof fortezza_CKE.server_write_iv);
+ } else {
+ /* generate IVs to make old servers happy */
+ rv = PK11_GenerateFortezzaIV(client_write_key,
+ fortezza_CKE.client_write_iv,
+ sizeof fortezza_CKE.client_write_iv);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ rv = PK11_GenerateFortezzaIV(server_write_key,
+ fortezza_CKE.server_write_iv,
+ sizeof fortezza_CKE.server_write_iv);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ }
+ /* NOTE: This technique of writing out the struct, rather than writing
+ * out the individual members works only because all the rest of the
+ * values are fixed-length strings of well-defined byte order.
+ * Add one SECItem or one Number and we will need to break the elements out.
+ */
+ rv = ssl3_AppendHandshake(ss, &fortezza_CKE.r_c,
+ (sizeof fortezza_CKE - sizeof fortezza_CKE.y_c));
+ if (rv != SECSuccess) {
+ goto loser; /* err was set by AppendHandshake. */
+ }
+
+ /* now we initialize our contexts */
+ sid->u.ssl3.hasFortezza = PR_TRUE;
+ sid->u.ssl3.tek = tek; tek = NULL; /* adopt.. */
+
+ if (pwSpec->cipher_def->calg == calg_fortezza) {
+ sid->u.ssl3.clientWriteKey =
+ PK11_ReferenceSymKey(pwSpec->client.write_key);
+ sid->u.ssl3.serverWriteKey=
+ PK11_ReferenceSymKey(pwSpec->server.write_key);
+
+ PORT_Memcpy(sid->u.ssl3.keys.client_write_iv,
+ pwSpec->client.write_iv,
+ sizeof sid->u.ssl3.keys.client_write_iv);
+ PORT_Memcpy(sid->u.ssl3.keys.server_write_iv,
+ pwSpec->server.write_iv,
+ sizeof sid->u.ssl3.keys.server_write_iv);
+
+ rv = PK11_SaveContext((PK11Context *)pwSpec->encodeContext,
+ sid->u.ssl3.clientWriteSave,
+ &sid->u.ssl3.clientWriteSaveLen,
+ sizeof sid->u.ssl3.clientWriteSave);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+ } else {
+ PK11_FreeSymKey(client_write_key);
+ pwSpec->client.write_key = client_write_key = NULL;
+
+ PK11_FreeSymKey(server_write_key);
+ pwSpec->server.write_key = server_write_key = NULL;
+
+ rv = SECSuccess;
+ }
+ /* FALL THROUGH */
+loser:
+ if (tek) PK11_FreeSymKey(tek);
+ if (slot) PK11_FreeSlot(slot);
+ if (pms) PK11_FreeSymKey(pms);
+ if (rv != SECSuccess) {
+ if (client_write_key) {
+ PK11_FreeSymKey(client_write_key);
+ pwSpec->client.write_key = client_write_key = NULL;
+ }
+ if (server_write_key) {
+ PK11_FreeSymKey(server_write_key);
+ pwSpec->server.write_key = server_write_key = NULL;
+ }
+ }
+ if (releaseSpecWriteLock)
+ ssl_GetSpecWriteLock(ss);
+ return rv;
+}
/* Called from ssl3_HandleServerHelloDone(). */
static SECStatus
@@ -3746,6 +4290,10 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
rv = sendRSAClientKeyExchange(ss, serverKey);
break;
+ case kt_fortezza:
+ rv = sendFortezzaClientKeyExchange(ss, serverKey);
+ break;
+
case kt_dh:
rv = sendDHClientKeyExchange(ss, serverKey);
break;
@@ -3813,7 +4361,7 @@ ssl3_SendCertificateVerify(sslSocket *ss)
PK11_FreeSlot(slot);
}
/* If we're doing RSA key exchange, we're all done with the private key
- * here. Diffie-Hellman key exchanges need the client's
+ * here. Diffie-Hellman & Fortezza key exchanges need the client's
* private key for the key exchange.
*/
if (ssl3->hs.kea_def->exchKeyType == kt_rsa) {
@@ -4038,11 +4586,39 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
}
+ /* reload the FORTEZZA key material. These keys aren't generated
+ * by the master secret, but by the key exchange. We restart by
+ * reusing these keys. */
+ if (sid->u.ssl3.hasFortezza) {
+ ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(sid->u.ssl3.tek);
+ }
+ if (ss->ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
+ ss->ssl3->pwSpec->client.write_key =
+ PK11_ReferenceSymKey(sid->u.ssl3.clientWriteKey);
+ ss->ssl3->pwSpec->server.write_key =
+ PK11_ReferenceSymKey(sid->u.ssl3.serverWriteKey);
+ /* add the tek later for pre-encrypted files */
+ PORT_Memcpy(ss->ssl3->pwSpec->client.write_iv,
+ sid->u.ssl3.keys.client_write_iv,
+ sizeof sid->u.ssl3.keys.client_write_iv);
+ PORT_Memcpy(ss->ssl3->pwSpec->server.write_iv,
+ sid->u.ssl3.keys.server_write_iv,
+ sizeof sid->u.ssl3.keys.server_write_iv);
+ }
/* NULL value for PMS signifies re-use of the old MS */
rv = ssl3_InitPendingCipherSpec(ss, NULL);
if (rv != SECSuccess) {
- goto alert_loser; /* err code was set */
+ goto alert_loser; /* err code was set by ssl3_InitPendingCipherSpec */
+ }
+ if (ss->ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
+ rv = PK11_RestoreContext(
+ (PK11Context *)ss->ssl3->pwSpec->encodeContext,
+ sid->u.ssl3.clientWriteSave,
+ sid->u.ssl3.clientWriteSaveLen);
+ if (rv != SECSuccess) {
+ goto alert_loser; /* err is set. */
+ }
}
SECITEM_ZfreeItem(&sidBytes, PR_FALSE);
return SECSuccess;
@@ -4398,6 +4974,26 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
return SECSuccess;
#endif /* NSS_ENABLE_ECC */
+ case kt_fortezza:
+
+ /* Fortezza needs *BOTH* a server cert message
+ * and a server key exchange message.
+ */
+ if (ss->ssl3->hs.ws == wait_server_cert) {
+ errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH;
+ desc = unexpected_message;
+ goto alert_loser;
+ }
+ /* Get the server's "random" public key. */
+ rv = ssl3_ConsumeHandshake(ss, ss->ssl3->fortezza.R_s,
+ sizeof ss->ssl3->fortezza.R_s, &b, &length);
+ if (rv != SECSuccess) {
+ goto loser; /* malformed */
+ }
+
+ ss->ssl3->hs.ws = wait_cert_request;
+ return SECSuccess;
+
default:
desc = handshake_failure;
errCode = SEC_ERROR_UNSUPPORTED_KEYALG;
@@ -4811,6 +5407,7 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server)
sid->u.ssl3.resumable = PR_TRUE;
sid->u.ssl3.policy = SSL_ALLOWED;
+ sid->u.ssl3.hasFortezza = PR_FALSE;
sid->u.ssl3.clientWriteKey = NULL;
sid->u.ssl3.serverWriteKey = NULL;
sid->u.ssl3.tek = NULL;
@@ -4859,8 +5456,12 @@ ssl3_SendServerHelloSequence(sslSocket *ss)
*/
kea_def = ss->ssl3->hs.kea_def;
ss->ssl3->hs.usedStepDownKey = PR_FALSE;
-
- if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
+ if (kea_def->kea == kea_fortezza) {
+ rv = ssl3_SendServerKeyExchange(ss);
+ if (rv != SECSuccess) {
+ return rv; /* err code was set. */
+ }
+ } else if (kea_def->is_limited && kea_def->exchKeyType == kt_rsa) {
/* see if we can legally use the key in the cert. */
int keyLen; /* bytes */
@@ -5116,6 +5717,7 @@ compression_found:
* as if the client had sent us no sid to begin with, and make a new one.
*/
if (sid != NULL) do {
+ PK11SlotInfo * slot;
PK11SymKey * wrapKey; /* wrapping key */
SECItem wrappedKey; /* wrapped key */
ssl3CipherSpec *pwSpec;
@@ -5196,6 +5798,74 @@ compression_found:
goto loser;
}
+ /* reload the FORTEZZA key material.
+ * On Fortezza, the following keys & IVs are generated by the KEA,
+ * not from the PMS. Since we're not going to redo the KEA, we
+ * have to save & restore them for Fortezza.
+ * use kea because we haven't call InitCipher Specs yet...?
+ */
+ if (ssl3->hs.suite_def->bulk_cipher_alg == cipher_fortezza) {
+ PK11SymKey * Ks;
+ SECItem item;
+
+ PORT_Memcpy(pwSpec->client.write_iv,
+ sid->u.ssl3.keys.client_write_iv,
+ sizeof sid->u.ssl3.keys.client_write_iv);
+ PORT_Memcpy(pwSpec->server.write_iv,
+ sid->u.ssl3.keys.server_write_iv,
+ sizeof sid->u.ssl3.keys.server_write_iv);
+
+ /* Now, unwrap the client and server write keys with Ks */
+
+ /* get the slot that the fortezza server private key is in. */
+ slot = PK11_GetSlotFromPrivateKey(
+ ss->serverCerts[kt_fortezza].serverKey);
+ if (slot == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ /* Look up the Token Fixed Key */
+ Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL,
+ ss->pkcs11PinArg);
+ PK11_FreeSlot(slot);
+ if (Ks == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
+
+ /* unwrap client write key with the local Ks */
+ item.data = sid->u.ssl3.keys.wrapped_client_write_key;
+ item.len = sizeof sid->u.ssl3.keys.wrapped_client_write_key;
+
+ pwSpec->client.write_key =
+ PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_WRAP, NULL, &item,
+ CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
+ if (pwSpec->client.write_key == NULL) {
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
+ goto loser;
+ }
+
+ /* unwrap server write key with the local Ks */
+ item.data = sid->u.ssl3.keys.wrapped_server_write_key;
+ item.len = sizeof sid->u.ssl3.keys.wrapped_server_write_key;
+
+ pwSpec->server.write_key =
+ PK11_UnwrapSymKey(Ks, CKM_SKIPJACK_WRAP, NULL, &item,
+ CKM_SKIPJACK_CBC64, CKA_ENCRYPT, 0);
+ if (pwSpec->server.write_key == NULL) {
+ PK11_FreeSymKey(pwSpec->client.write_key);
+ pwSpec->client.write_key = NULL;
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
+ goto loser;
+ }
+ /* Set flag that says "generate 8 byte random prefix plaintext." */
+ PK11_SetFortezzaHack(pwSpec->server.write_key); /* can't fail */
+
+ }
+
if (haveSpecWriteLock) {
ssl_ReleaseSpecWriteLock(ss);
haveSpecWriteLock = PR_FALSE;
@@ -5606,6 +6276,27 @@ const ssl3KEADef * kea_def = ss->ssl3->hs.kea_def;
PORT_Free(signed_hash.data);
return SECSuccess;
+ case kt_fortezza:
+
+ /* Set server's "random" public key R_s to the email value == 1 */
+ PORT_Memset(ss->ssl3->fortezza.R_s, 0, sizeof(ss->ssl3->fortezza.R_s));
+ ss->ssl3->fortezza.R_s[127] = 1;
+
+ /* don't waste time signing the random number */
+ length = sizeof (ss->ssl3->fortezza.R_s) /*+ 2 + signed_hash.len*/;
+
+ rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+
+ rv = ssl3_AppendHandshake( ss, &ss->ssl3->fortezza.R_s,
+ sizeof(ss->ssl3->fortezza.R_s));
+ if (rv != SECSuccess) {
+ goto loser; /* err set by AppendHandshake. */
+ }
+ return SECSuccess;
+
#ifdef NSS_ENABLE_ECC
case kt_ecdh:
/* Generate ephemeral ECDH key pair and send the public key */
@@ -5750,8 +6441,13 @@ const uint8 * certTypes;
calen += 2 + name->len;
}
- certTypes = certificate_types;
- certTypesLength = sizeof certificate_types;
+ if (ss->ssl3->hs.kea_def->exchKeyType == kt_fortezza) {
+ certTypes = fortezza_certificate_types;
+ certTypesLength = sizeof fortezza_certificate_types;
+ } else {
+ certTypes = certificate_types;
+ certTypesLength = sizeof certificate_types;
+ }
length = 1 + certTypesLength + 2 + calen;
@@ -5858,6 +6554,256 @@ loser:
return SECFailure;
}
+/*
+** Called from ssl3_HandleClientKeyExchange()
+*/
+static SECStatus
+ssl3_HandleFortezzaClientKeyExchange(sslSocket *ss, SSL3Opaque *b,
+ PRUint32 length,
+ SECKEYPrivateKey *serverKey)
+{
+ SECKEYPublicKey * pubKey = NULL;
+ PK11SymKey * tek = NULL;
+ PK11SymKey * pms;
+ PK11SymKey * Ks = NULL;
+ sslSessionID * sid = ss->sec.ci.sid;
+ ssl3CipherSpec * pwSpec = ss->ssl3->pwSpec;
+ void * pwArg = ss->pkcs11PinArg;
+ SECStatus rv;
+ SECItem raItem;
+ SECItem rbItem;
+ SECItem param;
+ SECItem item;
+ SECItem enc_pms;
+ SSL3FortezzaKeys fortezza_CKE;
+
+ PORT_Assert( ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+
+ fortezza_CKE.y_c.data = NULL;
+ rv = ssl3_ConsumeHandshakeVariable(ss, &fortezza_CKE.y_c, 1, &b, &length);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
+ goto fortezza_loser;
+ }
+ rv = ssl3_ConsumeHandshake(ss, &fortezza_CKE.r_c,
+ sizeof fortezza_CKE - sizeof fortezza_CKE.y_c,
+ &b, &length);
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
+ goto fortezza_loser;
+ }
+
+ /* Build a Token Encryption key (tek). TEK's can never be unloaded
+ * from the card, but given these parameters, and *OUR* fortezza
+ * card, we can always regenerate the same one on the fly.
+ */
+ if (ss->sec.peerCert != NULL) {
+ /* client-auth case */
+
+ pubKey = CERT_ExtractPublicKey(ss->sec.peerCert);
+ if (pubKey == NULL) {
+ SEND_ALERT
+ PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
+ rv = SECFailure;
+ goto fortezza_loser;
+ }
+
+ if (pubKey->keyType != fortezzaKey) {
+ /* handle V3 client-auth case */
+ SECItem sigItem;
+ SECItem hashItem;
+ unsigned char hash[SHA1_LENGTH];
+
+ rv = ssl3_ComputeFortezzaPublicKeyHash(fortezza_CKE.y_c, hash);
+ if (rv != SECSuccess) {
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+ sigItem.data = fortezza_CKE.y_signature;
+ sigItem.len = sizeof fortezza_CKE.y_signature;
+
+ hashItem.data = hash;
+ hashItem.len = sizeof hash;
+
+ rv = PK11_Verify(pubKey, &sigItem, &hashItem, pwArg);
+ if (rv != SECSuccess) {
+ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+ SECKEY_DestroyPublicKey(pubKey); pubKey = NULL;
+ }
+ }
+ rv = SECFailure;
+
+ /* Make the public key if necessary */
+ if (fortezza_CKE.y_c.len != 0) {
+ if (pubKey != NULL) {
+ /* The client is not allowed to send the public key
+ * if it can be extracted from the certificate. */
+ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+ pubKey = PK11_MakeKEAPubKey(fortezza_CKE.y_c.data,
+ fortezza_CKE.y_c.len);
+ }
+ if (pubKey == NULL) {
+ /* no public Key in either the cert or the protocol message*/
+ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+
+ /* Now we derive the TEK. r_c is the client's "random" public key. */
+ raItem.data = fortezza_CKE.r_c;
+ raItem.len = sizeof(fortezza_CKE.r_c);
+
+ /* R_s == server's "random" public key, sent in the Server Key Exchange */
+ rbItem.data = ss->ssl3->fortezza.R_s;
+ rbItem.len = sizeof ss->ssl3->fortezza.R_s;
+
+ tek = PK11_PubDerive(serverKey, pubKey, PR_FALSE, /* don't gen r_c */
+ &raItem, &rbItem, CKM_KEA_KEY_DERIVE,
+ CKM_SKIPJACK_WRAP, CKA_WRAP, 0, pwArg);
+ SECKEY_DestroyPublicKey(pubKey); pubKey = NULL;
+ if (tek == NULL) {
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+
+ ss->ssl3->fortezza.tek = PK11_ReferenceSymKey(tek);
+
+ if (pwSpec->cipher_def->calg == calg_fortezza) {
+ item.data = fortezza_CKE.wrapped_client_write_key;
+ item.len = sizeof fortezza_CKE.wrapped_client_write_key;
+
+ pwSpec->client.write_key =
+ PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, &item,
+ CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
+ if (pwSpec->client.write_key == NULL) {
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
+ goto fortezza_loser;
+ }
+
+ item.data = fortezza_CKE.wrapped_server_write_key;
+ item.len = sizeof fortezza_CKE.wrapped_server_write_key;
+
+ pwSpec->server.write_key =
+ PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL, &item,
+ CKM_SKIPJACK_CBC64, CKA_ENCRYPT, 0);
+ if (pwSpec->server.write_key == NULL) {
+ PK11_FreeSymKey(pwSpec->client.write_key);
+ pwSpec->client.write_key = NULL;
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
+ goto fortezza_loser;
+ }
+ /* Set a flag that says "generate 8 byte random prefix plaintext." */
+ PK11_SetFortezzaHack(pwSpec->server.write_key); /* can't fail */
+
+ PORT_Memcpy(pwSpec->client.write_iv, fortezza_CKE.client_write_iv,
+ sizeof fortezza_CKE.client_write_iv);
+ PORT_Memcpy(pwSpec->server.write_iv, fortezza_CKE.server_write_iv,
+ sizeof fortezza_CKE.server_write_iv);
+
+ }
+
+ /* decrypt the pms with the TEK */
+ enc_pms.data = fortezza_CKE.encrypted_preMasterSecret;
+ enc_pms.len = sizeof fortezza_CKE.encrypted_preMasterSecret;
+
+ param.data = fortezza_CKE.master_secret_iv;
+ param.len = sizeof fortezza_CKE.master_secret_iv;
+
+ pms = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_CBC64, &param, &enc_pms,
+ CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
+ if (pms == NULL) {
+ SEND_ALERT
+ ssl_MapLowLevelError(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE);
+ goto fortezza_loser;
+ }
+
+ rv = ssl3_InitPendingCipherSpec(ss, pms);
+ PK11_FreeSymKey(pms);
+ if (rv != SECSuccess) {
+ SEND_ALERT
+ goto fortezza_loser; /* err code is set. */
+ }
+
+ if (pwSpec->cipher_def->calg == calg_fortezza) {
+ PK11SlotInfo * slot;
+
+ sid->u.ssl3.clientWriteKey =
+ PK11_ReferenceSymKey(pwSpec->client.write_key);
+ sid->u.ssl3.serverWriteKey =
+ PK11_ReferenceSymKey(pwSpec->server.write_key);
+
+ PORT_Memcpy(sid->u.ssl3.keys.client_write_iv, pwSpec->client.write_iv,
+ sizeof sid->u.ssl3.keys.client_write_iv);
+ PORT_Memcpy(sid->u.ssl3.keys.server_write_iv, pwSpec->server.write_iv,
+ sizeof sid->u.ssl3.keys.server_write_iv);
+
+ /* Now, wrap the client and server write keys in Ks for storage
+ * in the on-disk sid.
+ */
+
+ slot = PK11_GetSlotFromKey(tek); /* get ref to the slot */
+ if (slot == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+
+ /* Look up the Token Fixed Key */
+ Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
+ PK11_FreeSlot(slot);
+ if (Ks == NULL) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+
+ /* rewrap server write key with the local Ks */
+ item.data = sid->u.ssl3.keys.wrapped_server_write_key;
+ item.len = sizeof sid->u.ssl3.keys.wrapped_server_write_key;
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks,
+ pwSpec->server.write_key, &item);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+
+ /* rewrap client write key with the local Ks */
+ item.data = sid->u.ssl3.keys.wrapped_client_write_key;
+ item.len = sizeof sid->u.ssl3.keys.wrapped_client_write_key;
+ rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks,
+ pwSpec->client.write_key, &item);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto fortezza_loser;
+ }
+
+ /* wrap the master secret later, when we handle the client's
+ * finished message.
+ */
+ }
+
+ sid->u.ssl3.hasFortezza = PR_TRUE;
+ sid->u.ssl3.tek = tek; tek = NULL;
+
+ rv = SECSuccess;
+
+fortezza_loser:
+ if (Ks) PK11_FreeSymKey(Ks);
+ if (tek) PK11_FreeSymKey(tek);
+ if (pubKey) SECKEY_DestroyPublicKey(pubKey);
+ if (fortezza_CKE.y_c.data != NULL)
+ SECITEM_FreeItem(&fortezza_CKE.y_c, PR_FALSE);
+ return rv;
+}
/* find a slot that is able to generate a PMS and wrap it with RSA.
* Then generate and return the PMS.
@@ -6163,6 +7109,12 @@ const ssl3KEADef * kea_def;
}
break;
+ case kt_fortezza:
+ rv = ssl3_HandleFortezzaClientKeyExchange(ss, b, length, serverKey);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error code set */
+ }
+ break;
#ifdef NSS_ENABLE_ECC
case kt_ecdh:
@@ -6541,8 +7493,18 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECKEY_UpdateCertPQG(ss->sec.peerCert);
/*
- * Ask caller-supplied callback function to validate cert chain.
+ * We're making a fortezza connection, and the card hasn't unloaded it's
+ * certs, try to unload those certs now.
*/
+ if (!trusted) {
+ CERTCertificate *ccert;
+
+ ccert = PK11_FindBestKEAMatch(ss->sec.peerCert, ss->pkcs11PinArg);
+ if (ccert)
+ CERT_DestroyCertificate(ccert);
+ }
+
+
rv = (SECStatus)(*ss->authCertificate)(ss->authCertificateArg, ss->fd,
PR_TRUE, isServer);
if (rv) {
@@ -6635,6 +7597,7 @@ cert_block:
ssl3->hs.ws = wait_cert_request; /* disallow server_key_exchange */
if (ssl3->hs.kea_def->is_limited ||
/* XXX OR server cert is signing only. */
+ ssl3->hs.kea_def->kea == kea_fortezza ||
#ifdef NSS_ENABLE_ECC
ssl3->hs.kea_def->kea == kea_ecdhe_ecdsa ||
ssl3->hs.kea_def->kea == kea_ecdhe_rsa ||
@@ -7662,6 +8625,7 @@ ssl3_InitState(sslSocket *ss)
ssl3->hs.rehandshake = PR_FALSE;
ssl3_InitCipherSpec(ss, ssl3->crSpec);
ssl3_InitCipherSpec(ss, ssl3->prSpec);
+ ssl3->fortezza.tek = NULL;
ssl3->hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello;
ssl_ReleaseSpecWriteLock(ss);
@@ -8030,6 +8994,9 @@ ssl3_DestroySSL3Info(ssl3State *ssl3)
PK11_DestroyContext(ssl3->hs.sha,PR_TRUE);
}
+ if (ssl3->fortezza.tek != NULL) {
+ PK11_FreeSymKey(ssl3->fortezza.tek);
+ }
/* free the SSL3Buffer (msg_body) */
PORT_Free(ssl3->hs.msg_body.buf);
diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h
index da1e0d180..c68fa8270 100644
--- a/security/nss/lib/ssl/ssl3prot.h
+++ b/security/nss/lib/ssl/ssl3prot.h
@@ -1,4 +1,4 @@
-/* Private header file of libSSL.
+/*
* Various and sundry protocol constants. DON'T CHANGE THESE. These
* values are defined by the SSL 3.0 protocol specification.
*
@@ -206,6 +206,7 @@ typedef enum {
kea_dhe_rsa_export,
kea_dh_anon,
kea_dh_anon_export,
+ kea_fortezza,
kea_rsa_fips,
kea_ecdh_ecdsa,
kea_ecdhe_ecdsa,
@@ -258,6 +259,7 @@ typedef enum {
ct_RSA_fixed_ECDH = 8,
ct_ECDSA_fixed_ECDH = 9,
+ ct_Fortezza = 20
} SSL3ClientCertificateType;
typedef SECItem *SSL3DistinquishedName;
@@ -269,6 +271,18 @@ typedef struct {
typedef SECItem SSL3EncryptedPreMasterSecret;
+/* Following struct is the format of a Fortezza ClientKeyExchange message. */
+typedef struct {
+ SECItem y_c;
+ SSL3Opaque r_c [128];
+ SSL3Opaque y_signature [40];
+ SSL3Opaque wrapped_client_write_key [12];
+ SSL3Opaque wrapped_server_write_key [12];
+ SSL3Opaque client_write_iv [24];
+ SSL3Opaque server_write_iv [24];
+ SSL3Opaque master_secret_iv [24];
+ SSL3Opaque encrypted_preMasterSecret[48];
+} SSL3FortezzaKeys;
typedef SSL3Opaque SSL3MasterSecret[48];
@@ -285,6 +299,7 @@ typedef struct {
union {
SSL3EncryptedPreMasterSecret rsa;
SSL3ClientDiffieHellmanPublic diffie_helman;
+ SSL3FortezzaKeys fortezza;
} exchange_keys;
} SSL3ClientKeyExchange;
diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c
index 24d250018..690008e42 100644
--- a/security/nss/lib/ssl/sslauth.c
+++ b/security/nss/lib/ssl/sslauth.c
@@ -117,7 +117,8 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
cipherName = ssl3_cipherName[ss->sec.cipherType];
}
if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
-
+ /* do same key stuff for fortezza */
+
if (cp) {
*cp = PORT_Strdup(cipherName);
}
diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c
index 278478fc6..da20986b5 100644
--- a/security/nss/lib/ssl/sslcon.c
+++ b/security/nss/lib/ssl/sslcon.c
@@ -145,7 +145,7 @@ const char * const ssl_cipherName[] = {
"DES-CBC",
"DES-EDE3-CBC",
"unknown",
- "unknown", /* was fortezza, NO LONGER USED */
+ "Fortezza",
};
diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c
index d28d689b7..2745155af 100644
--- a/security/nss/lib/ssl/sslenum.c
+++ b/security/nss/lib/ssl/sslenum.c
@@ -56,6 +56,7 @@ const PRUint16 SSL_ImplementedCiphers[] = {
TLS_RSA_WITH_AES_256_CBC_SHA,
/* 128-bit */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
@@ -83,6 +84,9 @@ const PRUint16 SSL_ImplementedCiphers[] = {
SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+ /* 80 bit skipjack */
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* KEA + SkipJack */
+
/* 56-bit DES "domestic" cipher suites */
SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_DHE_DSS_WITH_DES_CBC_SHA,
@@ -102,6 +106,7 @@ const PRUint16 SSL_ImplementedCiphers[] = {
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
/* ciphersuites with no encryption */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA,
#ifdef NSS_ENABLE_ECC
TLS_ECDH_RSA_WITH_NULL_SHA,
TLS_ECDH_ECDSA_WITH_NULL_SHA,
diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h
index ae6cb8a72..f42bd4be3 100644
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -84,7 +84,7 @@ typedef SSLSignType SSL3SignType;
#define calg_des ssl_calg_des
#define calg_3des ssl_calg_3des
#define calg_idea ssl_calg_idea
-#define calg_fortezza ssl_calg_fortezza /* deprecated, must preserve */
+#define calg_fortezza ssl_calg_fortezza
#define calg_aes ssl_calg_aes
#define mac_null ssl_mac_null
@@ -414,6 +414,7 @@ typedef enum {
cipher_3des,
cipher_des40,
cipher_idea,
+ cipher_fortezza,
cipher_aes_128,
cipher_aes_256,
cipher_missing /* reserved for no such supported cipher */
@@ -521,6 +522,7 @@ struct sslSessionIDStr {
SSL3CompressionMethod compression;
PRBool resumable;
int policy;
+ PRBool hasFortezza;
ssl3SidKeys keys;
CK_MECHANISM_TYPE masterWrapMech;
/* mechanism used to wrap master secret */
@@ -558,6 +560,11 @@ struct sslSessionIDStr {
char masterValid;
char clAuthValid;
+ /* the following values are used only in the client, and only
+ * with fortezza.
+ */
+ SSL3Opaque clientWriteSave[80];
+ int clientWriteSaveLen;
} ssl3;
} u;
};
@@ -653,7 +660,12 @@ const ssl3CipherSuiteDef *suite_def;
/* protected by recvBufLock */
} SSL3HandshakeState;
+struct SSL3FortezzaKEAParamsStr {
+ unsigned char R_s[128]; /* server's "random" public key */
+ PK11SymKey * tek;
+};
+typedef struct SSL3FortezzaKEAParamsStr SSL3FortezzaKEAParams;
/*
** This is the "ssl3" struct, as in "ss->ssl3".
@@ -692,7 +704,7 @@ struct ssl3StateStr {
/* chain while we are trying to validate it. */
CERTDistNames * ca_list;
/* used by server. trusted CAs for this socket. */
-
+ SSL3FortezzaKEAParams fortezza;
};
typedef struct {
diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c
index 40dd9b31f..218973a2a 100644
--- a/security/nss/lib/ssl/sslinfo.c
+++ b/security/nss/lib/ssl/sslinfo.c
@@ -100,6 +100,8 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
return SECSuccess;
}
+#define kt_kea kt_fortezza
+#define calg_sj calg_fortezza
#define CS(x) x, #x
#define CK(x) x | 0xff00, #x
@@ -141,6 +143,7 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 0, 0, 0, },
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 0, 0, 0, },
+{0,CS(SSL_FORTEZZA_DMS_WITH_RC4_128_SHA), S_KEA, K_KEA, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 0, 0, 0, },
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 0, 0, 0, },
@@ -153,6 +156,7 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 1, },
{0,CS(SSL_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0, },
+{0,CS(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA),S_KEA, K_KEA, C_SJ, B_SJ, M_SHA, 1, 0, 0, },
{0,CS(SSL_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
{0,CS(SSL_DHE_DSS_WITH_DES_CBC_SHA), S_DSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0, },
{0,CS(SSL_RSA_FIPS_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 1, 0, 1, },
@@ -162,6 +166,7 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 1, 1, 0, },
{0,CS(SSL_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0, },
{0,CS(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0, },
+{0,CS(SSL_FORTEZZA_DMS_WITH_NULL_SHA), S_KEA, K_KEA, C_NULL,B_0, M_SHA, 0, 1, 0, },
{0,CS(SSL_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0, },
{0,CS(SSL_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0, },
diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h
index e7a998126..fa0639605 100644
--- a/security/nss/lib/ssl/sslproto.h
+++ b/security/nss/lib/ssl/sslproto.h
@@ -139,9 +139,9 @@
#define SSL_DH_ANON_WITH_DES_CBC_SHA 0x001a
#define SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA 0x001b
-#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c /* deprecated */
-#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d /* deprecated */
-#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e /* deprecated */
+#define SSL_FORTEZZA_DMS_WITH_NULL_SHA 0x001c
+#define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d
+#define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e
/* New TLS cipher suites */
#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index 9f537a3ef..404f9a7dc 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -574,7 +574,12 @@ ssl_FindCertKEAType(CERTCertificate * cert)
case SEC_OID_PKCS1_RSA_ENCRYPTION:
keaType = kt_rsa;
break;
-
+ case SEC_OID_MISSI_KEA_DSS_OLD:
+ case SEC_OID_MISSI_KEA_DSS:
+ case SEC_OID_MISSI_DSS_OLD:
+ case SEC_OID_MISSI_DSS:
+ keaType = kt_fortezza;
+ break;
case SEC_OID_X942_DIFFIE_HELMAN_KEY:
keaType = kt_dh;
break;
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
index a0c164963..345104f1f 100644
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -147,7 +147,7 @@ struct sidCacheEntryStr {
/* 2 */ PRUint16 compression; /* SSL3CompressionMethod */
/*122 */ ssl3SidKeys keys; /* keys and ivs, wrapped as needed. */
-/* 1 */ PRUint8 unused; /* was hasFortezza; */
+/* 1 */ PRUint8 hasFortezza;
/* 1 */ PRUint8 resumable;
/* 4 */ PRUint32 masterWrapMech;
@@ -442,6 +442,7 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
to->u.ssl3.compression = (uint16)from->u.ssl3.compression;
to->u.ssl3.resumable = from->u.ssl3.resumable;
+ to->u.ssl3.hasFortezza = from->u.ssl3.hasFortezza;
to->u.ssl3.keys = from->u.ssl3.keys;
to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
@@ -517,6 +518,7 @@ ConvertToSID(sidCacheEntry *from, certCacheEntry *pcce,
to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
to->u.ssl3.compression = (SSL3CompressionMethod)from->u.ssl3.compression;
to->u.ssl3.resumable = from->u.ssl3.resumable;
+ to->u.ssl3.hasFortezza = from->u.ssl3.hasFortezza;
to->u.ssl3.keys = from->u.ssl3.keys;
to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
to->u.ssl3.exchKeyType = from->u.ssl3.exchKeyType;
@@ -542,6 +544,8 @@ ConvertToSID(sidCacheEntry *from, certCacheEntry *pcce,
to->u.ssl3.clAuthSeries = 0;
to->u.ssl3.clAuthValid = PR_FALSE;
+ to->u.ssl3.clientWriteSaveLen = 0;
+
if (from->u.ssl3.certIndex != -1 && pcce) {
SECItem derCert;
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
index 2e8d73219..9803eec96 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -71,6 +71,8 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
{ SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_ALLOWED, SSL_ALLOWED },
{ SSL_EN_DES_64_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
+ { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
+ { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_RSA_WITH_RC4_128_MD5, SSL_RESTRICTED, SSL_NOT_ALLOWED },
{ SSL_RSA_WITH_RC4_128_SHA, SSL_RESTRICTED, SSL_NOT_ALLOWED },
{ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
@@ -79,6 +81,7 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */
{ SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
{ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED, SSL_ALLOWED },
+ { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
{ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
diff --git a/security/nss/lib/ssl/sslt.h b/security/nss/lib/ssl/sslt.h
index 052339b7d..0223ee2ad 100644
--- a/security/nss/lib/ssl/sslt.h
+++ b/security/nss/lib/ssl/sslt.h
@@ -66,7 +66,7 @@ typedef enum {
ssl_kea_null = 0,
ssl_kea_rsa = 1,
ssl_kea_dh = 2,
- ssl_kea_fortezza = 3, /* deprecated, now unused */
+ ssl_kea_fortezza = 3,
ssl_kea_ecdh = 4,
ssl_kea_size /* number of ssl_kea_ algorithms */
} SSLKEAType;
@@ -79,7 +79,7 @@ typedef enum {
#define kt_null ssl_kea_null
#define kt_rsa ssl_kea_rsa
#define kt_dh ssl_kea_dh
-#define kt_fortezza ssl_kea_fortezza /* deprecated, now unused */
+#define kt_fortezza ssl_kea_fortezza
#define kt_ecdh ssl_kea_ecdh
#define kt_kea_size ssl_kea_size
@@ -105,7 +105,7 @@ typedef enum {
ssl_calg_des = 3,
ssl_calg_3des = 4,
ssl_calg_idea = 5,
- ssl_calg_fortezza = 6, /* deprecated, now unused */
+ ssl_calg_fortezza = 6, /* skipjack */
ssl_calg_aes = 7 /* coming soon */
} SSLCipherAlgorithm;
diff --git a/security/nss/pkg/solaris/SUNWtlsd/prototype b/security/nss/pkg/solaris/SUNWtlsd/prototype
index b742d2f9e..6581f32f1 100755
--- a/security/nss/pkg/solaris/SUNWtlsd/prototype
+++ b/security/nss/pkg/solaris/SUNWtlsd/prototype
@@ -160,4 +160,6 @@ f none usr/include/mps/ssl.h 0644 root bin
f none usr/include/mps/sslerr.h 0644 root bin
f none usr/include/mps/sslproto.h 0644 root bin
f none usr/include/mps/sslt.h 0644 root bin
+f none usr/include/mps/swfort.h 0644 root bin
+f none usr/include/mps/swfortt.h 0644 root bin
f none usr/include/mps/watcomfx.h 0644 root bin