зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1245053, landing NSS_3_23_BETA5, r=mt
This commit is contained in:
Родитель
e97ffb64eb
Коммит
5553a6adbf
|
@ -1 +1 @@
|
|||
NSS_3_23_BETA4
|
||||
NSS_3_23_BETA5
|
||||
|
|
|
@ -5,15 +5,14 @@ checkout:
|
|||
test:
|
||||
override:
|
||||
- make nss_build_all
|
||||
- cd tests; NSS_TESTS=ssl_gtests NSS_CYCLES=standard ./all.sh
|
||||
- cd tests; NSS_TESTS="ssl_gtests pk11_gtests der_gtests" NSS_CYCLES=standard ./all.sh
|
||||
- BUILD_OPT=1 make nss_build_all
|
||||
- cd tests; BUILD_OPT=1 NSS_TESTS=ssl_gtests NSS_CYCLES=standard ./all.sh
|
||||
- cd tests; BUILD_OPT=1 NSS_TESTS="ssl_gtests pk11_gtests der_gtests" NSS_CYCLES=standard ./all.sh
|
||||
|
||||
machine:
|
||||
environment:
|
||||
{ USE_64: 1,
|
||||
NSS_ENABLE_TLS_1_3: 1,
|
||||
NSS_BUILD_GTESTS: 1,
|
||||
}
|
||||
hosts:
|
||||
|
||||
|
|
|
@ -613,6 +613,17 @@ typedef SECStatus (* bltestSymmCipherFn)(void *cx,
|
|||
const unsigned char *input,
|
||||
unsigned int inputLen);
|
||||
|
||||
typedef SECStatus (* bltestAEADFn)(void *cx,
|
||||
unsigned char *output,
|
||||
unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen,
|
||||
const unsigned char *nonce,
|
||||
unsigned int nonceLen,
|
||||
const unsigned char *ad,
|
||||
unsigned int adLen);
|
||||
|
||||
typedef SECStatus (* bltestPubKeyCipherFn)(void *key,
|
||||
SECItem *output,
|
||||
const SECItem *input);
|
||||
|
@ -646,6 +657,7 @@ typedef enum {
|
|||
bltestCAMELLIA_CBC, /* . */
|
||||
bltestSEED_ECB, /* SEED algorithm */
|
||||
bltestSEED_CBC, /* SEED algorithm */
|
||||
bltestCHACHA20, /* ChaCha20 + Poly1305 */
|
||||
bltestRSA, /* Public Key Ciphers */
|
||||
bltestRSA_OAEP, /* . (Public Key Enc.) */
|
||||
bltestRSA_PSS, /* . (Public Key Sig.) */
|
||||
|
@ -685,6 +697,7 @@ static char *mode_strings[] =
|
|||
"camellia_cbc",
|
||||
"seed_ecb",
|
||||
"seed_cbc",
|
||||
"chacha20_poly1305",
|
||||
"rsa",
|
||||
"rsa_oaep",
|
||||
"rsa_pss",
|
||||
|
@ -805,6 +818,7 @@ struct bltestCipherInfoStr {
|
|||
/* Cipher function (encrypt/decrypt/sign/verify/hash) */
|
||||
union {
|
||||
bltestSymmCipherFn symmkeyCipher;
|
||||
bltestAEADFn aeadCipher;
|
||||
bltestPubKeyCipherFn pubkeyCipher;
|
||||
bltestHashCipherFn hashCipher;
|
||||
} cipher;
|
||||
|
@ -826,13 +840,29 @@ is_symmkeyCipher(bltestCipherMode mode)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
is_aeadCipher(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
switch (mode) {
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
is_authCipher(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
if (mode == bltestAES_GCM)
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
switch (mode) {
|
||||
case bltestAES_GCM:
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -840,11 +870,14 @@ PRBool
|
|||
is_singleShotCipher(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
if (mode == bltestAES_GCM)
|
||||
return PR_TRUE;
|
||||
if (mode == bltestAES_CTS)
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
switch (mode) {
|
||||
case bltestAES_GCM:
|
||||
case bltestAES_CTS:
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -878,16 +911,24 @@ PRBool
|
|||
cipher_requires_IV(bltestCipherMode mode)
|
||||
{
|
||||
/* change as needed! */
|
||||
if (mode == bltestDES_CBC || mode == bltestDES_EDE_CBC ||
|
||||
mode == bltestRC2_CBC ||
|
||||
switch (mode) {
|
||||
case bltestDES_CBC:
|
||||
case bltestDES_EDE_CBC:
|
||||
case bltestRC2_CBC:
|
||||
#ifdef NSS_SOFTOKEN_DOES_RC5
|
||||
mode == bltestRC5_CBC ||
|
||||
case bltestRC5_CBC:
|
||||
#endif
|
||||
mode == bltestAES_CBC || mode == bltestAES_CTS ||
|
||||
mode == bltestAES_CTR || mode == bltestAES_GCM ||
|
||||
mode == bltestCAMELLIA_CBC || mode == bltestSEED_CBC)
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
case bltestAES_CBC:
|
||||
case bltestAES_CTS:
|
||||
case bltestAES_CTR:
|
||||
case bltestAES_GCM:
|
||||
case bltestCAMELLIA_CBC:
|
||||
case bltestSEED_CBC:
|
||||
case bltestCHACHA20:
|
||||
return PR_TRUE;
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus finishIO(bltestIO *output, PRFileDesc *file);
|
||||
|
@ -1126,6 +1167,30 @@ aes_Decrypt(void *cx, unsigned char *output, unsigned int *outputLen,
|
|||
input, inputLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
chacha20_poly1305_Encrypt(void *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
return ChaCha20Poly1305_Seal((ChaCha20Poly1305Context *)cx, output,
|
||||
outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
chacha20_poly1305_Decrypt(void *cx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
return ChaCha20Poly1305_Open((ChaCha20Poly1305Context *)cx, output,
|
||||
outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
camellia_Encrypt(void *cx, unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen, const unsigned char *input,
|
||||
|
@ -1575,6 +1640,21 @@ bltest_seed_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
bltest_chacha20_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
||||
{
|
||||
const unsigned int tagLen = 16;
|
||||
const bltestSymmKeyParams *sk = &cipherInfo->params.sk;
|
||||
cipherInfo->cx = ChaCha20Poly1305_CreateContext(sk->key.buf.data,
|
||||
sk->key.buf.len, tagLen);
|
||||
|
||||
if (encrypt)
|
||||
cipherInfo->cipher.aeadCipher = chacha20_poly1305_Encrypt;
|
||||
else
|
||||
cipherInfo->cipher.aeadCipher = chacha20_poly1305_Decrypt;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
bltest_rsa_init(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
||||
{
|
||||
|
@ -2226,6 +2306,11 @@ cipherInit(bltestCipherInfo *cipherInfo, PRBool encrypt)
|
|||
cipherInfo->input.pBuf.len);
|
||||
return bltest_seed_init(cipherInfo, encrypt);
|
||||
break;
|
||||
case bltestCHACHA20:
|
||||
outlen = cipherInfo->input.pBuf.len + (encrypt ? 16 : 0);
|
||||
SECITEM_AllocItem(cipherInfo->arena, &cipherInfo->output.buf, outlen);
|
||||
return bltest_chacha20_init(cipherInfo, encrypt);
|
||||
break;
|
||||
case bltestRSA:
|
||||
case bltestRSA_OAEP:
|
||||
case bltestRSA_PSS:
|
||||
|
@ -2376,6 +2461,55 @@ cipherDoOp(bltestCipherInfo *cipherInfo)
|
|||
}
|
||||
}
|
||||
TIMEFINISH(cipherInfo->optime, 1.0);
|
||||
} else if (is_aeadCipher(cipherInfo->mode)) {
|
||||
const unsigned char *input = cipherInfo->input.pBuf.data;
|
||||
unsigned int inputLen = cipherInfo->input.pBuf.len;
|
||||
unsigned char *output = cipherInfo->output.pBuf.data;
|
||||
unsigned int outputLen;
|
||||
bltestSymmKeyParams *sk = &cipherInfo->params.sk;
|
||||
bltestAuthSymmKeyParams *ask = &cipherInfo->params.ask;
|
||||
|
||||
TIMESTART();
|
||||
rv = (*cipherInfo->cipher.aeadCipher)(
|
||||
cipherInfo->cx,
|
||||
output, &outputLen, maxLen,
|
||||
input, inputLen,
|
||||
sk->iv.buf.data, sk->iv.buf.len,
|
||||
ask->aad.buf.data, ask->aad.buf.len);
|
||||
CHECKERROR(rv, __LINE__);
|
||||
cipherInfo->output.pBuf.len = outputLen;
|
||||
TIMEFINISH(cipherInfo->optime, 1.0);
|
||||
|
||||
cipherInfo->repetitions = 0;
|
||||
if (cipherInfo->repetitionsToPerfom != 0) {
|
||||
TIMESTART();
|
||||
for (i=0; i<cipherInfo->repetitionsToPerfom; i++,
|
||||
cipherInfo->repetitions++) {
|
||||
rv = (*cipherInfo->cipher.aeadCipher)(
|
||||
cipherInfo->cx,
|
||||
output, &outputLen, maxLen,
|
||||
input, inputLen,
|
||||
sk->iv.buf.data, sk->iv.buf.len,
|
||||
ask->aad.buf.data, ask->aad.buf.len);
|
||||
CHECKERROR(rv, __LINE__);
|
||||
}
|
||||
} else {
|
||||
int opsBetweenChecks = 0;
|
||||
TIMEMARK(cipherInfo->seconds);
|
||||
while (! (TIMETOFINISH())) {
|
||||
int j = 0;
|
||||
for (;j < opsBetweenChecks;j++) {
|
||||
(*cipherInfo->cipher.aeadCipher)(
|
||||
cipherInfo->cx,
|
||||
output, &outputLen, maxLen,
|
||||
input, inputLen,
|
||||
sk->iv.buf.data, sk->iv.buf.len,
|
||||
ask->aad.buf.data, ask->aad.buf.len);
|
||||
}
|
||||
cipherInfo->repetitions += j;
|
||||
}
|
||||
}
|
||||
TIMEFINISH(cipherInfo->optime, 1.0);
|
||||
} else if (is_pubkeyCipher(cipherInfo->mode)) {
|
||||
TIMESTART();
|
||||
rv = (*cipherInfo->cipher.pubkeyCipher)(cipherInfo->cx,
|
||||
|
@ -2477,6 +2611,10 @@ cipherFinish(bltestCipherInfo *cipherInfo)
|
|||
case bltestSEED_CBC:
|
||||
SEED_DestroyContext((SEEDContext *)cipherInfo->cx, PR_TRUE);
|
||||
break;
|
||||
case bltestCHACHA20:
|
||||
ChaCha20Poly1305_DestroyContext((ChaCha20Poly1305Context *)
|
||||
cipherInfo->cx, PR_TRUE);
|
||||
break;
|
||||
case bltestRC2_ECB:
|
||||
case bltestRC2_CBC:
|
||||
RC2_DestroyContext((RC2Context *)cipherInfo->cx, PR_TRUE);
|
||||
|
@ -2808,6 +2946,7 @@ get_params(PLArenaPool *arena, bltestParams *params,
|
|||
#endif
|
||||
switch (mode) {
|
||||
case bltestAES_GCM:
|
||||
case bltestCHACHA20:
|
||||
sprintf(filename, "%s/tests/%s/%s%d", testdir, modestr, "aad", j);
|
||||
load_file_data(arena, ¶ms->ask.aad, filename, bltestBinary);
|
||||
case bltestDES_CBC:
|
||||
|
@ -3753,7 +3892,8 @@ print_usage:
|
|||
/* Set up an encryption key. */
|
||||
keysize = 0;
|
||||
file = NULL;
|
||||
if (is_symmkeyCipher(cipherInfo->mode)) {
|
||||
if (is_symmkeyCipher(cipherInfo->mode) ||
|
||||
is_aeadCipher(cipherInfo->mode)) {
|
||||
char *keystr = NULL; /* if key is on command line */
|
||||
if (bltest.options[opt_Key].activated) {
|
||||
if (bltest.options[opt_CmdLine].activated) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
PQRSタチツテトナニヌ
|
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
0xqNNGSOYNt7hq+8U+9+wqSt7VEpbgj+qeK1pzbuYtY9vqRejKlnEoL6+2naknKLGnHeCp4GCykF1qW2fs07NpLdvX8td4uMmAOu4ygJG1j6syTk+tZ1lFWFgItIMde8P/Te8I5Lep3ldtJlhs7GS2EWGuELWU8J4mp+kC7L0GAGkQ==
|
|
@ -0,0 +1 @@
|
|||
ZKCGFXWGGvRg8GLHm+ZDvV6AXP00XPOJ8QhnCsdsjLJMbPwYdV1D7qCe6U44LSawvbe3PDIbAQDU8Dt/NViUzzMvgw5xC5fOmMioSr0LlIEUrRduAI0zvWD5grH/N8hVl5egbvTw72HBhjJOKzUGODYGkHtqfAKw+fYVe1PIZ+S5Fmx2e4BNRqWbUhbN56TpkEDFpAQzIl7igqGwoGxSPq9FNNf4P6EVWwBHcYy8VGoNBysEs1ZO6htCInP1SCcaC7IxYFP6dpkZVevWMVlDTs67TkZtrloQc6ZydicJehBJ5hfZHTYQlPpo8P93mHEwMFvqui7aBN+Ze3FNbG8sKaatXLQCKwJwm+6tnWeJDLsiOSM2/qGFHzg=
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
≠ヤ<EFBFBD>㊧炎旧克署葬灯楓利劒屆撼<EFBFBD>
|
|
@ -0,0 +1 @@
|
|||
<1C>@<40><>Uӊ<55>3<EFBFBD><33><04><><EFBFBD>G9<17>@+<2B> <09><>\<5C> pu<70>
|
|
@ -0,0 +1 @@
|
|||
2
|
|
@ -0,0 +1 @@
|
|||
Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.
|
|
@ -0,0 +1 @@
|
|||
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as /“work in progress./”
|
|
@ -443,6 +443,10 @@ const char * V2CipherString(int cs_int)
|
|||
case 0x00C02C: cs_str = "TLS/ECDHE-ECDSA/AES256-GCM/SHA384"; break;
|
||||
case 0x00C02F: cs_str = "TLS/ECDHE-RSA/AES128-GCM/SHA256"; break;
|
||||
|
||||
case 0x00CCA8: cs_str = "TLS/ECDHE-RSA/CHACHA20-POLY1305/SHA256"; break;
|
||||
case 0x00CCA9: cs_str = "TLS/ECDHE-ECDSA/CHACHA20-POLY1305/SHA256"; break;
|
||||
case 0x00CCAA: cs_str = "TLS/DHE-RSA/CHACHA20-POLY1305/SHA256"; break;
|
||||
|
||||
case 0x00FEFF: cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA"; break;
|
||||
case 0x00FEFE: cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA"; break;
|
||||
case 0x00FFE1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
ifndef CC_IS_GCC
|
||||
CC_IS_GCC := $(shell $(CC) -x c -E -Wall -Werror /dev/null >/dev/null 2>&1 && echo 1)
|
||||
# Export CC_IS_GCC to save a shell invocation when recursing.
|
||||
export CC_IS_GCC
|
||||
endif
|
||||
|
||||
|
@ -16,9 +17,18 @@ ifndef CC_NAME
|
|||
else
|
||||
CC_NAME := $(notdir $(CC))
|
||||
endif
|
||||
# Export CC_NAME to save a shell invocation when recursing.
|
||||
export CC_NAME
|
||||
endif
|
||||
|
||||
ifndef GCC_VERSION
|
||||
ifeq (1,$(CC_IS_GCC))
|
||||
GCC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion || echo x.x.x))
|
||||
# Export GCC_VERSION to save a shell invocation when recursing.
|
||||
export GCC_VERSION
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef WARNING_CFLAGS
|
||||
ifneq (1,$(CC_IS_GCC))
|
||||
WARNING_CFLAGS = $(NULL)
|
||||
|
@ -55,18 +65,17 @@ ifndef WARNING_CFLAGS
|
|||
ifeq ($(CC_NAME),clang)
|
||||
# Clang reports its version as an older gcc, but it's OK
|
||||
NSS_ENABLE_WERROR = 1
|
||||
else
|
||||
CC_VERSION := $(subst ., ,$(shell $(CC) -dumpversion))
|
||||
ifneq (,$(filter 4.8 4.9,$(word 1,$(CC_VERSION)).$(word 2,$(CC_VERSION))))
|
||||
else ifeq ($(CC_NAME),gcc)
|
||||
ifneq (,$(filter 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
NSS_ENABLE_WERROR = 1
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(CC_VERSION))))
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
NSS_ENABLE_WERROR = 1
|
||||
endif
|
||||
ifndef NSS_ENABLE_WERROR
|
||||
$(warning Unable to find gcc 4.8 or greater, disabling -Werror)
|
||||
NSS_ENABLE_WERROR = 0
|
||||
endif
|
||||
endif
|
||||
ifndef NSS_ENABLE_WERROR
|
||||
$(warning Unable to find gcc 4.8 or greater, disabling -Werror)
|
||||
NSS_ENABLE_WERROR = 0
|
||||
endif
|
||||
endif
|
||||
endif #ndef NSS_ENABLE_WERROR
|
||||
|
|
|
@ -166,6 +166,10 @@ ifdef NSS_DISABLE_DBM
|
|||
DEFINES += -DNSS_DISABLE_DBM
|
||||
endif
|
||||
|
||||
ifdef NSS_DISABLE_CHACHAPOLY
|
||||
DEFINES += -DNSS_DISABLE_CHACHAPOLY
|
||||
endif
|
||||
|
||||
ifdef NSS_PKIX_NO_LDAP
|
||||
DEFINES += -DNSS_PKIX_NO_LDAP
|
||||
endif
|
||||
|
|
|
@ -10,3 +10,4 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ DEPTH = ../..
|
|||
MODULE = nss
|
||||
|
||||
CPPSRCS = \
|
||||
pk11_chacha20poly1305_unittest.cc \
|
||||
pk11_pbkdf2_unittest.cc \
|
||||
pk11_prf_unittest.cc \
|
||||
pk11_rsapss_unittest.cc \
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nss.h"
|
||||
#include "pk11pub.h"
|
||||
#include "sechash.h"
|
||||
#include <memory>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "scoped_ptrs.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
// ChaCha20/Poly1305 Test Vector 1, RFC 7539
|
||||
// <http://tools.ietf.org/html/rfc7539#section-2.8.2>
|
||||
const uint8_t kTestVector1Data[] = {
|
||||
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65,
|
||||
0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39,
|
||||
0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64,
|
||||
0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, 0x6e,
|
||||
0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f,
|
||||
0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c,
|
||||
0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f,
|
||||
0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e
|
||||
};
|
||||
const uint8_t kTestVector1AAD[] = {
|
||||
0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7
|
||||
};
|
||||
const uint8_t kTestVector1Key[] = {
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c,
|
||||
0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
|
||||
0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f
|
||||
};
|
||||
const uint8_t kTestVector1IV[] = {
|
||||
0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
|
||||
};
|
||||
const uint8_t kTestVector1CT[] = {
|
||||
0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53,
|
||||
0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2,
|
||||
0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67,
|
||||
0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, 0x1a, 0x71, 0xde, 0x0a,
|
||||
0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, 0x92,
|
||||
0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09,
|
||||
0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80,
|
||||
0x8b, 0x48, 0x31, 0xd7, 0xbc, 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d,
|
||||
0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16, 0x1a, 0xe1, 0x0b,
|
||||
0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91
|
||||
};
|
||||
|
||||
// ChaCha20/Poly1305 Test Vector 2, RFC 7539
|
||||
// <http://tools.ietf.org/html/rfc7539#appendix-A.5>
|
||||
const uint8_t kTestVector2Data[] = {
|
||||
0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66,
|
||||
0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x64, 0x72, 0x61, 0x66, 0x74, 0x20,
|
||||
0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c,
|
||||
0x69, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x78, 0x69,
|
||||
0x6d, 0x75, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x69, 0x78, 0x20, 0x6d, 0x6f,
|
||||
0x6e, 0x74, 0x68, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20,
|
||||
0x62, 0x65, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x72,
|
||||
0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6f,
|
||||
0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f,
|
||||
0x74, 0x68, 0x65, 0x72, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x2e, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x61, 0x70, 0x70,
|
||||
0x72, 0x6f, 0x70, 0x72, 0x69, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75,
|
||||
0x73, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44,
|
||||
0x72, 0x61, 0x66, 0x74, 0x73, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x66, 0x65,
|
||||
0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
|
||||
0x6c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x69, 0x74, 0x65, 0x20,
|
||||
0x74, 0x68, 0x65, 0x6d, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68,
|
||||
0x61, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x2f, 0xe2, 0x80, 0x9c, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73,
|
||||
0x2e, 0x2f, 0xe2, 0x80, 0x9d
|
||||
};
|
||||
const uint8_t kTestVector2AAD[] = {
|
||||
0xf3, 0x33, 0x88, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x91
|
||||
};
|
||||
const uint8_t kTestVector2Key[] = {
|
||||
0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, 0xf3, 0x33, 0x88, 0x86, 0x04,
|
||||
0xf6, 0xb5, 0xf0, 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, 0x9d, 0xca,
|
||||
0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
|
||||
};
|
||||
const uint8_t kTestVector2IV[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
|
||||
};
|
||||
const uint8_t kTestVector2CT[] = {
|
||||
0x64, 0xa0, 0x86, 0x15, 0x75, 0x86, 0x1a, 0xf4, 0x60, 0xf0, 0x62, 0xc7, 0x9b,
|
||||
0xe6, 0x43, 0xbd, 0x5e, 0x80, 0x5c, 0xfd, 0x34, 0x5c, 0xf3, 0x89, 0xf1, 0x08,
|
||||
0x67, 0x0a, 0xc7, 0x6c, 0x8c, 0xb2, 0x4c, 0x6c, 0xfc, 0x18, 0x75, 0x5d, 0x43,
|
||||
0xee, 0xa0, 0x9e, 0xe9, 0x4e, 0x38, 0x2d, 0x26, 0xb0, 0xbd, 0xb7, 0xb7, 0x3c,
|
||||
0x32, 0x1b, 0x01, 0x00, 0xd4, 0xf0, 0x3b, 0x7f, 0x35, 0x58, 0x94, 0xcf, 0x33,
|
||||
0x2f, 0x83, 0x0e, 0x71, 0x0b, 0x97, 0xce, 0x98, 0xc8, 0xa8, 0x4a, 0xbd, 0x0b,
|
||||
0x94, 0x81, 0x14, 0xad, 0x17, 0x6e, 0x00, 0x8d, 0x33, 0xbd, 0x60, 0xf9, 0x82,
|
||||
0xb1, 0xff, 0x37, 0xc8, 0x55, 0x97, 0x97, 0xa0, 0x6e, 0xf4, 0xf0, 0xef, 0x61,
|
||||
0xc1, 0x86, 0x32, 0x4e, 0x2b, 0x35, 0x06, 0x38, 0x36, 0x06, 0x90, 0x7b, 0x6a,
|
||||
0x7c, 0x02, 0xb0, 0xf9, 0xf6, 0x15, 0x7b, 0x53, 0xc8, 0x67, 0xe4, 0xb9, 0x16,
|
||||
0x6c, 0x76, 0x7b, 0x80, 0x4d, 0x46, 0xa5, 0x9b, 0x52, 0x16, 0xcd, 0xe7, 0xa4,
|
||||
0xe9, 0x90, 0x40, 0xc5, 0xa4, 0x04, 0x33, 0x22, 0x5e, 0xe2, 0x82, 0xa1, 0xb0,
|
||||
0xa0, 0x6c, 0x52, 0x3e, 0xaf, 0x45, 0x34, 0xd7, 0xf8, 0x3f, 0xa1, 0x15, 0x5b,
|
||||
0x00, 0x47, 0x71, 0x8c, 0xbc, 0x54, 0x6a, 0x0d, 0x07, 0x2b, 0x04, 0xb3, 0x56,
|
||||
0x4e, 0xea, 0x1b, 0x42, 0x22, 0x73, 0xf5, 0x48, 0x27, 0x1a, 0x0b, 0xb2, 0x31,
|
||||
0x60, 0x53, 0xfa, 0x76, 0x99, 0x19, 0x55, 0xeb, 0xd6, 0x31, 0x59, 0x43, 0x4e,
|
||||
0xce, 0xbb, 0x4e, 0x46, 0x6d, 0xae, 0x5a, 0x10, 0x73, 0xa6, 0x72, 0x76, 0x27,
|
||||
0x09, 0x7a, 0x10, 0x49, 0xe6, 0x17, 0xd9, 0x1d, 0x36, 0x10, 0x94, 0xfa, 0x68,
|
||||
0xf0, 0xff, 0x77, 0x98, 0x71, 0x30, 0x30, 0x5b, 0xea, 0xba, 0x2e, 0xda, 0x04,
|
||||
0xdf, 0x99, 0x7b, 0x71, 0x4d, 0x6c, 0x6f, 0x2c, 0x29, 0xa6, 0xad, 0x5c, 0xb4,
|
||||
0x02, 0x2b, 0x02, 0x70, 0x9b, 0xee, 0xad, 0x9d, 0x67, 0x89, 0x0c, 0xbb, 0x22,
|
||||
0x39, 0x23, 0x36, 0xfe, 0xa1, 0x85, 0x1f, 0x38
|
||||
};
|
||||
|
||||
class Pkcs11ChaCha20Poly1305Test : public ::testing::Test {
|
||||
public:
|
||||
void EncryptDecrypt(PK11SymKey* symKey,
|
||||
const uint8_t* data, size_t data_len,
|
||||
const uint8_t* aad, size_t aad_len,
|
||||
const uint8_t* iv, size_t iv_len,
|
||||
const uint8_t* ct = nullptr, size_t ct_len = 0)
|
||||
{
|
||||
// Prepare AEAD params.
|
||||
CK_NSS_AEAD_PARAMS aead_params;
|
||||
aead_params.pNonce = toUcharPtr(iv);
|
||||
aead_params.ulNonceLen = iv_len;
|
||||
aead_params.pAAD = toUcharPtr(aad);
|
||||
aead_params.ulAADLen = aad_len;
|
||||
aead_params.ulTagLen = 16;
|
||||
|
||||
SECItem params = { siBuffer, reinterpret_cast<unsigned char*>(&aead_params),
|
||||
sizeof(aead_params) };
|
||||
|
||||
// Encrypt.
|
||||
unsigned int outputLen = 0;
|
||||
std::vector<uint8_t> output(data_len + aead_params.ulTagLen);
|
||||
SECStatus rv = PK11_Encrypt(symKey, mech, ¶ms, &output[0], &outputLen,
|
||||
output.size(), data, data_len);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Check ciphertext and tag.
|
||||
if (ct) {
|
||||
EXPECT_TRUE(!memcmp(ct, &output[0], outputLen));
|
||||
}
|
||||
|
||||
// Decrypt.
|
||||
unsigned int decryptedLen = 0;
|
||||
std::vector<uint8_t> decrypted(data_len);
|
||||
rv = PK11_Decrypt(symKey, mech, ¶ms, &decrypted[0], &decryptedLen,
|
||||
decrypted.size(), &output[0], outputLen);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Check the plaintext.
|
||||
EXPECT_TRUE(!memcmp(data, &decrypted[0], decryptedLen));
|
||||
|
||||
// Decrypt with bogus data.
|
||||
{
|
||||
std::vector<uint8_t> bogusCiphertext(output);
|
||||
bogusCiphertext[0] ^= 0xff;
|
||||
rv = PK11_Decrypt(symKey, mech, ¶ms, &decrypted[0], &decryptedLen,
|
||||
decrypted.size(), &bogusCiphertext[0], outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
||||
// Decrypt with bogus tag.
|
||||
{
|
||||
std::vector<uint8_t> bogusTag(output);
|
||||
bogusTag[outputLen - 1] ^= 0xff;
|
||||
rv = PK11_Decrypt(symKey, mech, ¶ms, &decrypted[0], &decryptedLen,
|
||||
decrypted.size(), &bogusTag[0], outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
||||
// Decrypt with bogus IV.
|
||||
{
|
||||
SECItem bogusParams(params);
|
||||
CK_NSS_AEAD_PARAMS bogusAeadParams(aead_params);
|
||||
bogusParams.data = reinterpret_cast<unsigned char*>(&bogusAeadParams);
|
||||
|
||||
std::vector<uint8_t> bogusIV(iv, iv + iv_len);
|
||||
bogusAeadParams.pNonce = toUcharPtr(&bogusIV[0]);
|
||||
bogusIV[0] ^= 0xff;
|
||||
|
||||
rv = PK11_Decrypt(symKey, mech, &bogusParams, &decrypted[0],
|
||||
&decryptedLen, data_len, &output[0], outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
||||
// Decrypt with bogus additional data.
|
||||
{
|
||||
SECItem bogusParams(params);
|
||||
CK_NSS_AEAD_PARAMS bogusAeadParams(aead_params);
|
||||
bogusParams.data = reinterpret_cast<unsigned char*>(&bogusAeadParams);
|
||||
|
||||
std::vector<uint8_t> bogusAAD(aad, aad + aad_len);
|
||||
bogusAeadParams.pAAD = toUcharPtr(&bogusAAD[0]);
|
||||
bogusAAD[0] ^= 0xff;
|
||||
|
||||
rv = PK11_Decrypt(symKey, mech, &bogusParams, &decrypted[0],
|
||||
&decryptedLen, data_len, &output[0], outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
void EncryptDecrypt(const uint8_t* key, size_t key_len,
|
||||
const uint8_t* data, size_t data_len,
|
||||
const uint8_t* aad, size_t aad_len,
|
||||
const uint8_t* iv, size_t iv_len,
|
||||
const uint8_t* ct, size_t ct_len)
|
||||
{
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
SECItem keyItem = { siBuffer, toUcharPtr(key),
|
||||
static_cast<unsigned int>(key_len) };
|
||||
|
||||
// Import key.
|
||||
ScopedPK11SymKey symKey(PK11_ImportSymKey(slot.get(), mech,
|
||||
PK11_OriginUnwrap, CKA_ENCRYPT,
|
||||
&keyItem, nullptr));
|
||||
EXPECT_TRUE(!!symKey);
|
||||
|
||||
// Check.
|
||||
EncryptDecrypt(symKey.get(), data, data_len, aad, aad_len, iv, iv_len, ct,
|
||||
ct_len);
|
||||
}
|
||||
|
||||
protected:
|
||||
CK_MECHANISM_TYPE mech = CKM_NSS_CHACHA20_POLY1305;
|
||||
|
||||
unsigned char* toUcharPtr(const uint8_t* v) {
|
||||
return const_cast<unsigned char*>(
|
||||
static_cast<const unsigned char*>(v));
|
||||
}
|
||||
};
|
||||
|
||||
#define ENCRYPT_DECRYPT(v) \
|
||||
EncryptDecrypt(v ## Key, sizeof(v ## Key), \
|
||||
v ## Data, sizeof(v ## Data), \
|
||||
v ## AAD, sizeof(v ## AAD), \
|
||||
v ## IV, sizeof(v ## IV), \
|
||||
v ## CT, sizeof(v ## CT));
|
||||
|
||||
TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateEncryptDecrypt) {
|
||||
// Generate a random key.
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
ScopedPK11SymKey symKey(PK11_KeyGen(slot.get(), mech, nullptr, 32, nullptr));
|
||||
EXPECT_TRUE(!!symKey);
|
||||
|
||||
// Generate random data.
|
||||
std::vector<uint8_t> data(512);
|
||||
SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), &data[0], data.size());
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Generate random AAD.
|
||||
std::vector<uint8_t> aad(16);
|
||||
rv = PK11_GenerateRandomOnSlot(slot.get(), &aad[0], aad.size());
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Generate random IV.
|
||||
std::vector<uint8_t> iv(12);
|
||||
rv = PK11_GenerateRandomOnSlot(slot.get(), &iv[0], iv.size());
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Check.
|
||||
EncryptDecrypt(symKey.get(), &data[0], data.size(), &aad[0], aad.size(),
|
||||
&iv[0], iv.size());
|
||||
}
|
||||
|
||||
TEST_F(Pkcs11ChaCha20Poly1305Test, CheckTestVector1) {
|
||||
ENCRYPT_DECRYPT(kTestVector1);
|
||||
}
|
||||
|
||||
TEST_F(Pkcs11ChaCha20Poly1305Test, CheckTestVector2) {
|
||||
ENCRYPT_DECRYPT(kTestVector2);
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
|
@ -24,3 +24,24 @@ SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd)
|
|||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
SSLInt_DetermineKEABits(PRUint16 serverKeyBits, SSLAuthType authAlgorithm) {
|
||||
// For ECDSA authentication we expect a curve for key exchange with the
|
||||
// same strength as the one used for the certificate's signature.
|
||||
if (authAlgorithm == ssl_auth_ecdsa) {
|
||||
return serverKeyBits;
|
||||
}
|
||||
|
||||
PORT_Assert(authAlgorithm == ssl_auth_rsa);
|
||||
PRUint32 minKeaBits;
|
||||
#ifdef NSS_ECC_MORE_THAN_SUITE_B
|
||||
// P-192 is the smallest curve we want to use.
|
||||
minKeaBits = 192U;
|
||||
#else
|
||||
// P-256 is the smallest supported curve.
|
||||
minKeaBits = 256U;
|
||||
#endif
|
||||
|
||||
return PR_MAX(SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyBits), minKeaBits);
|
||||
}
|
||||
|
|
|
@ -9,9 +9,13 @@
|
|||
|
||||
#include "prio.h"
|
||||
#include "seccomon.h"
|
||||
#include "sslt.h"
|
||||
|
||||
SECStatus SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd);
|
||||
|
||||
PRUint32 SSLInt_DetermineKEABits(PRUint16 serverKeyBits,
|
||||
SSLAuthType authAlgorithm);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -108,6 +108,29 @@ class TlsServerKeyExchangeEcdhe {
|
|||
DataBuffer public_key_;
|
||||
};
|
||||
|
||||
class TlsChaCha20Poly1305Test : public TlsConnectTls12 {
|
||||
public:
|
||||
void ConnectSendReceive(PRUint32 cipher_suite)
|
||||
{
|
||||
// Disable all ciphers.
|
||||
client_->DisableCiphersByKeyExchange(ssl_kea_rsa);
|
||||
client_->DisableCiphersByKeyExchange(ssl_kea_dh);
|
||||
client_->DisableCiphersByKeyExchange(ssl_kea_ecdh);
|
||||
|
||||
// Re-enable ChaCha20/Poly1305.
|
||||
SECStatus rv = SSL_CipherPrefSet(client_->ssl_fd(), cipher_suite, PR_TRUE);
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
// Check that we used the right cipher suite.
|
||||
int16_t actual, expected = static_cast<int16_t>(cipher_suite);
|
||||
EXPECT_TRUE(client_->cipher_suite(&actual) && actual == expected);
|
||||
EXPECT_TRUE(server_->cipher_suite(&actual) && actual == expected);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectGeneric, SetupOnly) {}
|
||||
|
||||
TEST_P(TlsConnectGeneric, Connect) {
|
||||
|
@ -542,6 +565,19 @@ TEST_P(TlsConnectGeneric, ConnectSendReceive) {
|
|||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsChaCha20Poly1305Test, SendReceiveChaCha20Poly1305DheRsa) {
|
||||
ConnectSendReceive(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
|
||||
}
|
||||
|
||||
TEST_P(TlsChaCha20Poly1305Test, SendReceiveChaCha20Poly1305EcdheRsa) {
|
||||
ConnectSendReceive(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
|
||||
}
|
||||
|
||||
TEST_P(TlsChaCha20Poly1305Test, SendReceiveChaCha20Poly1305EcdheEcdsa) {
|
||||
ResetEcdsa();
|
||||
ConnectSendReceive(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
|
||||
}
|
||||
|
||||
// The next two tests takes advantage of the fact that we
|
||||
// automatically read the first 1024 bytes, so if
|
||||
// we provide 1200 bytes, they overrun the read buffer
|
||||
|
@ -946,6 +982,8 @@ INSTANTIATE_TEST_CASE_P(VersionsDatagram, TlsConnectDatagram,
|
|||
TlsConnectTestBase::kTlsV11V12);
|
||||
INSTANTIATE_TEST_CASE_P(Variants12, TlsConnectTls12,
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
INSTANTIATE_TEST_CASE_P(Variants12, TlsChaCha20Poly1305Test,
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
INSTANTIATE_TEST_CASE_P(Pre12Stream, TlsConnectPre12,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
#include "keyhi.h"
|
||||
#include "databuffer.h"
|
||||
|
||||
extern "C" {
|
||||
// This is not something that should make you happy.
|
||||
#include "libssl_internals.h"
|
||||
}
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
@ -195,6 +200,7 @@ void TlsAgent::DisableCiphersByKeyExchange(SSLKEAType kea) {
|
|||
SECStatus rv = SSL_GetCipherSuiteInfo(SSL_ImplementedCiphers[i],
|
||||
&csinfo, sizeof(csinfo));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(sizeof(csinfo), csinfo.length);
|
||||
|
||||
if (csinfo.keaType == kea) {
|
||||
rv = SSL_CipherPrefSet(ssl_fd_, SSL_ImplementedCiphers[i], PR_FALSE);
|
||||
|
@ -291,9 +297,12 @@ void TlsAgent::CheckKEAType(SSLKEAType type) const {
|
|||
EXPECT_EQ(STATE_CONNECTED, state_);
|
||||
EXPECT_EQ(type, csinfo_.keaType);
|
||||
|
||||
PRUint32 ecKEAKeyBits = SSLInt_DetermineKEABits(server_key_bits_,
|
||||
csinfo_.authAlgorithm);
|
||||
|
||||
switch (type) {
|
||||
case ssl_kea_ecdh:
|
||||
EXPECT_EQ(256U, info_.keaKeyBits);
|
||||
EXPECT_EQ(ecKEAKeyBits, info_.keaKeyBits);
|
||||
break;
|
||||
case ssl_kea_dh:
|
||||
EXPECT_EQ(2048U, info_.keaKeyBits);
|
||||
|
@ -378,6 +387,7 @@ void TlsAgent::CheckPreliminaryInfo() {
|
|||
SSLPreliminaryChannelInfo info;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_GetPreliminaryChannelInfo(ssl_fd_, &info, sizeof(info)));
|
||||
EXPECT_EQ(sizeof(info), info.length);
|
||||
EXPECT_TRUE(info.valuesSet & ssl_preinfo_version);
|
||||
EXPECT_TRUE(info.valuesSet & ssl_preinfo_cipher_suite);
|
||||
|
||||
|
@ -423,6 +433,7 @@ void TlsAgent::Connected() {
|
|||
|
||||
SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &info_, sizeof(info_));
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(sizeof(info_), info_.length);
|
||||
|
||||
// Preliminary values are exposed through callbacks during the handshake.
|
||||
// If either expected values were set or the callbacks were called, check
|
||||
|
@ -432,6 +443,7 @@ void TlsAgent::Connected() {
|
|||
|
||||
rv = SSL_GetCipherSuiteInfo(info_.cipherSuite, &csinfo_, sizeof(csinfo_));
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(sizeof(csinfo_), csinfo_.length);
|
||||
|
||||
SetState(STATE_CONNECTED);
|
||||
}
|
||||
|
|
|
@ -482,6 +482,33 @@ ifndef NSS_DISABLE_ECC
|
|||
endif
|
||||
endif
|
||||
|
||||
# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
|
||||
# in GCC 4.6.0.
|
||||
ifeq ($(CC_NAME),clang)
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
else ifeq (1,$(CC_IS_GCC))
|
||||
ifneq (,$(filter 4.6 4.7 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
endif
|
||||
ifeq (,$(filter 0 1 2 3 4,$(word 1,$(GCC_VERSION))))
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NSS_DISABLE_CHACHAPOLY
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
ifdef HAVE_INT128_SUPPORT
|
||||
EXTRA_SRCS += poly1305-donna-x64-sse2-incremental-source.c
|
||||
else
|
||||
EXTRA_SRCS += poly1305.c
|
||||
endif
|
||||
EXTRA_SRCS += chacha20_vec.c
|
||||
else
|
||||
EXTRA_SRCS += poly1305.c
|
||||
EXTRA_SRCS += chacha20.c
|
||||
endif # x86_64
|
||||
endif # NSS_DISABLE_CHACHAPOLY
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
|
|
@ -986,6 +986,35 @@ Camellia_Decrypt(CamelliaContext *cx, unsigned char *output,
|
|||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** ChaCha20+Poly1305 AEAD
|
||||
*/
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
unsigned int tagLen);
|
||||
|
||||
extern ChaCha20Poly1305Context *ChaCha20Poly1305_CreateContext(
|
||||
const unsigned char *key, unsigned int keyLen, unsigned int tagLen);
|
||||
|
||||
extern void ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx,
|
||||
PRBool freeit);
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_Seal(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
extern SECStatus ChaCha20Poly1305_Open(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
|
|
|
@ -222,6 +222,7 @@ struct SHA256ContextStr ;
|
|||
struct SHA512ContextStr ;
|
||||
struct AESKeyWrapContextStr ;
|
||||
struct SEEDContextStr ;
|
||||
struct ChaCha20Poly1305ContextStr;
|
||||
|
||||
typedef struct DESContextStr DESContext;
|
||||
typedef struct RC2ContextStr RC2Context;
|
||||
|
@ -240,6 +241,7 @@ typedef struct SHA512ContextStr SHA512Context;
|
|||
typedef struct SHA512ContextStr SHA384Context;
|
||||
typedef struct AESKeyWrapContextStr AESKeyWrapContext;
|
||||
typedef struct SEEDContextStr SEEDContext;
|
||||
typedef struct ChaCha20Poly1305ContextStr ChaCha20Poly1305Context;
|
||||
|
||||
/***************************************************************************
|
||||
** RSA Public and Private Key structures
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* Adopted from the public domain code in NaCl by djb. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "secport.h"
|
||||
#include "chacha20.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma intrinsic(_lrotl)
|
||||
#define ROTL32(x, n) _lrotl(x, n)
|
||||
#else
|
||||
#define ROTL32(x, n) ((x << n) | (x >> ((8 * sizeof x) - n)))
|
||||
#endif
|
||||
|
||||
#define ROTATE(v, c) ROTL32((v), (c))
|
||||
|
||||
#define U32TO8_LITTLE(p, v) \
|
||||
{ (p)[0] = ((v) ) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \
|
||||
(p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; }
|
||||
#define U8TO32_LITTLE(p) \
|
||||
(((PRUint32)((p)[0]) ) | ((PRUint32)((p)[1]) << 8) | \
|
||||
((PRUint32)((p)[2]) << 16) | ((PRUint32)((p)[3]) << 24))
|
||||
|
||||
#define QUARTERROUND(x, a, b, c, d) \
|
||||
x[a] = x[a] + x[b]; x[d] = ROTATE(x[d] ^ x[a], 16); \
|
||||
x[c] = x[c] + x[d]; x[b] = ROTATE(x[b] ^ x[c], 12); \
|
||||
x[a] = x[a] + x[b]; x[d] = ROTATE(x[d] ^ x[a], 8); \
|
||||
x[c] = x[c] + x[d]; x[b] = ROTATE(x[b] ^ x[c], 7);
|
||||
|
||||
static void
|
||||
ChaChaCore(unsigned char output[64], const PRUint32 input[16], int num_rounds)
|
||||
{
|
||||
PRUint32 x[16];
|
||||
int i;
|
||||
|
||||
PORT_Memcpy(x, input, sizeof(PRUint32) * 16);
|
||||
for (i = num_rounds; i > 0; i -= 2) {
|
||||
QUARTERROUND(x, 0, 4, 8, 12)
|
||||
QUARTERROUND(x, 1, 5, 9, 13)
|
||||
QUARTERROUND(x, 2, 6, 10, 14)
|
||||
QUARTERROUND(x, 3, 7, 11, 15)
|
||||
QUARTERROUND(x, 0, 5, 10, 15)
|
||||
QUARTERROUND(x, 1, 6, 11, 12)
|
||||
QUARTERROUND(x, 2, 7, 8, 13)
|
||||
QUARTERROUND(x, 3, 4, 9, 14)
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
x[i] = x[i] + input[i];
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
U32TO8_LITTLE(output + 4 * i, x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned char sigma[16] = "expand 32-byte k";
|
||||
|
||||
void
|
||||
ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inLen,
|
||||
const unsigned char key[32], const unsigned char nonce[12],
|
||||
uint32_t counter)
|
||||
{
|
||||
unsigned char block[64];
|
||||
PRUint32 input[16];
|
||||
unsigned int i;
|
||||
|
||||
input[4] = U8TO32_LITTLE(key + 0);
|
||||
input[5] = U8TO32_LITTLE(key + 4);
|
||||
input[6] = U8TO32_LITTLE(key + 8);
|
||||
input[7] = U8TO32_LITTLE(key + 12);
|
||||
|
||||
input[8] = U8TO32_LITTLE(key + 16);
|
||||
input[9] = U8TO32_LITTLE(key + 20);
|
||||
input[10] = U8TO32_LITTLE(key + 24);
|
||||
input[11] = U8TO32_LITTLE(key + 28);
|
||||
|
||||
input[0] = U8TO32_LITTLE(sigma + 0);
|
||||
input[1] = U8TO32_LITTLE(sigma + 4);
|
||||
input[2] = U8TO32_LITTLE(sigma + 8);
|
||||
input[3] = U8TO32_LITTLE(sigma + 12);
|
||||
|
||||
input[12] = counter;
|
||||
input[13] = U8TO32_LITTLE(nonce + 0);
|
||||
input[14] = U8TO32_LITTLE(nonce + 4);
|
||||
input[15] = U8TO32_LITTLE(nonce + 8);
|
||||
|
||||
while (inLen >= 64) {
|
||||
ChaChaCore(block, input, 20);
|
||||
for (i = 0; i < 64; i++) {
|
||||
out[i] = in[i] ^ block[i];
|
||||
}
|
||||
|
||||
input[12]++;
|
||||
inLen -= 64;
|
||||
in += 64;
|
||||
out += 64;
|
||||
}
|
||||
|
||||
if (inLen > 0) {
|
||||
ChaChaCore(block, input, 20);
|
||||
for (i = 0; i < inLen; i++) {
|
||||
out[i] = in[i] ^ block[i];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* chacha20.h - header file for ChaCha20 implementation.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FREEBL_CHACHA20_H_
|
||||
#define FREEBL_CHACHA20_H_
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
#include "prtypes.h"
|
||||
typedef PRUint32 uint32_t;
|
||||
typedef PRUint64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* ChaCha20XOR encrypts |inLen| bytes from |in| with the given key and
|
||||
* nonce and writes the result to |out|, which may be equal to |in|. The
|
||||
* initial block counter is specified by |counter|. */
|
||||
extern void ChaCha20XOR(unsigned char *out, const unsigned char *in,
|
||||
unsigned int inLen, const unsigned char key[32],
|
||||
const unsigned char nonce[12], uint32_t counter);
|
||||
|
||||
#endif /* FREEBL_CHACHA20_H_ */
|
|
@ -0,0 +1,278 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This implementation is by Ted Krovetz and was submitted to SUPERCOP and
|
||||
* marked as public domain. It was been altered to allow for non-aligned inputs
|
||||
* and to allow the block counter to be passed in specifically. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "chacha20.h"
|
||||
|
||||
#ifndef CHACHA_RNDS
|
||||
#define CHACHA_RNDS 20 /* 8 (high speed), 20 (conservative), 12 (middle) */
|
||||
#endif
|
||||
|
||||
/* Architecture-neutral way to specify 16-byte vector of ints */
|
||||
typedef unsigned vec __attribute__ ((vector_size (16)));
|
||||
|
||||
/* This implementation is designed for Neon, SSE and AltiVec machines. The
|
||||
* following specify how to do certain vector operations efficiently on
|
||||
* each architecture, using intrinsics.
|
||||
* This implementation supports parallel processing of multiple blocks,
|
||||
* including potentially using general-purpose registers.
|
||||
*/
|
||||
#if __ARM_NEON__
|
||||
#include <arm_neon.h>
|
||||
#define GPR_TOO 1
|
||||
#define VBPI 2
|
||||
#define ONE (vec)vsetq_lane_u32(1,vdupq_n_u32(0),0)
|
||||
#define LOAD(m) (vec)(*((vec*)(m)))
|
||||
#define STORE(m,r) (*((vec*)(m))) = (r)
|
||||
#define ROTV1(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,1)
|
||||
#define ROTV2(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,2)
|
||||
#define ROTV3(x) (vec)vextq_u32((uint32x4_t)x,(uint32x4_t)x,3)
|
||||
#define ROTW16(x) (vec)vrev32q_u16((uint16x8_t)x)
|
||||
#if __clang__
|
||||
#define ROTW7(x) (x << ((vec){ 7, 7, 7, 7})) ^ (x >> ((vec){25,25,25,25}))
|
||||
#define ROTW8(x) (x << ((vec){ 8, 8, 8, 8})) ^ (x >> ((vec){24,24,24,24}))
|
||||
#define ROTW12(x) (x << ((vec){12,12,12,12})) ^ (x >> ((vec){20,20,20,20}))
|
||||
#else
|
||||
#define ROTW7(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,7),(uint32x4_t)x,25)
|
||||
#define ROTW8(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,8),(uint32x4_t)x,24)
|
||||
#define ROTW12(x) (vec)vsriq_n_u32(vshlq_n_u32((uint32x4_t)x,12),(uint32x4_t)x,20)
|
||||
#endif
|
||||
#elif __SSE2__
|
||||
#include <emmintrin.h>
|
||||
#define GPR_TOO 0
|
||||
#if __clang__
|
||||
#define VBPI 4
|
||||
#else
|
||||
#define VBPI 3
|
||||
#endif
|
||||
#define ONE (vec)_mm_set_epi32(0,0,0,1)
|
||||
#define LOAD(m) (vec)_mm_loadu_si128((__m128i*)(m))
|
||||
#define STORE(m,r) _mm_storeu_si128((__m128i*)(m), (__m128i) (r))
|
||||
#define ROTV1(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(0,3,2,1))
|
||||
#define ROTV2(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(1,0,3,2))
|
||||
#define ROTV3(x) (vec)_mm_shuffle_epi32((__m128i)x,_MM_SHUFFLE(2,1,0,3))
|
||||
#define ROTW7(x) (vec)(_mm_slli_epi32((__m128i)x, 7) ^ _mm_srli_epi32((__m128i)x,25))
|
||||
#define ROTW12(x) (vec)(_mm_slli_epi32((__m128i)x,12) ^ _mm_srli_epi32((__m128i)x,20))
|
||||
#if __SSSE3__
|
||||
#include <tmmintrin.h>
|
||||
#define ROTW8(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(14,13,12,15,10,9,8,11,6,5,4,7,2,1,0,3))
|
||||
#define ROTW16(x) (vec)_mm_shuffle_epi8((__m128i)x,_mm_set_epi8(13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2))
|
||||
#else
|
||||
#define ROTW8(x) (vec)(_mm_slli_epi32((__m128i)x, 8) ^ _mm_srli_epi32((__m128i)x,24))
|
||||
#define ROTW16(x) (vec)(_mm_slli_epi32((__m128i)x,16) ^ _mm_srli_epi32((__m128i)x,16))
|
||||
#endif
|
||||
#else
|
||||
#error -- Implementation supports only machines with neon or SSE2
|
||||
#endif
|
||||
|
||||
#ifndef REVV_BE
|
||||
#define REVV_BE(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef REVW_BE
|
||||
#define REVW_BE(x) (x)
|
||||
#endif
|
||||
|
||||
#define BPI (VBPI + GPR_TOO) /* Blocks computed per loop iteration */
|
||||
|
||||
#define DQROUND_VECTORS(a,b,c,d) \
|
||||
a += b; d ^= a; d = ROTW16(d); \
|
||||
c += d; b ^= c; b = ROTW12(b); \
|
||||
a += b; d ^= a; d = ROTW8(d); \
|
||||
c += d; b ^= c; b = ROTW7(b); \
|
||||
b = ROTV1(b); c = ROTV2(c); d = ROTV3(d); \
|
||||
a += b; d ^= a; d = ROTW16(d); \
|
||||
c += d; b ^= c; b = ROTW12(b); \
|
||||
a += b; d ^= a; d = ROTW8(d); \
|
||||
c += d; b ^= c; b = ROTW7(b); \
|
||||
b = ROTV3(b); c = ROTV2(c); d = ROTV1(d);
|
||||
|
||||
#define QROUND_WORDS(a,b,c,d) \
|
||||
a = a+b; d ^= a; d = d<<16 | d>>16; \
|
||||
c = c+d; b ^= c; b = b<<12 | b>>20; \
|
||||
a = a+b; d ^= a; d = d<< 8 | d>>24; \
|
||||
c = c+d; b ^= c; b = b<< 7 | b>>25;
|
||||
|
||||
#define WRITE_XOR(in, op, d, v0, v1, v2, v3) \
|
||||
STORE(op + d + 0, LOAD(in + d + 0) ^ REVV_BE(v0)); \
|
||||
STORE(op + d + 4, LOAD(in + d + 4) ^ REVV_BE(v1)); \
|
||||
STORE(op + d + 8, LOAD(in + d + 8) ^ REVV_BE(v2)); \
|
||||
STORE(op + d +12, LOAD(in + d +12) ^ REVV_BE(v3));
|
||||
|
||||
void
|
||||
ChaCha20XOR(unsigned char *out, const unsigned char *in, unsigned int inlen,
|
||||
const unsigned char key[32], const unsigned char nonce[12],
|
||||
uint32_t counter)
|
||||
{
|
||||
unsigned iters, i, *op=(unsigned *)out, *ip=(unsigned *)in, *kp;
|
||||
#if defined(__ARM_NEON__)
|
||||
unsigned *np;
|
||||
#endif
|
||||
vec s0, s1, s2, s3;
|
||||
#if !defined(__ARM_NEON__) && !defined(__SSE2__)
|
||||
__attribute__ ((aligned (16))) unsigned key[8], nonce[4];
|
||||
#endif
|
||||
__attribute__ ((aligned (16))) unsigned chacha_const[] =
|
||||
{0x61707865,0x3320646E,0x79622D32,0x6B206574};
|
||||
#if defined(__ARM_NEON__) || defined(__SSE2__)
|
||||
kp = (unsigned *)key;
|
||||
#else
|
||||
((vec *)key)[0] = REVV_BE(((vec *)key)[0]);
|
||||
((vec *)key)[1] = REVV_BE(((vec *)key)[1]);
|
||||
((unsigned *)nonce)[0] = REVW_BE(((unsigned *)nonce)[0]);
|
||||
((unsigned *)nonce)[1] = REVW_BE(((unsigned *)nonce)[1]);
|
||||
((unsigned *)nonce)[2] = REVW_BE(((unsigned *)nonce)[2]);
|
||||
((unsigned *)nonce)[3] = REVW_BE(((unsigned *)nonce)[3]);
|
||||
kp = (unsigned *)key;
|
||||
np = (unsigned *)nonce;
|
||||
#endif
|
||||
#if defined(__ARM_NEON__)
|
||||
np = (unsigned*) nonce;
|
||||
#endif
|
||||
s0 = LOAD(chacha_const);
|
||||
s1 = LOAD(&((vec*)kp)[0]);
|
||||
s2 = LOAD(&((vec*)kp)[1]);
|
||||
s3 = (vec) {
|
||||
counter,
|
||||
((uint32_t*)nonce)[0],
|
||||
((uint32_t*)nonce)[1],
|
||||
((uint32_t*)nonce)[2]
|
||||
};
|
||||
|
||||
for (iters = 0; iters < inlen/(BPI*64); iters++) {
|
||||
#if GPR_TOO
|
||||
register unsigned x0, x1, x2, x3, x4, x5, x6, x7, x8,
|
||||
x9, x10, x11, x12, x13, x14, x15;
|
||||
#endif
|
||||
#if VBPI > 2
|
||||
vec v8,v9,v10,v11;
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
vec v12,v13,v14,v15;
|
||||
#endif
|
||||
|
||||
vec v0,v1,v2,v3,v4,v5,v6,v7;
|
||||
v4 = v0 = s0; v5 = v1 = s1; v6 = v2 = s2; v3 = s3;
|
||||
v7 = v3 + ONE;
|
||||
#if VBPI > 2
|
||||
v8 = v4; v9 = v5; v10 = v6;
|
||||
v11 = v7 + ONE;
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
v12 = v8; v13 = v9; v14 = v10;
|
||||
v15 = v11 + ONE;
|
||||
#endif
|
||||
#if GPR_TOO
|
||||
x0 = chacha_const[0]; x1 = chacha_const[1];
|
||||
x2 = chacha_const[2]; x3 = chacha_const[3];
|
||||
x4 = kp[0]; x5 = kp[1]; x6 = kp[2]; x7 = kp[3];
|
||||
x8 = kp[4]; x9 = kp[5]; x10 = kp[6]; x11 = kp[7];
|
||||
x12 = counter+BPI*iters+(BPI-1); x13 = np[0];
|
||||
x14 = np[1]; x15 = np[2];
|
||||
#endif
|
||||
for (i = CHACHA_RNDS/2; i; i--) {
|
||||
DQROUND_VECTORS(v0,v1,v2,v3)
|
||||
DQROUND_VECTORS(v4,v5,v6,v7)
|
||||
#if VBPI > 2
|
||||
DQROUND_VECTORS(v8,v9,v10,v11)
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
DQROUND_VECTORS(v12,v13,v14,v15)
|
||||
#endif
|
||||
#if GPR_TOO
|
||||
QROUND_WORDS( x0, x4, x8,x12)
|
||||
QROUND_WORDS( x1, x5, x9,x13)
|
||||
QROUND_WORDS( x2, x6,x10,x14)
|
||||
QROUND_WORDS( x3, x7,x11,x15)
|
||||
QROUND_WORDS( x0, x5,x10,x15)
|
||||
QROUND_WORDS( x1, x6,x11,x12)
|
||||
QROUND_WORDS( x2, x7, x8,x13)
|
||||
QROUND_WORDS( x3, x4, x9,x14)
|
||||
#endif
|
||||
}
|
||||
|
||||
WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
||||
s3 += ONE;
|
||||
WRITE_XOR(ip, op, 16, v4+s0, v5+s1, v6+s2, v7+s3)
|
||||
s3 += ONE;
|
||||
#if VBPI > 2
|
||||
WRITE_XOR(ip, op, 32, v8+s0, v9+s1, v10+s2, v11+s3)
|
||||
s3 += ONE;
|
||||
#endif
|
||||
#if VBPI > 3
|
||||
WRITE_XOR(ip, op, 48, v12+s0, v13+s1, v14+s2, v15+s3)
|
||||
s3 += ONE;
|
||||
#endif
|
||||
ip += VBPI*16;
|
||||
op += VBPI*16;
|
||||
#if GPR_TOO
|
||||
op[0] = REVW_BE(REVW_BE(ip[0]) ^ (x0 + chacha_const[0]));
|
||||
op[1] = REVW_BE(REVW_BE(ip[1]) ^ (x1 + chacha_const[1]));
|
||||
op[2] = REVW_BE(REVW_BE(ip[2]) ^ (x2 + chacha_const[2]));
|
||||
op[3] = REVW_BE(REVW_BE(ip[3]) ^ (x3 + chacha_const[3]));
|
||||
op[4] = REVW_BE(REVW_BE(ip[4]) ^ (x4 + kp[0]));
|
||||
op[5] = REVW_BE(REVW_BE(ip[5]) ^ (x5 + kp[1]));
|
||||
op[6] = REVW_BE(REVW_BE(ip[6]) ^ (x6 + kp[2]));
|
||||
op[7] = REVW_BE(REVW_BE(ip[7]) ^ (x7 + kp[3]));
|
||||
op[8] = REVW_BE(REVW_BE(ip[8]) ^ (x8 + kp[4]));
|
||||
op[9] = REVW_BE(REVW_BE(ip[9]) ^ (x9 + kp[5]));
|
||||
op[10] = REVW_BE(REVW_BE(ip[10]) ^ (x10 + kp[6]));
|
||||
op[11] = REVW_BE(REVW_BE(ip[11]) ^ (x11 + kp[7]));
|
||||
op[12] = REVW_BE(REVW_BE(ip[12]) ^ (x12 + counter+BPI*iters+(BPI-1)));
|
||||
op[13] = REVW_BE(REVW_BE(ip[13]) ^ (x13 + np[0]));
|
||||
op[14] = REVW_BE(REVW_BE(ip[14]) ^ (x14 + np[1]));
|
||||
op[15] = REVW_BE(REVW_BE(ip[15]) ^ (x15 + np[2]));
|
||||
s3 += ONE;
|
||||
ip += 16;
|
||||
op += 16;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (iters = inlen%(BPI*64)/64; iters != 0; iters--) {
|
||||
vec v0 = s0, v1 = s1, v2 = s2, v3 = s3;
|
||||
for (i = CHACHA_RNDS/2; i; i--) {
|
||||
DQROUND_VECTORS(v0,v1,v2,v3);
|
||||
}
|
||||
WRITE_XOR(ip, op, 0, v0+s0, v1+s1, v2+s2, v3+s3)
|
||||
s3 += ONE;
|
||||
ip += 16;
|
||||
op += 16;
|
||||
}
|
||||
|
||||
inlen = inlen % 64;
|
||||
if (inlen) {
|
||||
__attribute__ ((aligned (16))) vec buf[4];
|
||||
vec v0,v1,v2,v3;
|
||||
v0 = s0; v1 = s1; v2 = s2; v3 = s3;
|
||||
for (i = CHACHA_RNDS/2; i; i--) {
|
||||
DQROUND_VECTORS(v0,v1,v2,v3);
|
||||
}
|
||||
|
||||
if (inlen >= 16) {
|
||||
STORE(op + 0, LOAD(ip + 0) ^ REVV_BE(v0 + s0));
|
||||
if (inlen >= 32) {
|
||||
STORE(op + 4, LOAD(ip + 4) ^ REVV_BE(v1 + s1));
|
||||
if (inlen >= 48) {
|
||||
STORE(op + 8, LOAD(ip + 8) ^ REVV_BE(v2 + s2));
|
||||
buf[3] = REVV_BE(v3 + s3);
|
||||
} else {
|
||||
buf[2] = REVV_BE(v2 + s2);
|
||||
}
|
||||
} else {
|
||||
buf[1] = REVV_BE(v1 + s1);
|
||||
}
|
||||
} else {
|
||||
buf[0] = REVV_BE(v0 + s0);
|
||||
}
|
||||
|
||||
for (i=inlen & ~15; i<inlen; i++) {
|
||||
((char *)op)[i] = ((char *)ip)[i] ^ ((char *)buf)[i];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secerr.h"
|
||||
#include "blapit.h"
|
||||
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
#include "poly1305.h"
|
||||
#include "chacha20.h"
|
||||
#include "chacha20poly1305.h"
|
||||
#endif
|
||||
|
||||
/* Poly1305Do writes the Poly1305 authenticator of the given additional data
|
||||
* and ciphertext to |out|. */
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
static void
|
||||
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
|
||||
const unsigned char *ciphertext, unsigned int ciphertextLen,
|
||||
const unsigned char key[32])
|
||||
{
|
||||
poly1305_state state;
|
||||
unsigned int j;
|
||||
unsigned char lengthBytes[8];
|
||||
static const unsigned char zeros[15];
|
||||
unsigned int i;
|
||||
|
||||
Poly1305Init(&state, key);
|
||||
Poly1305Update(&state, ad, adLen);
|
||||
if (adLen % 16 > 0) {
|
||||
Poly1305Update(&state, zeros, 16 - adLen % 16);
|
||||
}
|
||||
Poly1305Update(&state, ciphertext, ciphertextLen);
|
||||
if (ciphertextLen % 16 > 0) {
|
||||
Poly1305Update(&state, zeros, 16 - ciphertextLen % 16);
|
||||
}
|
||||
j = adLen;
|
||||
for (i = 0; i < sizeof(lengthBytes); i++) {
|
||||
lengthBytes[i] = j;
|
||||
j >>= 8;
|
||||
}
|
||||
Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
||||
j = ciphertextLen;
|
||||
for (i = 0; i < sizeof(lengthBytes); i++) {
|
||||
lengthBytes[i] = j;
|
||||
j >>= 8;
|
||||
}
|
||||
Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
|
||||
Poly1305Finish(&state, out);
|
||||
}
|
||||
#endif
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
if (keyLen != 32) {
|
||||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return SECFailure;
|
||||
}
|
||||
if (tagLen == 0 || tagLen > 16) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memcpy(ctx->key, key, sizeof(ctx->key));
|
||||
ctx->tagLen = tagLen;
|
||||
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
ChaCha20Poly1305Context *
|
||||
ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return NULL;
|
||||
#else
|
||||
ChaCha20Poly1305Context *ctx;
|
||||
|
||||
ctx = PORT_New(ChaCha20Poly1305Context);
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ChaCha20Poly1305_InitContext(ctx, key, keyLen, tagLen) != SECSuccess) {
|
||||
PORT_Free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
||||
{
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
PORT_Memset(ctx, 0, sizeof(*ctx));
|
||||
if (freeit) {
|
||||
PORT_Free(ctx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
unsigned char block[64];
|
||||
unsigned char tag[16];
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = inputLen + ctx->tagLen;
|
||||
if (maxOutputLen < *outputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
// Generate a block of keystream. The first 32 bytes will be the poly1305
|
||||
// key. The remainder of the block is discarded.
|
||||
ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
||||
ChaCha20XOR(output, input, inputLen, ctx->key, nonce, 1);
|
||||
|
||||
Poly1305Do(tag, ad, adLen, output, inputLen, block);
|
||||
PORT_Memcpy(output + inputLen, tag, ctx->tagLen);
|
||||
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
unsigned char block[64];
|
||||
unsigned char tag[16];
|
||||
unsigned int ciphertextLen;
|
||||
|
||||
if (nonceLen != 12) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
if (inputLen < ctx->tagLen) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
ciphertextLen = inputLen - ctx->tagLen;
|
||||
*outputLen = ciphertextLen;
|
||||
if (maxOutputLen < *outputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memset(block, 0, sizeof(block));
|
||||
// Generate a block of keystream. The first 32 bytes will be the poly1305
|
||||
// key. The remainder of the block is discarded.
|
||||
ChaCha20XOR(block, block, sizeof(block), ctx->key, nonce, 0);
|
||||
Poly1305Do(tag, ad, adLen, input, ciphertextLen, block);
|
||||
if (NSS_SecureMemcmp(tag, &input[ciphertextLen], ctx->tagLen) != 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ChaCha20XOR(output, input, ciphertextLen, ctx->key, nonce, 1);
|
||||
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _CHACHA20_POLY1305_H_
|
||||
#define _CHACHA20_POLY1305_H_ 1
|
||||
|
||||
/* ChaCha20Poly1305ContextStr saves the key and tag length for a
|
||||
* ChaCha20+Poly1305 AEAD operation. */
|
||||
struct ChaCha20Poly1305ContextStr {
|
||||
unsigned char key[32];
|
||||
unsigned char tagLen;
|
||||
};
|
||||
|
||||
#endif /* _CHACHA20_POLY1305_H_ */
|
|
@ -7,6 +7,20 @@
|
|||
#define IV_OFFSET 16
|
||||
#define EXPANDED_KEY_OFFSET 48
|
||||
|
||||
/*
|
||||
* Warning: the length values used in this module are "unsigned int"
|
||||
* in C, which is 32-bit. When they're passed in registers, use only
|
||||
* the low 32 bits, because the top half is unspecified.
|
||||
*
|
||||
* This is called from C code, so the contents of those bits can
|
||||
* depend on the C compiler's optimization decisions. This means that
|
||||
* mistakes might not be obvious in testing if those bits happen to be
|
||||
* zero in your build.
|
||||
*
|
||||
* Exception: 32-bit lea instructions use a 64-bit address because the
|
||||
* address size doesn't affect the result, and that form is more
|
||||
* compactly encoded and preferred by compilers over a 32-bit address.
|
||||
*/
|
||||
|
||||
/* in %rdi : the key
|
||||
in %rsi : buffer for expanded key
|
||||
|
@ -119,10 +133,11 @@ key_expansion128:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_encrypt_ecb_128,@function
|
||||
|
@ -135,11 +150,11 @@ intel_aes_encrypt_ecb_128:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 160(%rdi), %xmm12
|
||||
xor %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -260,11 +275,11 @@ intel_aes_encrypt_ecb_128:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm3
|
||||
|
@ -290,8 +305,8 @@ intel_aes_encrypt_ecb_128:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdc,0xcb /* aesenc %xmm11, %xmm1 */
|
||||
.byte 0x66,0x41,0x0f,0x38,0xdd,0xcc /* aesenclast %xmm12, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: xor %eax, %eax
|
||||
|
@ -302,10 +317,11 @@ intel_aes_encrypt_ecb_128:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_decrypt_ecb_128,@function
|
||||
|
@ -318,11 +334,11 @@ intel_aes_decrypt_ecb_128:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 160(%rdi), %xmm12
|
||||
xorl %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -443,11 +459,11 @@ intel_aes_decrypt_ecb_128:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm3
|
||||
|
@ -473,8 +489,8 @@ intel_aes_decrypt_ecb_128:
|
|||
.byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm7, %xmm1 */
|
||||
.byte 0x66,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: xor %eax, %eax
|
||||
|
@ -485,17 +501,18 @@ intel_aes_decrypt_ecb_128:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_encrypt_cbc_128,@function
|
||||
.globl intel_aes_encrypt_cbc_128
|
||||
.align 16
|
||||
intel_aes_encrypt_cbc_128:
|
||||
testq %r9, %r9
|
||||
testl %r9d, %r9d
|
||||
je 2f
|
||||
|
||||
// leaq IV_OFFSET(%rdi), %rdx
|
||||
|
@ -532,8 +549,8 @@ intel_aes_encrypt_cbc_128:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdd,0xcc /* aesenclast %xmm12, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
movdqa %xmm1, %xmm0
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 1b
|
||||
|
||||
movdqu %xmm0, (%rdx)
|
||||
|
@ -546,10 +563,11 @@ intel_aes_encrypt_cbc_128:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_decrypt_cbc_128,@function
|
||||
|
@ -565,9 +583,9 @@ intel_aes_decrypt_cbc_128:
|
|||
movdqu (%rdi), %xmm2 /* first key block */
|
||||
movdqu 160(%rdi), %xmm12 /* last key block */
|
||||
xorl %eax, %eax
|
||||
cmpq $128, %r9
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
leaq -128(%r9), %r11
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3 /* 1st data block */
|
||||
movdqu 16(%r8, %rax), %xmm4 /* 2d data block */
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -704,10 +722,10 @@ intel_aes_decrypt_cbc_128:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm3
|
||||
|
@ -736,8 +754,8 @@ intel_aes_decrypt_cbc_128:
|
|||
pxor %xmm0, %xmm1
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
movdqa %xmm13, %xmm0
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: movdqu %xmm0, (%rdx)
|
||||
|
@ -873,10 +891,11 @@ key_expansion192:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_encrypt_ecb_192,@function
|
||||
|
@ -889,11 +908,11 @@ intel_aes_encrypt_ecb_192:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 192(%rdi), %xmm14
|
||||
xorl %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -1033,11 +1052,11 @@ intel_aes_encrypt_ecb_192:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm3
|
||||
|
@ -1067,8 +1086,8 @@ intel_aes_encrypt_ecb_192:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdc,0xcd /* aesenc %xmm13, %xmm1 */
|
||||
.byte 0x66,0x41,0x0f,0x38,0xdd,0xce /* aesenclast %xmm14, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: xor %eax, %eax
|
||||
|
@ -1079,10 +1098,11 @@ intel_aes_encrypt_ecb_192:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_decrypt_ecb_192,@function
|
||||
|
@ -1095,11 +1115,11 @@ intel_aes_decrypt_ecb_192:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 192(%rdi), %xmm14
|
||||
xorl %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -1239,11 +1259,11 @@ intel_aes_decrypt_ecb_192:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm3
|
||||
|
@ -1273,8 +1293,8 @@ intel_aes_decrypt_ecb_192:
|
|||
.byte 0x66,0x0f,0x38,0xde,0xcb /* aesdec %xmm3, %xmm1 */
|
||||
.byte 0x66,0x0f,0x38,0xdf,0xca /* aesdeclast %xmm2, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: xor %eax, %eax
|
||||
|
@ -1285,17 +1305,18 @@ intel_aes_decrypt_ecb_192:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_encrypt_cbc_192,@function
|
||||
.globl intel_aes_encrypt_cbc_192
|
||||
.align 16
|
||||
intel_aes_encrypt_cbc_192:
|
||||
testq %r9, %r9
|
||||
testl %r9d, %r9d
|
||||
je 2f
|
||||
|
||||
// leaq IV_OFFSET(%rdi), %rdx
|
||||
|
@ -1336,8 +1357,8 @@ intel_aes_encrypt_cbc_192:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdd,0xce /* aesenclast %xmm14, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
movdqa %xmm1, %xmm0
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 1b
|
||||
|
||||
movdqu %xmm0, (%rdx)
|
||||
|
@ -1350,10 +1371,11 @@ intel_aes_encrypt_cbc_192:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %exx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_decrypt_cbc_192,@function
|
||||
|
@ -1367,9 +1389,9 @@ intel_aes_decrypt_cbc_192:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 192(%rdi), %xmm14
|
||||
xorl %eax, %eax
|
||||
cmpq $128, %r9
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
leaq -128(%r9), %r11
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -1525,10 +1547,10 @@ intel_aes_decrypt_cbc_192:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm3
|
||||
|
@ -1561,8 +1583,8 @@ intel_aes_decrypt_cbc_192:
|
|||
pxor %xmm0, %xmm1
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
movdqa %xmm15, %xmm0
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: movdqu %xmm0, (%rdx)
|
||||
|
@ -1705,10 +1727,11 @@ key_expansion256:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_encrypt_ecb_256,@function
|
||||
|
@ -1721,11 +1744,11 @@ intel_aes_encrypt_ecb_256:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 224(%rdi), %xmm15
|
||||
xorl %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -1884,11 +1907,11 @@ intel_aes_encrypt_ecb_256:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu (%rdi), %xmm8
|
||||
|
@ -1924,8 +1947,8 @@ intel_aes_encrypt_ecb_256:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdc,0xce /* aesenc %xmm14, %xmm1 */
|
||||
.byte 0x66,0x41,0x0f,0x38,0xdd,0xcf /* aesenclast %xmm15, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: xor %eax, %eax
|
||||
|
@ -1936,10 +1959,11 @@ intel_aes_encrypt_ecb_256:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_decrypt_ecb_256,@function
|
||||
|
@ -1952,11 +1976,11 @@ intel_aes_decrypt_ecb_256:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 224(%rdi), %xmm15
|
||||
xorl %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -2115,11 +2139,11 @@ intel_aes_decrypt_ecb_256:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm2
|
||||
|
@ -2155,8 +2179,8 @@ intel_aes_decrypt_ecb_256:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdf,0xc8 /* aesdeclast %xmm8, %xmm1 */
|
||||
movdqu 112(%rdi), %xmm8
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: xor %eax, %eax
|
||||
|
@ -2167,17 +2191,18 @@ intel_aes_decrypt_ecb_256:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_encrypt_cbc_256,@function
|
||||
.globl intel_aes_encrypt_cbc_256
|
||||
.align 16
|
||||
intel_aes_encrypt_cbc_256:
|
||||
testq %r9, %r9
|
||||
testl %r9d, %r9d
|
||||
je 2f
|
||||
|
||||
// leaq IV_OFFSET(%rdi), %rdx
|
||||
|
@ -2223,8 +2248,8 @@ intel_aes_encrypt_cbc_256:
|
|||
.byte 0x66,0x41,0x0f,0x38,0xdd,0xcf /* aesenclast %xmm15, %xmm1 */
|
||||
movdqu %xmm1, (%rsi, %rax)
|
||||
movdqa %xmm1, %xmm0
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 1b
|
||||
|
||||
movdqu %xmm0, (%rdx)
|
||||
|
@ -2237,10 +2262,11 @@ intel_aes_encrypt_cbc_256:
|
|||
/* in %rdi : cx - context
|
||||
in %rsi : output - pointer to output buffer
|
||||
in %rdx : outputLen - pointer to variable for length of output
|
||||
(filled by caller)
|
||||
in %rcx : maxOutputLen - length of output buffer
|
||||
(already filled in by caller)
|
||||
in %ecx : maxOutputLen - length of output buffer
|
||||
(already checked by caller)
|
||||
in %r8 : input - pointer to input buffer
|
||||
in %r9 : inputLen - length of input buffer
|
||||
in %r9d : inputLen - length of input buffer
|
||||
on stack: blocksize - AES blocksize (always 16, unused)
|
||||
*/
|
||||
.type intel_aes_decrypt_cbc_256,@function
|
||||
|
@ -2256,11 +2282,11 @@ intel_aes_decrypt_cbc_256:
|
|||
movdqu (%rdi), %xmm2
|
||||
movdqu 224(%rdi), %xmm15
|
||||
xorl %eax, %eax
|
||||
// cmpq $8*16, %r9
|
||||
cmpq $128, %r9
|
||||
// cmpl $8*16, %r9d
|
||||
cmpl $128, %r9d
|
||||
jb 1f
|
||||
// leaq -8*16(%r9), %r11
|
||||
leaq -128(%r9), %r11
|
||||
// leal -8*16(%r9), %r11d
|
||||
leal -128(%r9), %r11d
|
||||
2: movdqu (%r8, %rax), %xmm3
|
||||
movdqu 16(%r8, %rax), %xmm4
|
||||
movdqu 32(%r8, %rax), %xmm5
|
||||
|
@ -2435,11 +2461,11 @@ intel_aes_decrypt_cbc_256:
|
|||
movdqu %xmm8, 80(%rsi, %rax)
|
||||
movdqu %xmm9, 96(%rsi, %rax)
|
||||
movdqu %xmm10, 112(%rsi, %rax)
|
||||
// addq $8*16, %rax
|
||||
addq $128, %rax
|
||||
cmpq %r11, %rax
|
||||
// addl $8*16, %eax
|
||||
addl $128, %eax
|
||||
cmpl %r11d, %eax
|
||||
jbe 2b
|
||||
1: cmpq %rax, %r9
|
||||
1: cmpl %eax, %r9d
|
||||
je 5f
|
||||
|
||||
movdqu 16(%rdi), %xmm2
|
||||
|
@ -2477,8 +2503,8 @@ intel_aes_decrypt_cbc_256:
|
|||
pxor %xmm0, %xmm1
|
||||
movdqu (%r8, %rax), %xmm0 /* fetch the IV before we store the block */
|
||||
movdqu %xmm1, (%rsi, %rax) /* in case input buf = output buf */
|
||||
addq $16, %rax
|
||||
cmpq %rax, %r9
|
||||
addl $16, %eax
|
||||
cmpl %eax, %r9d
|
||||
jne 4b
|
||||
|
||||
5: movdqu %xmm0, (%rdx)
|
||||
|
|
|
@ -286,9 +286,17 @@ static const struct FREEBLVectorStr vector =
|
|||
|
||||
EC_FillParams,
|
||||
EC_DecodeParams,
|
||||
EC_CopyParams
|
||||
EC_CopyParams,
|
||||
|
||||
/* End of Version 3.017 */
|
||||
|
||||
ChaCha20Poly1305_InitContext,
|
||||
ChaCha20Poly1305_CreateContext,
|
||||
ChaCha20Poly1305_DestroyContext,
|
||||
ChaCha20Poly1305_Seal,
|
||||
ChaCha20Poly1305_Open
|
||||
|
||||
/* End of Version 3.018 */
|
||||
};
|
||||
|
||||
const FREEBLVector *
|
||||
|
|
|
@ -2128,3 +2128,59 @@ SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
|
|||
return (vector->p_EC_CopyParams)(arena, dstParams, srcParams);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_InitContext)(ctx, key, keyLen, tagLen);
|
||||
}
|
||||
|
||||
ChaCha20Poly1305Context *
|
||||
ChaCha20Poly1305_CreateContext(const unsigned char *key, unsigned int keyLen,
|
||||
unsigned int tagLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_ChaCha20Poly1305_CreateContext)(key, keyLen, tagLen);
|
||||
}
|
||||
|
||||
void
|
||||
ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_ChaCha20Poly1305_DestroyContext)(ctx, freeit);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_Seal)(
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return SECFailure;
|
||||
return (vector->p_ChaCha20Poly1305_Open)(
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "blapi.h"
|
||||
|
||||
#define FREEBL_VERSION 0x0311
|
||||
#define FREEBL_VERSION 0x0312
|
||||
|
||||
struct FREEBLVectorStr {
|
||||
|
||||
|
@ -707,6 +707,33 @@ struct FREEBLVectorStr {
|
|||
|
||||
/* Version 3.017 came to here */
|
||||
|
||||
SECStatus (* p_ChaCha20Poly1305_InitContext)(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
unsigned int tagLen);
|
||||
|
||||
ChaCha20Poly1305Context *(* p_ChaCha20Poly1305_CreateContext)(
|
||||
const unsigned char *key, unsigned int keyLen, unsigned int tagLen);
|
||||
|
||||
void (* p_ChaCha20Poly1305_DestroyContext)(ChaCha20Poly1305Context *ctx,
|
||||
PRBool freeit);
|
||||
|
||||
SECStatus (* p_ChaCha20Poly1305_Seal)(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
SECStatus (* p_ChaCha20Poly1305_Open)(
|
||||
const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
unsigned int *outputLen, unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen,
|
||||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
/* Version 3.018 came to here */
|
||||
|
||||
/* Add new function pointers at the end of this struct and bump
|
||||
* FREEBL_VERSION at the beginning of this file. */
|
||||
};
|
||||
|
|
|
@ -56,6 +56,7 @@ EXPORTS = \
|
|||
PRIVATE_EXPORTS = \
|
||||
alghmac.h \
|
||||
blapi.h \
|
||||
chacha20poly1305.h \
|
||||
hmacct.h \
|
||||
secmpi.h \
|
||||
secrng.h \
|
||||
|
@ -101,6 +102,7 @@ CSRCS = \
|
|||
desblapi.c \
|
||||
des.c \
|
||||
drbg.c \
|
||||
chacha20poly1305.c \
|
||||
cts.c \
|
||||
ctr.c \
|
||||
gcm.c \
|
||||
|
|
|
@ -0,0 +1,623 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This implementation of poly1305 is by Andrew Moon
|
||||
* (https://github.com/floodyberry/poly1305-donna) and released as public
|
||||
* domain. It implements SIMD vectorization based on the algorithm described in
|
||||
* http://cr.yp.to/papers.html#neoncrypto. Unrolled to 2 powers, i.e. 64 byte
|
||||
* block size. */
|
||||
|
||||
#include <emmintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "poly1305.h"
|
||||
|
||||
#define ALIGN(x) __attribute__((aligned(x)))
|
||||
#define INLINE inline
|
||||
#define U8TO64_LE(m) (*(uint64_t*)(m))
|
||||
#define U8TO32_LE(m) (*(uint32_t*)(m))
|
||||
#define U64TO8_LE(m,v) (*(uint64_t*)(m)) = v
|
||||
|
||||
typedef __m128i xmmi;
|
||||
typedef unsigned __int128 uint128_t;
|
||||
|
||||
static const uint32_t ALIGN(16) poly1305_x64_sse2_message_mask[4] = {(1 << 26) - 1, 0, (1 << 26) - 1, 0};
|
||||
static const uint32_t ALIGN(16) poly1305_x64_sse2_5[4] = {5, 0, 5, 0};
|
||||
static const uint32_t ALIGN(16) poly1305_x64_sse2_1shl128[4] = {(1 << 24), 0, (1 << 24), 0};
|
||||
|
||||
static uint128_t INLINE
|
||||
add128(uint128_t a, uint128_t b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
static uint128_t INLINE
|
||||
add128_64(uint128_t a, uint64_t b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
static uint128_t INLINE
|
||||
mul64x64_128(uint64_t a, uint64_t b) {
|
||||
return (uint128_t)a * b;
|
||||
}
|
||||
|
||||
static uint64_t INLINE
|
||||
lo128(uint128_t a) {
|
||||
return (uint64_t)a;
|
||||
}
|
||||
|
||||
static uint64_t INLINE
|
||||
shr128(uint128_t v, const int shift) {
|
||||
return (uint64_t)(v >> shift);
|
||||
}
|
||||
|
||||
static uint64_t INLINE
|
||||
shr128_pair(uint64_t hi, uint64_t lo, const int shift) {
|
||||
return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift);
|
||||
}
|
||||
|
||||
typedef struct poly1305_power_t {
|
||||
union {
|
||||
xmmi v;
|
||||
uint64_t u[2];
|
||||
uint32_t d[4];
|
||||
} R20,R21,R22,R23,R24,S21,S22,S23,S24;
|
||||
} poly1305_power;
|
||||
|
||||
typedef struct poly1305_state_internal_t {
|
||||
poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 bytes of free storage */
|
||||
union {
|
||||
xmmi H[5]; /* 80 bytes */
|
||||
uint64_t HH[10];
|
||||
};
|
||||
/* uint64_t r0,r1,r2; [24 bytes] */
|
||||
/* uint64_t pad0,pad1; [16 bytes] */
|
||||
uint64_t started; /* 8 bytes */
|
||||
uint64_t leftover; /* 8 bytes */
|
||||
uint8_t buffer[64]; /* 64 bytes */
|
||||
} poly1305_state_internal; /* 448 bytes total + 63 bytes for alignment = 511 bytes raw */
|
||||
|
||||
static poly1305_state_internal INLINE
|
||||
*poly1305_aligned_state(poly1305_state *state) {
|
||||
return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
|
||||
}
|
||||
|
||||
/* copy 0-63 bytes */
|
||||
static void INLINE
|
||||
poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes) {
|
||||
size_t offset = src - dst;
|
||||
if (bytes & 32) {
|
||||
_mm_storeu_si128((xmmi *)(dst + 0), _mm_loadu_si128((xmmi *)(dst + offset + 0)));
|
||||
_mm_storeu_si128((xmmi *)(dst + 16), _mm_loadu_si128((xmmi *)(dst + offset + 16)));
|
||||
dst += 32;
|
||||
}
|
||||
if (bytes & 16) { _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((xmmi *)(dst + offset))); dst += 16; }
|
||||
if (bytes & 8) { *(uint64_t *)dst = *(uint64_t *)(dst + offset); dst += 8; }
|
||||
if (bytes & 4) { *(uint32_t *)dst = *(uint32_t *)(dst + offset); dst += 4; }
|
||||
if (bytes & 2) { *(uint16_t *)dst = *(uint16_t *)(dst + offset); dst += 2; }
|
||||
if (bytes & 1) { *( uint8_t *)dst = *( uint8_t *)(dst + offset); }
|
||||
}
|
||||
|
||||
/* zero 0-15 bytes */
|
||||
static void INLINE
|
||||
poly1305_block_zero(uint8_t *dst, size_t bytes) {
|
||||
if (bytes & 8) { *(uint64_t *)dst = 0; dst += 8; }
|
||||
if (bytes & 4) { *(uint32_t *)dst = 0; dst += 4; }
|
||||
if (bytes & 2) { *(uint16_t *)dst = 0; dst += 2; }
|
||||
if (bytes & 1) { *( uint8_t *)dst = 0; }
|
||||
}
|
||||
|
||||
static size_t INLINE
|
||||
poly1305_min(size_t a, size_t b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
void
|
||||
Poly1305Init(poly1305_state *state, const unsigned char key[32]) {
|
||||
poly1305_state_internal *st = poly1305_aligned_state(state);
|
||||
poly1305_power *p;
|
||||
uint64_t r0,r1,r2;
|
||||
uint64_t t0,t1;
|
||||
|
||||
/* clamp key */
|
||||
t0 = U8TO64_LE(key + 0);
|
||||
t1 = U8TO64_LE(key + 8);
|
||||
r0 = t0 & 0xffc0fffffff; t0 >>= 44; t0 |= t1 << 20;
|
||||
r1 = t0 & 0xfffffc0ffff; t1 >>= 24;
|
||||
r2 = t1 & 0x00ffffffc0f;
|
||||
|
||||
/* store r in un-used space of st->P[1] */
|
||||
p = &st->P[1];
|
||||
p->R20.d[1] = (uint32_t)(r0 );
|
||||
p->R20.d[3] = (uint32_t)(r0 >> 32);
|
||||
p->R21.d[1] = (uint32_t)(r1 );
|
||||
p->R21.d[3] = (uint32_t)(r1 >> 32);
|
||||
p->R22.d[1] = (uint32_t)(r2 );
|
||||
p->R22.d[3] = (uint32_t)(r2 >> 32);
|
||||
|
||||
/* store pad */
|
||||
p->R23.d[1] = U8TO32_LE(key + 16);
|
||||
p->R23.d[3] = U8TO32_LE(key + 20);
|
||||
p->R24.d[1] = U8TO32_LE(key + 24);
|
||||
p->R24.d[3] = U8TO32_LE(key + 28);
|
||||
|
||||
/* H = 0 */
|
||||
st->H[0] = _mm_setzero_si128();
|
||||
st->H[1] = _mm_setzero_si128();
|
||||
st->H[2] = _mm_setzero_si128();
|
||||
st->H[3] = _mm_setzero_si128();
|
||||
st->H[4] = _mm_setzero_si128();
|
||||
|
||||
st->started = 0;
|
||||
st->leftover = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
poly1305_first_block(poly1305_state_internal *st, const uint8_t *m) {
|
||||
const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
|
||||
const xmmi FIVE = _mm_load_si128((xmmi*)poly1305_x64_sse2_5);
|
||||
const xmmi HIBIT = _mm_load_si128((xmmi*)poly1305_x64_sse2_1shl128);
|
||||
xmmi T5,T6;
|
||||
poly1305_power *p;
|
||||
uint128_t d[3];
|
||||
uint64_t r0,r1,r2;
|
||||
uint64_t r20,r21,r22,s22;
|
||||
uint64_t pad0,pad1;
|
||||
uint64_t c;
|
||||
uint64_t i;
|
||||
|
||||
/* pull out stored info */
|
||||
p = &st->P[1];
|
||||
|
||||
r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
|
||||
r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
|
||||
r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
|
||||
pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
|
||||
pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
|
||||
|
||||
/* compute powers r^2,r^4 */
|
||||
r20 = r0;
|
||||
r21 = r1;
|
||||
r22 = r2;
|
||||
for (i = 0; i < 2; i++) {
|
||||
s22 = r22 * (5 << 2);
|
||||
|
||||
d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22));
|
||||
d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21));
|
||||
d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20));
|
||||
|
||||
r20 = lo128(d[0]) & 0xfffffffffff; c = shr128(d[0], 44);
|
||||
d[1] = add128_64(d[1], c); r21 = lo128(d[1]) & 0xfffffffffff; c = shr128(d[1], 44);
|
||||
d[2] = add128_64(d[2], c); r22 = lo128(d[2]) & 0x3ffffffffff; c = shr128(d[2], 42);
|
||||
r20 += c * 5; c = (r20 >> 44); r20 = r20 & 0xfffffffffff;
|
||||
r21 += c;
|
||||
|
||||
p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)( r20 ) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R21.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R22.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8) ) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R23.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), _MM_SHUFFLE(1,0,1,0));
|
||||
p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16) ) ), _MM_SHUFFLE(1,0,1,0));
|
||||
p->S21.v = _mm_mul_epu32(p->R21.v, FIVE);
|
||||
p->S22.v = _mm_mul_epu32(p->R22.v, FIVE);
|
||||
p->S23.v = _mm_mul_epu32(p->R23.v, FIVE);
|
||||
p->S24.v = _mm_mul_epu32(p->R24.v, FIVE);
|
||||
p--;
|
||||
}
|
||||
|
||||
/* put saved info back */
|
||||
p = &st->P[1];
|
||||
p->R20.d[1] = (uint32_t)(r0 );
|
||||
p->R20.d[3] = (uint32_t)(r0 >> 32);
|
||||
p->R21.d[1] = (uint32_t)(r1 );
|
||||
p->R21.d[3] = (uint32_t)(r1 >> 32);
|
||||
p->R22.d[1] = (uint32_t)(r2 );
|
||||
p->R22.d[3] = (uint32_t)(r2 >> 32);
|
||||
p->R23.d[1] = (uint32_t)(pad0 );
|
||||
p->R23.d[3] = (uint32_t)(pad0 >> 32);
|
||||
p->R24.d[1] = (uint32_t)(pad1 );
|
||||
p->R24.d[3] = (uint32_t)(pad1 >> 32);
|
||||
|
||||
/* H = [Mx,My] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
|
||||
st->H[0] = _mm_and_si128(MMASK, T5);
|
||||
st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
st->H[2] = _mm_and_si128(MMASK, T5);
|
||||
st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
}
|
||||
|
||||
static void
|
||||
poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, size_t bytes) {
|
||||
const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
|
||||
const xmmi FIVE = _mm_load_si128((xmmi*)poly1305_x64_sse2_5);
|
||||
const xmmi HIBIT = _mm_load_si128((xmmi*)poly1305_x64_sse2_1shl128);
|
||||
|
||||
poly1305_power *p;
|
||||
xmmi H0,H1,H2,H3,H4;
|
||||
xmmi T0,T1,T2,T3,T4,T5,T6;
|
||||
xmmi M0,M1,M2,M3,M4;
|
||||
xmmi C1,C2;
|
||||
|
||||
H0 = st->H[0];
|
||||
H1 = st->H[1];
|
||||
H2 = st->H[2];
|
||||
H3 = st->H[3];
|
||||
H4 = st->H[4];
|
||||
|
||||
while (bytes >= 64) {
|
||||
/* H *= [r^4,r^4] */
|
||||
p = &st->P[0];
|
||||
T0 = _mm_mul_epu32(H0, p->R20.v);
|
||||
T1 = _mm_mul_epu32(H0, p->R21.v);
|
||||
T2 = _mm_mul_epu32(H0, p->R22.v);
|
||||
T3 = _mm_mul_epu32(H0, p->R23.v);
|
||||
T4 = _mm_mul_epu32(H0, p->R24.v);
|
||||
T5 = _mm_mul_epu32(H1, p->S24.v); T6 = _mm_mul_epu32(H1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->S23.v); T6 = _mm_mul_epu32(H2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S22.v); T6 = _mm_mul_epu32(H3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S21.v); T6 = _mm_mul_epu32(H4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R21.v); T6 = _mm_mul_epu32(H1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->R20.v); T6 = _mm_mul_epu32(H2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S24.v); T6 = _mm_mul_epu32(H3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S23.v); T6 = _mm_mul_epu32(H4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
/* H += [Mx,My]*[r^2,r^2] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
|
||||
M0 = _mm_and_si128(MMASK, T5);
|
||||
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
M2 = _mm_and_si128(MMASK, T5);
|
||||
M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
|
||||
p = &st->P[1];
|
||||
T5 = _mm_mul_epu32(M0, p->R20.v); T6 = _mm_mul_epu32(M0, p->R21.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M1, p->S24.v); T6 = _mm_mul_epu32(M1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M2, p->S23.v); T6 = _mm_mul_epu32(M2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M3, p->S22.v); T6 = _mm_mul_epu32(M3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M4, p->S21.v); T6 = _mm_mul_epu32(M4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(M0, p->R22.v); T6 = _mm_mul_epu32(M0, p->R23.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M1, p->R21.v); T6 = _mm_mul_epu32(M1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M2, p->R20.v); T6 = _mm_mul_epu32(M2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M3, p->S24.v); T6 = _mm_mul_epu32(M3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M4, p->S23.v); T6 = _mm_mul_epu32(M4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(M0, p->R24.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(M4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
/* H += [Mx,My] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 32)), _mm_loadl_epi64((xmmi *)(m + 48)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 40)), _mm_loadl_epi64((xmmi *)(m + 56)));
|
||||
M0 = _mm_and_si128(MMASK, T5);
|
||||
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
M2 = _mm_and_si128(MMASK, T5);
|
||||
M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
|
||||
T0 = _mm_add_epi64(T0, M0);
|
||||
T1 = _mm_add_epi64(T1, M1);
|
||||
T2 = _mm_add_epi64(T2, M2);
|
||||
T3 = _mm_add_epi64(T3, M3);
|
||||
T4 = _mm_add_epi64(T4, M4);
|
||||
|
||||
/* reduce */
|
||||
C1 = _mm_srli_epi64(T0, 26); C2 = _mm_srli_epi64(T3, 26); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_and_si128(T3, MMASK); T1 = _mm_add_epi64(T1, C1); T4 = _mm_add_epi64(T4, C2);
|
||||
C1 = _mm_srli_epi64(T1, 26); C2 = _mm_srli_epi64(T4, 26); T1 = _mm_and_si128(T1, MMASK); T4 = _mm_and_si128(T4, MMASK); T2 = _mm_add_epi64(T2, C1); T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
|
||||
C1 = _mm_srli_epi64(T2, 26); C2 = _mm_srli_epi64(T0, 26); T2 = _mm_and_si128(T2, MMASK); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_add_epi64(T3, C1); T1 = _mm_add_epi64(T1, C2);
|
||||
C1 = _mm_srli_epi64(T3, 26); T3 = _mm_and_si128(T3, MMASK); T4 = _mm_add_epi64(T4, C1);
|
||||
|
||||
/* H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) */
|
||||
H0 = T0;
|
||||
H1 = T1;
|
||||
H2 = T2;
|
||||
H3 = T3;
|
||||
H4 = T4;
|
||||
|
||||
m += 64;
|
||||
bytes -= 64;
|
||||
}
|
||||
|
||||
st->H[0] = H0;
|
||||
st->H[1] = H1;
|
||||
st->H[2] = H2;
|
||||
st->H[3] = H3;
|
||||
st->H[4] = H4;
|
||||
}
|
||||
|
||||
static size_t
|
||||
poly1305_combine(poly1305_state_internal *st, const uint8_t *m, size_t bytes) {
|
||||
const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
|
||||
const xmmi HIBIT = _mm_load_si128((xmmi*)poly1305_x64_sse2_1shl128);
|
||||
const xmmi FIVE = _mm_load_si128((xmmi*)poly1305_x64_sse2_5);
|
||||
|
||||
poly1305_power *p;
|
||||
xmmi H0,H1,H2,H3,H4;
|
||||
xmmi M0,M1,M2,M3,M4;
|
||||
xmmi T0,T1,T2,T3,T4,T5,T6;
|
||||
xmmi C1,C2;
|
||||
|
||||
uint64_t r0,r1,r2;
|
||||
uint64_t t0,t1,t2,t3,t4;
|
||||
uint64_t c;
|
||||
size_t consumed = 0;
|
||||
|
||||
H0 = st->H[0];
|
||||
H1 = st->H[1];
|
||||
H2 = st->H[2];
|
||||
H3 = st->H[3];
|
||||
H4 = st->H[4];
|
||||
|
||||
/* p = [r^2,r^2] */
|
||||
p = &st->P[1];
|
||||
|
||||
if (bytes >= 32) {
|
||||
/* H *= [r^2,r^2] */
|
||||
T0 = _mm_mul_epu32(H0, p->R20.v);
|
||||
T1 = _mm_mul_epu32(H0, p->R21.v);
|
||||
T2 = _mm_mul_epu32(H0, p->R22.v);
|
||||
T3 = _mm_mul_epu32(H0, p->R23.v);
|
||||
T4 = _mm_mul_epu32(H0, p->R24.v);
|
||||
T5 = _mm_mul_epu32(H1, p->S24.v); T6 = _mm_mul_epu32(H1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->S23.v); T6 = _mm_mul_epu32(H2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S22.v); T6 = _mm_mul_epu32(H3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S21.v); T6 = _mm_mul_epu32(H4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R21.v); T6 = _mm_mul_epu32(H1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->R20.v); T6 = _mm_mul_epu32(H2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S24.v); T6 = _mm_mul_epu32(H3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S23.v); T6 = _mm_mul_epu32(H4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
/* H += [Mx,My] */
|
||||
T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
|
||||
T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
|
||||
M0 = _mm_and_si128(MMASK, T5);
|
||||
M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
|
||||
M2 = _mm_and_si128(MMASK, T5);
|
||||
M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
|
||||
M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
|
||||
|
||||
T0 = _mm_add_epi64(T0, M0);
|
||||
T1 = _mm_add_epi64(T1, M1);
|
||||
T2 = _mm_add_epi64(T2, M2);
|
||||
T3 = _mm_add_epi64(T3, M3);
|
||||
T4 = _mm_add_epi64(T4, M4);
|
||||
|
||||
/* reduce */
|
||||
C1 = _mm_srli_epi64(T0, 26); C2 = _mm_srli_epi64(T3, 26); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_and_si128(T3, MMASK); T1 = _mm_add_epi64(T1, C1); T4 = _mm_add_epi64(T4, C2);
|
||||
C1 = _mm_srli_epi64(T1, 26); C2 = _mm_srli_epi64(T4, 26); T1 = _mm_and_si128(T1, MMASK); T4 = _mm_and_si128(T4, MMASK); T2 = _mm_add_epi64(T2, C1); T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
|
||||
C1 = _mm_srli_epi64(T2, 26); C2 = _mm_srli_epi64(T0, 26); T2 = _mm_and_si128(T2, MMASK); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_add_epi64(T3, C1); T1 = _mm_add_epi64(T1, C2);
|
||||
C1 = _mm_srli_epi64(T3, 26); T3 = _mm_and_si128(T3, MMASK); T4 = _mm_add_epi64(T4, C1);
|
||||
|
||||
/* H = (H*[r^2,r^2] + [Mx,My]) */
|
||||
H0 = T0;
|
||||
H1 = T1;
|
||||
H2 = T2;
|
||||
H3 = T3;
|
||||
H4 = T4;
|
||||
|
||||
consumed = 32;
|
||||
}
|
||||
|
||||
/* finalize, H *= [r^2,r] */
|
||||
r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
|
||||
r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
|
||||
r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
|
||||
|
||||
p->R20.d[2] = (uint32_t)( r0 ) & 0x3ffffff;
|
||||
p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff;
|
||||
p->R22.d[2] = (uint32_t)((r1 >> 8) ) & 0x3ffffff;
|
||||
p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff;
|
||||
p->R24.d[2] = (uint32_t)((r2 >> 16) ) ;
|
||||
p->S21.d[2] = p->R21.d[2] * 5;
|
||||
p->S22.d[2] = p->R22.d[2] * 5;
|
||||
p->S23.d[2] = p->R23.d[2] * 5;
|
||||
p->S24.d[2] = p->R24.d[2] * 5;
|
||||
|
||||
/* H *= [r^2,r] */
|
||||
T0 = _mm_mul_epu32(H0, p->R20.v);
|
||||
T1 = _mm_mul_epu32(H0, p->R21.v);
|
||||
T2 = _mm_mul_epu32(H0, p->R22.v);
|
||||
T3 = _mm_mul_epu32(H0, p->R23.v);
|
||||
T4 = _mm_mul_epu32(H0, p->R24.v);
|
||||
T5 = _mm_mul_epu32(H1, p->S24.v); T6 = _mm_mul_epu32(H1, p->R20.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->S23.v); T6 = _mm_mul_epu32(H2, p->S24.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S22.v); T6 = _mm_mul_epu32(H3, p->S23.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S21.v); T6 = _mm_mul_epu32(H4, p->S22.v); T0 = _mm_add_epi64(T0, T5); T1 = _mm_add_epi64(T1, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R21.v); T6 = _mm_mul_epu32(H1, p->R22.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H2, p->R20.v); T6 = _mm_mul_epu32(H2, p->R21.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H3, p->S24.v); T6 = _mm_mul_epu32(H3, p->R20.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H4, p->S23.v); T6 = _mm_mul_epu32(H4, p->S24.v); T2 = _mm_add_epi64(T2, T5); T3 = _mm_add_epi64(T3, T6);
|
||||
T5 = _mm_mul_epu32(H1, p->R23.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H2, p->R22.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H3, p->R21.v); T4 = _mm_add_epi64(T4, T5);
|
||||
T5 = _mm_mul_epu32(H4, p->R20.v); T4 = _mm_add_epi64(T4, T5);
|
||||
|
||||
C1 = _mm_srli_epi64(T0, 26); C2 = _mm_srli_epi64(T3, 26); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_and_si128(T3, MMASK); T1 = _mm_add_epi64(T1, C1); T4 = _mm_add_epi64(T4, C2);
|
||||
C1 = _mm_srli_epi64(T1, 26); C2 = _mm_srli_epi64(T4, 26); T1 = _mm_and_si128(T1, MMASK); T4 = _mm_and_si128(T4, MMASK); T2 = _mm_add_epi64(T2, C1); T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
|
||||
C1 = _mm_srli_epi64(T2, 26); C2 = _mm_srli_epi64(T0, 26); T2 = _mm_and_si128(T2, MMASK); T0 = _mm_and_si128(T0, MMASK); T3 = _mm_add_epi64(T3, C1); T1 = _mm_add_epi64(T1, C2);
|
||||
C1 = _mm_srli_epi64(T3, 26); T3 = _mm_and_si128(T3, MMASK); T4 = _mm_add_epi64(T4, C1);
|
||||
|
||||
/* H = H[0]+H[1] */
|
||||
H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8));
|
||||
H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8));
|
||||
H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8));
|
||||
H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8));
|
||||
H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8));
|
||||
|
||||
t0 = _mm_cvtsi128_si32(H0) ; c = (t0 >> 26); t0 &= 0x3ffffff;
|
||||
t1 = _mm_cvtsi128_si32(H1) + c; c = (t1 >> 26); t1 &= 0x3ffffff;
|
||||
t2 = _mm_cvtsi128_si32(H2) + c; c = (t2 >> 26); t2 &= 0x3ffffff;
|
||||
t3 = _mm_cvtsi128_si32(H3) + c; c = (t3 >> 26); t3 &= 0x3ffffff;
|
||||
t4 = _mm_cvtsi128_si32(H4) + c; c = (t4 >> 26); t4 &= 0x3ffffff;
|
||||
t0 = t0 + (c * 5); c = (t0 >> 26); t0 &= 0x3ffffff;
|
||||
t1 = t1 + c;
|
||||
|
||||
st->HH[0] = ((t0 ) | (t1 << 26) ) & 0xfffffffffffull;
|
||||
st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & 0xfffffffffffull;
|
||||
st->HH[2] = ((t3 >> 10) | (t4 << 16) ) & 0x3ffffffffffull;
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void
|
||||
Poly1305Update(poly1305_state *state, const unsigned char *m, size_t bytes) {
|
||||
poly1305_state_internal *st = poly1305_aligned_state(state);
|
||||
size_t want;
|
||||
|
||||
/* need at least 32 initial bytes to start the accelerated branch */
|
||||
if (!st->started) {
|
||||
if ((st->leftover == 0) && (bytes > 32)) {
|
||||
poly1305_first_block(st, m);
|
||||
m += 32;
|
||||
bytes -= 32;
|
||||
} else {
|
||||
want = poly1305_min(32 - st->leftover, bytes);
|
||||
poly1305_block_copy(st->buffer + st->leftover, m, want);
|
||||
bytes -= want;
|
||||
m += want;
|
||||
st->leftover += want;
|
||||
if ((st->leftover < 32) || (bytes == 0))
|
||||
return;
|
||||
poly1305_first_block(st, st->buffer);
|
||||
st->leftover = 0;
|
||||
}
|
||||
st->started = 1;
|
||||
}
|
||||
|
||||
/* handle leftover */
|
||||
if (st->leftover) {
|
||||
want = poly1305_min(64 - st->leftover, bytes);
|
||||
poly1305_block_copy(st->buffer + st->leftover, m, want);
|
||||
bytes -= want;
|
||||
m += want;
|
||||
st->leftover += want;
|
||||
if (st->leftover < 64)
|
||||
return;
|
||||
poly1305_blocks(st, st->buffer, 64);
|
||||
st->leftover = 0;
|
||||
}
|
||||
|
||||
/* process 64 byte blocks */
|
||||
if (bytes >= 64) {
|
||||
want = (bytes & ~63);
|
||||
poly1305_blocks(st, m, want);
|
||||
m += want;
|
||||
bytes -= want;
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
poly1305_block_copy(st->buffer + st->leftover, m, bytes);
|
||||
st->leftover += bytes;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Poly1305Finish(poly1305_state *state, unsigned char mac[16]) {
|
||||
poly1305_state_internal *st = poly1305_aligned_state(state);
|
||||
size_t leftover = st->leftover;
|
||||
uint8_t *m = st->buffer;
|
||||
uint128_t d[3];
|
||||
uint64_t h0,h1,h2;
|
||||
uint64_t t0,t1;
|
||||
uint64_t g0,g1,g2,c,nc;
|
||||
uint64_t r0,r1,r2,s1,s2;
|
||||
poly1305_power *p;
|
||||
|
||||
if (st->started) {
|
||||
size_t consumed = poly1305_combine(st, m, leftover);
|
||||
leftover -= consumed;
|
||||
m += consumed;
|
||||
}
|
||||
|
||||
/* st->HH will either be 0 or have the combined result */
|
||||
h0 = st->HH[0];
|
||||
h1 = st->HH[1];
|
||||
h2 = st->HH[2];
|
||||
|
||||
p = &st->P[1];
|
||||
r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
|
||||
r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
|
||||
r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
|
||||
s1 = r1 * (5 << 2);
|
||||
s2 = r2 * (5 << 2);
|
||||
|
||||
if (leftover < 16)
|
||||
goto poly1305_donna_atmost15bytes;
|
||||
|
||||
poly1305_donna_atleast16bytes:
|
||||
t0 = U8TO64_LE(m + 0);
|
||||
t1 = U8TO64_LE(m + 8);
|
||||
h0 += t0 & 0xfffffffffff;
|
||||
t0 = shr128_pair(t1, t0, 44);
|
||||
h1 += t0 & 0xfffffffffff;
|
||||
h2 += (t1 >> 24) | ((uint64_t)1 << 40);
|
||||
|
||||
poly1305_donna_mul:
|
||||
d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), mul64x64_128(h2, s1));
|
||||
d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), mul64x64_128(h2, s2));
|
||||
d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), mul64x64_128(h2, r0));
|
||||
h0 = lo128(d[0]) & 0xfffffffffff; c = shr128(d[0], 44);
|
||||
d[1] = add128_64(d[1], c); h1 = lo128(d[1]) & 0xfffffffffff; c = shr128(d[1], 44);
|
||||
d[2] = add128_64(d[2], c); h2 = lo128(d[2]) & 0x3ffffffffff; c = shr128(d[2], 42);
|
||||
h0 += c * 5;
|
||||
|
||||
m += 16;
|
||||
leftover -= 16;
|
||||
if (leftover >= 16) goto poly1305_donna_atleast16bytes;
|
||||
|
||||
/* final bytes */
|
||||
poly1305_donna_atmost15bytes:
|
||||
if (!leftover) goto poly1305_donna_finish;
|
||||
|
||||
m[leftover++] = 1;
|
||||
poly1305_block_zero(m + leftover, 16 - leftover);
|
||||
leftover = 16;
|
||||
|
||||
t0 = U8TO64_LE(m+0);
|
||||
t1 = U8TO64_LE(m+8);
|
||||
h0 += t0 & 0xfffffffffff; t0 = shr128_pair(t1, t0, 44);
|
||||
h1 += t0 & 0xfffffffffff;
|
||||
h2 += (t1 >> 24);
|
||||
|
||||
goto poly1305_donna_mul;
|
||||
|
||||
poly1305_donna_finish:
|
||||
c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5;
|
||||
|
||||
g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
|
||||
g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
|
||||
g2 = h2 + c - ((uint64_t)1 << 42);
|
||||
|
||||
c = (g2 >> 63) - 1;
|
||||
nc = ~c;
|
||||
h0 = (h0 & nc) | (g0 & c);
|
||||
h1 = (h1 & nc) | (g1 & c);
|
||||
h2 = (h2 & nc) | (g2 & c);
|
||||
|
||||
/* pad */
|
||||
t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
|
||||
t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
|
||||
h0 += (t0 & 0xfffffffffff) ; c = (h0 >> 44); h0 &= 0xfffffffffff; t0 = shr128_pair(t1, t0, 44);
|
||||
h1 += (t0 & 0xfffffffffff) + c; c = (h1 >> 44); h1 &= 0xfffffffffff; t1 = (t1 >> 24);
|
||||
h2 += (t1 ) + c;
|
||||
|
||||
U64TO8_LE(mac + 0, ((h0 ) | (h1 << 44)));
|
||||
U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24)));
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* This implementation of poly1305 is by Andrew Moon
|
||||
* (https://github.com/floodyberry/poly1305-donna) and released as public
|
||||
* domain. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "poly1305.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
#include "prtypes.h"
|
||||
typedef PRUint32 uint32_t;
|
||||
typedef PRUint64 uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined(NSS_X86) || defined(NSS_X64)
|
||||
/* We can assume little-endian. */
|
||||
static uint32_t U8TO32_LE(const unsigned char *m) {
|
||||
uint32_t r;
|
||||
memcpy(&r, m, sizeof(r));
|
||||
return r;
|
||||
}
|
||||
|
||||
static void U32TO8_LE(unsigned char *m, uint32_t v) {
|
||||
memcpy(m, &v, sizeof(v));
|
||||
}
|
||||
#else
|
||||
static uint32_t U8TO32_LE(const unsigned char *m) {
|
||||
return (uint32_t)m[0] |
|
||||
(uint32_t)m[1] << 8 |
|
||||
(uint32_t)m[2] << 16 |
|
||||
(uint32_t)m[3] << 24;
|
||||
}
|
||||
|
||||
static void U32TO8_LE(unsigned char *m, uint32_t v) {
|
||||
m[0] = v;
|
||||
m[1] = v >> 8;
|
||||
m[2] = v >> 16;
|
||||
m[3] = v >> 24;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint64_t
|
||||
mul32x32_64(uint32_t a, uint32_t b) {
|
||||
return (uint64_t)a * b;
|
||||
}
|
||||
|
||||
struct poly1305_state_st {
|
||||
uint32_t r0,r1,r2,r3,r4;
|
||||
uint32_t s1,s2,s3,s4;
|
||||
uint32_t h0,h1,h2,h3,h4;
|
||||
unsigned char buf[16];
|
||||
unsigned int buf_used;
|
||||
unsigned char key[16];
|
||||
};
|
||||
|
||||
/* update updates |state| given some amount of input data. This function may
|
||||
* only be called with a |len| that is not a multiple of 16 at the end of the
|
||||
* data. Otherwise the input must be buffered into 16 byte blocks. */
|
||||
static void update(struct poly1305_state_st *state, const unsigned char *in,
|
||||
size_t len) {
|
||||
uint32_t t0,t1,t2,t3;
|
||||
uint64_t t[5];
|
||||
uint32_t b;
|
||||
uint64_t c;
|
||||
size_t j;
|
||||
unsigned char mp[16];
|
||||
|
||||
if (len < 16)
|
||||
goto poly1305_donna_atmost15bytes;
|
||||
|
||||
poly1305_donna_16bytes:
|
||||
t0 = U8TO32_LE(in);
|
||||
t1 = U8TO32_LE(in+4);
|
||||
t2 = U8TO32_LE(in+8);
|
||||
t3 = U8TO32_LE(in+12);
|
||||
|
||||
in += 16;
|
||||
len -= 16;
|
||||
|
||||
state->h0 += t0 & 0x3ffffff;
|
||||
state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
|
||||
state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
|
||||
state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
state->h4 += (t3 >> 8) | (1 << 24);
|
||||
|
||||
poly1305_donna_mul:
|
||||
t[0] = mul32x32_64(state->h0,state->r0) +
|
||||
mul32x32_64(state->h1,state->s4) +
|
||||
mul32x32_64(state->h2,state->s3) +
|
||||
mul32x32_64(state->h3,state->s2) +
|
||||
mul32x32_64(state->h4,state->s1);
|
||||
t[1] = mul32x32_64(state->h0,state->r1) +
|
||||
mul32x32_64(state->h1,state->r0) +
|
||||
mul32x32_64(state->h2,state->s4) +
|
||||
mul32x32_64(state->h3,state->s3) +
|
||||
mul32x32_64(state->h4,state->s2);
|
||||
t[2] = mul32x32_64(state->h0,state->r2) +
|
||||
mul32x32_64(state->h1,state->r1) +
|
||||
mul32x32_64(state->h2,state->r0) +
|
||||
mul32x32_64(state->h3,state->s4) +
|
||||
mul32x32_64(state->h4,state->s3);
|
||||
t[3] = mul32x32_64(state->h0,state->r3) +
|
||||
mul32x32_64(state->h1,state->r2) +
|
||||
mul32x32_64(state->h2,state->r1) +
|
||||
mul32x32_64(state->h3,state->r0) +
|
||||
mul32x32_64(state->h4,state->s4);
|
||||
t[4] = mul32x32_64(state->h0,state->r4) +
|
||||
mul32x32_64(state->h1,state->r3) +
|
||||
mul32x32_64(state->h2,state->r2) +
|
||||
mul32x32_64(state->h3,state->r1) +
|
||||
mul32x32_64(state->h4,state->r0);
|
||||
|
||||
state->h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);
|
||||
t[1] += c; state->h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
|
||||
t[2] += b; state->h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
|
||||
t[3] += b; state->h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
|
||||
t[4] += b; state->h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
|
||||
state->h0 += b * 5;
|
||||
|
||||
if (len >= 16)
|
||||
goto poly1305_donna_16bytes;
|
||||
|
||||
/* final bytes */
|
||||
poly1305_donna_atmost15bytes:
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
for (j = 0; j < len; j++)
|
||||
mp[j] = in[j];
|
||||
mp[j++] = 1;
|
||||
for (; j < 16; j++)
|
||||
mp[j] = 0;
|
||||
len = 0;
|
||||
|
||||
t0 = U8TO32_LE(mp+0);
|
||||
t1 = U8TO32_LE(mp+4);
|
||||
t2 = U8TO32_LE(mp+8);
|
||||
t3 = U8TO32_LE(mp+12);
|
||||
|
||||
state->h0 += t0 & 0x3ffffff;
|
||||
state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
|
||||
state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
|
||||
state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
state->h4 += (t3 >> 8);
|
||||
|
||||
goto poly1305_donna_mul;
|
||||
}
|
||||
|
||||
void Poly1305Init(poly1305_state *statep, const unsigned char key[32]) {
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st*) statep;
|
||||
uint32_t t0,t1,t2,t3;
|
||||
|
||||
t0 = U8TO32_LE(key+0);
|
||||
t1 = U8TO32_LE(key+4);
|
||||
t2 = U8TO32_LE(key+8);
|
||||
t3 = U8TO32_LE(key+12);
|
||||
|
||||
/* precompute multipliers */
|
||||
state->r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
|
||||
state->r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
|
||||
state->r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
|
||||
state->r3 = t2 & 0x3f03fff; t3 >>= 8;
|
||||
state->r4 = t3 & 0x00fffff;
|
||||
|
||||
state->s1 = state->r1 * 5;
|
||||
state->s2 = state->r2 * 5;
|
||||
state->s3 = state->r3 * 5;
|
||||
state->s4 = state->r4 * 5;
|
||||
|
||||
/* init state */
|
||||
state->h0 = 0;
|
||||
state->h1 = 0;
|
||||
state->h2 = 0;
|
||||
state->h3 = 0;
|
||||
state->h4 = 0;
|
||||
|
||||
state->buf_used = 0;
|
||||
memcpy(state->key, key + 16, sizeof(state->key));
|
||||
}
|
||||
|
||||
void Poly1305Update(poly1305_state *statep, const unsigned char *in,
|
||||
size_t in_len) {
|
||||
unsigned int i;
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st*) statep;
|
||||
|
||||
if (state->buf_used) {
|
||||
unsigned int todo = 16 - state->buf_used;
|
||||
if (todo > in_len)
|
||||
todo = in_len;
|
||||
for (i = 0; i < todo; i++)
|
||||
state->buf[state->buf_used + i] = in[i];
|
||||
state->buf_used += todo;
|
||||
in_len -= todo;
|
||||
in += todo;
|
||||
|
||||
if (state->buf_used == 16) {
|
||||
update(state, state->buf, 16);
|
||||
state->buf_used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_len >= 16) {
|
||||
size_t todo = in_len & ~0xf;
|
||||
update(state, in, todo);
|
||||
in += todo;
|
||||
in_len &= 0xf;
|
||||
}
|
||||
|
||||
if (in_len) {
|
||||
for (i = 0; i < in_len; i++)
|
||||
state->buf[i] = in[i];
|
||||
state->buf_used = in_len;
|
||||
}
|
||||
}
|
||||
|
||||
void Poly1305Finish(poly1305_state *statep, unsigned char mac[16]) {
|
||||
struct poly1305_state_st *state = (struct poly1305_state_st*) statep;
|
||||
uint64_t f0,f1,f2,f3;
|
||||
uint32_t g0,g1,g2,g3,g4;
|
||||
uint32_t b, nb;
|
||||
|
||||
if (state->buf_used)
|
||||
update(state, state->buf, state->buf_used);
|
||||
|
||||
b = state->h0 >> 26; state->h0 = state->h0 & 0x3ffffff;
|
||||
state->h1 += b; b = state->h1 >> 26; state->h1 = state->h1 & 0x3ffffff;
|
||||
state->h2 += b; b = state->h2 >> 26; state->h2 = state->h2 & 0x3ffffff;
|
||||
state->h3 += b; b = state->h3 >> 26; state->h3 = state->h3 & 0x3ffffff;
|
||||
state->h4 += b; b = state->h4 >> 26; state->h4 = state->h4 & 0x3ffffff;
|
||||
state->h0 += b * 5;
|
||||
|
||||
g0 = state->h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
|
||||
g1 = state->h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
|
||||
g2 = state->h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
|
||||
g3 = state->h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
|
||||
g4 = state->h4 + b - (1 << 26);
|
||||
|
||||
b = (g4 >> 31) - 1;
|
||||
nb = ~b;
|
||||
state->h0 = (state->h0 & nb) | (g0 & b);
|
||||
state->h1 = (state->h1 & nb) | (g1 & b);
|
||||
state->h2 = (state->h2 & nb) | (g2 & b);
|
||||
state->h3 = (state->h3 & nb) | (g3 & b);
|
||||
state->h4 = (state->h4 & nb) | (g4 & b);
|
||||
|
||||
f0 = ((state->h0 ) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]);
|
||||
f1 = ((state->h1 >> 6) | (state->h2 << 20)) + (uint64_t)U8TO32_LE(&state->key[4]);
|
||||
f2 = ((state->h2 >> 12) | (state->h3 << 14)) + (uint64_t)U8TO32_LE(&state->key[8]);
|
||||
f3 = ((state->h3 >> 18) | (state->h4 << 8)) + (uint64_t)U8TO32_LE(&state->key[12]);
|
||||
|
||||
U32TO8_LE(&mac[ 0], (uint32_t)f0); f1 += (f0 >> 32);
|
||||
U32TO8_LE(&mac[ 4], (uint32_t)f1); f2 += (f1 >> 32);
|
||||
U32TO8_LE(&mac[ 8], (uint32_t)f2); f3 += (f2 >> 32);
|
||||
U32TO8_LE(&mac[12], (uint32_t)f3);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* poly1305.h - header file for Poly1305 implementation.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef FREEBL_POLY1305_H_
|
||||
#define FREEBL_POLY1305_H_
|
||||
|
||||
typedef unsigned char poly1305_state[512];
|
||||
|
||||
/* Poly1305Init sets up |state| so that it can be used to calculate an
|
||||
* authentication tag with the one-time key |key|. Note that |key| is a
|
||||
* one-time key and therefore there is no `reset' method because that would
|
||||
* enable several messages to be authenticated with the same key. */
|
||||
extern void Poly1305Init(poly1305_state* state, const unsigned char key[32]);
|
||||
|
||||
/* Poly1305Update processes |in_len| bytes from |in|. It can be called zero or
|
||||
* more times after poly1305_init. */
|
||||
extern void Poly1305Update(poly1305_state* state, const unsigned char* in,
|
||||
size_t inLen);
|
||||
|
||||
/* Poly1305Finish completes the poly1305 calculation and writes a 16 byte
|
||||
* authentication tag to |mac|. */
|
||||
extern void Poly1305Finish(poly1305_state* state, unsigned char mac[16]);
|
||||
|
||||
#endif /* FREEBL_POLY1305_H_ */
|
|
@ -152,6 +152,8 @@ PK11_GetKeyMechanism(CK_KEY_TYPE type)
|
|||
return CKM_SEED_CBC;
|
||||
case CKK_CAMELLIA:
|
||||
return CKM_CAMELLIA_CBC;
|
||||
case CKK_NSS_CHACHA20:
|
||||
return CKM_NSS_CHACHA20_POLY1305;
|
||||
case CKK_AES:
|
||||
return CKM_AES_CBC;
|
||||
case CKK_DES:
|
||||
|
@ -219,6 +221,9 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len)
|
|||
case CKM_CAMELLIA_CBC_PAD:
|
||||
case CKM_CAMELLIA_KEY_GEN:
|
||||
return CKK_CAMELLIA;
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
case CKM_NSS_CHACHA20_KEY_GEN:
|
||||
return CKK_NSS_CHACHA20;
|
||||
case CKM_AES_ECB:
|
||||
case CKM_AES_CBC:
|
||||
case CKM_AES_CCM:
|
||||
|
@ -431,6 +436,8 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
|
|||
case CKM_CAMELLIA_CBC_PAD:
|
||||
case CKM_CAMELLIA_KEY_GEN:
|
||||
return CKM_CAMELLIA_KEY_GEN;
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
return CKM_NSS_CHACHA20_KEY_GEN;
|
||||
case CKM_AES_ECB:
|
||||
case CKM_AES_CBC:
|
||||
case CKM_AES_CCM:
|
||||
|
|
|
@ -354,6 +354,7 @@ static const oidValDef algOptList[] = {
|
|||
{CIPHER_NAME("CAMELLIA128-CBC"), SEC_OID_CAMELLIA_128_CBC, NSS_USE_ALG_IN_SSL},
|
||||
{CIPHER_NAME("CAMELLIA192-CBC"), SEC_OID_CAMELLIA_192_CBC, NSS_USE_ALG_IN_SSL},
|
||||
{CIPHER_NAME("CAMELLIA256-CBC"), SEC_OID_CAMELLIA_256_CBC, NSS_USE_ALG_IN_SSL},
|
||||
{CIPHER_NAME("CHACHA20-POLY1305"), SEC_OID_CHACHA20_POLY1305, NSS_USE_ALG_IN_SSL},
|
||||
{CIPHER_NAME("SEED-CBC"), SEC_OID_SEED_CBC, NSS_USE_ALG_IN_SSL},
|
||||
{CIPHER_NAME("DES-EDE3-CBC"), SEC_OID_DES_EDE3_CBC, NSS_USE_ALG_IN_SSL},
|
||||
{CIPHER_NAME("DES-40-CBC"), SEC_OID_DES_40_CBC, NSS_USE_ALG_IN_SSL},
|
||||
|
|
|
@ -711,7 +711,7 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output,
|
|||
}
|
||||
|
||||
if (final) {
|
||||
padlen = padsize - (pcount % padsize);
|
||||
padlen = padsize ? padsize - (pcount % padsize) : 0;
|
||||
PORT_Memset (pbuf + pcount, padlen, padlen);
|
||||
rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len,
|
||||
pbuf, pcount+padlen);
|
||||
|
|
|
@ -370,6 +370,11 @@ static const struct mechanismList mechanisms[] = {
|
|||
{CKM_SEED_MAC, {16, 16, CKF_SN_VR}, PR_TRUE},
|
||||
{CKM_SEED_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE},
|
||||
{CKM_SEED_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE},
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
/* ------------------------- ChaCha20 Operations ---------------------- */
|
||||
{CKM_NSS_CHACHA20_KEY_GEN, {32, 32, CKF_GENERATE}, PR_TRUE},
|
||||
{CKM_NSS_CHACHA20_POLY1305,{32, 32, CKF_EN_DE}, PR_TRUE},
|
||||
#endif /* NSS_DISABLE_CHACHAPOLY */
|
||||
/* ------------------------- Hashing Operations ----------------------- */
|
||||
{CKM_MD2, {0, 0, CKF_DIGEST}, PR_FALSE},
|
||||
{CKM_MD2_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE},
|
||||
|
|
|
@ -665,6 +665,97 @@ sftk_RSADecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
|
|||
return rv;
|
||||
}
|
||||
|
||||
static SFTKChaCha20Poly1305Info *
|
||||
sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key,
|
||||
unsigned int keyLen,
|
||||
const CK_NSS_AEAD_PARAMS *params)
|
||||
{
|
||||
SFTKChaCha20Poly1305Info *ctx;
|
||||
|
||||
if (params->ulNonceLen != sizeof(ctx->nonce)) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx = PORT_New(SFTKChaCha20Poly1305Info);
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen,
|
||||
params->ulTagLen) != SECSuccess) {
|
||||
PORT_Free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PORT_Memcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce));
|
||||
|
||||
if (params->ulAADLen > sizeof(ctx->ad)) {
|
||||
/* Need to allocate an overflow buffer for the additional data. */
|
||||
ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen);
|
||||
if (!ctx->adOverflow) {
|
||||
PORT_Free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen);
|
||||
} else {
|
||||
ctx->adOverflow = NULL;
|
||||
PORT_Memcpy(ctx->ad, params->pAAD, params->ulAADLen);
|
||||
}
|
||||
ctx->adLen = params->ulAADLen;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
sftk_ChaCha20Poly1305_DestroyContext(SFTKChaCha20Poly1305Info *ctx,
|
||||
PRBool freeit)
|
||||
{
|
||||
ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE);
|
||||
if (ctx->adOverflow != NULL) {
|
||||
PORT_Free(ctx->adOverflow);
|
||||
ctx->adOverflow = NULL;
|
||||
}
|
||||
ctx->adLen = 0;
|
||||
if (freeit) {
|
||||
PORT_Free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
sftk_ChaCha20Poly1305_Encrypt(const SFTKChaCha20Poly1305Info *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
const unsigned char *ad = ctx->adOverflow;
|
||||
|
||||
if (ad == NULL) {
|
||||
ad = ctx->ad;
|
||||
}
|
||||
|
||||
return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen,
|
||||
maxOutputLen, input, inputLen, ctx->nonce,
|
||||
sizeof(ctx->nonce), ad, ctx->adLen);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
const unsigned char *ad = ctx->adOverflow;
|
||||
|
||||
if (ad == NULL) {
|
||||
ad = ctx->ad;
|
||||
}
|
||||
|
||||
return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen,
|
||||
maxOutputLen, input, inputLen, ctx->nonce,
|
||||
sizeof(ctx->nonce), ad, ctx->adLen);
|
||||
}
|
||||
|
||||
/** NSC_CryptInit initializes an encryption/Decryption operation.
|
||||
*
|
||||
* Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
|
||||
|
@ -882,7 +973,6 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
|||
break;
|
||||
}
|
||||
t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
|
||||
if (crv != CKR_OK) break;
|
||||
goto finish_des;
|
||||
case CKM_DES_ECB:
|
||||
if (key_type != CKK_DES) {
|
||||
|
@ -1058,6 +1148,34 @@ finish_des:
|
|||
context->destroy = (SFTKDestroy) AES_DestroyContext;
|
||||
break;
|
||||
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
if (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS)) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
context->multi = PR_FALSE;
|
||||
if (key_type != CKK_NSS_CHACHA20) {
|
||||
crv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
break;
|
||||
}
|
||||
att = sftk_FindAttribute(key,CKA_VALUE);
|
||||
if (att == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
break;
|
||||
}
|
||||
context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext(
|
||||
(unsigned char*) att->attrib.pValue, att->attrib.ulValueLen,
|
||||
(CK_NSS_AEAD_PARAMS*) pMechanism->pParameter);
|
||||
sftk_FreeAttribute(att);
|
||||
if (context->cipherInfo == NULL) {
|
||||
crv = sftk_MapCryptError(PORT_GetError());
|
||||
break;
|
||||
}
|
||||
context->update = (SFTKCipher) (isEncrypt ? sftk_ChaCha20Poly1305_Encrypt :
|
||||
sftk_ChaCha20Poly1305_Decrypt);
|
||||
context->destroy = (SFTKDestroy) sftk_ChaCha20Poly1305_DestroyContext;
|
||||
break;
|
||||
|
||||
case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
|
||||
context->doPad = PR_TRUE;
|
||||
/* fall thru */
|
||||
|
@ -3655,6 +3773,10 @@ nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
|
|||
*key_type = CKK_AES;
|
||||
if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
|
||||
break;
|
||||
case CKM_NSS_CHACHA20_KEY_GEN:
|
||||
*key_type = CKK_NSS_CHACHA20;
|
||||
if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE;
|
||||
break;
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
crv = CKR_MECHANISM_INVALID;
|
||||
|
@ -3916,6 +4038,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
|
|||
case CKM_SEED_KEY_GEN:
|
||||
case CKM_CAMELLIA_KEY_GEN:
|
||||
case CKM_AES_KEY_GEN:
|
||||
case CKM_NSS_CHACHA20_KEY_GEN:
|
||||
#if NSS_SOFTOKEN_DOES_RC5
|
||||
case CKM_RC5_KEY_GEN:
|
||||
#endif
|
||||
|
@ -4057,14 +4180,15 @@ jpake1:
|
|||
*/
|
||||
crv = sftk_handleObject(key,session);
|
||||
sftk_FreeSession(session);
|
||||
if (sftk_isTrue(key,CKA_SENSITIVE)) {
|
||||
sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
|
||||
if (crv == CKR_OK && sftk_isTrue(key,CKA_SENSITIVE)) {
|
||||
crv = sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
|
||||
}
|
||||
if (!sftk_isTrue(key,CKA_EXTRACTABLE)) {
|
||||
sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
|
||||
if (crv == CKR_OK && !sftk_isTrue(key,CKA_EXTRACTABLE)) {
|
||||
crv = sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL));
|
||||
}
|
||||
if (crv == CKR_OK) {
|
||||
*phKey = key->handle;
|
||||
}
|
||||
|
||||
*phKey = key->handle;
|
||||
sftk_FreeObject(key);
|
||||
return crv;
|
||||
}
|
||||
|
@ -4863,41 +4987,46 @@ ecgn_done:
|
|||
return crv;
|
||||
}
|
||||
if (sftk_isTrue(privateKey,CKA_SENSITIVE)) {
|
||||
sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
|
||||
crv = sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE,
|
||||
&cktrue,sizeof(CK_BBOOL));
|
||||
}
|
||||
if (sftk_isTrue(publicKey,CKA_SENSITIVE)) {
|
||||
sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
|
||||
if (crv == CKR_OK && sftk_isTrue(publicKey,CKA_SENSITIVE)) {
|
||||
crv = sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE,
|
||||
&cktrue,sizeof(CK_BBOOL));
|
||||
}
|
||||
if (!sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
|
||||
sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
|
||||
if (crv == CKR_OK && !sftk_isTrue(privateKey,CKA_EXTRACTABLE)) {
|
||||
crv = sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE,
|
||||
&cktrue,sizeof(CK_BBOOL));
|
||||
}
|
||||
if (!sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
|
||||
sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
|
||||
if (crv == CKR_OK && !sftk_isTrue(publicKey,CKA_EXTRACTABLE)) {
|
||||
crv = sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE,
|
||||
&cktrue,sizeof(CK_BBOOL));
|
||||
}
|
||||
|
||||
/* Perform FIPS 140-2 pairwise consistency check. */
|
||||
crv = sftk_PairwiseConsistencyCheck(hSession,
|
||||
publicKey, privateKey, key_type);
|
||||
if (crv == CKR_OK) {
|
||||
/* Perform FIPS 140-2 pairwise consistency check. */
|
||||
crv = sftk_PairwiseConsistencyCheck(hSession,
|
||||
publicKey, privateKey, key_type);
|
||||
if (crv != CKR_OK) {
|
||||
if (sftk_audit_enabled) {
|
||||
char msg[128];
|
||||
PR_snprintf(msg,sizeof msg,
|
||||
"C_GenerateKeyPair(hSession=0x%08lX, "
|
||||
"pMechanism->mechanism=0x%08lX)=0x%08lX "
|
||||
"self-test: pair-wise consistency test failed",
|
||||
(PRUint32)hSession,(PRUint32)pMechanism->mechanism,
|
||||
(PRUint32)crv);
|
||||
sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
|
||||
if (crv != CKR_OK) {
|
||||
NSC_DestroyObject(hSession,publicKey->handle);
|
||||
sftk_FreeObject(publicKey);
|
||||
NSC_DestroyObject(hSession,privateKey->handle);
|
||||
sftk_FreeObject(privateKey);
|
||||
if (sftk_audit_enabled) {
|
||||
char msg[128];
|
||||
PR_snprintf(msg,sizeof msg,
|
||||
"C_GenerateKeyPair(hSession=0x%08lX, "
|
||||
"pMechanism->mechanism=0x%08lX)=0x%08lX "
|
||||
"self-test: pair-wise consistency test failed",
|
||||
(PRUint32)hSession,(PRUint32)pMechanism->mechanism,
|
||||
(PRUint32)crv);
|
||||
sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
*phPrivateKey = privateKey->handle;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "pkcs11t.h"
|
||||
|
||||
#include "sftkdbt.h"
|
||||
#include "chacha20poly1305.h"
|
||||
#include "hasht.h"
|
||||
|
||||
/*
|
||||
|
@ -104,6 +105,7 @@ typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
|
|||
typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
|
||||
typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
|
||||
typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
|
||||
typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
|
||||
typedef struct SFTKItemTemplateStr SFTKItemTemplate;
|
||||
|
||||
/* define function pointer typdefs for pointer tables */
|
||||
|
@ -399,6 +401,16 @@ struct SFTKSSLMACInfoStr {
|
|||
unsigned int keySize;
|
||||
};
|
||||
|
||||
/* SFTKChaCha20Poly1305Info saves the key, tag length, nonce,
|
||||
* and additional data for a ChaCha20+Poly1305 AEAD operation. */
|
||||
struct SFTKChaCha20Poly1305InfoStr {
|
||||
ChaCha20Poly1305Context freeblCtx;
|
||||
unsigned char nonce[12];
|
||||
unsigned char ad[16];
|
||||
unsigned char *adOverflow;
|
||||
unsigned int adLen;
|
||||
};
|
||||
|
||||
/*
|
||||
* Template based on SECItems, suitable for passing as arrays
|
||||
*/
|
||||
|
|
|
@ -5,462 +5,463 @@
|
|||
/* SSL-specific security error codes */
|
||||
/* caller must include "sslerr.h" */
|
||||
|
||||
ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
|
||||
"Unable to communicate securely. Peer does not support high-grade encryption.")
|
||||
ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
|
||||
"Unable to communicate securely. Peer does not support high-grade encryption.")
|
||||
|
||||
ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
|
||||
"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
|
||||
ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
|
||||
"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
|
||||
|
||||
ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
|
||||
"Cannot communicate securely with peer: no common encryption algorithm(s).")
|
||||
ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
|
||||
"Cannot communicate securely with peer: no common encryption algorithm(s).")
|
||||
|
||||
ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
|
||||
"Unable to find the certificate or key necessary for authentication.")
|
||||
ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
|
||||
"Unable to find the certificate or key necessary for authentication.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
|
||||
"Unable to communicate securely with peer: peers's certificate was rejected.")
|
||||
ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
|
||||
"Unable to communicate securely with peer: peers's certificate was rejected.")
|
||||
|
||||
ER3(SSL_ERROR_UNUSED_5, SSL_ERROR_BASE + 5,
|
||||
"Unrecognized SSL error code.")
|
||||
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.")
|
||||
ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
|
||||
"The server has encountered bad data from the client.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
|
||||
"The client has encountered bad data from the server.")
|
||||
ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
|
||||
"The client has encountered bad data from the server.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
|
||||
"Unsupported certificate type.")
|
||||
ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
|
||||
"Unsupported certificate type.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
|
||||
"Peer using unsupported version of security protocol.")
|
||||
ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
|
||||
"Peer using unsupported version of security protocol.")
|
||||
|
||||
ER3(SSL_ERROR_UNUSED_10, SSL_ERROR_BASE + 10,
|
||||
"Unrecognized SSL error code.")
|
||||
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.")
|
||||
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.")
|
||||
|
||||
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.")
|
||||
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.")
|
||||
|
||||
ER3(SSL_ERROR_POST_WARNING, SSL_ERROR_BASE + 13,
|
||||
"Unrecognized SSL error code.")
|
||||
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.")
|
||||
ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
|
||||
"Peer only supports SSL version 2, which is locally disabled.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
|
||||
"SSL received a record with an incorrect Message Authentication Code.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
|
||||
"SSL received a record with an incorrect Message Authentication Code.")
|
||||
ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
|
||||
"SSL peer reports incorrect Message Authentication Code.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
|
||||
"SSL peer reports incorrect Message Authentication Code.")
|
||||
ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
|
||||
"SSL peer cannot verify your certificate.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
|
||||
"SSL peer cannot verify your certificate.")
|
||||
ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
|
||||
"SSL peer rejected your certificate as revoked.")
|
||||
|
||||
ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
|
||||
"SSL peer rejected your certificate as revoked.")
|
||||
ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
|
||||
"SSL peer rejected your certificate as expired.")
|
||||
|
||||
ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
|
||||
"SSL peer rejected your certificate as expired.")
|
||||
ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
|
||||
"Cannot connect: SSL is disabled.")
|
||||
|
||||
ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
|
||||
"Cannot connect: SSL is disabled.")
|
||||
ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
|
||||
"Cannot connect: SSL peer is in another FORTEZZA domain.")
|
||||
|
||||
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.")
|
||||
|
||||
ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
|
||||
"An unknown SSL cipher suite has been requested.")
|
||||
ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED, (SSL_ERROR_BASE + 23),
|
||||
"No cipher suites are present and enabled in this program.")
|
||||
|
||||
ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
|
||||
"No cipher suites are present and enabled in this program.")
|
||||
ER3(SSL_ERROR_BAD_BLOCK_PADDING, (SSL_ERROR_BASE + 24),
|
||||
"SSL received a record with bad block padding.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
|
||||
"SSL received a record with bad block padding.")
|
||||
ER3(SSL_ERROR_RX_RECORD_TOO_LONG, (SSL_ERROR_BASE + 25),
|
||||
"SSL received a record that exceeded the maximum permissible length.")
|
||||
|
||||
ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
|
||||
"SSL received a record that exceeded the maximum permissible length.")
|
||||
|
||||
ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
|
||||
"SSL attempted to send a record that exceeded the maximum permissible length.")
|
||||
ER3(SSL_ERROR_TX_RECORD_TOO_LONG, (SSL_ERROR_BASE + 26),
|
||||
"SSL attempted to send a record that exceeded the maximum permissible length.")
|
||||
|
||||
/*
|
||||
* Received a malformed (too long or short or invalid content) SSL handshake.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
|
||||
"SSL received a malformed Hello Request handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST, (SSL_ERROR_BASE + 27),
|
||||
"SSL received a malformed Hello Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
|
||||
"SSL received a malformed Client Hello handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, (SSL_ERROR_BASE + 28),
|
||||
"SSL received a malformed Client Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
|
||||
"SSL received a malformed Server Hello handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, (SSL_ERROR_BASE + 29),
|
||||
"SSL received a malformed Server Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
|
||||
"SSL received a malformed Certificate handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE, (SSL_ERROR_BASE + 30),
|
||||
"SSL received a malformed Certificate handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
|
||||
"SSL received a malformed Server Key Exchange handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH, (SSL_ERROR_BASE + 31),
|
||||
"SSL received a malformed Server Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
|
||||
"SSL received a malformed Certificate Request handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST, (SSL_ERROR_BASE + 32),
|
||||
"SSL received a malformed Certificate Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
|
||||
"SSL received a malformed Server Hello Done handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE, (SSL_ERROR_BASE + 33),
|
||||
"SSL received a malformed Server Hello Done handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
|
||||
"SSL received a malformed Certificate Verify handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY, (SSL_ERROR_BASE + 34),
|
||||
"SSL received a malformed Certificate Verify handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
|
||||
"SSL received a malformed Client Key Exchange handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH, (SSL_ERROR_BASE + 35),
|
||||
"SSL received a malformed Client Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
|
||||
"SSL received a malformed Finished handshake message.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_FINISHED, (SSL_ERROR_BASE + 36),
|
||||
"SSL received a malformed Finished handshake message.")
|
||||
|
||||
/*
|
||||
* Received a malformed (too long or short) SSL record.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
|
||||
"SSL received a malformed Change Cipher Spec record.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER, (SSL_ERROR_BASE + 37),
|
||||
"SSL received a malformed Change Cipher Spec record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
|
||||
"SSL received a malformed Alert record.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_ALERT, (SSL_ERROR_BASE + 38),
|
||||
"SSL received a malformed Alert record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
|
||||
"SSL received a malformed Handshake record.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE, (SSL_ERROR_BASE + 39),
|
||||
"SSL received a malformed Handshake record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
|
||||
"SSL received a malformed Application Data record.")
|
||||
ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA, (SSL_ERROR_BASE + 40),
|
||||
"SSL received a malformed Application Data record.")
|
||||
|
||||
/*
|
||||
* Received an SSL handshake that was inappropriate for the state we're in.
|
||||
* E.g. Server received message from server, or wrong state in state machine.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
|
||||
"SSL received an unexpected Hello Request handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST, (SSL_ERROR_BASE + 41),
|
||||
"SSL received an unexpected Hello Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
|
||||
"SSL received an unexpected Client Hello handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO, (SSL_ERROR_BASE + 42),
|
||||
"SSL received an unexpected Client Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
|
||||
"SSL received an unexpected Server Hello handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO, (SSL_ERROR_BASE + 43),
|
||||
"SSL received an unexpected Server Hello handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
|
||||
"SSL received an unexpected Certificate handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE, (SSL_ERROR_BASE + 44),
|
||||
"SSL received an unexpected Certificate handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
|
||||
"SSL received an unexpected Server Key Exchange handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH, (SSL_ERROR_BASE + 45),
|
||||
"SSL received an unexpected Server Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
|
||||
"SSL received an unexpected Certificate Request handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST, (SSL_ERROR_BASE + 46),
|
||||
"SSL received an unexpected Certificate Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
|
||||
"SSL received an unexpected Server Hello Done handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE, (SSL_ERROR_BASE + 47),
|
||||
"SSL received an unexpected Server Hello Done handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
|
||||
"SSL received an unexpected Certificate Verify handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY, (SSL_ERROR_BASE + 48),
|
||||
"SSL received an unexpected Certificate Verify handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
|
||||
"SSL received an unexpected Client Key Exchange handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH, (SSL_ERROR_BASE + 49),
|
||||
"SSL received an unexpected Client Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
|
||||
"SSL received an unexpected Finished handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED, (SSL_ERROR_BASE + 50),
|
||||
"SSL received an unexpected Finished handshake message.")
|
||||
|
||||
/*
|
||||
* Received an SSL record that was inappropriate for the state we're in.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
|
||||
"SSL received an unexpected Change Cipher Spec record.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER, (SSL_ERROR_BASE + 51),
|
||||
"SSL received an unexpected Change Cipher Spec record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
|
||||
"SSL received an unexpected Alert record.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_ALERT, (SSL_ERROR_BASE + 52),
|
||||
"SSL received an unexpected Alert record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
|
||||
"SSL received an unexpected Handshake record.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE, (SSL_ERROR_BASE + 53),
|
||||
"SSL received an unexpected Handshake record.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
|
||||
"SSL received an unexpected Application Data record.")
|
||||
"SSL received an unexpected Application Data record.")
|
||||
|
||||
/*
|
||||
* Received record/message with unknown discriminant.
|
||||
*/
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
|
||||
"SSL received a record with an unknown content type.")
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, (SSL_ERROR_BASE + 55),
|
||||
"SSL received a record with an unknown content type.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
|
||||
"SSL received a handshake message with an unknown message type.")
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE, (SSL_ERROR_BASE + 56),
|
||||
"SSL received a handshake message with an unknown message type.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
|
||||
"SSL received an alert record with an unknown alert description.")
|
||||
ER3(SSL_ERROR_RX_UNKNOWN_ALERT, (SSL_ERROR_BASE + 57),
|
||||
"SSL received an alert record with an unknown alert description.")
|
||||
|
||||
/*
|
||||
* Received an alert reporting what we did wrong. (more alerts above)
|
||||
*/
|
||||
ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
|
||||
"SSL peer has closed this connection.")
|
||||
ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT, (SSL_ERROR_BASE + 58),
|
||||
"SSL peer has closed this connection.")
|
||||
|
||||
ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
|
||||
"SSL peer was not expecting a handshake message it received.")
|
||||
ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, (SSL_ERROR_BASE + 59),
|
||||
"SSL peer was not expecting a handshake message it received.")
|
||||
|
||||
ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
|
||||
"SSL peer was unable to successfully decompress an SSL record it received.")
|
||||
ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT, (SSL_ERROR_BASE + 60),
|
||||
"SSL peer was unable to successfully decompress an SSL record it received.")
|
||||
|
||||
ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
|
||||
"SSL peer was unable to negotiate an acceptable set of security parameters.")
|
||||
ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT, (SSL_ERROR_BASE + 61),
|
||||
"SSL peer was unable to negotiate an acceptable set of security parameters.")
|
||||
|
||||
ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
|
||||
"SSL peer rejected a handshake message for unacceptable content.")
|
||||
ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT, (SSL_ERROR_BASE + 62),
|
||||
"SSL peer rejected a handshake message for unacceptable content.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
|
||||
"SSL peer does not support certificates of the type it received.")
|
||||
ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT, (SSL_ERROR_BASE + 63),
|
||||
"SSL peer does not support certificates of the type it received.")
|
||||
|
||||
ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
|
||||
"SSL peer had some unspecified issue with the certificate it received.")
|
||||
ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT, (SSL_ERROR_BASE + 64),
|
||||
"SSL peer had some unspecified issue with the certificate it received.")
|
||||
|
||||
ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE, (SSL_ERROR_BASE + 65),
|
||||
"SSL experienced a failure of its random number generator.")
|
||||
|
||||
ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
|
||||
"SSL experienced a failure of its random number generator.")
|
||||
ER3(SSL_ERROR_SIGN_HASHES_FAILURE, (SSL_ERROR_BASE + 66),
|
||||
"Unable to digitally sign data required to verify your certificate.")
|
||||
|
||||
ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
|
||||
"Unable to digitally sign data required to verify your certificate.")
|
||||
ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE, (SSL_ERROR_BASE + 67),
|
||||
"SSL was unable to extract the public key from the peer's certificate.")
|
||||
|
||||
ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
|
||||
"SSL was unable to extract the public key from the peer's certificate.")
|
||||
ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE, (SSL_ERROR_BASE + 68),
|
||||
"Unspecified failure while processing SSL Server Key Exchange handshake.")
|
||||
|
||||
ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
|
||||
"Unspecified failure while processing SSL Server Key Exchange handshake.")
|
||||
ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE, (SSL_ERROR_BASE + 69),
|
||||
"Unspecified failure while processing SSL Client Key Exchange handshake.")
|
||||
|
||||
ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
|
||||
"Unspecified failure while processing SSL Client Key Exchange handshake.")
|
||||
ER3(SSL_ERROR_ENCRYPTION_FAILURE, (SSL_ERROR_BASE + 70),
|
||||
"Bulk data encryption algorithm failed in selected cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
|
||||
"Bulk data encryption algorithm failed in selected cipher suite.")
|
||||
ER3(SSL_ERROR_DECRYPTION_FAILURE, (SSL_ERROR_BASE + 71),
|
||||
"Bulk data decryption algorithm failed in selected cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
|
||||
"Bulk data decryption algorithm failed in selected cipher suite.")
|
||||
ER3(SSL_ERROR_SOCKET_WRITE_FAILURE, (SSL_ERROR_BASE + 72),
|
||||
"Attempt to write encrypted data to underlying socket failed.")
|
||||
|
||||
ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
|
||||
"Attempt to write encrypted data to underlying socket failed.")
|
||||
ER3(SSL_ERROR_MD5_DIGEST_FAILURE, (SSL_ERROR_BASE + 73),
|
||||
"MD5 digest function failed.")
|
||||
|
||||
ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
|
||||
"MD5 digest function failed.")
|
||||
ER3(SSL_ERROR_SHA_DIGEST_FAILURE, (SSL_ERROR_BASE + 74),
|
||||
"SHA-1 digest function failed.")
|
||||
|
||||
ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
|
||||
"SHA-1 digest function failed.")
|
||||
ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE, (SSL_ERROR_BASE + 75),
|
||||
"MAC computation failed.")
|
||||
|
||||
ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
|
||||
"MAC computation failed.")
|
||||
ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE, (SSL_ERROR_BASE + 76),
|
||||
"Failure to create Symmetric Key context.")
|
||||
|
||||
ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
|
||||
"Failure to create Symmetric Key context.")
|
||||
ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE, (SSL_ERROR_BASE + 77),
|
||||
"Failure to unwrap the Symmetric key in Client Key Exchange message.")
|
||||
|
||||
ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
|
||||
"Failure to unwrap the Symmetric key in Client Key Exchange message.")
|
||||
ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED, (SSL_ERROR_BASE + 78),
|
||||
"SSL Server attempted to use domestic-grade public key with export cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
|
||||
"SSL Server attempted to use domestic-grade public key with export cipher suite.")
|
||||
ER3(SSL_ERROR_IV_PARAM_FAILURE, (SSL_ERROR_BASE + 79),
|
||||
"PKCS11 code failed to translate an IV into a param.")
|
||||
|
||||
ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
|
||||
"PKCS11 code failed to translate an IV into a param.")
|
||||
ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, (SSL_ERROR_BASE + 80),
|
||||
"Failed to initialize the selected cipher suite.")
|
||||
|
||||
ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
|
||||
"Failed to initialize the selected cipher suite.")
|
||||
ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE, (SSL_ERROR_BASE + 81),
|
||||
"Client failed to generate session keys for SSL session.")
|
||||
|
||||
ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
|
||||
"Client failed to generate session keys for SSL session.")
|
||||
ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG, (SSL_ERROR_BASE + 82),
|
||||
"Server has no key for the attempted key exchange algorithm.")
|
||||
|
||||
ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
|
||||
"Server has no key for the attempted key exchange algorithm.")
|
||||
ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL, (SSL_ERROR_BASE + 83),
|
||||
"PKCS#11 token was inserted or removed while operation was in progress.")
|
||||
|
||||
ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
|
||||
"PKCS#11 token was inserted or removed while operation was in progress.")
|
||||
ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND, (SSL_ERROR_BASE + 84),
|
||||
"No PKCS#11 token could be found to do a required operation.")
|
||||
|
||||
ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
|
||||
"No PKCS#11 token could be found to do a required operation.")
|
||||
ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP, (SSL_ERROR_BASE + 85),
|
||||
"Cannot communicate securely with peer: no common compression algorithm(s).")
|
||||
|
||||
ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
|
||||
"Cannot communicate securely with peer: no common compression algorithm(s).")
|
||||
ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED, (SSL_ERROR_BASE + 86),
|
||||
"Cannot perform the operation until the handshake is complete.")
|
||||
|
||||
ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
|
||||
"Cannot perform the operation until the handshake is complete.")
|
||||
ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE, (SSL_ERROR_BASE + 87),
|
||||
"Received incorrect handshakes hash values from peer.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
|
||||
"Received incorrect handshakes hash values from peer.")
|
||||
ER3(SSL_ERROR_CERT_KEA_MISMATCH, (SSL_ERROR_BASE + 88),
|
||||
"The certificate provided cannot be used with the selected key exchange algorithm.")
|
||||
|
||||
ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
|
||||
"The certificate provided cannot be used with the selected key exchange algorithm.")
|
||||
ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA, (SSL_ERROR_BASE + 89),
|
||||
"No certificate authority is trusted for SSL client authentication.")
|
||||
|
||||
ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
|
||||
"No certificate authority is trusted for SSL client authentication.")
|
||||
ER3(SSL_ERROR_SESSION_NOT_FOUND, (SSL_ERROR_BASE + 90),
|
||||
"Client's SSL session ID not found in server's session cache.")
|
||||
|
||||
ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
|
||||
"Client's SSL session ID not found in server's session cache.")
|
||||
ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT, (SSL_ERROR_BASE + 91),
|
||||
"Peer was unable to decrypt an SSL record it received.")
|
||||
|
||||
ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
|
||||
"Peer was unable to decrypt an SSL record it received.")
|
||||
ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT, (SSL_ERROR_BASE + 92),
|
||||
"Peer received an SSL record that was longer than is permitted.")
|
||||
|
||||
ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
|
||||
"Peer received an SSL record that was longer than is permitted.")
|
||||
ER3(SSL_ERROR_UNKNOWN_CA_ALERT, (SSL_ERROR_BASE + 93),
|
||||
"Peer does not recognize and trust the CA that issued your certificate.")
|
||||
|
||||
ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
|
||||
"Peer does not recognize and trust the CA that issued your certificate.")
|
||||
ER3(SSL_ERROR_ACCESS_DENIED_ALERT, (SSL_ERROR_BASE + 94),
|
||||
"Peer received a valid certificate, but access was denied.")
|
||||
|
||||
ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
|
||||
"Peer received a valid certificate, but access was denied.")
|
||||
ER3(SSL_ERROR_DECODE_ERROR_ALERT, (SSL_ERROR_BASE + 95),
|
||||
"Peer could not decode an SSL handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
|
||||
"Peer could not decode an SSL handshake message.")
|
||||
ER3(SSL_ERROR_DECRYPT_ERROR_ALERT, (SSL_ERROR_BASE + 96),
|
||||
"Peer reports failure of signature verification or key exchange.")
|
||||
|
||||
ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
|
||||
"Peer reports failure of signature verification or key exchange.")
|
||||
ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT, (SSL_ERROR_BASE + 97),
|
||||
"Peer reports negotiation not in compliance with export regulations.")
|
||||
|
||||
ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
|
||||
"Peer reports negotiation not in compliance with export regulations.")
|
||||
ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT, (SSL_ERROR_BASE + 98),
|
||||
"Peer reports incompatible or unsupported protocol version.")
|
||||
|
||||
ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
|
||||
"Peer reports incompatible or unsupported protocol version.")
|
||||
ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT, (SSL_ERROR_BASE + 99),
|
||||
"Server requires ciphers more secure than those supported by client.")
|
||||
|
||||
ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
|
||||
"Server requires ciphers more secure than those supported by client.")
|
||||
ER3(SSL_ERROR_INTERNAL_ERROR_ALERT, (SSL_ERROR_BASE + 100),
|
||||
"Peer reports it experienced an internal error.")
|
||||
|
||||
ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
|
||||
"Peer reports it experienced an internal error.")
|
||||
ER3(SSL_ERROR_USER_CANCELED_ALERT, (SSL_ERROR_BASE + 101),
|
||||
"Peer user canceled handshake.")
|
||||
|
||||
ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
|
||||
"Peer user canceled handshake.")
|
||||
ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT, (SSL_ERROR_BASE + 102),
|
||||
"Peer does not permit renegotiation of SSL security parameters.")
|
||||
|
||||
ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
|
||||
"Peer does not permit renegotiation of SSL security parameters.")
|
||||
ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED, (SSL_ERROR_BASE + 103),
|
||||
"SSL server cache not configured and not disabled for this socket.")
|
||||
|
||||
ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
|
||||
"SSL server cache not configured and not disabled for this socket.")
|
||||
ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT, (SSL_ERROR_BASE + 104),
|
||||
"SSL peer does not support requested TLS hello extension.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
|
||||
"SSL peer does not support requested TLS hello extension.")
|
||||
ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT, (SSL_ERROR_BASE + 105),
|
||||
"SSL peer could not obtain your certificate from the supplied URL.")
|
||||
|
||||
ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
|
||||
"SSL peer could not obtain your certificate from the supplied URL.")
|
||||
ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT, (SSL_ERROR_BASE + 106),
|
||||
"SSL peer has no certificate for the requested DNS name.")
|
||||
|
||||
ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
|
||||
"SSL peer has no certificate for the requested DNS name.")
|
||||
ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT, (SSL_ERROR_BASE + 107),
|
||||
"SSL peer was unable to get an OCSP response for its certificate.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
|
||||
"SSL peer was unable to get an OCSP response for its certificate.")
|
||||
|
||||
ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
|
||||
"SSL peer reported bad certificate hash value.")
|
||||
ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT, (SSL_ERROR_BASE + 108),
|
||||
"SSL peer reported bad certificate hash value.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 109),
|
||||
"SSL received an unexpected New Session Ticket handshake message.")
|
||||
"SSL received an unexpected New Session Ticket handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110),
|
||||
"SSL received a malformed New Session Ticket handshake message.")
|
||||
"SSL received a malformed New Session Ticket handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_DECOMPRESSION_FAILURE, (SSL_ERROR_BASE + 111),
|
||||
"SSL received a compressed record that could not be decompressed.")
|
||||
ER3(SSL_ERROR_DECOMPRESSION_FAILURE, (SSL_ERROR_BASE + 111),
|
||||
"SSL received a compressed record that could not be decompressed.")
|
||||
|
||||
ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, (SSL_ERROR_BASE + 112),
|
||||
"Renegotiation is not allowed on this SSL socket.")
|
||||
ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, (SSL_ERROR_BASE + 112),
|
||||
"Renegotiation is not allowed on this SSL socket.")
|
||||
|
||||
ER3(SSL_ERROR_UNSAFE_NEGOTIATION, (SSL_ERROR_BASE + 113),
|
||||
"Peer attempted old style (potentially vulnerable) handshake.")
|
||||
ER3(SSL_ERROR_UNSAFE_NEGOTIATION, (SSL_ERROR_BASE + 113),
|
||||
"Peer attempted old style (potentially vulnerable) handshake.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD, (SSL_ERROR_BASE + 114),
|
||||
"SSL received an unexpected uncompressed record.")
|
||||
"SSL received an unexpected uncompressed record.")
|
||||
|
||||
ER3(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY, (SSL_ERROR_BASE + 115),
|
||||
"SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message.")
|
||||
ER3(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY, (SSL_ERROR_BASE + 115),
|
||||
"SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID, (SSL_ERROR_BASE + 116),
|
||||
"SSL received invalid NPN extension data.")
|
||||
ER3(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID, (SSL_ERROR_BASE + 116),
|
||||
"SSL received invalid NPN extension data.")
|
||||
|
||||
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2, (SSL_ERROR_BASE + 117),
|
||||
"SSL feature not supported for SSL 2.0 connections.")
|
||||
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2, (SSL_ERROR_BASE + 117),
|
||||
"SSL feature not supported for SSL 2.0 connections.")
|
||||
|
||||
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS, (SSL_ERROR_BASE + 118),
|
||||
"SSL feature not supported for servers.")
|
||||
"SSL feature not supported for servers.")
|
||||
|
||||
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS, (SSL_ERROR_BASE + 119),
|
||||
"SSL feature not supported for clients.")
|
||||
"SSL feature not supported for clients.")
|
||||
|
||||
ER3(SSL_ERROR_INVALID_VERSION_RANGE, (SSL_ERROR_BASE + 120),
|
||||
"SSL version range is not valid.")
|
||||
ER3(SSL_ERROR_INVALID_VERSION_RANGE, (SSL_ERROR_BASE + 120),
|
||||
"SSL version range is not valid.")
|
||||
|
||||
ER3(SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION, (SSL_ERROR_BASE + 121),
|
||||
"SSL peer selected a cipher suite disallowed for the selected protocol version.")
|
||||
ER3(SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION, (SSL_ERROR_BASE + 121),
|
||||
"SSL peer selected a cipher suite disallowed for the selected protocol version.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 122),
|
||||
"SSL received a malformed Hello Verify Request handshake message.")
|
||||
"SSL received a malformed Hello Verify Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST, (SSL_ERROR_BASE + 123),
|
||||
"SSL received an unexpected Hello Verify Request handshake message.")
|
||||
"SSL received an unexpected Hello Verify Request handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, (SSL_ERROR_BASE + 124),
|
||||
"SSL feature not supported for the protocol version.")
|
||||
"SSL feature not supported for the protocol version.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 125),
|
||||
"SSL received an unexpected Certificate Status handshake message.")
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_CERT_STATUS, (SSL_ERROR_BASE + 125),
|
||||
"SSL received an unexpected Certificate Status handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM, (SSL_ERROR_BASE + 126),
|
||||
"Unsupported hash algorithm used by TLS peer.")
|
||||
"Unsupported hash algorithm used by TLS peer.")
|
||||
|
||||
ER3(SSL_ERROR_DIGEST_FAILURE, (SSL_ERROR_BASE + 127),
|
||||
"Digest function failed.")
|
||||
"Digest function failed.")
|
||||
|
||||
ER3(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 128),
|
||||
"Incorrect signature algorithm specified in a digitally-signed element.")
|
||||
"Incorrect signature algorithm specified in a digitally-signed element.")
|
||||
|
||||
ER3(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK, (SSL_ERROR_BASE + 129),
|
||||
"The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.")
|
||||
"The next protocol negotiation extension was enabled, but the callback was cleared prior to being needed.")
|
||||
|
||||
ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130),
|
||||
"The server supports no protocols that the client advertises in the ALPN extension.")
|
||||
"The server supports no protocols that the client advertises in the ALPN extension.")
|
||||
|
||||
ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131),
|
||||
"The server rejected the handshake because the client downgraded to a lower "
|
||||
"TLS version than the server supports.")
|
||||
"The server rejected the handshake because the client downgraded to a lower "
|
||||
"TLS version than the server supports.")
|
||||
|
||||
ER3(SSL_ERROR_WEAK_SERVER_CERT_KEY, (SSL_ERROR_BASE + 132),
|
||||
"The server certificate included a public key that was too weak.")
|
||||
"The server certificate included a public key that was too weak.")
|
||||
|
||||
ER3(SSL_ERROR_RX_SHORT_DTLS_READ, (SSL_ERROR_BASE + 133),
|
||||
"Not enough room in buffer for DTLS record.")
|
||||
"Not enough room in buffer for DTLS record.")
|
||||
|
||||
ER3(SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 134),
|
||||
"No supported TLS signature algorithm was configured.")
|
||||
"No supported TLS signature algorithm was configured.")
|
||||
|
||||
ER3(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 135),
|
||||
"The peer used an unsupported combination of signature and hash algorithm.")
|
||||
"The peer used an unsupported combination of signature and hash algorithm.")
|
||||
|
||||
ER3(SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 136),
|
||||
"The peer tried to resume without a correct extended_master_secret extension")
|
||||
"The peer tried to resume without a correct extended_master_secret extension")
|
||||
|
||||
ER3(SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET, (SSL_ERROR_BASE + 137),
|
||||
"The peer tried to resume with an unexpected extended_master_secret extension")
|
||||
"The peer tried to resume with an unexpected extended_master_secret extension")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_KEY_SHARE, (SSL_ERROR_BASE + 138),
|
||||
"SSL received a malformed Key Share extension.")
|
||||
"SSL received a malformed Key Share extension.")
|
||||
|
||||
ER3(SSL_ERROR_MISSING_KEY_SHARE, (SSL_ERROR_BASE + 139),
|
||||
"SSL expected a Key Share extension.")
|
||||
"SSL expected a Key Share extension.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE, (SSL_ERROR_BASE + 140),
|
||||
"SSL received a malformed ECDHE key share handshake extension.")
|
||||
"SSL received a malformed ECDHE key share handshake extension.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE, (SSL_ERROR_BASE + 141),
|
||||
"SSL received a malformed DHE key share handshake extension.")
|
||||
"SSL received a malformed DHE key share handshake extension.")
|
||||
|
||||
ER3(SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS, (SSL_ERROR_BASE + 142),
|
||||
"SSL received a malformed Encrypted Extensions handshake message.")
|
||||
"SSL received an unexpected Encrypted Extensions handshake message.")
|
||||
|
||||
ER3(SSL_ERROR_MISSING_EXTENSION_ALERT, (SSL_ERROR_BASE + 143),
|
||||
"SSL received a missing_extenson alert.")
|
||||
"SSL received a missing_extenson alert.")
|
||||
|
||||
ER3(SSL_ERROR_KEY_EXCHANGE_FAILURE, (SSL_ERROR_BASE + 144),
|
||||
"SSL had an error performing key exchange.")
|
||||
"SSL had an error performing key exchange.")
|
||||
|
||||
ER3(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, (SSL_ERROR_BASE + 145),
|
||||
"SSL received an extension that is not permitted for this version.")
|
||||
"SSL received an extension that is not permitted for this version.")
|
||||
|
||||
ER3(SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS, (SSL_ERROR_BASE + 146),
|
||||
"SSL received a malformed Encrypted Extensions handshake message.")
|
||||
|
|
|
@ -16,74 +16,76 @@
|
|||
#include "key.h"
|
||||
#include "nss.h"
|
||||
#include "ssl.h"
|
||||
#include "pk11func.h" /* for PK11_ function calls */
|
||||
#include "pk11func.h" /* for PK11_ function calls */
|
||||
|
||||
/*
|
||||
* This callback used by SSL to pull client sertificate upon
|
||||
* server request
|
||||
*/
|
||||
SECStatus
|
||||
NSS_GetClientAuthData(void * arg,
|
||||
PRFileDesc * socket,
|
||||
struct CERTDistNamesStr * caNames,
|
||||
struct CERTCertificateStr ** pRetCert,
|
||||
struct SECKEYPrivateKeyStr **pRetKey)
|
||||
SECStatus
|
||||
NSS_GetClientAuthData(void *arg,
|
||||
PRFileDesc *socket,
|
||||
struct CERTDistNamesStr *caNames,
|
||||
struct CERTCertificateStr **pRetCert,
|
||||
struct SECKEYPrivateKeyStr **pRetKey)
|
||||
{
|
||||
CERTCertificate * cert = NULL;
|
||||
SECKEYPrivateKey * privkey = NULL;
|
||||
char * chosenNickName = (char *)arg; /* CONST */
|
||||
void * proto_win = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
proto_win = SSL_RevealPinArg(socket);
|
||||
|
||||
if (chosenNickName) {
|
||||
cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
|
||||
chosenNickName, certUsageSSLClient,
|
||||
PR_FALSE, proto_win);
|
||||
if ( cert ) {
|
||||
privkey = PK11_FindKeyByAnyCert(cert, proto_win);
|
||||
if ( privkey ) {
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
}
|
||||
} else { /* no name given, automatically find the right cert. */
|
||||
CERTCertNicknames * names;
|
||||
int i;
|
||||
|
||||
names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
|
||||
SEC_CERT_NICKNAMES_USER, proto_win);
|
||||
if (names != NULL) {
|
||||
for (i = 0; i < names->numnicknames; i++) {
|
||||
cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
|
||||
names->nicknames[i], certUsageSSLClient,
|
||||
PR_FALSE, proto_win);
|
||||
if ( !cert )
|
||||
continue;
|
||||
/* Only check unexpired certs */
|
||||
if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
|
||||
secCertTimeValid ) {
|
||||
CERT_DestroyCertificate(cert);
|
||||
continue;
|
||||
}
|
||||
rv = NSS_CmpCertChainWCANames(cert, caNames);
|
||||
if ( rv == SECSuccess ) {
|
||||
privkey = PK11_FindKeyByAnyCert(cert, proto_win);
|
||||
if ( privkey )
|
||||
break;
|
||||
}
|
||||
rv = SECFailure;
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
CERT_FreeNicknames(names);
|
||||
}
|
||||
}
|
||||
if (rv == SECSuccess) {
|
||||
*pRetCert = cert;
|
||||
*pRetKey = privkey;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
CERTCertificate *cert = NULL;
|
||||
SECKEYPrivateKey *privkey = NULL;
|
||||
char *chosenNickName = (char *)arg; /* CONST */
|
||||
void *proto_win = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
proto_win = SSL_RevealPinArg(socket);
|
||||
|
||||
if (chosenNickName) {
|
||||
cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
|
||||
chosenNickName, certUsageSSLClient,
|
||||
PR_FALSE, proto_win);
|
||||
if (cert) {
|
||||
privkey = PK11_FindKeyByAnyCert(cert, proto_win);
|
||||
if (privkey) {
|
||||
rv = SECSuccess;
|
||||
}
|
||||
else {
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* no name given, automatically find the right cert. */
|
||||
CERTCertNicknames *names;
|
||||
int i;
|
||||
|
||||
names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(),
|
||||
SEC_CERT_NICKNAMES_USER, proto_win);
|
||||
if (names != NULL) {
|
||||
for (i = 0; i < names->numnicknames; i++) {
|
||||
cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
|
||||
names->nicknames[i], certUsageSSLClient,
|
||||
PR_FALSE, proto_win);
|
||||
if (!cert)
|
||||
continue;
|
||||
/* Only check unexpired certs */
|
||||
if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE) !=
|
||||
secCertTimeValid) {
|
||||
CERT_DestroyCertificate(cert);
|
||||
continue;
|
||||
}
|
||||
rv = NSS_CmpCertChainWCANames(cert, caNames);
|
||||
if (rv == SECSuccess) {
|
||||
privkey =
|
||||
PK11_FindKeyByAnyCert(cert, proto_win);
|
||||
if (privkey)
|
||||
break;
|
||||
}
|
||||
rv = SECFailure;
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
CERT_FreeNicknames(names);
|
||||
}
|
||||
}
|
||||
if (rv == SECSuccess) {
|
||||
*pRetCert = cert;
|
||||
*pRetKey = privkey;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -18,73 +18,75 @@
|
|||
|
||||
/*
|
||||
* Look to see if any of the signers in the cert chain for "cert" are found
|
||||
* in the list of caNames.
|
||||
* in the list of caNames.
|
||||
* Returns SECSuccess if so, SECFailure if not.
|
||||
*/
|
||||
SECStatus
|
||||
NSS_CmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames)
|
||||
{
|
||||
SECItem * caname;
|
||||
CERTCertificate * curcert;
|
||||
CERTCertificate * oldcert;
|
||||
PRInt32 contentlen;
|
||||
int j;
|
||||
int headerlen;
|
||||
int depth;
|
||||
SECStatus rv;
|
||||
SECItem issuerName;
|
||||
SECItem compatIssuerName;
|
||||
SECItem *caname;
|
||||
CERTCertificate *curcert;
|
||||
CERTCertificate *oldcert;
|
||||
PRInt32 contentlen;
|
||||
int j;
|
||||
int headerlen;
|
||||
int depth;
|
||||
SECStatus rv;
|
||||
SECItem issuerName;
|
||||
SECItem compatIssuerName;
|
||||
|
||||
if (!cert || !caNames || !caNames->nnames || !caNames->names ||
|
||||
!caNames->names->data)
|
||||
return SECFailure;
|
||||
depth=0;
|
||||
curcert = CERT_DupCertificate(cert);
|
||||
|
||||
while( curcert ) {
|
||||
issuerName = curcert->derIssuer;
|
||||
|
||||
/* compute an alternate issuer name for compatibility with 2.0
|
||||
* enterprise server, which send the CA names without
|
||||
* the outer layer of DER header
|
||||
*/
|
||||
rv = DER_Lengths(&issuerName, &headerlen, (PRUint32 *)&contentlen);
|
||||
if ( rv == SECSuccess ) {
|
||||
compatIssuerName.data = &issuerName.data[headerlen];
|
||||
compatIssuerName.len = issuerName.len - headerlen;
|
||||
} else {
|
||||
compatIssuerName.data = NULL;
|
||||
compatIssuerName.len = 0;
|
||||
if (!cert || !caNames || !caNames->nnames || !caNames->names ||
|
||||
!caNames->names->data)
|
||||
return SECFailure;
|
||||
depth = 0;
|
||||
curcert = CERT_DupCertificate(cert);
|
||||
|
||||
while (curcert) {
|
||||
issuerName = curcert->derIssuer;
|
||||
|
||||
/* compute an alternate issuer name for compatibility with 2.0
|
||||
* enterprise server, which send the CA names without
|
||||
* the outer layer of DER header
|
||||
*/
|
||||
rv = DER_Lengths(&issuerName, &headerlen, (PRUint32 *)&contentlen);
|
||||
if (rv == SECSuccess) {
|
||||
compatIssuerName.data = &issuerName.data[headerlen];
|
||||
compatIssuerName.len = issuerName.len - headerlen;
|
||||
}
|
||||
else {
|
||||
compatIssuerName.data = NULL;
|
||||
compatIssuerName.len = 0;
|
||||
}
|
||||
|
||||
for (j = 0; j < caNames->nnames; j++) {
|
||||
caname = &caNames->names[j];
|
||||
if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) {
|
||||
rv = SECSuccess;
|
||||
CERT_DestroyCertificate(curcert);
|
||||
goto done;
|
||||
}
|
||||
else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) {
|
||||
rv = SECSuccess;
|
||||
CERT_DestroyCertificate(curcert);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if ((depth <= 20) &&
|
||||
(SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject) !=
|
||||
SECEqual)) {
|
||||
oldcert = curcert;
|
||||
curcert = CERT_FindCertByName(curcert->dbhandle,
|
||||
&curcert->derIssuer);
|
||||
CERT_DestroyCertificate(oldcert);
|
||||
depth++;
|
||||
}
|
||||
else {
|
||||
CERT_DestroyCertificate(curcert);
|
||||
curcert = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < caNames->nnames; j++) {
|
||||
caname = &caNames->names[j];
|
||||
if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) {
|
||||
rv = SECSuccess;
|
||||
CERT_DestroyCertificate(curcert);
|
||||
goto done;
|
||||
} else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) {
|
||||
rv = SECSuccess;
|
||||
CERT_DestroyCertificate(curcert);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if ( ( depth <= 20 ) &&
|
||||
( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject)
|
||||
!= SECEqual ) ) {
|
||||
oldcert = curcert;
|
||||
curcert = CERT_FindCertByName(curcert->dbhandle,
|
||||
&curcert->derIssuer);
|
||||
CERT_DestroyCertificate(oldcert);
|
||||
depth++;
|
||||
} else {
|
||||
CERT_DestroyCertificate(curcert);
|
||||
curcert = NULL;
|
||||
}
|
||||
}
|
||||
rv = SECFailure;
|
||||
|
||||
rv = SECFailure;
|
||||
|
||||
done:
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -11,7 +11,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#ifndef PR_ARRAY_SIZE
|
||||
#define PR_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
#define PR_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
static SECStatus dtls_TransmitMessageFlight(sslSocket *ss);
|
||||
|
@ -20,10 +20,10 @@ static SECStatus dtls_SendSavedWriteData(sslSocket *ss);
|
|||
|
||||
/* -28 adjusts for the IP/UDP header */
|
||||
static const PRUint16 COMMON_MTU_VALUES[] = {
|
||||
1500 - 28, /* Ethernet MTU */
|
||||
1280 - 28, /* IPv6 minimum MTU */
|
||||
576 - 28, /* Common assumption */
|
||||
256 - 28 /* We're in serious trouble now */
|
||||
1500 - 28, /* Ethernet MTU */
|
||||
1280 - 28, /* IPv6 minimum MTU */
|
||||
576 - 28, /* Common assumption */
|
||||
256 - 28 /* We're in serious trouble now */
|
||||
};
|
||||
|
||||
#define DTLS_COOKIE_BYTES 32
|
||||
|
@ -104,9 +104,9 @@ dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv)
|
|||
|
||||
/* On this socket, Disable non-DTLS cipher suites in the argument's list */
|
||||
SECStatus
|
||||
ssl3_DisableNonDTLSSuites(sslSocket * ss)
|
||||
ssl3_DisableNonDTLSSuites(sslSocket *ss)
|
||||
{
|
||||
const ssl3CipherSuite * suite;
|
||||
const ssl3CipherSuite *suite;
|
||||
|
||||
for (suite = nonDTLSSuites; *suite; ++suite) {
|
||||
PORT_CheckSuccess(ssl3_CipherPrefSet(ss, *suite, PR_FALSE));
|
||||
|
@ -190,8 +190,8 @@ dtls_FreeHandshakeMessages(PRCList *list)
|
|||
* the state of reassembly (i.e., whether one is in progress). That
|
||||
* is carried in recvdHighWater and recvdFragments.
|
||||
*/
|
||||
#define OFFSET_BYTE(o) (o/8)
|
||||
#define OFFSET_MASK(o) (1 << (o%8))
|
||||
#define OFFSET_BYTE(o) (o / 8)
|
||||
#define OFFSET_MASK(o) (1 << (o % 8))
|
||||
|
||||
SECStatus
|
||||
dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
|
@ -229,7 +229,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
fragment_offset = (buf.buf[6] << 16) | (buf.buf[7] << 8) | buf.buf[8];
|
||||
fragment_length = (buf.buf[9] << 16) | (buf.buf[10] << 8) | buf.buf[11];
|
||||
|
||||
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
|
||||
#define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */
|
||||
if (message_length > MAX_HANDSHAKE_MSG_LEN) {
|
||||
(void)ssl3_DecodeError(ss);
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
|
||||
|
@ -263,9 +263,9 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
* If it's the complete next message we accept it right away.
|
||||
* This is the common case for short messages
|
||||
*/
|
||||
if ((message_seq == ss->ssl3.hs.recvMessageSeq)
|
||||
&& (fragment_offset == 0)
|
||||
&& (fragment_length == message_length)) {
|
||||
if ((message_seq == ss->ssl3.hs.recvMessageSeq) &&
|
||||
(fragment_offset == 0) &&
|
||||
(fragment_length == message_length)) {
|
||||
/* Complete next message. Process immediately */
|
||||
ss->ssl3.hs.msg_type = (SSL3HandshakeType)type;
|
||||
ss->ssl3.hs.msg_len = message_length;
|
||||
|
@ -287,13 +287,15 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
/* Do not attempt to process rest of messages in this record */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (message_seq < ss->ssl3.hs.recvMessageSeq) {
|
||||
/* Case 3: we do an immediate retransmit if we're
|
||||
* in a waiting state*/
|
||||
if (ss->ssl3.hs.rtTimerCb == NULL) {
|
||||
/* Ignore */
|
||||
} else if (ss->ssl3.hs.rtTimerCb ==
|
||||
}
|
||||
else if (ss->ssl3.hs.rtTimerCb ==
|
||||
dtls_RetransmitTimerExpiredCb) {
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: Retransmit detected",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
@ -304,24 +306,26 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
*/
|
||||
if ((PR_IntervalNow() - ss->ssl3.hs.rtTimerStarted) >
|
||||
(ss->ssl3.hs.rtTimeoutMs / 4)) {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: Shortcutting retransmit timer",
|
||||
SSL_GETPID(), ss->fd));
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: Shortcutting retransmit timer",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
||||
/* Cancel the timer and call the CB,
|
||||
* which re-arms the timer */
|
||||
dtls_CancelTimer(ss);
|
||||
dtls_RetransmitTimerExpiredCb(ss);
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
} else {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: We just retransmitted. Ignoring.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
} else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
|
||||
/* Cancel the timer and call the CB,
|
||||
* which re-arms the timer */
|
||||
dtls_CancelTimer(ss);
|
||||
dtls_RetransmitTimerExpiredCb(ss);
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
SSL_TRC(30,
|
||||
("%d: SSL3[%d]: We just retransmitted. Ignoring.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ss->ssl3.hs.rtTimerCb == dtls_FinishedTimerCb) {
|
||||
/* Retransmit the messages and re-arm the timer
|
||||
* Note that we are not backing off the timer here.
|
||||
* The spec isn't clear and my reasoning is that this
|
||||
|
@ -336,7 +340,8 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
return rv;
|
||||
break;
|
||||
}
|
||||
} else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
|
||||
}
|
||||
else if (message_seq > ss->ssl3.hs.recvMessageSeq) {
|
||||
/* Case 2
|
||||
*
|
||||
* Ignore this message. This means we don't handle out of
|
||||
|
@ -345,7 +350,8 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
*
|
||||
* XXX OK for now. Maybe do something smarter at some point?
|
||||
*/
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Case 1
|
||||
*
|
||||
* Buffer the fragment for reassembly
|
||||
|
@ -404,7 +410,8 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
* fragment */
|
||||
ss->ssl3.hs.recvdHighWater = fragment_offset +
|
||||
fragment_length;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (offset = fragment_offset;
|
||||
offset < fragment_offset + fragment_length;
|
||||
offset++) {
|
||||
|
@ -422,7 +429,8 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
if (ss->ssl3.hs.recvdFragments.buf[OFFSET_BYTE(offset)] &
|
||||
OFFSET_MASK(offset)) {
|
||||
ss->ssl3.hs.recvdHighWater++;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -455,7 +463,7 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
buf.len -= fragment_length;
|
||||
}
|
||||
|
||||
origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
|
||||
origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
|
||||
|
||||
/* XXX OK for now. In future handle rv == SECWouldBlock safely in order
|
||||
* to deal with asynchronous certificate verification */
|
||||
|
@ -468,8 +476,9 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
|||
* dtls_StageHandshakeMessage()
|
||||
* ssl3_SendChangeCipherSpecs()
|
||||
*/
|
||||
SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
|
||||
const SSL3Opaque *pIn, PRInt32 nIn)
|
||||
SECStatus
|
||||
dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
|
||||
const SSL3Opaque *pIn, PRInt32 nIn)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
DTLSQueuedMessage *msg = NULL;
|
||||
|
@ -482,7 +491,8 @@ SECStatus dtls_QueueMessage(sslSocket *ss, SSL3ContentType type,
|
|||
if (!msg) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PR_APPEND_LINK(&msg->link, &ss->ssl3.hs.lastMessageFlight);
|
||||
}
|
||||
|
||||
|
@ -639,7 +649,7 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
|||
sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
|
||||
msg->data, msg->len,
|
||||
ssl_SEND_FLAG_FORCE_INTO_BUFFER |
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
if (sent != msg->len) {
|
||||
rv = SECFailure;
|
||||
if (sent != -1) {
|
||||
|
@ -649,7 +659,8 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
|||
}
|
||||
|
||||
room_left = ss->ssl3.mtu - ss->pendingBuf.len;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* The message will not fit, so fragment.
|
||||
*
|
||||
* XXX OK for now. Arrange to coalesce the last fragment
|
||||
|
@ -699,12 +710,12 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
|||
/* Offset */
|
||||
fragment[6] = (fragment_offset >> 16) & 0xff;
|
||||
fragment[7] = (fragment_offset >> 8) & 0xff;
|
||||
fragment[8] = (fragment_offset) & 0xff;
|
||||
fragment[8] = (fragment_offset)&0xff;
|
||||
|
||||
/* Fragment length */
|
||||
fragment[9] = (fragment_len >> 16) & 0xff;
|
||||
fragment[10] = (fragment_len >> 8) & 0xff;
|
||||
fragment[11] = (fragment_len) & 0xff;
|
||||
fragment[11] = (fragment_len)&0xff;
|
||||
|
||||
PORT_Memcpy(fragment + 12, content + fragment_offset,
|
||||
fragment_len);
|
||||
|
@ -716,7 +727,7 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
|||
sent = ssl3_SendRecord(ss, msg->epoch, msg->type,
|
||||
fragment, fragment_len + 12,
|
||||
ssl_SEND_FLAG_FORCE_INTO_BUFFER |
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
ssl_SEND_FLAG_USE_EPOCH);
|
||||
if (sent != (fragment_len + 12)) {
|
||||
rv = SECFailure;
|
||||
if (sent != -1) {
|
||||
|
@ -752,8 +763,8 @@ dtls_TransmitMessageFlight(sslSocket *ss)
|
|||
*
|
||||
* Called from dtls_TransmitMessageFlight()
|
||||
*/
|
||||
static
|
||||
SECStatus dtls_SendSavedWriteData(sslSocket *ss)
|
||||
static SECStatus
|
||||
dtls_SendSavedWriteData(sslSocket *ss)
|
||||
{
|
||||
PRInt32 sent;
|
||||
|
||||
|
@ -784,18 +795,18 @@ SECStatus dtls_SendSavedWriteData(sslSocket *ss)
|
|||
* Called from ssl3_SendRecord()
|
||||
*/
|
||||
SECStatus
|
||||
dtls_CompressMACEncryptRecord(sslSocket * ss,
|
||||
DTLSEpoch epoch,
|
||||
PRBool use_epoch,
|
||||
SSL3ContentType type,
|
||||
const SSL3Opaque * pIn,
|
||||
PRUint32 contentLen,
|
||||
sslBuffer * wrBuf)
|
||||
dtls_CompressMACEncryptRecord(sslSocket *ss,
|
||||
DTLSEpoch epoch,
|
||||
PRBool use_epoch,
|
||||
SSL3ContentType type,
|
||||
const SSL3Opaque *pIn,
|
||||
PRUint32 contentLen,
|
||||
sslBuffer *wrBuf)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
ssl3CipherSpec * cwSpec;
|
||||
ssl3CipherSpec *cwSpec;
|
||||
|
||||
ssl_GetSpecReadLock(ss); /********************************/
|
||||
ssl_GetSpecReadLock(ss); /********************************/
|
||||
|
||||
/* The reason for this switch-hitting code is that we might have
|
||||
* a flight of records spanning an epoch boundary, e.g.,
|
||||
|
@ -814,7 +825,8 @@ dtls_CompressMACEncryptRecord(sslSocket * ss,
|
|||
cwSpec = ss->ssl3.pwSpec;
|
||||
else
|
||||
cwSpec = NULL;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
cwSpec = ss->ssl3.cwSpec;
|
||||
}
|
||||
|
||||
|
@ -823,10 +835,12 @@ dtls_CompressMACEncryptRecord(sslSocket * ss,
|
|||
rv = ssl3_CompressMACEncryptRecord(cwSpec, ss->sec.isServer, PR_TRUE,
|
||||
PR_FALSE, type, pIn, contentLen,
|
||||
wrBuf);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
rv = tls13_ProtectRecord(ss, type, pIn, contentLen, wrBuf);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PR_NOT_REACHED("Couldn't find a cipher spec matching epoch");
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
|
@ -965,7 +979,7 @@ dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
|
|||
}
|
||||
|
||||
/* Fallback */
|
||||
ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES)-1];
|
||||
ss->ssl3.mtu = COMMON_MTU_VALUES[PR_ARRAY_SIZE(COMMON_MTU_VALUES) - 1];
|
||||
SSL_TRC(30, ("Resetting MTU to %d", ss->ssl3.mtu));
|
||||
}
|
||||
|
||||
|
@ -976,27 +990,27 @@ dtls_SetMTU(sslSocket *ss, PRUint16 advertised)
|
|||
SECStatus
|
||||
dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
||||
{
|
||||
int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
|
||||
SECStatus rv;
|
||||
PRInt32 temp;
|
||||
SECItem cookie = {siBuffer, NULL, 0};
|
||||
SSL3AlertDescription desc = illegal_parameter;
|
||||
int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
|
||||
SECStatus rv;
|
||||
PRInt32 temp;
|
||||
SECItem cookie = { siBuffer, NULL, 0 };
|
||||
SSL3AlertDescription desc = illegal_parameter;
|
||||
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
|
||||
SSL_GETPID(), ss->fd));
|
||||
SSL_GETPID(), ss->fd));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
||||
|
||||
if (ss->ssl3.hs.ws != wait_server_hello) {
|
||||
errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST;
|
||||
desc = unexpected_message;
|
||||
desc = unexpected_message;
|
||||
goto alert_loser;
|
||||
}
|
||||
|
||||
/* The version */
|
||||
temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
|
||||
if (temp < 0) {
|
||||
goto loser; /* alert has been sent */
|
||||
goto loser; /* alert has been sent */
|
||||
}
|
||||
|
||||
if (temp != SSL_LIBRARY_VERSION_DTLS_1_0_WIRE &&
|
||||
|
@ -1007,23 +1021,22 @@ dtls_HandleHelloVerifyRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
|||
/* The cookie */
|
||||
rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser; /* alert has been sent */
|
||||
goto loser; /* alert has been sent */
|
||||
}
|
||||
if (cookie.len > DTLS_COOKIE_BYTES) {
|
||||
desc = decode_error;
|
||||
goto alert_loser; /* malformed. */
|
||||
goto alert_loser; /* malformed. */
|
||||
}
|
||||
|
||||
PORT_Memcpy(ss->ssl3.hs.cookie, cookie.data, cookie.len);
|
||||
ss->ssl3.hs.cookieLen = cookie.len;
|
||||
|
||||
|
||||
ssl_GetXmitBufLock(ss); /*******************************/
|
||||
ssl_GetXmitBufLock(ss); /*******************************/
|
||||
|
||||
/* Now re-send the client hello */
|
||||
rv = ssl3_SendClientHello(ss, PR_TRUE);
|
||||
|
||||
ssl_ReleaseXmitBufLock(ss); /*******************************/
|
||||
ssl_ReleaseXmitBufLock(ss); /*******************************/
|
||||
|
||||
if (rv == SECSuccess)
|
||||
return rv;
|
||||
|
@ -1127,7 +1140,7 @@ dtls_RecordSetRecvd(DTLSRecvdRecords *records, PRUint64 seq)
|
|||
SECStatus
|
||||
DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
|
||||
{
|
||||
sslSocket * ss = NULL;
|
||||
sslSocket *ss = NULL;
|
||||
PRIntervalTime elapsed;
|
||||
PRIntervalTime desired;
|
||||
|
||||
|
@ -1147,7 +1160,8 @@ DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
|
|||
if (elapsed > desired) {
|
||||
/* Timer expired */
|
||||
*timeout = PR_INTERVAL_NO_WAIT;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*timeout = desired - elapsed;
|
||||
}
|
||||
|
||||
|
@ -1175,7 +1189,8 @@ dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *crSpec,
|
|||
|
||||
if (crSpec->epoch != epoch) {
|
||||
SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, received packet "
|
||||
"from irrelevant epoch %d", SSL_GETPID(), ss->fd, epoch));
|
||||
"from irrelevant epoch %d",
|
||||
SSL_GETPID(), ss->fd, epoch));
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1184,7 +1199,8 @@ dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *crSpec,
|
|||
|
||||
if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
|
||||
SSL_DBG(("%d: SSL3[%d]: dtls_IsRelevant, rejecting "
|
||||
"potentially replayed packet", SSL_GETPID(), ss->fd));
|
||||
"potentially replayed packet",
|
||||
SSL_GETPID(), ss->fd));
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,49 +10,49 @@ incoming:
|
|||
gs = ss->gather
|
||||
hs = ss->ssl3->hs
|
||||
|
||||
gs->inbuf SSL3 only: incoming (encrypted) ssl records are placed here,
|
||||
and then decrypted (or copied) to gs->buf.
|
||||
gs->inbuf SSL3 only: incoming (encrypted) ssl records are placed here,
|
||||
and then decrypted (or copied) to gs->buf.
|
||||
|
||||
gs->buf SSL2: incoming SSL records are put here, and then decrypted
|
||||
in place.
|
||||
SSL3: ssl3_HandleHandshake puts decrypted ssl records here.
|
||||
gs->buf SSL2: incoming SSL records are put here, and then decrypted
|
||||
in place.
|
||||
SSL3: ssl3_HandleHandshake puts decrypted ssl records here.
|
||||
|
||||
hs.msg_body (SSL3 only) When an incoming handshake message spans more
|
||||
than one ssl record, the first part(s) of it are accumulated
|
||||
here until it all arrives.
|
||||
hs.msg_body (SSL3 only) When an incoming handshake message spans more
|
||||
than one ssl record, the first part(s) of it are accumulated
|
||||
here until it all arrives.
|
||||
|
||||
hs.msgState (SSL3 only) an alternative set of pointers/lengths for gs->buf.
|
||||
Used only when a handleHandshake function returns SECWouldBlock.
|
||||
ssl3_HandleHandshake remembers how far it previously got by
|
||||
using these pointers instead of gs->buf when it is called
|
||||
after a previous SECWouldBlock return.
|
||||
hs.msgState (SSL3 only) an alternative set of pointers/lengths for gs->buf.
|
||||
Used only when a handleHandshake function returns SECWouldBlock.
|
||||
ssl3_HandleHandshake remembers how far it previously got by
|
||||
using these pointers instead of gs->buf when it is called
|
||||
after a previous SECWouldBlock return.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
outgoing:
|
||||
|
||||
sec = ss->sec
|
||||
ci = ss->sec->ci /* connect info */
|
||||
ci = ss->sec->ci /* connect info */
|
||||
|
||||
ci->sendBuf Outgoing handshake messages are appended to this buffer.
|
||||
This buffer will then be sent as a single SSL record.
|
||||
ci->sendBuf Outgoing handshake messages are appended to this buffer.
|
||||
This buffer will then be sent as a single SSL record.
|
||||
|
||||
sec->writeBuf outgoing ssl records are constructed here and encrypted in
|
||||
place before being written or copied to pendingBuf.
|
||||
sec->writeBuf outgoing ssl records are constructed here and encrypted in
|
||||
place before being written or copied to pendingBuf.
|
||||
|
||||
ss->pendingBuf contains outgoing ciphertext that was saved after a write
|
||||
attempt to the socket failed, e.g. EWouldBlock.
|
||||
Generally empty with blocking sockets (should be no incomplete
|
||||
writes).
|
||||
ss->pendingBuf contains outgoing ciphertext that was saved after a write
|
||||
attempt to the socket failed, e.g. EWouldBlock.
|
||||
Generally empty with blocking sockets (should be no incomplete
|
||||
writes).
|
||||
|
||||
ss->saveBuf Used only by socks code. Intended to be used to buffer
|
||||
outgoing data until a socks handshake completes. However,
|
||||
this buffer is always empty. There is no code to put
|
||||
anything into it.
|
||||
ss->saveBuf Used only by socks code. Intended to be used to buffer
|
||||
outgoing data until a socks handshake completes. However,
|
||||
this buffer is always empty. There is no code to put
|
||||
anything into it.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
SECWouldBlock means that the function cannot make progress because it is
|
||||
waiting for some event OTHER THAN socket I/O completion (e.g. waiting for
|
||||
SECWouldBlock means that the function cannot make progress because it is
|
||||
waiting for some event OTHER THAN socket I/O completion (e.g. waiting for
|
||||
user dialog to finish). It is not the same as EWOULDBLOCK.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
@ -65,51 +65,51 @@ sendLock ->/
|
|||
crypto and hash Data that must be protected while turning plaintext into
|
||||
ciphertext:
|
||||
|
||||
SSL2: (in ssl2_Send*)
|
||||
sec->hash*
|
||||
sec->hashcx (ptr and data)
|
||||
sec->enc
|
||||
sec->writecx* (ptr and content)
|
||||
sec->sendSecret*(ptr and content)
|
||||
sec->sendSequence locked by xmitBufLock
|
||||
sec->blockSize
|
||||
sec->writeBuf* (ptr & content) locked by xmitBufLock
|
||||
"in" locked by xmitBufLock
|
||||
SSL2: (in ssl2_Send*)
|
||||
sec->hash*
|
||||
sec->hashcx (ptr and data)
|
||||
sec->enc
|
||||
sec->writecx* (ptr and content)
|
||||
sec->sendSecret*(ptr and content)
|
||||
sec->sendSequence locked by xmitBufLock
|
||||
sec->blockSize
|
||||
sec->writeBuf* (ptr & content) locked by xmitBufLock
|
||||
"in" locked by xmitBufLock
|
||||
|
||||
SSl3: (in ssl3_SendPlainText)
|
||||
ss->ssl3 (the pointer)
|
||||
ss->ssl3->current_write* (the pointer and the data in the spec
|
||||
and any data referenced by the spec.
|
||||
SSl3: (in ssl3_SendPlainText)
|
||||
ss->ssl3 (the pointer)
|
||||
ss->ssl3->current_write* (the pointer and the data in the spec
|
||||
and any data referenced by the spec.
|
||||
|
||||
ss->sec->isServer
|
||||
ss->sec->writebuf* (ptr & content) locked by xmitBufLock
|
||||
"buf" locked by xmitBufLock
|
||||
ss->sec->isServer
|
||||
ss->sec->writebuf* (ptr & content) locked by xmitBufLock
|
||||
"buf" locked by xmitBufLock
|
||||
|
||||
crypto and hash data that must be protected while turning ciphertext into
|
||||
crypto and hash data that must be protected while turning ciphertext into
|
||||
plaintext:
|
||||
|
||||
SSL2: (in ssl2_GatherData)
|
||||
gs->* (locked by recvBufLock )
|
||||
sec->dec
|
||||
sec->readcx
|
||||
sec->hash* (ptr and data)
|
||||
sec->hashcx (ptr and data)
|
||||
SSL2: (in ssl2_GatherData)
|
||||
gs->* (locked by recvBufLock )
|
||||
sec->dec
|
||||
sec->readcx
|
||||
sec->hash* (ptr and data)
|
||||
sec->hashcx (ptr and data)
|
||||
|
||||
SSL3: (in ssl3_HandleRecord )
|
||||
ssl3->current_read* (the pointer and all data refernced)
|
||||
ss->sec->isServer
|
||||
SSL3: (in ssl3_HandleRecord )
|
||||
ssl3->current_read* (the pointer and all data refernced)
|
||||
ss->sec->isServer
|
||||
|
||||
|
||||
Data that must be protected while being used by a "writer":
|
||||
|
||||
ss->pendingBuf.*
|
||||
ss->saveBuf.* (which is dead)
|
||||
ss->saveBuf.* (which is dead)
|
||||
|
||||
in ssl3_sendPlainText
|
||||
|
||||
ss->ssl3->current_write-> (spec)
|
||||
ss->sec->writeBuf.*
|
||||
ss->sec->isServer
|
||||
ss->sec->isServer
|
||||
|
||||
in SendBlock
|
||||
|
||||
|
@ -118,17 +118,17 @@ ss->sec->blockSize
|
|||
ss->sec->writeBuf.*
|
||||
ss->sec->sendSecret
|
||||
ss->sec->sendSequence
|
||||
ss->sec->writecx *
|
||||
ss->sec->writecx *
|
||||
ss->pendingBuf
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
Data variables (not const) protected by the "sslGlobalDataLock".
|
||||
Data variables (not const) protected by the "sslGlobalDataLock".
|
||||
Note, this really should be a reader/writer lock.
|
||||
|
||||
allowedByPolicy sslcon.c
|
||||
maybeAllowedByPolicy sslcon.c
|
||||
chosenPreference sslcon.c
|
||||
policyWasSet sslcon.c
|
||||
allowedByPolicy sslcon.c
|
||||
maybeAllowedByPolicy sslcon.c
|
||||
chosenPreference sslcon.c
|
||||
policyWasSet sslcon.c
|
||||
|
||||
cipherSuites[] ssl3con.c
|
||||
cipherSuites[] ssl3con.c
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* This file essentially replicates NSPR's source for the functions that
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* NSPR's functions, instead of duplicating them, but they're private.
|
||||
* As long as SSL's server session cache code must do platform native I/O
|
||||
* to accomplish its job, and NSPR's error mapping functions remain private,
|
||||
* this code will continue to need to be replicated.
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -15,7 +15,6 @@
|
|||
#include "prlog.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/*
|
||||
* Based on win32err.c
|
||||
* OS2TODO Stub everything for now to build. HCT
|
||||
|
@ -24,79 +23,94 @@
|
|||
/* forward declaration. */
|
||||
void nss_MD_os2_map_default_error(PRInt32 err);
|
||||
|
||||
void nss_MD_os2_map_opendir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_opendir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_closedir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_closedir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_readdir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_readdir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_delete_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_delete_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
/* The error code for stat() is in errno. */
|
||||
void nss_MD_os2_map_stat_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_stat_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_fstat_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_fstat_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_rename_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_rename_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
/* The error code for access() is in errno. */
|
||||
void nss_MD_os2_map_access_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_access_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_mkdir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_mkdir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_rmdir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_rmdir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_read_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_read_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_transmitfile_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_transmitfile_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_write_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_write_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_lseek_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_lseek_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_fsync_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_fsync_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
@ -104,177 +118,213 @@ void nss_MD_os2_map_fsync_error(PRInt32 err)
|
|||
/*
|
||||
* For both CloseHandle() and closesocket().
|
||||
*/
|
||||
void nss_MD_os2_map_close_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_close_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_socket_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_socket_error(PRInt32 err)
|
||||
{
|
||||
// PR_ASSERT(err != WSANOTINITIALISED);
|
||||
// PR_ASSERT(err != WSANOTINITIALISED);
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_recv_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_recv_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_recvfrom_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_recvfrom_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_send_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_send_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_sendto_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_sendto_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_accept_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_accept_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
|
||||
// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
|
||||
// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_acceptex_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_acceptex_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_connect_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_connect_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEWOULDBLOCK: prError = PR_IN_PROGRESS_ERROR; break;
|
||||
// case WSAEINVAL: prError = PR_ALREADY_INITIATED_ERROR; break;
|
||||
// case WSAETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEWOULDBLOCK: prError = PR_IN_PROGRESS_ERROR; break;
|
||||
// case WSAEINVAL: prError = PR_ALREADY_INITIATED_ERROR; break;
|
||||
// case WSAETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_bind_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_bind_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_listen_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_listen_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
|
||||
// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
|
||||
// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_shutdown_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_shutdown_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_getsockname_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_getsockname_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_getpeername_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_getpeername_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_getsockopt_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_getsockopt_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_setsockopt_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_setsockopt_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_open_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_open_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_gethostname_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_gethostname_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
/* Win32 select() only works on sockets. So in this
|
||||
** context, WSAENOTSOCK is equivalent to EBADF on Unix.
|
||||
** context, WSAENOTSOCK is equivalent to EBADF on Unix.
|
||||
*/
|
||||
void nss_MD_os2_map_select_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_select_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
// case WSAENOTSOCK: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
default: nss_MD_os2_map_default_error(err); return;
|
||||
// case WSAENOTSOCK: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
default:
|
||||
nss_MD_os2_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_os2_map_lockf_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_lockf_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_os2_map_default_error(err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void nss_MD_os2_map_default_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_os2_map_default_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
|
||||
switch (err) {
|
||||
// case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
// case ERROR_ACCESS_DENIED: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
|
||||
// case ERROR_ALREADY_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
|
||||
// case ERROR_DISK_CORRUPT: prError = PR_IO_ERROR; break;
|
||||
// case ERROR_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
|
||||
// case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
// case ERROR_ACCESS_DENIED: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
|
||||
// case ERROR_ALREADY_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
|
||||
// case ERROR_DISK_CORRUPT: prError = PR_IO_ERROR; break;
|
||||
// case ERROR_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
|
||||
// case ERROR_DISK_OPERATION_FAILED: prError = PR_IO_ERROR; break;
|
||||
// case ERROR_DRIVE_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
|
||||
// case ERROR_DRIVE_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
|
||||
// case ERROR_FILENAME_EXCED_RANGE: prError = PR_NAME_TOO_LONG_ERROR; break;
|
||||
// case ERROR_FILE_CORRUPT: prError = PR_IO_ERROR; break;
|
||||
// case ERROR_FILE_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
|
||||
// case ERROR_FILE_INVALID: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
// case ERROR_FILE_CORRUPT: prError = PR_IO_ERROR; break;
|
||||
// case ERROR_FILE_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
|
||||
// case ERROR_FILE_INVALID: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
#if ERROR_FILE_NOT_FOUND != ENOENT
|
||||
// case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
// case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
#endif
|
||||
default: prError = PR_UNKNOWN_ERROR; break;
|
||||
default:
|
||||
prError = PR_UNKNOWN_ERROR;
|
||||
break;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file essentially replicates NSPR's source for the functions that
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* NSPR's functions, instead of duplicating them, but they're private.
|
||||
* As long as SSL's server session cache code must do platform native I/O
|
||||
* to accomplish its job, and NSPR's error mapping functions remain private,
|
||||
* This code will continue to need to be replicated.
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
|
@ -25,89 +25,89 @@ 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];
|
||||
unsigned char iv[24];
|
||||
unsigned char hash[20];
|
||||
unsigned char serial[8];
|
||||
};
|
||||
|
||||
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];
|
||||
unsigned char iv[24];
|
||||
unsigned char hash[20];
|
||||
unsigned char Ra[128];
|
||||
unsigned char Y[128];
|
||||
};
|
||||
|
||||
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];
|
||||
unsigned char labelLen[2];
|
||||
unsigned char keyIDLen[2];
|
||||
unsigned char ivLen[2];
|
||||
unsigned char keyLen[2];
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
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];
|
||||
unsigned char issuerLen[2];
|
||||
unsigned char serialLen[2];
|
||||
unsigned char ivLen[2];
|
||||
unsigned char keyLen[2];
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
#define PEFIXED_Label(header) (header->data)
|
||||
#define PEFIXED_KeyID(header) (&header->data[GetInt2(header->labelLen)])
|
||||
#define PEFIXED_IV(header) (&header->data[GetInt2(header->labelLen)\
|
||||
+GetInt2(header->keyIDLen)])
|
||||
#define PEFIXED_Key(header) (&header->data[GetInt2(header->labelLen)\
|
||||
+GetInt2(header->keyIDLen)+GetInt2(header->keyLen)])
|
||||
#define PEFIXED_IV(header) (&header->data[GetInt2(header->labelLen) + \
|
||||
GetInt2(header->keyIDLen)])
|
||||
#define PEFIXED_Key(header) (&header->data[GetInt2(header->labelLen) + \
|
||||
GetInt2(header->keyIDLen) + \
|
||||
GetInt2(header->keyLen)])
|
||||
#define PERSA_Issuer(header) (header->data)
|
||||
#define PERSA_Serial(header) (&header->data[GetInt2(header->issuerLen)])
|
||||
#define PERSA_IV(header) (&header->data[GetInt2(header->issuerLen)\
|
||||
+GetInt2(header->serialLen)])
|
||||
#define PERSA_Key(header) (&header->data[GetInt2(header->issuerLen)\
|
||||
+GetInt2(header->serialLen)+GetInt2(header->keyLen)])
|
||||
#define PERSA_IV(header) (&header->data[GetInt2(header->issuerLen) + \
|
||||
GetInt2(header->serialLen)])
|
||||
#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];
|
||||
unsigned char len[2];
|
||||
unsigned char type[2];
|
||||
unsigned char version[2];
|
||||
union {
|
||||
PEFortezzaHeader fortezza;
|
||||
PEFortezzaHeader fortezza;
|
||||
PEFortezzaGeneratedHeader g_fortezza;
|
||||
PEFixedKeyHeader fixed;
|
||||
PERSAKeyHeader rsa;
|
||||
PEFixedKeyHeader fixed;
|
||||
PERSAKeyHeader rsa;
|
||||
} u;
|
||||
};
|
||||
|
||||
#define PE_CRYPT_INTRO_LEN 8
|
||||
#define PE_INTRO_LEN 4
|
||||
#define PE_BASE_HEADER_LEN 8
|
||||
|
||||
#define PRE_BLOCK_SIZE 8
|
||||
#define PE_BASE_HEADER_LEN 8
|
||||
|
||||
#define PRE_BLOCK_SIZE 8
|
||||
|
||||
#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]))
|
||||
#define PutInt2(c,i) ((c[1] = (i) & 0xff), (c[0] = ((i) >> 8) & 0xff))
|
||||
#define PutInt4(c,i) ((c[0]=((i) >> 24) & 0xff),(c[1]=((i) >> 16) & 0xff),\
|
||||
(c[2] = ((i) >> 8) & 0xff), (c[3] = (i) & 0xff))
|
||||
#define GetInt4(c) (((unsigned long)c[0] << 24) | ((unsigned long)c[1] << 16) | \
|
||||
((unsigned long)c[2] << 8) | ((unsigned long)c[3]))
|
||||
#define PutInt2(c, i) ((c[1] = (i)&0xff), (c[0] = ((i) >> 8) & 0xff))
|
||||
#define PutInt4(c, i) ((c[0] = ((i) >> 24) & 0xff), (c[1] = ((i) >> 16) & 0xff), \
|
||||
(c[2] = ((i) >> 8) & 0xff), (c[3] = (i)&0xff))
|
||||
|
||||
#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_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
|
||||
|
||||
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *,
|
||||
int *headerSize);
|
||||
int *headerSize);
|
||||
|
||||
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *,
|
||||
int *headerSize);
|
||||
|
||||
int *headerSize);
|
||||
|
|
|
@ -17,18 +17,18 @@
|
|||
#include "preenc.h"
|
||||
#include "pk11func.h"
|
||||
|
||||
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
|
||||
int *headerSize)
|
||||
PEHeader *
|
||||
SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader,
|
||||
int *headerSize)
|
||||
{
|
||||
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
|
||||
int *headerSize)
|
||||
PEHeader *
|
||||
SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header,
|
||||
int *headerSize)
|
||||
{
|
||||
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -194,3 +194,9 @@ SSL_SetSignedCertTimestamps;
|
|||
;+ local:
|
||||
;+*;
|
||||
;+};
|
||||
;+NSS_3.23 { # NSS 3.23 release
|
||||
;+ global:
|
||||
SSL_SetDowngradeCheckVersion;
|
||||
;+ local:
|
||||
;+*;
|
||||
;+};
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "cert.h"
|
||||
#include "keyt.h"
|
||||
|
||||
#include "sslt.h" /* public ssl data types */
|
||||
#include "sslt.h" /* public ssl data types */
|
||||
|
||||
#if defined(_WIN32) && !defined(IN_LIBSSL) && !defined(NSS_USE_STATIC_LIBS)
|
||||
#define SSL_IMPORT extern __declspec(dllimport)
|
||||
|
@ -38,7 +38,7 @@ SSL_IMPORT const PRUint16 SSL_NumImplementedCiphers;
|
|||
SSL_IMPORT PRUint16 SSL_GetNumImplementedCiphers(void);
|
||||
|
||||
/* Macro to tell which ciphers in table are SSL2 vs SSL3/TLS. */
|
||||
#define SSL_IS_SSL2_CIPHER(which) (((which) & 0xfff0) == 0xff00)
|
||||
#define SSL_IS_SSL2_CIPHER(which) (((which)&0xfff0) == 0xff00)
|
||||
|
||||
/*
|
||||
** Imports fd into SSL, returning a new socket. Copies SSL configuration
|
||||
|
@ -55,72 +55,72 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
|
|||
/*
|
||||
** Enable/disable an ssl mode
|
||||
**
|
||||
** SSL_SECURITY:
|
||||
** enable/disable use of SSL security protocol before connect
|
||||
** SSL_SECURITY:
|
||||
** enable/disable use of SSL security protocol before connect
|
||||
**
|
||||
** SSL_SOCKS:
|
||||
** enable/disable use of socks before connect
|
||||
** (No longer supported).
|
||||
** SSL_SOCKS:
|
||||
** enable/disable use of socks before connect
|
||||
** (No longer supported).
|
||||
**
|
||||
** SSL_REQUEST_CERTIFICATE:
|
||||
** require a certificate during secure connect
|
||||
** SSL_REQUEST_CERTIFICATE:
|
||||
** require a certificate during secure connect
|
||||
*/
|
||||
/* options */
|
||||
#define SSL_SECURITY 1 /* (on by default) */
|
||||
#define SSL_SOCKS 2 /* (off by default) */
|
||||
#define SSL_REQUEST_CERTIFICATE 3 /* (off by default) */
|
||||
#define SSL_HANDSHAKE_AS_CLIENT 5 /* force accept to hs as client */
|
||||
/* (off by default) */
|
||||
#define SSL_HANDSHAKE_AS_SERVER 6 /* force connect to hs as server */
|
||||
/* (off by default) */
|
||||
#define SSL_SECURITY 1 /* (on by default) */
|
||||
#define SSL_SOCKS 2 /* (off by default) */
|
||||
#define SSL_REQUEST_CERTIFICATE 3 /* (off by default) */
|
||||
#define SSL_HANDSHAKE_AS_CLIENT 5 /* force accept to hs as client */
|
||||
/* (off by default) */
|
||||
#define SSL_HANDSHAKE_AS_SERVER 6 /* force connect to hs as server */
|
||||
/* (off by default) */
|
||||
|
||||
/* OBSOLETE: SSL v2 is obsolete and may be removed soon. */
|
||||
#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (off by default) */
|
||||
#define SSL_ENABLE_SSL2 7 /* enable ssl v2 (off by default) */
|
||||
|
||||
/* OBSOLETE: See "SSL Version Range API" below for the replacement and a
|
||||
** description of the non-obvious semantics of using SSL_ENABLE_SSL3.
|
||||
*/
|
||||
#define SSL_ENABLE_SSL3 8 /* enable ssl v3 (on 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) */
|
||||
#define SSL_REQUIRE_CERTIFICATE 10 /* (SSL_REQUIRE_FIRST_HANDSHAKE */
|
||||
/* by default) */
|
||||
#define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */
|
||||
/* (off by default) */
|
||||
#define SSL_NO_CACHE 9 /* don't use the session cache */
|
||||
/* (off by default) */
|
||||
#define SSL_REQUIRE_CERTIFICATE 10 /* (SSL_REQUIRE_FIRST_HANDSHAKE */
|
||||
/* by default) */
|
||||
#define SSL_ENABLE_FDX 11 /* permit simultaneous read/write */
|
||||
/* (off by default) */
|
||||
|
||||
/* OBSOLETE: SSL v2 compatible hellos are not accepted by some TLS servers
|
||||
** and cannot negotiate extensions. SSL v2 is obsolete. This option may be
|
||||
** removed soon.
|
||||
*/
|
||||
#define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */
|
||||
/* (off by default) */
|
||||
#define SSL_V2_COMPATIBLE_HELLO 12 /* send v3 client hello in v2 fmt */
|
||||
/* (off by default) */
|
||||
|
||||
/* OBSOLETE: See "SSL Version Range API" below for the replacement and a
|
||||
** description of the non-obvious semantics of using SSL_ENABLE_TLS.
|
||||
*/
|
||||
#define SSL_ENABLE_TLS 13 /* enable TLS (on 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 */
|
||||
/* if step-down keys are needed. */
|
||||
/* default: off, generate */
|
||||
/* step-down keys if needed. */
|
||||
#define SSL_BYPASS_PKCS11 16 /* use PKCS#11 for pub key only */
|
||||
#define SSL_NO_LOCKS 17 /* Don't use locks for protection */
|
||||
#define SSL_ENABLE_SESSION_TICKETS 18 /* Enable TLS SessionTicket */
|
||||
/* extension (off by default) */
|
||||
#define SSL_ENABLE_DEFLATE 19 /* Enable TLS compression with */
|
||||
/* DEFLATE (off by default) */
|
||||
#define SSL_ENABLE_RENEGOTIATION 20 /* Values below (default: never) */
|
||||
#define SSL_REQUIRE_SAFE_NEGOTIATION 21 /* Peer must send Signaling */
|
||||
/* Cipher Suite Value (SCSV) or */
|
||||
/* Renegotiation Info (RI) */
|
||||
/* extension in ALL handshakes. */
|
||||
/* default: off */
|
||||
#define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */
|
||||
/* default, applies only to */
|
||||
/* clients). False start is a */
|
||||
#define SSL_ROLLBACK_DETECTION 14 /* for compatibility, default: on */
|
||||
#define SSL_NO_STEP_DOWN 15 /* Disable export cipher suites */
|
||||
/* if step-down keys are needed. */
|
||||
/* default: off, generate */
|
||||
/* step-down keys if needed. */
|
||||
#define SSL_BYPASS_PKCS11 16 /* use PKCS#11 for pub key only */
|
||||
#define SSL_NO_LOCKS 17 /* Don't use locks for protection */
|
||||
#define SSL_ENABLE_SESSION_TICKETS 18 /* Enable TLS SessionTicket */
|
||||
/* extension (off by default) */
|
||||
#define SSL_ENABLE_DEFLATE 19 /* Enable TLS compression with */
|
||||
/* DEFLATE (off by default) */
|
||||
#define SSL_ENABLE_RENEGOTIATION 20 /* Values below (default: never) */
|
||||
#define SSL_REQUIRE_SAFE_NEGOTIATION 21 /* Peer must send Signaling */
|
||||
/* Cipher Suite Value (SCSV) or */
|
||||
/* Renegotiation Info (RI) */
|
||||
/* extension in ALL handshakes. */
|
||||
/* default: off */
|
||||
#define SSL_ENABLE_FALSE_START 22 /* Enable SSL false start (off by */
|
||||
/* default, applies only to */
|
||||
/* clients). False start is a */
|
||||
/* mode where an SSL client will start sending application data before
|
||||
* verifying the server's Finished message. This means that we could end up
|
||||
* sending data to an imposter. However, the data will be encrypted and
|
||||
|
@ -160,7 +160,7 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
|
|||
* accept fragmented alerts).
|
||||
*/
|
||||
#define SSL_CBC_RANDOM_IV 23
|
||||
#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
|
||||
#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
|
||||
|
||||
/* SSL_ENABLE_NPN controls whether the NPN extension is enabled for the initial
|
||||
* handshake when application layer protocol negotiation is used.
|
||||
|
@ -189,8 +189,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
|
|||
*/
|
||||
#define SSL_REUSE_SERVER_ECDHE_KEY 27
|
||||
|
||||
#define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in
|
||||
* handshakes. */
|
||||
#define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in \
|
||||
* handshakes. */
|
||||
|
||||
/* SSL_ENABLE_SERVER_DHE controls whether DHE is enabled for the server socket.
|
||||
*/
|
||||
|
@ -206,7 +206,7 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
|
|||
/* Request Signed Certificate Timestamps via TLS extension (client) */
|
||||
#define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 31
|
||||
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
/* Old deprecated function names */
|
||||
SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on);
|
||||
SSL_IMPORT SECStatus SSL_EnableDefault(int option, PRBool on);
|
||||
|
@ -229,13 +229,13 @@ SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHan
|
|||
*
|
||||
* The callback must return SECFailure or SECSuccess (not SECWouldBlock).
|
||||
*/
|
||||
typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)(
|
||||
typedef SECStatus(PR_CALLBACK *SSLNextProtoCallback)(
|
||||
void *arg,
|
||||
PRFileDesc *fd,
|
||||
const unsigned char* protos,
|
||||
const unsigned char *protos,
|
||||
unsigned int protosLen,
|
||||
unsigned char* protoOut,
|
||||
unsigned int* protoOutLen,
|
||||
unsigned char *protoOut,
|
||||
unsigned int *protoOutLen,
|
||||
unsigned int protoMaxOut);
|
||||
|
||||
/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol
|
||||
|
@ -263,14 +263,14 @@ SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd,
|
|||
* The supported protocols are specified in |data| in wire-format (8-bit
|
||||
* length-prefixed). For example: "\010http/1.1\006spdy/2". */
|
||||
SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
|
||||
const unsigned char *data,
|
||||
unsigned int length);
|
||||
const unsigned char *data,
|
||||
unsigned int length);
|
||||
|
||||
typedef enum SSLNextProtoState {
|
||||
SSL_NEXT_PROTO_NO_SUPPORT = 0, /* No peer support */
|
||||
SSL_NEXT_PROTO_NEGOTIATED = 1, /* Mutual agreement */
|
||||
SSL_NEXT_PROTO_NO_OVERLAP = 2, /* No protocol overlap found */
|
||||
SSL_NEXT_PROTO_SELECTED = 3 /* Server selected proto (ALPN) */
|
||||
typedef enum SSLNextProtoState {
|
||||
SSL_NEXT_PROTO_NO_SUPPORT = 0, /* No peer support */
|
||||
SSL_NEXT_PROTO_NEGOTIATED = 1, /* Mutual agreement */
|
||||
SSL_NEXT_PROTO_NO_OVERLAP = 2, /* No protocol overlap found */
|
||||
SSL_NEXT_PROTO_SELECTED = 3 /* Server selected proto (ALPN) */
|
||||
} SSLNextProtoState;
|
||||
|
||||
/* SSL_GetNextProto can be used in the HandshakeCallback or any time after
|
||||
|
@ -281,19 +281,19 @@ typedef enum SSLNextProtoState {
|
|||
* returned. Otherwise, the negotiated protocol, if any, is written into buf,
|
||||
* and SECSuccess is returned. */
|
||||
SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd,
|
||||
SSLNextProtoState *state,
|
||||
unsigned char *buf,
|
||||
unsigned int *bufLen,
|
||||
unsigned int bufLenMax);
|
||||
SSLNextProtoState *state,
|
||||
unsigned char *buf,
|
||||
unsigned int *bufLen,
|
||||
unsigned int bufLenMax);
|
||||
|
||||
/*
|
||||
** Control ciphers that SSL uses. If on is non-zero then the named cipher
|
||||
** is enabled, otherwise it is disabled.
|
||||
** is enabled, otherwise it is disabled.
|
||||
** The "cipher" values are defined in sslproto.h (the SSL_EN_* values).
|
||||
** EnableCipher records user preferences.
|
||||
** SetPolicy sets the policy according to the policy module.
|
||||
*/
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
/* Old deprecated function names */
|
||||
SSL_IMPORT SECStatus SSL_EnableCipher(long which, PRBool enabled);
|
||||
SSL_IMPORT SECStatus SSL_SetPolicy(long which, int policy);
|
||||
|
@ -451,11 +451,11 @@ SSL_IMPORT SECStatus SSL_VersionRangeSetDefault(
|
|||
|
||||
/* Returns, in |*vrange|, the range of enabled SSL3/TLS versions for |fd|. */
|
||||
SSL_IMPORT SECStatus SSL_VersionRangeGet(PRFileDesc *fd,
|
||||
SSLVersionRange *vrange);
|
||||
SSLVersionRange *vrange);
|
||||
|
||||
/* Sets the range of enabled SSL3/TLS versions for |fd| to |*vrange|. */
|
||||
SSL_IMPORT SECStatus SSL_VersionRangeSet(PRFileDesc *fd,
|
||||
const SSLVersionRange *vrange);
|
||||
const SSLVersionRange *vrange);
|
||||
|
||||
/* Sets the version to check the server random against for the
|
||||
* fallback check defined in [draft-ietf-tls-tls13-11 Section 6.3.1.1].
|
||||
|
@ -472,25 +472,25 @@ SSL_IMPORT SECStatus SSL_SetDowngradeCheckVersion(PRFileDesc *fd,
|
|||
|
||||
/* Values for "policy" argument to SSL_CipherPolicySet */
|
||||
/* Values returned by SSL_CipherPolicyGet. */
|
||||
#define SSL_NOT_ALLOWED 0 /* or invalid or unimplemented */
|
||||
#define SSL_ALLOWED 1
|
||||
#define SSL_RESTRICTED 2 /* only with "Step-Up" certs. */
|
||||
#define SSL_NOT_ALLOWED 0 /* or invalid or unimplemented */
|
||||
#define SSL_ALLOWED 1
|
||||
#define SSL_RESTRICTED 2 /* only with "Step-Up" certs. */
|
||||
|
||||
/* Values for "on" with SSL_REQUIRE_CERTIFICATE. */
|
||||
#define SSL_REQUIRE_NEVER ((PRBool)0)
|
||||
#define SSL_REQUIRE_ALWAYS ((PRBool)1)
|
||||
#define SSL_REQUIRE_NEVER ((PRBool)0)
|
||||
#define SSL_REQUIRE_ALWAYS ((PRBool)1)
|
||||
#define SSL_REQUIRE_FIRST_HANDSHAKE ((PRBool)2)
|
||||
#define SSL_REQUIRE_NO_ERROR ((PRBool)3)
|
||||
#define SSL_REQUIRE_NO_ERROR ((PRBool)3)
|
||||
|
||||
/* Values for "on" with SSL_ENABLE_RENEGOTIATION */
|
||||
/* Never renegotiate at all. */
|
||||
#define SSL_RENEGOTIATE_NEVER ((PRBool)0)
|
||||
#define SSL_RENEGOTIATE_NEVER ((PRBool)0)
|
||||
/* Renegotiate without restriction, whether or not the peer's client hello */
|
||||
/* bears the renegotiation info extension. Vulnerable, as in the past. */
|
||||
#define SSL_RENEGOTIATE_UNRESTRICTED ((PRBool)1)
|
||||
/* Only renegotiate if the peer's hello bears the TLS renegotiation_info */
|
||||
/* extension. This is safe renegotiation. */
|
||||
#define SSL_RENEGOTIATE_REQUIRES_XTN ((PRBool)2)
|
||||
#define SSL_RENEGOTIATE_REQUIRES_XTN ((PRBool)2)
|
||||
/* Disallow unsafe renegotiation in server sockets only, but allow clients */
|
||||
/* to continue to renegotiate with vulnerable servers. */
|
||||
/* This value should only be used during the transition period when few */
|
||||
|
@ -528,22 +528,22 @@ SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
|
|||
** by the caller, and need to be freed with PORT_Free.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_SecurityStatus(PRFileDesc *fd, int *on, char **cipher,
|
||||
int *keySize, int *secretKeySize,
|
||||
char **issuer, char **subject);
|
||||
int *keySize, int *secretKeySize,
|
||||
char **issuer, char **subject);
|
||||
|
||||
/* Values for "on" */
|
||||
#define SSL_SECURITY_STATUS_NOOPT -1
|
||||
#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_NOOPT -1
|
||||
#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 */
|
||||
|
||||
/*
|
||||
** Return the certificate for our SSL peer. If the client calls this
|
||||
** it will always return the server's certificate. If the server calls
|
||||
** this, it may return NULL if client authentication is not enabled or
|
||||
** if the client had no certificate when asked.
|
||||
** "fd" the socket "file" descriptor
|
||||
** "fd" the socket "file" descriptor
|
||||
*/
|
||||
SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
|
||||
|
||||
|
@ -552,7 +552,7 @@ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd);
|
|||
** did not present certificates, return NULL with the
|
||||
** SSL_ERROR_NO_CERTIFICATE error. On failure, return NULL with an error
|
||||
** code other than SSL_ERROR_NO_CERTIFICATE.
|
||||
** "fd" the socket "file" descriptor
|
||||
** "fd" the socket "file" descriptor
|
||||
*/
|
||||
SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
|
||||
|
||||
|
@ -572,7 +572,7 @@ SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd);
|
|||
* authenticate certificate hook, SSL_AuthCertificate, does not implement
|
||||
* any OCSP stapling funtionality, but this may change in future versions.
|
||||
*/
|
||||
SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
|
||||
SSL_IMPORT const SECItemArray *SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
|
||||
|
||||
/* SSL_PeerSignedCertTimestamps returns the signed_certificate_timestamp
|
||||
* extension data provided by the TLS server. The return value is a pointer
|
||||
|
@ -589,7 +589,7 @@ SSL_IMPORT const SECItemArray * SSL_PeerStapledOCSPResponses(PRFileDesc *fd);
|
|||
*
|
||||
* libssl does not do any parsing or validation of the response itself.
|
||||
*/
|
||||
SSL_IMPORT const SECItem * SSL_PeerSignedCertTimestamps(PRFileDesc *fd);
|
||||
SSL_IMPORT const SECItem *SSL_PeerSignedCertTimestamps(PRFileDesc *fd);
|
||||
|
||||
/* SSL_SetStapledOCSPResponses stores an array of one or multiple OCSP responses
|
||||
* in the fd's data, which may be sent as part of a server side cert_status
|
||||
|
@ -599,7 +599,7 @@ SSL_IMPORT const SECItem * SSL_PeerSignedCertTimestamps(PRFileDesc *fd);
|
|||
*/
|
||||
SSL_IMPORT SECStatus
|
||||
SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
|
||||
SSLKEAType kea);
|
||||
SSLKEAType kea);
|
||||
|
||||
/*
|
||||
* SSL_SetSignedCertTimestamps stores serialized signed_certificate_timestamp
|
||||
|
@ -644,41 +644,40 @@ SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts,
|
|||
** Consequently, the current version of libssl does not ever send the
|
||||
** bad_certificate_status_response alert. This may change in future releases.
|
||||
*/
|
||||
typedef SECStatus (PR_CALLBACK *SSLAuthCertificate)(void *arg, PRFileDesc *fd,
|
||||
PRBool checkSig,
|
||||
PRBool isServer);
|
||||
typedef SECStatus(PR_CALLBACK *SSLAuthCertificate)(void *arg, PRFileDesc *fd,
|
||||
PRBool checkSig,
|
||||
PRBool isServer);
|
||||
|
||||
SSL_IMPORT SECStatus SSL_AuthCertificateHook(PRFileDesc *fd,
|
||||
SSLAuthCertificate f,
|
||||
void *arg);
|
||||
SSL_IMPORT SECStatus SSL_AuthCertificateHook(PRFileDesc *fd,
|
||||
SSLAuthCertificate f,
|
||||
void *arg);
|
||||
|
||||
/* An implementation of the certificate authentication hook */
|
||||
SSL_IMPORT SECStatus SSL_AuthCertificate(void *arg, PRFileDesc *fd,
|
||||
PRBool checkSig, PRBool isServer);
|
||||
SSL_IMPORT SECStatus SSL_AuthCertificate(void *arg, PRFileDesc *fd,
|
||||
PRBool checkSig, PRBool isServer);
|
||||
|
||||
/*
|
||||
* Prototype for SSL callback to get client auth data from the application.
|
||||
* arg - application passed argument
|
||||
* caNames - pointer to distinguished names of CAs that the server likes
|
||||
* pRetCert - pointer to pointer to cert, for return of cert
|
||||
* pRetKey - pointer to key pointer, for return of key
|
||||
* arg - application passed argument
|
||||
* caNames - pointer to distinguished names of CAs that the server likes
|
||||
* pRetCert - pointer to pointer to cert, for return of cert
|
||||
* pRetKey - pointer to key pointer, for return of key
|
||||
*/
|
||||
typedef SECStatus (PR_CALLBACK *SSLGetClientAuthData)(void *arg,
|
||||
PRFileDesc *fd,
|
||||
CERTDistNames *caNames,
|
||||
CERTCertificate **pRetCert,/*return */
|
||||
SECKEYPrivateKey **pRetKey);/* return */
|
||||
typedef SECStatus(PR_CALLBACK *SSLGetClientAuthData)(void *arg,
|
||||
PRFileDesc *fd,
|
||||
CERTDistNames *caNames,
|
||||
CERTCertificate **pRetCert, /*return */
|
||||
SECKEYPrivateKey **pRetKey); /* return */
|
||||
|
||||
/*
|
||||
* Set the client side callback for SSL to retrieve user's private key
|
||||
* and certificate.
|
||||
* fd - the file descriptor for the connection in question
|
||||
* f - the application's callback that delivers the key and cert
|
||||
* a - application specific data
|
||||
* fd - the file descriptor for the connection in question
|
||||
* f - the application's callback that delivers the key and cert
|
||||
* a - application specific data
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
|
||||
SSLGetClientAuthData f, void *a);
|
||||
|
||||
SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
|
||||
SSLGetClientAuthData f, void *a);
|
||||
|
||||
/*
|
||||
** SNI extension processing callback function.
|
||||
|
@ -706,10 +705,10 @@ SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
|
|||
** send an "unrecognized_name" alert if SNI extension name list contains more
|
||||
** then one name of a type.
|
||||
*/
|
||||
typedef PRInt32 (PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd,
|
||||
const SECItem *srvNameArr,
|
||||
PRUint32 srvNameArrSize,
|
||||
void *arg);
|
||||
typedef PRInt32(PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd,
|
||||
const SECItem *srvNameArr,
|
||||
PRUint32 srvNameArrSize,
|
||||
void *arg);
|
||||
|
||||
/*
|
||||
** SSLSNISocketConfig should return an index within 0 and srvNameArrSize-1
|
||||
|
@ -718,13 +717,13 @@ typedef PRInt32 (PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd,
|
|||
** tells libSSL to use the default cert and key. The other tells libSSL
|
||||
** to send the "unrecognized_name" alert. These values are:
|
||||
**/
|
||||
#define SSL_SNI_CURRENT_CONFIG_IS_USED -1
|
||||
#define SSL_SNI_SEND_ALERT -2
|
||||
#define SSL_SNI_CURRENT_CONFIG_IS_USED -1
|
||||
#define SSL_SNI_SEND_ALERT -2
|
||||
|
||||
/*
|
||||
** Set application implemented SNISocketConfig callback.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_SNISocketConfigHook(PRFileDesc *fd,
|
||||
SSL_IMPORT SECStatus SSL_SNISocketConfigHook(PRFileDesc *fd,
|
||||
SSLSNISocketConfig f,
|
||||
void *arg);
|
||||
|
||||
|
@ -737,8 +736,8 @@ SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd);
|
|||
|
||||
/*
|
||||
* Set the client side argument for SSL to retrieve PKCS #11 pin.
|
||||
* fd - the file descriptor for the connection in question
|
||||
* a - pkcs11 application specific data
|
||||
* fd - the file descriptor for the connection in question
|
||||
* a - pkcs11 application specific data
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
|
||||
|
||||
|
@ -757,9 +756,9 @@ SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a);
|
|||
** about the asynchronous behavior that occurs when the bad cert hook returns
|
||||
** SECWouldBlock.
|
||||
*/
|
||||
typedef SECStatus (PR_CALLBACK *SSLBadCertHandler)(void *arg, PRFileDesc *fd);
|
||||
SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
|
||||
void *arg);
|
||||
typedef SECStatus(PR_CALLBACK *SSLBadCertHandler)(void *arg, PRFileDesc *fd);
|
||||
SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
|
||||
void *arg);
|
||||
|
||||
/*
|
||||
** Configure SSL socket for running a secure server. Needs the
|
||||
|
@ -767,8 +766,8 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
|
|||
** are copied.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_ConfigSecureServer(
|
||||
PRFileDesc *fd, CERTCertificate *cert,
|
||||
SECKEYPrivateKey *key, SSLKEAType kea);
|
||||
PRFileDesc *fd, CERTCertificate *cert,
|
||||
SECKEYPrivateKey *key, SSLKEAType kea);
|
||||
|
||||
/*
|
||||
** Allows SSL socket configuration with caller-supplied certificate chain.
|
||||
|
@ -782,63 +781,63 @@ SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
|
|||
/*
|
||||
** Configure a secure server's session-id cache. Define the maximum number
|
||||
** of entries in the cache, the longevity of the entires, and the directory
|
||||
** where the cache files will be placed. These values can be zero, and
|
||||
** where the cache files will be placed. These values can be zero, and
|
||||
** if so, the implementation will choose defaults.
|
||||
** This version of the function is for use in applications that have only one
|
||||
** This version of the function is for use in applications that have only one
|
||||
** process that uses the cache (even if that process has multiple threads).
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCache(int maxCacheEntries,
|
||||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
const char * directory);
|
||||
SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCache(int maxCacheEntries,
|
||||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
const char *directory);
|
||||
|
||||
/* Configure a secure server's session-id cache. Depends on value of
|
||||
* enableMPCache, configures malti-proc or single proc cache. */
|
||||
SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCacheWithOpt(
|
||||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
const char * directory,
|
||||
int maxCacheEntries,
|
||||
int maxCertCacheEntries,
|
||||
int maxSrvNameCacheEntries,
|
||||
PRBool enableMPCache);
|
||||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
const char *directory,
|
||||
int maxCacheEntries,
|
||||
int maxCertCacheEntries,
|
||||
int maxSrvNameCacheEntries,
|
||||
PRBool enableMPCache);
|
||||
|
||||
/*
|
||||
** Like SSL_ConfigServerSessionIDCache, with one important difference.
|
||||
** If the application will run multiple processes (as opposed to, or in
|
||||
** If the application will run multiple processes (as opposed to, or in
|
||||
** addition to multiple threads), then it must call this function, instead
|
||||
** of calling SSL_ConfigServerSessionIDCache().
|
||||
** This has nothing to do with the number of processORs, only processEs.
|
||||
** This function sets up a Server Session ID (SID) cache that is safe for
|
||||
** access by multiple processes on the same system.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_ConfigMPServerSIDCache(int maxCacheEntries,
|
||||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
const char * directory);
|
||||
SSL_IMPORT SECStatus SSL_ConfigMPServerSIDCache(int maxCacheEntries,
|
||||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
const char *directory);
|
||||
|
||||
/* Get and set the configured maximum number of mutexes used for the
|
||||
** server's store of SSL sessions. This value is used by the server
|
||||
** session ID cache initialization functions shown above. Note that on
|
||||
** some platforms, these mutexes are actually implemented with POSIX
|
||||
/* Get and set the configured maximum number of mutexes used for the
|
||||
** server's store of SSL sessions. This value is used by the server
|
||||
** session ID cache initialization functions shown above. Note that on
|
||||
** some platforms, these mutexes are actually implemented with POSIX
|
||||
** semaphores, or with unnamed pipes. The default value varies by platform.
|
||||
** An attempt to set a too-low maximum will return an error and the
|
||||
** An attempt to set a too-low maximum will return an error and the
|
||||
** configured value will not be changed.
|
||||
*/
|
||||
SSL_IMPORT PRUint32 SSL_GetMaxServerCacheLocks(void);
|
||||
SSL_IMPORT PRUint32 SSL_GetMaxServerCacheLocks(void);
|
||||
SSL_IMPORT SECStatus SSL_SetMaxServerCacheLocks(PRUint32 maxLocks);
|
||||
|
||||
/* environment variable set by SSL_ConfigMPServerSIDCache, and queried by
|
||||
* SSL_InheritMPServerSIDCache when envString is NULL.
|
||||
*/
|
||||
#define SSL_ENV_VAR_NAME "SSL_INHERITANCE"
|
||||
#define SSL_ENV_VAR_NAME "SSL_INHERITANCE"
|
||||
|
||||
/* called in child to inherit SID Cache variables.
|
||||
/* called in child to inherit SID Cache variables.
|
||||
* If envString is NULL, this function will use the value of the environment
|
||||
* variable "SSL_INHERITANCE", otherwise the string value passed in will be
|
||||
* variable "SSL_INHERITANCE", otherwise the string value passed in will be
|
||||
* used.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
|
||||
SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char *envString);
|
||||
|
||||
/*
|
||||
** Set the callback that gets called when a TLS handshake is complete. The
|
||||
|
@ -850,10 +849,10 @@ SSL_IMPORT SECStatus SSL_InheritMPServerSIDCache(const char * envString);
|
|||
** before the handshake callback is called. If we did not false start then the
|
||||
** callback will get called before any application data is sent.
|
||||
*/
|
||||
typedef void (PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
|
||||
void *client_data);
|
||||
SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
|
||||
SSLHandshakeCallback cb, void *client_data);
|
||||
typedef void(PR_CALLBACK *SSLHandshakeCallback)(PRFileDesc *fd,
|
||||
void *client_data);
|
||||
SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
|
||||
SSLHandshakeCallback cb, void *client_data);
|
||||
|
||||
/* Applications that wish to enable TLS false start must set this callback
|
||||
** function. NSS will invoke the functon to determine if a particular
|
||||
|
@ -866,7 +865,7 @@ SSL_IMPORT SECStatus SSL_HandshakeCallback(PRFileDesc *fd,
|
|||
** If no false start callback is registered then false start will never be
|
||||
** done, even if the SSL_ENABLE_FALSE_START option is enabled.
|
||||
**/
|
||||
typedef SECStatus (PR_CALLBACK *SSLCanFalseStartCallback)(
|
||||
typedef SECStatus(PR_CALLBACK *SSLCanFalseStartCallback)(
|
||||
PRFileDesc *fd, void *arg, PRBool *canFalseStart);
|
||||
|
||||
SSL_IMPORT SECStatus SSL_SetCanFalseStartCallback(
|
||||
|
@ -882,10 +881,10 @@ SSL_IMPORT SECStatus SSL_RecommendedCanFalseStart(PRFileDesc *fd,
|
|||
|
||||
/*
|
||||
** For the server, request a new handshake. For the client, begin a new
|
||||
** handshake. If flushCache is non-zero, the SSL3 cache entry will be
|
||||
** handshake. If flushCache is non-zero, the SSL3 cache entry will be
|
||||
** flushed first, ensuring that a full SSL handshake will be done.
|
||||
** If flushCache is zero, and an SSL connection is established, it will
|
||||
** do the much faster session restart handshake. This will change the
|
||||
** If flushCache is zero, and an SSL connection is established, it will
|
||||
** do the much faster session restart handshake. This will change the
|
||||
** session keys without doing another private key operation.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache);
|
||||
|
@ -897,12 +896,11 @@ SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd,
|
|||
PRBool flushCache,
|
||||
PRIntervalTime timeout);
|
||||
|
||||
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
#ifdef SSL_DEPRECATED_FUNCTION
|
||||
/* deprecated!
|
||||
** For the server, request a new handshake. For the client, begin a new
|
||||
** handshake. Flushes SSL3 session cache entry first, ensuring that a
|
||||
** full handshake will be done.
|
||||
** handshake. Flushes SSL3 session cache entry first, ensuring that a
|
||||
** full handshake will be done.
|
||||
** This call is equivalent to SSL_ReHandshake(fd, PR_TRUE)
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_RedoHandshake(PRFileDesc *fd);
|
||||
|
@ -952,11 +950,11 @@ SSL_IMPORT SECStatus SSL_ShutdownServerSessionIDCache(void);
|
|||
SSL_IMPORT SECStatus SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID);
|
||||
|
||||
/*
|
||||
** Reveal the security information for the peer.
|
||||
** Reveal the security information for the peer.
|
||||
*/
|
||||
SSL_IMPORT CERTCertificate * SSL_RevealCert(PRFileDesc * socket);
|
||||
SSL_IMPORT void * SSL_RevealPinArg(PRFileDesc * socket);
|
||||
SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket);
|
||||
SSL_IMPORT CERTCertificate *SSL_RevealCert(PRFileDesc *socket);
|
||||
SSL_IMPORT void *SSL_RevealPinArg(PRFileDesc *socket);
|
||||
SSL_IMPORT char *SSL_RevealURL(PRFileDesc *socket);
|
||||
|
||||
/* This callback may be passed to the SSL library via a call to
|
||||
* SSL_GetClientAuthDataHook() for each SSL client socket.
|
||||
|
@ -964,14 +962,14 @@ SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket);
|
|||
* (if any) to use to respond to a request for client authentication.
|
||||
* If arg is non-NULL, it is a pointer to a NULL-terminated string containing
|
||||
* the nickname of the cert/key pair to use.
|
||||
* If arg is NULL, this function will search the cert and key databases for
|
||||
* If arg is NULL, this function will search the cert and key databases for
|
||||
* a suitable match and send it if one is found.
|
||||
*/
|
||||
SSL_IMPORT SECStatus
|
||||
NSS_GetClientAuthData(void * arg,
|
||||
PRFileDesc * socket,
|
||||
struct CERTDistNamesStr * caNames,
|
||||
struct CERTCertificateStr ** pRetCert,
|
||||
NSS_GetClientAuthData(void *arg,
|
||||
PRFileDesc *socket,
|
||||
struct CERTDistNamesStr *caNames,
|
||||
struct CERTCertificateStr **pRetCert,
|
||||
struct SECKEYPrivateKeyStr **pRetKey);
|
||||
|
||||
/*
|
||||
|
@ -985,8 +983,8 @@ NSS_GetClientAuthData(void * arg,
|
|||
** Otherwise returns SECFailure.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
|
||||
const PRUint16 *ciphers,
|
||||
unsigned int numCiphers);
|
||||
const PRUint16 *ciphers,
|
||||
unsigned int numCiphers);
|
||||
|
||||
/*
|
||||
** Get the selected DTLS-SRTP cipher suite (if any).
|
||||
|
@ -994,21 +992,21 @@ SSL_IMPORT SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
|
|||
** Returns SECFailure if not negotiated.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_GetSRTPCipher(PRFileDesc *fd,
|
||||
PRUint16 *cipher);
|
||||
PRUint16 *cipher);
|
||||
|
||||
/*
|
||||
* Look to see if any of the signers in the cert chain for "cert" are found
|
||||
* in the list of caNames.
|
||||
* in the list of caNames.
|
||||
* Returns SECSuccess if so, SECFailure if not.
|
||||
* Used by NSS_GetClientAuthData. May be used by other callback functions.
|
||||
*/
|
||||
SSL_IMPORT SECStatus NSS_CmpCertChainWCANames(CERTCertificate *cert,
|
||||
CERTDistNames *caNames);
|
||||
SSL_IMPORT SECStatus NSS_CmpCertChainWCANames(CERTCertificate *cert,
|
||||
CERTDistNames *caNames);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Returns key exchange type of the keys in an SSL server certificate.
|
||||
*/
|
||||
SSL_IMPORT SSLKEAType NSS_FindCertKEAType(CERTCertificate * cert);
|
||||
SSL_IMPORT SSLKEAType NSS_FindCertKEAType(CERTCertificate *cert);
|
||||
|
||||
/* Set cipher policies to a predefined Domestic (U.S.A.) policy.
|
||||
* This essentially allows all supported ciphers.
|
||||
|
@ -1022,16 +1020,18 @@ SSL_IMPORT SECStatus NSS_SetDomesticPolicy(void);
|
|||
SSL_IMPORT SECStatus NSS_SetExportPolicy(void);
|
||||
|
||||
/* Set cipher policies to a predefined Policy that is exportable from the USA
|
||||
* according to present U.S. policies as we understand them, and that the
|
||||
* according to present U.S. policies as we understand them, and that the
|
||||
* nation of France will permit to be imported into their country.
|
||||
* It is the same as NSS_SetDomesticPolicy now.
|
||||
*/
|
||||
SSL_IMPORT SECStatus NSS_SetFrancePolicy(void);
|
||||
|
||||
SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
|
||||
SSL_IMPORT SSL3Statistics *SSL_GetStatistics(void);
|
||||
|
||||
/* Report more information than SSL_SecurityStatus.
|
||||
* Caller supplies the info struct. This function fills it in.
|
||||
* Caller supplies the info struct. This function fills it in. Caller should
|
||||
* pass sizeof(SSLChannelInfo) as the |len| argument.
|
||||
*
|
||||
* The information here will be zeroed prior to details being confirmed. The
|
||||
* details are confirmed either when a Finished message is received, or - for a
|
||||
* client - when the second flight of messages have been sent. This function
|
||||
|
@ -1041,8 +1041,9 @@ SSL_IMPORT SSL3Statistics * SSL_GetStatistics(void);
|
|||
SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info,
|
||||
PRUintn len);
|
||||
/* Get preliminary information about a channel.
|
||||
* This function can be called prior to handshake details being confirmed (see
|
||||
* SSL_GetChannelInfo above for what that means). Thus, information provided by
|
||||
* Caller supplies the info struct. This function fills it in. Caller should
|
||||
* pass sizeof(SSLPreliminaryChannelInfo) as the |len| argument.
|
||||
*
|
||||
* this function is available to SSLAuthCertificate, SSLGetClientAuthData,
|
||||
* SSLSNISocketConfig, and other callbacks that might be called during the
|
||||
* processing of the first flight of client of server handshake messages.
|
||||
|
@ -1052,8 +1053,12 @@ SSL_IMPORT SECStatus
|
|||
SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
|
||||
SSLPreliminaryChannelInfo *info,
|
||||
PRUintn len);
|
||||
SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
|
||||
SSLCipherSuiteInfo *info, PRUintn len);
|
||||
/* Get information about cipher suite with id of |cipherSuite|.
|
||||
* Caller supplies the info struct. This function fills it in. Caller should
|
||||
* pass sizeof(SSLCipherSuiteInfo) as the |len| argument.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
|
||||
SSLCipherSuiteInfo *info, PRUintn len);
|
||||
|
||||
/* Returnes negotiated through SNI host info. */
|
||||
SSL_IMPORT SECItem *SSL_GetNegotiatedHostInfo(PRFileDesc *fd);
|
||||
|
@ -1077,7 +1082,7 @@ SSL_IMPORT SECStatus SSL_ExportKeyingMaterial(PRFileDesc *fd,
|
|||
** Return a new reference to the certificate that was most recently sent
|
||||
** to the peer on this SSL/TLS connection, or NULL if none has been sent.
|
||||
*/
|
||||
SSL_IMPORT CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd);
|
||||
SSL_IMPORT CERTCertificate *SSL_LocalCertificate(PRFileDesc *fd);
|
||||
|
||||
/* Test an SSL configuration to see if SSL_BYPASS_PKCS11 can be turned on.
|
||||
** Check the key exchange algorithm for each cipher in the list to see if
|
||||
|
@ -1101,20 +1106,20 @@ SSL_IMPORT CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd);
|
|||
**/
|
||||
|
||||
/* protocol mask bits */
|
||||
#define SSL_CBP_SSL3 0x0001 /* test SSL v3 mechanisms */
|
||||
#define SSL_CBP_TLS1_0 0x0002 /* test TLS v1.0 mechanisms */
|
||||
#define SSL_CBP_SSL3 0x0001 /* test SSL v3 mechanisms */
|
||||
#define SSL_CBP_TLS1_0 0x0002 /* test TLS v1.0 mechanisms */
|
||||
|
||||
SSL_IMPORT SECStatus SSL_CanBypass(CERTCertificate *cert,
|
||||
SECKEYPrivateKey *privKey,
|
||||
PRUint32 protocolmask,
|
||||
PRUint16 *ciphers, int nciphers,
|
||||
PRUint32 protocolmask,
|
||||
PRUint16 *ciphers, int nciphers,
|
||||
PRBool *pcanbypass, void *pwArg);
|
||||
|
||||
/*
|
||||
** Did the handshake with the peer negotiate the given extension?
|
||||
** Output parameter valid only if function returns SECSuccess
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
|
||||
SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc *socket,
|
||||
SSLExtensionType extId,
|
||||
PRBool *yes);
|
||||
|
||||
|
@ -1204,7 +1209,7 @@ extern const char *NSSSSL_GetVersion(void);
|
|||
* connection.
|
||||
*/
|
||||
SSL_IMPORT SECStatus SSL_AuthCertificateComplete(PRFileDesc *fd,
|
||||
PRErrorCode error);
|
||||
PRErrorCode error);
|
||||
SEC_END_PROTOS
|
||||
|
||||
#endif /* __ssl_h_ */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Gather (Read) entire SSL3 records from socket into buffer.
|
||||
* Gather (Read) entire SSL3 records from socket into buffer.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
@ -10,15 +10,15 @@
|
|||
#include "sslimpl.h"
|
||||
#include "ssl3prot.h"
|
||||
|
||||
/*
|
||||
/*
|
||||
* Attempt to read in an entire SSL3 record.
|
||||
* Blocks here for blocking sockets, otherwise returns -1 with
|
||||
* PR_WOULD_BLOCK_ERROR when socket would block.
|
||||
* Blocks here for blocking sockets, otherwise returns -1 with
|
||||
* PR_WOULD_BLOCK_ERROR when socket would block.
|
||||
*
|
||||
* returns 1 if received a complete SSL3 record.
|
||||
* returns 0 if recv returns EOF
|
||||
* returns -1 if recv returns < 0
|
||||
* (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
|
||||
* returns -1 if recv returns < 0
|
||||
* (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
|
||||
*
|
||||
* Caller must hold the recv buf lock.
|
||||
*
|
||||
|
@ -28,108 +28,109 @@
|
|||
*
|
||||
* This loop returns when either
|
||||
* (a) an error or EOF occurs,
|
||||
* (b) PR_WOULD_BLOCK_ERROR,
|
||||
* (c) data (entire SSL3 record) has been received.
|
||||
* (b) PR_WOULD_BLOCK_ERROR,
|
||||
* (c) data (entire SSL3 record) has been received.
|
||||
*/
|
||||
static int
|
||||
ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
||||
{
|
||||
unsigned char *bp;
|
||||
unsigned char *lbp;
|
||||
int nb;
|
||||
int err;
|
||||
int rv = 1;
|
||||
int nb;
|
||||
int err;
|
||||
int rv = 1;
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
if (gs->state == GS_INIT) {
|
||||
gs->state = GS_HEADER;
|
||||
gs->remainder = 5;
|
||||
gs->offset = 0;
|
||||
gs->writeOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->inbuf.len = 0;
|
||||
gs->state = GS_HEADER;
|
||||
gs->remainder = 5;
|
||||
gs->offset = 0;
|
||||
gs->writeOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->inbuf.len = 0;
|
||||
}
|
||||
|
||||
|
||||
lbp = gs->inbuf.buf;
|
||||
for(;;) {
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
|
||||
SSL_GETPID(), ss->fd, gs->state, gs->remainder));
|
||||
bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
|
||||
nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
|
||||
for (;;) {
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: gather state %d (need %d more)",
|
||||
SSL_GETPID(), ss->fd, gs->state, gs->remainder));
|
||||
bp = ((gs->state != GS_HEADER) ? lbp : gs->hdr) + gs->offset;
|
||||
nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
|
||||
|
||||
if (nb > 0) {
|
||||
PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
|
||||
} else if (nb == 0) {
|
||||
/* EOF */
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
|
||||
rv = 0;
|
||||
break;
|
||||
} else /* if (nb < 0) */ {
|
||||
SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
|
||||
PR_GetError()));
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
if (nb > 0) {
|
||||
PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
|
||||
}
|
||||
else if (nb == 0) {
|
||||
/* EOF */
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
else /* if (nb < 0) */ {
|
||||
SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
|
||||
PR_GetError()));
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
PORT_Assert( (unsigned int)nb <= gs->remainder );
|
||||
if ((unsigned int)nb > gs->remainder) {
|
||||
/* ssl_DefRecv is misbehaving! this error is fatal to SSL. */
|
||||
gs->state = GS_INIT; /* so we don't crash next time */
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
PORT_Assert((unsigned int)nb <= gs->remainder);
|
||||
if ((unsigned int)nb > gs->remainder) {
|
||||
/* ssl_DefRecv is misbehaving! this error is fatal to SSL. */
|
||||
gs->state = GS_INIT; /* so we don't crash next time */
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
gs->offset += nb;
|
||||
gs->remainder -= nb;
|
||||
if (gs->state == GS_DATA)
|
||||
gs->inbuf.len += nb;
|
||||
gs->offset += nb;
|
||||
gs->remainder -= nb;
|
||||
if (gs->state == GS_DATA)
|
||||
gs->inbuf.len += nb;
|
||||
|
||||
/* if there's more to go, read some more. */
|
||||
if (gs->remainder > 0) {
|
||||
continue;
|
||||
}
|
||||
/* if there's more to go, read some more. */
|
||||
if (gs->remainder > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* have received entire record header, or entire record. */
|
||||
switch (gs->state) {
|
||||
case GS_HEADER:
|
||||
/*
|
||||
** Have received SSL3 record header in gs->hdr.
|
||||
** Now extract the length of the following encrypted data,
|
||||
** and then read in the rest of the SSL3 record into gs->inbuf.
|
||||
*/
|
||||
gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
|
||||
/* have received entire record header, or entire record. */
|
||||
switch (gs->state) {
|
||||
case GS_HEADER:
|
||||
/*
|
||||
** Have received SSL3 record header in gs->hdr.
|
||||
** Now extract the length of the following encrypted data,
|
||||
** and then read in the rest of the SSL3 record into gs->inbuf.
|
||||
*/
|
||||
gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
|
||||
|
||||
/* This is the max fragment length for an encrypted fragment
|
||||
** plus the size of the record header.
|
||||
*/
|
||||
if(gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
|
||||
SSL3_SendAlert(ss, alert_fatal, unexpected_message);
|
||||
gs->state = GS_INIT;
|
||||
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
|
||||
return SECFailure;
|
||||
}
|
||||
/* This is the max fragment length for an encrypted fragment
|
||||
** plus the size of the record header.
|
||||
*/
|
||||
if (gs->remainder > (MAX_FRAGMENT_LENGTH + 2048 + 5)) {
|
||||
SSL3_SendAlert(ss, alert_fatal, unexpected_message);
|
||||
gs->state = GS_INIT;
|
||||
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
gs->state = GS_DATA;
|
||||
gs->offset = 0;
|
||||
gs->inbuf.len = 0;
|
||||
gs->state = GS_DATA;
|
||||
gs->offset = 0;
|
||||
gs->inbuf.len = 0;
|
||||
|
||||
if (gs->remainder > gs->inbuf.space) {
|
||||
err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
|
||||
if (err) { /* realloc has set error code to no mem. */
|
||||
return err;
|
||||
}
|
||||
lbp = gs->inbuf.buf;
|
||||
}
|
||||
break; /* End this case. Continue around the loop. */
|
||||
if (gs->remainder > gs->inbuf.space) {
|
||||
err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
|
||||
if (err) { /* realloc has set error code to no mem. */
|
||||
return err;
|
||||
}
|
||||
lbp = gs->inbuf.buf;
|
||||
}
|
||||
break; /* End this case. Continue around the loop. */
|
||||
|
||||
|
||||
case GS_DATA:
|
||||
/*
|
||||
** SSL3 record has been completely received.
|
||||
*/
|
||||
gs->state = GS_INIT;
|
||||
return 1;
|
||||
}
|
||||
case GS_DATA:
|
||||
/*
|
||||
** SSL3 record has been completely received.
|
||||
*/
|
||||
gs->state = GS_INIT;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -139,7 +140,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
* Read in an entire DTLS record.
|
||||
*
|
||||
* Blocks here for blocking sockets, otherwise returns -1 with
|
||||
* PR_WOULD_BLOCK_ERROR when socket would block.
|
||||
* PR_WOULD_BLOCK_ERROR when socket would block.
|
||||
*
|
||||
* This is simpler than SSL because we are reading on a datagram socket
|
||||
* and datagrams must contain >=1 complete records.
|
||||
|
@ -147,43 +148,43 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
* returns 1 if received a complete DTLS record.
|
||||
* returns 0 if recv returns EOF
|
||||
* returns -1 if recv returns < 0
|
||||
* (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
|
||||
* (The error value may have already been set to PR_WOULD_BLOCK_ERROR)
|
||||
*
|
||||
* Caller must hold the recv buf lock.
|
||||
*
|
||||
* This loop returns when either
|
||||
* (a) an error or EOF occurs,
|
||||
* (b) PR_WOULD_BLOCK_ERROR,
|
||||
* (c) data (entire DTLS record) has been received.
|
||||
* (b) PR_WOULD_BLOCK_ERROR,
|
||||
* (c) data (entire DTLS record) has been received.
|
||||
*/
|
||||
static int
|
||||
dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
||||
{
|
||||
int nb;
|
||||
int err;
|
||||
int rv = 1;
|
||||
int nb;
|
||||
int err;
|
||||
int rv = 1;
|
||||
|
||||
SSL_TRC(30, ("dtls_GatherData"));
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
|
||||
gs->state = GS_HEADER;
|
||||
gs->offset = 0;
|
||||
|
||||
if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
|
||||
if (gs->dtlsPacketOffset == gs->dtlsPacket.len) { /* No data left */
|
||||
gs->dtlsPacketOffset = 0;
|
||||
gs->dtlsPacket.len = 0;
|
||||
|
||||
/* Resize to the maximum possible size so we can fit a full datagram */
|
||||
/* This is the max fragment length for an encrypted fragment
|
||||
** plus the size of the record header.
|
||||
** This magic constant is copied from ssl3_GatherData, with 5 changed
|
||||
** to 13 (the size of the record header).
|
||||
*/
|
||||
/* This is the max fragment length for an encrypted fragment
|
||||
** plus the size of the record header.
|
||||
** This magic constant is copied from ssl3_GatherData, with 5 changed
|
||||
** to 13 (the size of the record header).
|
||||
*/
|
||||
if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
|
||||
err = sslBuffer_Grow(&gs->dtlsPacket,
|
||||
MAX_FRAGMENT_LENGTH + 2048 + 13);
|
||||
if (err) { /* realloc has set error code to no mem. */
|
||||
MAX_FRAGMENT_LENGTH + 2048 + 13);
|
||||
if (err) { /* realloc has set error code to no mem. */
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
@ -193,12 +194,14 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
|
||||
if (nb > 0) {
|
||||
PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
|
||||
} else if (nb == 0) {
|
||||
}
|
||||
else if (nb == 0) {
|
||||
/* EOF */
|
||||
SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
|
||||
rv = 0;
|
||||
return rv;
|
||||
} else /* if (nb < 0) */ {
|
||||
}
|
||||
else /* if (nb < 0) */ {
|
||||
SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
|
||||
PR_GetError()));
|
||||
rv = SECFailure;
|
||||
|
@ -213,7 +216,8 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
*/
|
||||
if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) {
|
||||
SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
|
||||
"too short to contain header", SSL_GETPID(), ss->fd));
|
||||
"too short to contain header",
|
||||
SSL_GETPID(), ss->fd));
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
|
||||
gs->dtlsPacketOffset = 0;
|
||||
gs->dtlsPacket.len = 0;
|
||||
|
@ -228,7 +232,8 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
|
||||
if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
|
||||
SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
|
||||
"to contain rest of body", SSL_GETPID(), ss->fd));
|
||||
"to contain rest of body",
|
||||
SSL_GETPID(), ss->fd));
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
|
||||
gs->dtlsPacketOffset = 0;
|
||||
gs->dtlsPacket.len = 0;
|
||||
|
@ -238,14 +243,14 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
|
||||
/* OK, we have at least one complete packet, copy into inbuf */
|
||||
if (gs->remainder > gs->inbuf.space) {
|
||||
err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
|
||||
if (err) { /* realloc has set error code to no mem. */
|
||||
return err;
|
||||
}
|
||||
err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
|
||||
if (err) { /* realloc has set error code to no mem. */
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
|
||||
gs->remainder);
|
||||
gs->remainder);
|
||||
gs->inbuf.len = gs->remainder;
|
||||
gs->offset = gs->remainder;
|
||||
gs->dtlsPacketOffset += gs->remainder;
|
||||
|
@ -255,16 +260,16 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
|||
}
|
||||
|
||||
/* Gather in a record and when complete, Handle that record.
|
||||
* Repeat this until the handshake is complete,
|
||||
* Repeat this until the handshake is complete,
|
||||
* or until application data is available.
|
||||
*
|
||||
* Returns 1 when the handshake is completed without error, or
|
||||
* Returns 1 when the handshake is completed without error, or
|
||||
* application data is available.
|
||||
* Returns 0 if ssl3_GatherData hits EOF.
|
||||
* Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
|
||||
* Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
|
||||
*
|
||||
* Called from ssl_GatherRecord1stHandshake in sslcon.c,
|
||||
* Called from ssl_GatherRecord1stHandshake in sslcon.c,
|
||||
* and from SSL_ForceHandshake in sslsecur.c
|
||||
* and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
|
||||
*
|
||||
|
@ -274,8 +279,8 @@ int
|
|||
ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
||||
{
|
||||
SSL3Ciphertext cText;
|
||||
int rv;
|
||||
PRBool keepGoing = PR_TRUE;
|
||||
int rv;
|
||||
PRBool keepGoing = PR_TRUE;
|
||||
|
||||
SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));
|
||||
|
||||
|
@ -283,143 +288,150 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
* which requires the 1stHandshakeLock, which must be acquired before the
|
||||
* RecvBufLock.
|
||||
*/
|
||||
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
|
||||
do {
|
||||
PRBool handleRecordNow = PR_FALSE;
|
||||
PRBool handleRecordNow = PR_FALSE;
|
||||
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
|
||||
/* Without this, we may end up wrongly reporting
|
||||
* SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
|
||||
* peer while we are waiting to be restarted.
|
||||
*/
|
||||
if (ss->ssl3.hs.restartTarget) {
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return (int) SECFailure;
|
||||
}
|
||||
/* Without this, we may end up wrongly reporting
|
||||
* SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
|
||||
* peer while we are waiting to be restarted.
|
||||
*/
|
||||
if (ss->ssl3.hs.restartTarget) {
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
return (int)SECFailure;
|
||||
}
|
||||
|
||||
/* Treat an empty msgState like a NULL msgState. (Most of the time
|
||||
* when ssl3_HandleHandshake returns SECWouldBlock, it leaves
|
||||
* behind a non-NULL but zero-length msgState).
|
||||
* Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
|
||||
*/
|
||||
if (ss->ssl3.hs.msgState.buf) {
|
||||
if (ss->ssl3.hs.msgState.len == 0) {
|
||||
ss->ssl3.hs.msgState.buf = NULL;
|
||||
} else {
|
||||
handleRecordNow = PR_TRUE;
|
||||
}
|
||||
}
|
||||
/* Treat an empty msgState like a NULL msgState. (Most of the time
|
||||
* when ssl3_HandleHandshake returns SECWouldBlock, it leaves
|
||||
* behind a non-NULL but zero-length msgState).
|
||||
* Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
|
||||
*/
|
||||
if (ss->ssl3.hs.msgState.buf) {
|
||||
if (ss->ssl3.hs.msgState.len == 0) {
|
||||
ss->ssl3.hs.msgState.buf = NULL;
|
||||
}
|
||||
else {
|
||||
handleRecordNow = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
|
||||
if (handleRecordNow) {
|
||||
/* ssl3_HandleHandshake previously returned SECWouldBlock and the
|
||||
* as-yet-unprocessed plaintext of that previous handshake record.
|
||||
* We need to process it now before we overwrite it with the next
|
||||
* handshake record.
|
||||
*/
|
||||
rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
|
||||
} else {
|
||||
/* bring in the next sslv3 record. */
|
||||
if (ss->recvdCloseNotify) {
|
||||
/* RFC 5246 Section 7.2.1:
|
||||
* Any data received after a closure alert is ignored.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
if (!IS_DTLS(ss)) {
|
||||
rv = ssl3_GatherData(ss, &ss->gs, flags);
|
||||
} else {
|
||||
rv = dtls_GatherData(ss, &ss->gs, flags);
|
||||
|
||||
/* If we got a would block error, that means that no data was
|
||||
* available, so we check the timer to see if it's time to
|
||||
* retransmit */
|
||||
if (rv == SECFailure &&
|
||||
(PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
dtls_CheckTimer(ss);
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
/* Restore the error in case something succeeded */
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
}
|
||||
}
|
||||
if (handleRecordNow) {
|
||||
/* ssl3_HandleHandshake previously returned SECWouldBlock and the
|
||||
* as-yet-unprocessed plaintext of that previous handshake record.
|
||||
* We need to process it now before we overwrite it with the next
|
||||
* handshake record.
|
||||
*/
|
||||
rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
|
||||
}
|
||||
else {
|
||||
/* bring in the next sslv3 record. */
|
||||
if (ss->recvdCloseNotify) {
|
||||
/* RFC 5246 Section 7.2.1:
|
||||
* Any data received after a closure alert is ignored.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
if (!IS_DTLS(ss)) {
|
||||
rv = ssl3_GatherData(ss, &ss->gs, flags);
|
||||
}
|
||||
else {
|
||||
rv = dtls_GatherData(ss, &ss->gs, flags);
|
||||
|
||||
if (rv <= 0) {
|
||||
return rv;
|
||||
}
|
||||
/* If we got a would block error, that means that no data was
|
||||
* available, so we check the timer to see if it's time to
|
||||
* retransmit */
|
||||
if (rv == SECFailure &&
|
||||
(PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
dtls_CheckTimer(ss);
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
/* Restore the error in case something succeeded */
|
||||
PORT_SetError(PR_WOULD_BLOCK_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* decipher it, and handle it if it's a handshake.
|
||||
* If it's application data, ss->gs.buf will not be empty upon return.
|
||||
* If it's a change cipher spec, alert, or handshake message,
|
||||
* ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
|
||||
*/
|
||||
cText.type = (SSL3ContentType)ss->gs.hdr[0];
|
||||
cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
|
||||
if (rv <= 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (IS_DTLS(ss)) {
|
||||
int i;
|
||||
/* decipher it, and handle it if it's a handshake.
|
||||
* If it's application data, ss->gs.buf will not be empty upon return.
|
||||
* If it's a change cipher spec, alert, or handshake message,
|
||||
* ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
|
||||
*/
|
||||
cText.type = (SSL3ContentType)ss->gs.hdr[0];
|
||||
cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
|
||||
|
||||
cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
|
||||
/* DTLS sequence number */
|
||||
cText.seq_num.high = 0; cText.seq_num.low = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
|
||||
cText.seq_num.high |= ss->gs.hdr[3 + i];
|
||||
cText.seq_num.low |= ss->gs.hdr[7 + i];
|
||||
}
|
||||
}
|
||||
if (IS_DTLS(ss)) {
|
||||
int i;
|
||||
|
||||
cText.buf = &ss->gs.inbuf;
|
||||
rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
|
||||
}
|
||||
if (rv < 0) {
|
||||
return ss->recvdCloseNotify ? 0 : rv;
|
||||
}
|
||||
if (ss->gs.buf.len > 0) {
|
||||
/* We have application data to return to the application. This
|
||||
* prioritizes returning application data to the application over
|
||||
* completing any renegotiation handshake we may be doing.
|
||||
*/
|
||||
PORT_Assert(ss->firstHsDone);
|
||||
PORT_Assert(cText.type == content_application_data);
|
||||
break;
|
||||
}
|
||||
cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
|
||||
/* DTLS sequence number */
|
||||
cText.seq_num.high = 0;
|
||||
cText.seq_num.low = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
cText.seq_num.high <<= 8;
|
||||
cText.seq_num.low <<= 8;
|
||||
cText.seq_num.high |= ss->gs.hdr[3 + i];
|
||||
cText.seq_num.low |= ss->gs.hdr[7 + i];
|
||||
}
|
||||
}
|
||||
|
||||
PORT_Assert(keepGoing);
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
if (ss->ssl3.hs.ws == idle_handshake) {
|
||||
/* We are done with the current handshake so stop trying to
|
||||
* handshake. Note that it would be safe to test ss->firstHsDone
|
||||
* instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
|
||||
* we prioritize completing a renegotiation handshake over sending
|
||||
* application data.
|
||||
*/
|
||||
PORT_Assert(ss->firstHsDone);
|
||||
PORT_Assert(!ss->ssl3.hs.canFalseStart);
|
||||
keepGoing = PR_FALSE;
|
||||
} else if (ss->ssl3.hs.canFalseStart) {
|
||||
/* Prioritize sending application data over trying to complete
|
||||
* the handshake if we're false starting.
|
||||
*
|
||||
* If we were to do this check at the beginning of the loop instead
|
||||
* of here, then this function would become be a no-op after
|
||||
* receiving the ServerHelloDone in the false start case, and we
|
||||
* would never complete the handshake.
|
||||
*/
|
||||
PORT_Assert(!ss->firstHsDone);
|
||||
cText.buf = &ss->gs.inbuf;
|
||||
rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
|
||||
}
|
||||
if (rv < 0) {
|
||||
return ss->recvdCloseNotify ? 0 : rv;
|
||||
}
|
||||
if (ss->gs.buf.len > 0) {
|
||||
/* We have application data to return to the application. This
|
||||
* prioritizes returning application data to the application over
|
||||
* completing any renegotiation handshake we may be doing.
|
||||
*/
|
||||
PORT_Assert(ss->firstHsDone);
|
||||
PORT_Assert(cText.type == content_application_data);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ssl3_WaitingForServerSecondRound(ss)) {
|
||||
keepGoing = PR_FALSE;
|
||||
} else {
|
||||
ss->ssl3.hs.canFalseStart = PR_FALSE;
|
||||
}
|
||||
}
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
PORT_Assert(keepGoing);
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
if (ss->ssl3.hs.ws == idle_handshake) {
|
||||
/* We are done with the current handshake so stop trying to
|
||||
* handshake. Note that it would be safe to test ss->firstHsDone
|
||||
* instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
|
||||
* we prioritize completing a renegotiation handshake over sending
|
||||
* application data.
|
||||
*/
|
||||
PORT_Assert(ss->firstHsDone);
|
||||
PORT_Assert(!ss->ssl3.hs.canFalseStart);
|
||||
keepGoing = PR_FALSE;
|
||||
}
|
||||
else if (ss->ssl3.hs.canFalseStart) {
|
||||
/* Prioritize sending application data over trying to complete
|
||||
* the handshake if we're false starting.
|
||||
*
|
||||
* If we were to do this check at the beginning of the loop instead
|
||||
* of here, then this function would become be a no-op after
|
||||
* receiving the ServerHelloDone in the false start case, and we
|
||||
* would never complete the handshake.
|
||||
*/
|
||||
PORT_Assert(!ss->firstHsDone);
|
||||
|
||||
if (ssl3_WaitingForServerSecondRound(ss)) {
|
||||
keepGoing = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
ss->ssl3.hs.canFalseStart = PR_FALSE;
|
||||
}
|
||||
}
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
} while (keepGoing);
|
||||
|
||||
ss->gs.readOffset = 0;
|
||||
|
@ -441,14 +453,14 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
|
|||
int
|
||||
ssl3_GatherAppDataRecord(sslSocket *ss, int flags)
|
||||
{
|
||||
int rv;
|
||||
int rv;
|
||||
|
||||
/* ssl3_GatherCompleteHandshake requires both of these locks. */
|
||||
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
|
||||
do {
|
||||
rv = ssl3_GatherCompleteHandshake(ss, flags);
|
||||
rv = ssl3_GatherCompleteHandshake(ss, flags);
|
||||
} while (rv > 0 && ss->gs.buf.len == 0);
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -17,57 +17,57 @@ typedef PRUint16 SSL3ProtocolVersion;
|
|||
/* The TLS 1.3 draft version. Used to avoid negotiating
|
||||
* between incompatible pre-standard TLS 1.3 drafts.
|
||||
* TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
|
||||
#define TLS_1_3_DRAFT_VERSION 11
|
||||
#define TLS_1_3_DRAFT_VERSION 11
|
||||
|
||||
typedef PRUint16 ssl3CipherSuite;
|
||||
/* The cipher suites are defined in sslproto.h */
|
||||
|
||||
#define MAX_CERT_TYPES 10
|
||||
#define MAX_COMPRESSION_METHODS 10
|
||||
#define MAX_MAC_LENGTH 64
|
||||
#define MAX_PADDING_LENGTH 64
|
||||
#define MAX_KEY_LENGTH 64
|
||||
#define EXPORT_KEY_LENGTH 5
|
||||
#define SSL3_RANDOM_LENGTH 32
|
||||
#define MAX_CERT_TYPES 10
|
||||
#define MAX_COMPRESSION_METHODS 10
|
||||
#define MAX_MAC_LENGTH 64
|
||||
#define MAX_PADDING_LENGTH 64
|
||||
#define MAX_KEY_LENGTH 64
|
||||
#define EXPORT_KEY_LENGTH 5
|
||||
#define SSL3_RANDOM_LENGTH 32
|
||||
|
||||
#define SSL3_RECORD_HEADER_LENGTH 5
|
||||
#define SSL3_RECORD_HEADER_LENGTH 5
|
||||
|
||||
/* SSL3_RECORD_HEADER_LENGTH + epoch/sequence_number */
|
||||
#define DTLS_RECORD_HEADER_LENGTH 13
|
||||
#define DTLS_RECORD_HEADER_LENGTH 13
|
||||
|
||||
#define MAX_FRAGMENT_LENGTH 16384
|
||||
#define MAX_FRAGMENT_LENGTH 16384
|
||||
|
||||
typedef enum {
|
||||
content_change_cipher_spec = 20,
|
||||
content_alert = 21,
|
||||
content_handshake = 22,
|
||||
content_application_data = 23
|
||||
content_alert = 21,
|
||||
content_handshake = 22,
|
||||
content_application_data = 23
|
||||
} SSL3ContentType;
|
||||
|
||||
typedef struct {
|
||||
SSL3ContentType type;
|
||||
SSL3ContentType type;
|
||||
SSL3ProtocolVersion version;
|
||||
PRUint16 length;
|
||||
SECItem fragment;
|
||||
PRUint16 length;
|
||||
SECItem fragment;
|
||||
} SSL3Plaintext;
|
||||
|
||||
typedef struct {
|
||||
SSL3ContentType type;
|
||||
SSL3ContentType type;
|
||||
SSL3ProtocolVersion version;
|
||||
PRUint16 length;
|
||||
SECItem fragment;
|
||||
PRUint16 length;
|
||||
SECItem fragment;
|
||||
} SSL3Compressed;
|
||||
|
||||
typedef struct {
|
||||
SECItem content;
|
||||
SECItem content;
|
||||
SSL3Opaque MAC[MAX_MAC_LENGTH];
|
||||
} SSL3GenericStreamCipher;
|
||||
|
||||
typedef struct {
|
||||
SECItem content;
|
||||
SECItem content;
|
||||
SSL3Opaque MAC[MAX_MAC_LENGTH];
|
||||
PRUint8 padding[MAX_PADDING_LENGTH];
|
||||
PRUint8 padding_length;
|
||||
PRUint8 padding[MAX_PADDING_LENGTH];
|
||||
PRUint8 padding_length;
|
||||
} SSL3GenericBlockCipher;
|
||||
|
||||
typedef enum { change_cipher_spec_choice = 1 } SSL3ChangeCipherSpecChoice;
|
||||
|
@ -76,70 +76,71 @@ typedef struct {
|
|||
SSL3ChangeCipherSpecChoice choice;
|
||||
} SSL3ChangeCipherSpec;
|
||||
|
||||
typedef enum { alert_warning = 1, alert_fatal = 2 } SSL3AlertLevel;
|
||||
typedef enum { alert_warning = 1,
|
||||
alert_fatal = 2 } SSL3AlertLevel;
|
||||
|
||||
typedef enum {
|
||||
close_notify = 0,
|
||||
unexpected_message = 10,
|
||||
bad_record_mac = 20,
|
||||
decryption_failed_RESERVED = 21, /* do not send; see RFC 5246 */
|
||||
record_overflow = 22, /* TLS only */
|
||||
decompression_failure = 30,
|
||||
handshake_failure = 40,
|
||||
no_certificate = 41, /* SSL3 only, NOT TLS */
|
||||
bad_certificate = 42,
|
||||
close_notify = 0,
|
||||
unexpected_message = 10,
|
||||
bad_record_mac = 20,
|
||||
decryption_failed_RESERVED = 21, /* do not send; see RFC 5246 */
|
||||
record_overflow = 22, /* TLS only */
|
||||
decompression_failure = 30,
|
||||
handshake_failure = 40,
|
||||
no_certificate = 41, /* SSL3 only, NOT TLS */
|
||||
bad_certificate = 42,
|
||||
unsupported_certificate = 43,
|
||||
certificate_revoked = 44,
|
||||
certificate_expired = 45,
|
||||
certificate_unknown = 46,
|
||||
illegal_parameter = 47,
|
||||
certificate_revoked = 44,
|
||||
certificate_expired = 45,
|
||||
certificate_unknown = 46,
|
||||
illegal_parameter = 47,
|
||||
|
||||
/* All alerts below are TLS only. */
|
||||
unknown_ca = 48,
|
||||
access_denied = 49,
|
||||
decode_error = 50,
|
||||
decrypt_error = 51,
|
||||
export_restriction = 60,
|
||||
protocol_version = 70,
|
||||
insufficient_security = 71,
|
||||
internal_error = 80,
|
||||
inappropriate_fallback = 86, /* could also be sent for SSLv3 */
|
||||
user_canceled = 90,
|
||||
no_renegotiation = 100,
|
||||
/* All alerts below are TLS only. */
|
||||
unknown_ca = 48,
|
||||
access_denied = 49,
|
||||
decode_error = 50,
|
||||
decrypt_error = 51,
|
||||
export_restriction = 60,
|
||||
protocol_version = 70,
|
||||
insufficient_security = 71,
|
||||
internal_error = 80,
|
||||
inappropriate_fallback = 86, /* could also be sent for SSLv3 */
|
||||
user_canceled = 90,
|
||||
no_renegotiation = 100,
|
||||
|
||||
/* Alerts for client hello extensions */
|
||||
missing_extension = 109,
|
||||
unsupported_extension = 110,
|
||||
certificate_unobtainable = 111,
|
||||
unrecognized_name = 112,
|
||||
/* Alerts for client hello extensions */
|
||||
missing_extension = 109,
|
||||
unsupported_extension = 110,
|
||||
certificate_unobtainable = 111,
|
||||
unrecognized_name = 112,
|
||||
bad_certificate_status_response = 113,
|
||||
bad_certificate_hash_value = 114,
|
||||
no_application_protocol = 120
|
||||
bad_certificate_hash_value = 114,
|
||||
no_application_protocol = 120
|
||||
|
||||
} SSL3AlertDescription;
|
||||
|
||||
typedef struct {
|
||||
SSL3AlertLevel level;
|
||||
SSL3AlertLevel level;
|
||||
SSL3AlertDescription description;
|
||||
} SSL3Alert;
|
||||
|
||||
typedef enum {
|
||||
hello_request = 0,
|
||||
client_hello = 1,
|
||||
server_hello = 2,
|
||||
hello_request = 0,
|
||||
client_hello = 1,
|
||||
server_hello = 2,
|
||||
hello_verify_request = 3,
|
||||
new_session_ticket = 4,
|
||||
new_session_ticket = 4,
|
||||
hello_retry_request = 6,
|
||||
encrypted_extensions = 8,
|
||||
certificate = 11,
|
||||
certificate = 11,
|
||||
server_key_exchange = 12,
|
||||
certificate_request = 13,
|
||||
server_hello_done = 14,
|
||||
certificate_verify = 15,
|
||||
server_hello_done = 14,
|
||||
certificate_verify = 15,
|
||||
client_key_exchange = 16,
|
||||
finished = 20,
|
||||
certificate_status = 22,
|
||||
next_proto = 67
|
||||
finished = 20,
|
||||
certificate_status = 22,
|
||||
next_proto = 67
|
||||
} SSL3HandshakeType;
|
||||
|
||||
typedef struct {
|
||||
|
@ -156,20 +157,20 @@ typedef struct {
|
|||
} SSL3SessionID;
|
||||
|
||||
typedef struct {
|
||||
SSL3ProtocolVersion client_version;
|
||||
SSL3Random random;
|
||||
SSL3SessionID session_id;
|
||||
SECItem cipher_suites;
|
||||
PRUint8 cm_count;
|
||||
SSLCompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
|
||||
SSL3ProtocolVersion client_version;
|
||||
SSL3Random random;
|
||||
SSL3SessionID session_id;
|
||||
SECItem cipher_suites;
|
||||
PRUint8 cm_count;
|
||||
SSLCompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
|
||||
} SSL3ClientHello;
|
||||
|
||||
typedef struct {
|
||||
SSL3ProtocolVersion server_version;
|
||||
SSL3Random random;
|
||||
SSL3SessionID session_id;
|
||||
ssl3CipherSuite cipher_suite;
|
||||
SSLCompressionMethod compression_method;
|
||||
typedef struct {
|
||||
SSL3ProtocolVersion server_version;
|
||||
SSL3Random random;
|
||||
SSL3SessionID session_id;
|
||||
ssl3CipherSuite cipher_suite;
|
||||
SSLCompressionMethod compression_method;
|
||||
} SSL3ServerHello;
|
||||
|
||||
typedef struct {
|
||||
|
@ -247,15 +248,15 @@ typedef struct {
|
|||
} SSL3ServerKeyExchange;
|
||||
|
||||
typedef enum {
|
||||
ct_RSA_sign = 1,
|
||||
ct_DSS_sign = 2,
|
||||
ct_RSA_fixed_DH = 3,
|
||||
ct_DSS_fixed_DH = 4,
|
||||
ct_RSA_ephemeral_DH = 5,
|
||||
ct_DSS_ephemeral_DH = 6,
|
||||
ct_ECDSA_sign = 64,
|
||||
ct_RSA_fixed_ECDH = 65,
|
||||
ct_ECDSA_fixed_ECDH = 66
|
||||
ct_RSA_sign = 1,
|
||||
ct_DSS_sign = 2,
|
||||
ct_RSA_fixed_DH = 3,
|
||||
ct_DSS_fixed_DH = 4,
|
||||
ct_RSA_ephemeral_DH = 5,
|
||||
ct_DSS_ephemeral_DH = 6,
|
||||
ct_ECDSA_sign = 64,
|
||||
ct_RSA_fixed_ECDH = 65,
|
||||
ct_ECDSA_fixed_ECDH = 66
|
||||
|
||||
} SSL3ClientCertificateType;
|
||||
|
||||
|
@ -287,11 +288,11 @@ typedef struct {
|
|||
typedef struct {
|
||||
PRUint32 received_timestamp;
|
||||
PRUint32 ticket_lifetime_hint;
|
||||
SECItem ticket;
|
||||
SECItem ticket;
|
||||
} NewSessionTicket;
|
||||
|
||||
typedef enum {
|
||||
CLIENT_AUTH_ANONYMOUS = 0,
|
||||
CLIENT_AUTH_ANONYMOUS = 0,
|
||||
CLIENT_AUTH_CERTIFICATE = 1
|
||||
} ClientAuthenticationType;
|
||||
|
||||
|
@ -302,10 +303,10 @@ typedef struct {
|
|||
} identity;
|
||||
} ClientIdentity;
|
||||
|
||||
#define SESS_TICKET_KEY_NAME_LEN 16
|
||||
#define SESS_TICKET_KEY_NAME_PREFIX "NSS!"
|
||||
#define SESS_TICKET_KEY_NAME_LEN 16
|
||||
#define SESS_TICKET_KEY_NAME_PREFIX "NSS!"
|
||||
#define SESS_TICKET_KEY_NAME_PREFIX_LEN 4
|
||||
#define SESS_TICKET_KEY_VAR_NAME_LEN 12
|
||||
#define SESS_TICKET_KEY_VAR_NAME_LEN 12
|
||||
|
||||
typedef struct {
|
||||
unsigned char *key_name;
|
||||
|
@ -316,6 +317,6 @@ typedef struct {
|
|||
|
||||
#define TLS_EX_SESS_TICKET_MAC_LENGTH 32
|
||||
|
||||
#define TLS_STE_NO_SERVER_NAME -1
|
||||
#define TLS_STE_NO_SERVER_NAME -1
|
||||
|
||||
#endif /* __ssl3proto_h_ */
|
||||
|
|
|
@ -17,12 +17,12 @@ SSL_PeerCertificate(PRFileDesc *fd)
|
|||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
|
||||
SSL_GETPID(), fd));
|
||||
return 0;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
|
||||
SSL_GETPID(), fd));
|
||||
return 0;
|
||||
}
|
||||
if (ss->opt.useSecurity && ss->sec.peerCert) {
|
||||
return CERT_DupCertificate(ss->sec.peerCert);
|
||||
return CERT_DupCertificate(ss->sec.peerCert);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -38,27 +38,27 @@ SSL_PeerCertificateChain(PRFileDesc *fd)
|
|||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain",
|
||||
SSL_GETPID(), fd));
|
||||
return NULL;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain",
|
||||
SSL_GETPID(), fd));
|
||||
return NULL;
|
||||
}
|
||||
if (!ss->opt.useSecurity || !ss->sec.peerCert) {
|
||||
PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
|
||||
return NULL;
|
||||
PORT_SetError(SSL_ERROR_NO_CERTIFICATE);
|
||||
return NULL;
|
||||
}
|
||||
chain = CERT_NewCertList();
|
||||
if (!chain) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
cert = CERT_DupCertificate(ss->sec.peerCert);
|
||||
if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
|
||||
goto loser;
|
||||
goto loser;
|
||||
}
|
||||
for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) {
|
||||
cert = CERT_DupCertificate(cur->cert);
|
||||
if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
cert = CERT_DupCertificate(cur->cert);
|
||||
if (CERT_AddCertToListTail(chain, cert) != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
return chain;
|
||||
|
||||
|
@ -75,27 +75,25 @@ SSL_LocalCertificate(PRFileDesc *fd)
|
|||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
|
||||
SSL_GETPID(), fd));
|
||||
return NULL;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
|
||||
SSL_GETPID(), fd));
|
||||
return NULL;
|
||||
}
|
||||
if (ss->opt.useSecurity) {
|
||||
if (ss->sec.localCert) {
|
||||
return CERT_DupCertificate(ss->sec.localCert);
|
||||
}
|
||||
if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) {
|
||||
return CERT_DupCertificate(ss->sec.ci.sid->localCert);
|
||||
}
|
||||
if (ss->sec.localCert) {
|
||||
return CERT_DupCertificate(ss->sec.localCert);
|
||||
}
|
||||
if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) {
|
||||
return CERT_DupCertificate(ss->sec.ci.sid->localCert);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NEED LOCKS IN HERE. */
|
||||
SECStatus
|
||||
SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
|
||||
char **ip, char **sp)
|
||||
char **ip, char **sp)
|
||||
{
|
||||
sslSocket *ss;
|
||||
const char *cipherName;
|
||||
|
@ -103,74 +101,85 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1,
|
|||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SecurityStatus",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (cp) *cp = 0;
|
||||
if (kp0) *kp0 = 0;
|
||||
if (kp1) *kp1 = 0;
|
||||
if (ip) *ip = 0;
|
||||
if (sp) *sp = 0;
|
||||
if (cp)
|
||||
*cp = 0;
|
||||
if (kp0)
|
||||
*kp0 = 0;
|
||||
if (kp1)
|
||||
*kp1 = 0;
|
||||
if (ip)
|
||||
*ip = 0;
|
||||
if (sp)
|
||||
*sp = 0;
|
||||
if (op) {
|
||||
*op = SSL_SECURITY_STATUS_OFF;
|
||||
*op = SSL_SECURITY_STATUS_OFF;
|
||||
}
|
||||
|
||||
if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) {
|
||||
cipherName = ssl_cipherName[ss->sec.cipherType];
|
||||
} else {
|
||||
cipherName = ssl3_cipherName[ss->sec.cipherType];
|
||||
}
|
||||
PORT_Assert(cipherName);
|
||||
if (cipherName) {
|
||||
if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE;
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) {
|
||||
cipherName = ssl_cipherName[ss->sec.cipherType];
|
||||
}
|
||||
else {
|
||||
cipherName = ssl3_cipherName[ss->sec.cipherType];
|
||||
}
|
||||
PORT_Assert(cipherName);
|
||||
if (cipherName) {
|
||||
if (PORT_Strstr(cipherName, "DES"))
|
||||
isDes = PR_TRUE;
|
||||
|
||||
if (cp) {
|
||||
*cp = PORT_Strdup(cipherName);
|
||||
}
|
||||
}
|
||||
|
||||
if (kp0) {
|
||||
*kp0 = ss->sec.keyBits;
|
||||
if (isDes) *kp0 = (*kp0 * 7) / 8;
|
||||
}
|
||||
if (kp1) {
|
||||
*kp1 = ss->sec.secretKeyBits;
|
||||
if (isDes) *kp1 = (*kp1 * 7) / 8;
|
||||
}
|
||||
if (op) {
|
||||
if (ss->sec.keyBits == 0) {
|
||||
*op = SSL_SECURITY_STATUS_OFF;
|
||||
} else if (ss->sec.secretKeyBits < 90) {
|
||||
*op = SSL_SECURITY_STATUS_ON_LOW;
|
||||
if (kp0) {
|
||||
*kp0 = ss->sec.keyBits;
|
||||
if (isDes)
|
||||
*kp0 = (*kp0 * 7) / 8;
|
||||
}
|
||||
if (kp1) {
|
||||
*kp1 = ss->sec.secretKeyBits;
|
||||
if (isDes)
|
||||
*kp1 = (*kp1 * 7) / 8;
|
||||
}
|
||||
if (op) {
|
||||
if (ss->sec.keyBits == 0) {
|
||||
*op = SSL_SECURITY_STATUS_OFF;
|
||||
}
|
||||
else if (ss->sec.secretKeyBits < 90) {
|
||||
*op = SSL_SECURITY_STATUS_ON_LOW;
|
||||
}
|
||||
else {
|
||||
*op = SSL_SECURITY_STATUS_ON_HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
*op = SSL_SECURITY_STATUS_ON_HIGH;
|
||||
}
|
||||
}
|
||||
if (ip || sp) {
|
||||
CERTCertificate *cert;
|
||||
|
||||
if (ip || sp) {
|
||||
CERTCertificate *cert;
|
||||
|
||||
cert = ss->sec.peerCert;
|
||||
if (cert) {
|
||||
if (ip) {
|
||||
*ip = CERT_NameToAscii(&cert->issuer);
|
||||
}
|
||||
if (sp) {
|
||||
*sp = CERT_NameToAscii(&cert->subject);
|
||||
}
|
||||
} else {
|
||||
if (ip) {
|
||||
*ip = PORT_Strdup("no certificate");
|
||||
}
|
||||
if (sp) {
|
||||
*sp = PORT_Strdup("no certificate");
|
||||
}
|
||||
}
|
||||
}
|
||||
cert = ss->sec.peerCert;
|
||||
if (cert) {
|
||||
if (ip) {
|
||||
*ip = CERT_NameToAscii(&cert->issuer);
|
||||
}
|
||||
if (sp) {
|
||||
*sp = CERT_NameToAscii(&cert->subject);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ip) {
|
||||
*ip = PORT_Strdup("no certificate");
|
||||
}
|
||||
if (sp) {
|
||||
*sp = PORT_Strdup("no certificate");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
|
@ -186,9 +195,9 @@ SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
|
|||
|
||||
ss = ssl_FindSocket(s);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
|
||||
SSL_GETPID(), s));
|
||||
return SECFailure;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in AuthCertificateHook",
|
||||
SSL_GETPID(), s));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->authCertificate = func;
|
||||
|
@ -198,17 +207,17 @@ SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
|
|||
}
|
||||
|
||||
/* NEED LOCKS IN HERE. */
|
||||
SECStatus
|
||||
SECStatus
|
||||
SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
|
||||
void *arg)
|
||||
void *arg)
|
||||
{
|
||||
sslSocket *ss;
|
||||
|
||||
ss = ssl_FindSocket(s);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
|
||||
SSL_GETPID(), s));
|
||||
return SECFailure;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
|
||||
SSL_GETPID(), s));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->getClientAuthData = func;
|
||||
|
@ -217,77 +226,76 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
|
|||
}
|
||||
|
||||
/* NEED LOCKS IN HERE. */
|
||||
SECStatus
|
||||
SECStatus
|
||||
SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
|
||||
{
|
||||
sslSocket *ss;
|
||||
|
||||
ss = ssl_FindSocket(s);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
|
||||
SSL_GETPID(), s));
|
||||
return SECFailure;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in GetClientAuthDataHook",
|
||||
SSL_GETPID(), s));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->pkcs11PinArg = arg;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
||||
/* This is the "default" authCert callback function. It is called when a
|
||||
/* This is the "default" authCert callback function. It is called when a
|
||||
* certificate message is received from the peer and the local application
|
||||
* has not registered an authCert callback function.
|
||||
*/
|
||||
SECStatus
|
||||
SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
|
||||
{
|
||||
SECStatus rv;
|
||||
CERTCertDBHandle * handle;
|
||||
sslSocket * ss;
|
||||
SECCertUsage certUsage;
|
||||
const char * hostname = NULL;
|
||||
PRTime now = PR_Now();
|
||||
SECItemArray * certStatusArray;
|
||||
|
||||
SECStatus rv;
|
||||
CERTCertDBHandle *handle;
|
||||
sslSocket *ss;
|
||||
SECCertUsage certUsage;
|
||||
const char *hostname = NULL;
|
||||
PRTime now = PR_Now();
|
||||
SECItemArray *certStatusArray;
|
||||
|
||||
ss = ssl_FindSocket(fd);
|
||||
PORT_Assert(ss != NULL);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
handle = (CERTCertDBHandle *)arg;
|
||||
certStatusArray = &ss->sec.ci.sid->peerCertStatus;
|
||||
|
||||
if (certStatusArray->len) {
|
||||
PORT_SetError(0);
|
||||
if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now,
|
||||
&certStatusArray->items[0],
|
||||
ss->pkcs11PinArg)
|
||||
!= SECSuccess) {
|
||||
PORT_Assert(PR_GetError() != 0);
|
||||
}
|
||||
PORT_SetError(0);
|
||||
if (CERT_CacheOCSPResponseFromSideChannel(handle, ss->sec.peerCert, now,
|
||||
&certStatusArray->items[0],
|
||||
ss->pkcs11PinArg) !=
|
||||
SECSuccess) {
|
||||
PORT_Assert(PR_GetError() != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* this may seem backwards, but isn't. */
|
||||
certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
|
||||
|
||||
rv = CERT_VerifyCert(handle, ss->sec.peerCert, checkSig, certUsage,
|
||||
now, ss->pkcs11PinArg, NULL);
|
||||
now, ss->pkcs11PinArg, NULL);
|
||||
|
||||
if (rv != SECSuccess || isServer)
|
||||
return rv;
|
||||
|
||||
if ( rv != SECSuccess || isServer )
|
||||
return rv;
|
||||
|
||||
/* cert is OK. This is the client side of an SSL connection.
|
||||
* Now check the name field in the cert against the desired hostname.
|
||||
* NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
|
||||
*/
|
||||
hostname = ss->url;
|
||||
if (hostname && hostname[0])
|
||||
rv = CERT_VerifyCertName(ss->sec.peerCert, hostname);
|
||||
else
|
||||
rv = SECFailure;
|
||||
rv = CERT_VerifyCertName(ss->sec.peerCert, hostname);
|
||||
else
|
||||
rv = SECFailure;
|
||||
if (rv != SECSuccess)
|
||||
PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -10,14 +10,18 @@
|
|||
#include "sslimpl.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define MAP_ERROR(from,to) if (err == from) { PORT_SetError(to); }
|
||||
#define DEFINE_ERROR PRErrorCode err = PR_GetError();
|
||||
#define MAP_ERROR(from, to) \
|
||||
if (err == from) { \
|
||||
PORT_SetError(to); \
|
||||
}
|
||||
#define DEFINE_ERROR PRErrorCode err = PR_GetError();
|
||||
#else
|
||||
#define MAP_ERROR(from,to)
|
||||
#define MAP_ERROR(from, to)
|
||||
#define DEFINE_ERROR
|
||||
#endif
|
||||
|
||||
int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
|
||||
int
|
||||
ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
@ -26,7 +30,8 @@ int ssl_DefConnect(sslSocket *ss, const PRNetAddr *sa)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
|
||||
int
|
||||
ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
@ -35,7 +40,8 @@ int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefListen(sslSocket *ss, int backlog)
|
||||
int
|
||||
ssl_DefListen(sslSocket *ss, int backlog)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
@ -44,7 +50,8 @@ int ssl_DefListen(sslSocket *ss, int backlog)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefShutdown(sslSocket *ss, int how)
|
||||
int
|
||||
ssl_DefShutdown(sslSocket *ss, int how)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
@ -53,19 +60,21 @@ int ssl_DefShutdown(sslSocket *ss, int how)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
|
||||
int
|
||||
ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
||||
rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout);
|
||||
if (rv < 0) {
|
||||
DEFINE_ERROR
|
||||
MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
} else if (rv > len) {
|
||||
PORT_Assert(rv <= len);
|
||||
PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
|
||||
rv = SECFailure;
|
||||
DEFINE_ERROR
|
||||
MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
}
|
||||
else if (rv > len) {
|
||||
PORT_Assert(rv <= len);
|
||||
PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
|
||||
rv = SECFailure;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -73,87 +82,91 @@ int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
|
|||
/* Default (unencrypted) send.
|
||||
* For blocking sockets, always returns len or SECFailure, no short writes.
|
||||
* For non-blocking sockets:
|
||||
* Returns positive count if any data was written, else returns SECFailure.
|
||||
* Returns positive count if any data was written, else returns SECFailure.
|
||||
* Short writes may occur. Does not return SECWouldBlock.
|
||||
*/
|
||||
int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
|
||||
int
|
||||
ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int sent = 0;
|
||||
|
||||
#if NSS_DISABLE_NAGLE_DELAYS
|
||||
/* Although this is overkill, we disable Nagle delays completely for
|
||||
/* Although this is overkill, we disable Nagle delays completely for
|
||||
** SSL sockets.
|
||||
*/
|
||||
if (ss->opt.useSecurity && !ss->delayDisabled) {
|
||||
ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */
|
||||
ss->delayDisabled = 1;
|
||||
ssl_EnableNagleDelay(ss, PR_FALSE); /* ignore error */
|
||||
ss->delayDisabled = 1;
|
||||
}
|
||||
#endif
|
||||
do {
|
||||
int rv = lower->methods->send(lower, (const void *)(buf + sent),
|
||||
len - sent, flags, ss->wTimeout);
|
||||
if (rv < 0) {
|
||||
PRErrorCode err = PR_GetError();
|
||||
if (err == PR_WOULD_BLOCK_ERROR) {
|
||||
ss->lastWriteBlocked = 1;
|
||||
return sent ? sent : SECFailure;
|
||||
}
|
||||
ss->lastWriteBlocked = 0;
|
||||
MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
/* Loser */
|
||||
return rv;
|
||||
}
|
||||
sent += rv;
|
||||
|
||||
if (IS_DTLS(ss) && (len > sent)) {
|
||||
/* We got a partial write so just return it */
|
||||
return sent;
|
||||
}
|
||||
int rv = lower->methods->send(lower, (const void *)(buf + sent),
|
||||
len - sent, flags, ss->wTimeout);
|
||||
if (rv < 0) {
|
||||
PRErrorCode err = PR_GetError();
|
||||
if (err == PR_WOULD_BLOCK_ERROR) {
|
||||
ss->lastWriteBlocked = 1;
|
||||
return sent ? sent : SECFailure;
|
||||
}
|
||||
ss->lastWriteBlocked = 0;
|
||||
MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
/* Loser */
|
||||
return rv;
|
||||
}
|
||||
sent += rv;
|
||||
|
||||
if (IS_DTLS(ss) && (len > sent)) {
|
||||
/* We got a partial write so just return it */
|
||||
return sent;
|
||||
}
|
||||
} while (len > sent);
|
||||
ss->lastWriteBlocked = 0;
|
||||
return sent;
|
||||
}
|
||||
|
||||
int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
|
||||
int
|
||||
ssl_DefRead(sslSocket *ss, unsigned char *buf, int len)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
||||
rv = lower->methods->read(lower, (void *)buf, len);
|
||||
if (rv < 0) {
|
||||
DEFINE_ERROR
|
||||
MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
DEFINE_ERROR
|
||||
MAP_ERROR(PR_SOCKET_SHUTDOWN_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
|
||||
int
|
||||
ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int sent = 0;
|
||||
|
||||
do {
|
||||
int rv = lower->methods->write(lower, (const void *)(buf + sent),
|
||||
len - sent);
|
||||
if (rv < 0) {
|
||||
PRErrorCode err = PR_GetError();
|
||||
if (err == PR_WOULD_BLOCK_ERROR) {
|
||||
ss->lastWriteBlocked = 1;
|
||||
return sent ? sent : SECFailure;
|
||||
}
|
||||
ss->lastWriteBlocked = 0;
|
||||
MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
/* Loser */
|
||||
return rv;
|
||||
}
|
||||
sent += rv;
|
||||
int rv = lower->methods->write(lower, (const void *)(buf + sent),
|
||||
len - sent);
|
||||
if (rv < 0) {
|
||||
PRErrorCode err = PR_GetError();
|
||||
if (err == PR_WOULD_BLOCK_ERROR) {
|
||||
ss->lastWriteBlocked = 1;
|
||||
return sent ? sent : SECFailure;
|
||||
}
|
||||
ss->lastWriteBlocked = 0;
|
||||
MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR)
|
||||
/* Loser */
|
||||
return rv;
|
||||
}
|
||||
sent += rv;
|
||||
} while (len > sent);
|
||||
ss->lastWriteBlocked = 0;
|
||||
return sent;
|
||||
}
|
||||
|
||||
int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
|
||||
int
|
||||
ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
@ -162,7 +175,8 @@ int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
|
||||
int
|
||||
ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
|
||||
{
|
||||
PRFileDesc *lower = ss->fd->lower;
|
||||
int rv;
|
||||
|
@ -171,22 +185,23 @@ int ssl_DefGetsockname(sslSocket *ss, PRNetAddr *name)
|
|||
return rv;
|
||||
}
|
||||
|
||||
int ssl_DefClose(sslSocket *ss)
|
||||
int
|
||||
ssl_DefClose(sslSocket *ss)
|
||||
{
|
||||
PRFileDesc *fd;
|
||||
PRFileDesc *popped;
|
||||
int rv;
|
||||
int rv;
|
||||
|
||||
fd = ss->fd;
|
||||
fd = ss->fd;
|
||||
|
||||
/* First, remove the SSL layer PRFileDesc from the socket's stack,
|
||||
/* First, remove the SSL layer PRFileDesc from the socket's stack,
|
||||
** then invoke the SSL layer's PRFileDesc destructor.
|
||||
** This must happen before the next layer down is closed.
|
||||
*/
|
||||
PORT_Assert(fd->higher == NULL);
|
||||
if (fd->higher) {
|
||||
PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
|
||||
return SECFailure;
|
||||
PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
ss->fd = NULL;
|
||||
|
||||
|
@ -194,17 +209,17 @@ int ssl_DefClose(sslSocket *ss)
|
|||
** the stack, and then remove the second one. This way, the address
|
||||
** of the PRFileDesc on the top of the stack doesn't change.
|
||||
*/
|
||||
popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
|
||||
popped = PR_PopIOLayer(fd, PR_TOP_IO_LAYER);
|
||||
popped->dtor(popped);
|
||||
|
||||
/* fd is now the PRFileDesc for the next layer down.
|
||||
** Now close the underlying socket.
|
||||
** Now close the underlying socket.
|
||||
*/
|
||||
rv = fd->methods->close(fd);
|
||||
|
||||
ssl_FreeSocket(ss);
|
||||
|
||||
SSL_TRC(5, ("%d: SSL[%d]: closing, rv=%d errno=%d",
|
||||
SSL_GETPID(), fd, rv, PORT_GetError()));
|
||||
SSL_GETPID(), fd, rv, PORT_GetError()));
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ const PRUint16 SSL_ImplementedCiphers[] = {
|
|||
#ifndef NSS_DISABLE_ECC
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before
|
||||
* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA to work around bug 946147.
|
||||
*/
|
||||
|
@ -66,6 +68,7 @@ const PRUint16 SSL_ImplementedCiphers[] = {
|
|||
#endif /* NSS_DISABLE_ECC */
|
||||
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
|
||||
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
|
||||
|
@ -121,7 +124,7 @@ const PRUint16 SSL_ImplementedCiphers[] = {
|
|||
TLS_RSA_EXPORT_WITH_RC4_40_MD5,
|
||||
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
|
||||
|
||||
/* ciphersuites with no encryption */
|
||||
/* ciphersuites with no encryption */
|
||||
#ifndef NSS_DISABLE_ECC
|
||||
TLS_ECDHE_ECDSA_WITH_NULL_SHA,
|
||||
TLS_ECDHE_RSA_WITH_NULL_SHA,
|
||||
|
@ -135,7 +138,7 @@ const PRUint16 SSL_ImplementedCiphers[] = {
|
|||
/* SSL2 cipher suites. */
|
||||
SSL_EN_RC4_128_WITH_MD5,
|
||||
SSL_EN_RC2_128_CBC_WITH_MD5,
|
||||
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* actually 112, not 192 */
|
||||
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* actually 112, not 192 */
|
||||
SSL_EN_DES_64_CBC_WITH_MD5,
|
||||
SSL_EN_RC4_128_EXPORT40_WITH_MD5,
|
||||
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,
|
||||
|
@ -144,10 +147,10 @@ const PRUint16 SSL_ImplementedCiphers[] = {
|
|||
|
||||
};
|
||||
|
||||
const PRUint16 SSL_NumImplementedCiphers =
|
||||
const PRUint16 SSL_NumImplementedCiphers =
|
||||
(sizeof SSL_ImplementedCiphers) / (sizeof SSL_ImplementedCiphers[0]) - 1;
|
||||
|
||||
const PRUint16 *
|
||||
const PRUint16*
|
||||
SSL_GetImplementedCiphers(void)
|
||||
{
|
||||
return SSL_ImplementedCiphers;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Function to set error code only when meaningful error has not already
|
||||
* Function to set error code only when meaningful error has not already
|
||||
* been set.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|
@ -12,30 +12,30 @@
|
|||
#include "seccomon.h"
|
||||
|
||||
/* look at the current value of PR_GetError, and evaluate it to see
|
||||
* if it is meaningful or meaningless (out of context).
|
||||
* if it is meaningful or meaningless (out of context).
|
||||
* If it is meaningless, replace it with the hiLevelError.
|
||||
* Returns the chosen error value.
|
||||
*/
|
||||
int
|
||||
ssl_MapLowLevelError(int hiLevelError)
|
||||
{
|
||||
int oldErr = PORT_GetError();
|
||||
int oldErr = PORT_GetError();
|
||||
|
||||
switch (oldErr) {
|
||||
|
||||
case 0:
|
||||
case PR_IO_ERROR:
|
||||
case SEC_ERROR_IO:
|
||||
case SEC_ERROR_BAD_DATA:
|
||||
case SEC_ERROR_LIBRARY_FAILURE:
|
||||
case SEC_ERROR_EXTENSION_NOT_FOUND:
|
||||
case SSL_ERROR_BAD_CLIENT:
|
||||
case SSL_ERROR_BAD_SERVER:
|
||||
case SSL_ERROR_SESSION_NOT_FOUND:
|
||||
PORT_SetError(hiLevelError);
|
||||
return hiLevelError;
|
||||
case 0:
|
||||
case PR_IO_ERROR:
|
||||
case SEC_ERROR_IO:
|
||||
case SEC_ERROR_BAD_DATA:
|
||||
case SEC_ERROR_LIBRARY_FAILURE:
|
||||
case SEC_ERROR_EXTENSION_NOT_FOUND:
|
||||
case SSL_ERROR_BAD_CLIENT:
|
||||
case SSL_ERROR_BAD_SERVER:
|
||||
case SSL_ERROR_SESSION_NOT_FOUND:
|
||||
PORT_SetError(hiLevelError);
|
||||
return hiLevelError;
|
||||
|
||||
default: /* leave the majority of error codes alone. */
|
||||
return oldErr;
|
||||
default: /* leave the majority of error codes alone. */
|
||||
return oldErr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef __SSL_ERR_H_
|
||||
#define __SSL_ERR_H_
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define SSL_ERROR_BASE (-0x3000)
|
||||
#define SSL_ERROR_LIMIT (SSL_ERROR_BASE + 1000)
|
||||
|
@ -16,211 +17,213 @@
|
|||
|
||||
#ifndef NO_SECURITY_ERROR_ENUM
|
||||
typedef enum {
|
||||
SSL_ERROR_EXPORT_ONLY_SERVER = (SSL_ERROR_BASE + 0),
|
||||
SSL_ERROR_US_ONLY_SERVER = (SSL_ERROR_BASE + 1),
|
||||
SSL_ERROR_NO_CYPHER_OVERLAP = (SSL_ERROR_BASE + 2),
|
||||
/*
|
||||
* Received an alert reporting what we did wrong. (more alerts below)
|
||||
*/
|
||||
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),
|
||||
SSL_ERROR_POST_WARNING = (SSL_ERROR_BASE + 13),
|
||||
SSL_ERROR_SSL2_DISABLED = (SSL_ERROR_BASE + 14),
|
||||
SSL_ERROR_BAD_MAC_READ = (SSL_ERROR_BASE + 15),
|
||||
/*
|
||||
* Received an alert reporting what we did wrong.
|
||||
* (two more alerts above, and many more below)
|
||||
*/
|
||||
SSL_ERROR_BAD_MAC_ALERT = (SSL_ERROR_BASE + 16),
|
||||
SSL_ERROR_BAD_CERT_ALERT = (SSL_ERROR_BASE + 17),
|
||||
SSL_ERROR_REVOKED_CERT_ALERT = (SSL_ERROR_BASE + 18),
|
||||
SSL_ERROR_EXPIRED_CERT_ALERT = (SSL_ERROR_BASE + 19),
|
||||
SSL_ERROR_EXPORT_ONLY_SERVER = (SSL_ERROR_BASE + 0),
|
||||
SSL_ERROR_US_ONLY_SERVER = (SSL_ERROR_BASE + 1),
|
||||
SSL_ERROR_NO_CYPHER_OVERLAP = (SSL_ERROR_BASE + 2),
|
||||
/*
|
||||
* Received an alert reporting what we did wrong. (more alerts below)
|
||||
*/
|
||||
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),
|
||||
SSL_ERROR_POST_WARNING = (SSL_ERROR_BASE + 13),
|
||||
SSL_ERROR_SSL2_DISABLED = (SSL_ERROR_BASE + 14),
|
||||
SSL_ERROR_BAD_MAC_READ = (SSL_ERROR_BASE + 15),
|
||||
/*
|
||||
* Received an alert reporting what we did wrong.
|
||||
* (two more alerts above, and many more below)
|
||||
*/
|
||||
SSL_ERROR_BAD_MAC_ALERT = (SSL_ERROR_BASE + 16),
|
||||
SSL_ERROR_BAD_CERT_ALERT = (SSL_ERROR_BASE + 17),
|
||||
SSL_ERROR_REVOKED_CERT_ALERT = (SSL_ERROR_BASE + 18),
|
||||
SSL_ERROR_EXPIRED_CERT_ALERT = (SSL_ERROR_BASE + 19),
|
||||
|
||||
SSL_ERROR_SSL_DISABLED = (SSL_ERROR_BASE + 20),
|
||||
SSL_ERROR_FORTEZZA_PQG = (SSL_ERROR_BASE + 21),
|
||||
SSL_ERROR_UNKNOWN_CIPHER_SUITE = (SSL_ERROR_BASE + 22),
|
||||
SSL_ERROR_NO_CIPHERS_SUPPORTED = (SSL_ERROR_BASE + 23),
|
||||
SSL_ERROR_BAD_BLOCK_PADDING = (SSL_ERROR_BASE + 24),
|
||||
SSL_ERROR_RX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 25),
|
||||
SSL_ERROR_TX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 26),
|
||||
/*
|
||||
* Received a malformed (too long or short) SSL handshake.
|
||||
*/
|
||||
SSL_ERROR_RX_MALFORMED_HELLO_REQUEST = (SSL_ERROR_BASE + 27),
|
||||
SSL_ERROR_RX_MALFORMED_CLIENT_HELLO = (SSL_ERROR_BASE + 28),
|
||||
SSL_ERROR_RX_MALFORMED_SERVER_HELLO = (SSL_ERROR_BASE + 29),
|
||||
SSL_ERROR_RX_MALFORMED_CERTIFICATE = (SSL_ERROR_BASE + 30),
|
||||
SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 31),
|
||||
SSL_ERROR_RX_MALFORMED_CERT_REQUEST = (SSL_ERROR_BASE + 32),
|
||||
SSL_ERROR_RX_MALFORMED_HELLO_DONE = (SSL_ERROR_BASE + 33),
|
||||
SSL_ERROR_RX_MALFORMED_CERT_VERIFY = (SSL_ERROR_BASE + 34),
|
||||
SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 35),
|
||||
SSL_ERROR_RX_MALFORMED_FINISHED = (SSL_ERROR_BASE + 36),
|
||||
/*
|
||||
* Received a malformed (too long or short) SSL record.
|
||||
*/
|
||||
SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER = (SSL_ERROR_BASE + 37),
|
||||
SSL_ERROR_RX_MALFORMED_ALERT = (SSL_ERROR_BASE + 38),
|
||||
SSL_ERROR_RX_MALFORMED_HANDSHAKE = (SSL_ERROR_BASE + 39),
|
||||
SSL_ERROR_RX_MALFORMED_APPLICATION_DATA = (SSL_ERROR_BASE + 40),
|
||||
/*
|
||||
* Received an SSL handshake that was inappropriate for the state we're in.
|
||||
* E.g. Server received message from server, or wrong state in state machine.
|
||||
*/
|
||||
SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST = (SSL_ERROR_BASE + 41),
|
||||
SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO = (SSL_ERROR_BASE + 42),
|
||||
SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO = (SSL_ERROR_BASE + 43),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERTIFICATE = (SSL_ERROR_BASE + 44),
|
||||
SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 45),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST = (SSL_ERROR_BASE + 46),
|
||||
SSL_ERROR_RX_UNEXPECTED_HELLO_DONE = (SSL_ERROR_BASE + 47),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY = (SSL_ERROR_BASE + 48),
|
||||
SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 49),
|
||||
SSL_ERROR_RX_UNEXPECTED_FINISHED = (SSL_ERROR_BASE + 50),
|
||||
/*
|
||||
* Received an SSL record that was inappropriate for the state we're in.
|
||||
*/
|
||||
SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER = (SSL_ERROR_BASE + 51),
|
||||
SSL_ERROR_RX_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 52),
|
||||
SSL_ERROR_RX_UNEXPECTED_HANDSHAKE = (SSL_ERROR_BASE + 53),
|
||||
SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA = (SSL_ERROR_BASE + 54),
|
||||
/*
|
||||
* Received record/message with unknown discriminant.
|
||||
*/
|
||||
SSL_ERROR_RX_UNKNOWN_RECORD_TYPE = (SSL_ERROR_BASE + 55),
|
||||
SSL_ERROR_RX_UNKNOWN_HANDSHAKE = (SSL_ERROR_BASE + 56),
|
||||
SSL_ERROR_RX_UNKNOWN_ALERT = (SSL_ERROR_BASE + 57),
|
||||
/*
|
||||
* Received an alert reporting what we did wrong. (more alerts above)
|
||||
*/
|
||||
SSL_ERROR_CLOSE_NOTIFY_ALERT = (SSL_ERROR_BASE + 58),
|
||||
SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 59),
|
||||
SSL_ERROR_DECOMPRESSION_FAILURE_ALERT = (SSL_ERROR_BASE + 60),
|
||||
SSL_ERROR_HANDSHAKE_FAILURE_ALERT = (SSL_ERROR_BASE + 61),
|
||||
SSL_ERROR_ILLEGAL_PARAMETER_ALERT = (SSL_ERROR_BASE + 62),
|
||||
SSL_ERROR_UNSUPPORTED_CERT_ALERT = (SSL_ERROR_BASE + 63),
|
||||
SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT = (SSL_ERROR_BASE + 64),
|
||||
SSL_ERROR_SSL_DISABLED = (SSL_ERROR_BASE + 20),
|
||||
SSL_ERROR_FORTEZZA_PQG = (SSL_ERROR_BASE + 21),
|
||||
SSL_ERROR_UNKNOWN_CIPHER_SUITE = (SSL_ERROR_BASE + 22),
|
||||
SSL_ERROR_NO_CIPHERS_SUPPORTED = (SSL_ERROR_BASE + 23),
|
||||
SSL_ERROR_BAD_BLOCK_PADDING = (SSL_ERROR_BASE + 24),
|
||||
SSL_ERROR_RX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 25),
|
||||
SSL_ERROR_TX_RECORD_TOO_LONG = (SSL_ERROR_BASE + 26),
|
||||
/*
|
||||
* Received a malformed (too long or short) SSL handshake.
|
||||
*/
|
||||
SSL_ERROR_RX_MALFORMED_HELLO_REQUEST = (SSL_ERROR_BASE + 27),
|
||||
SSL_ERROR_RX_MALFORMED_CLIENT_HELLO = (SSL_ERROR_BASE + 28),
|
||||
SSL_ERROR_RX_MALFORMED_SERVER_HELLO = (SSL_ERROR_BASE + 29),
|
||||
SSL_ERROR_RX_MALFORMED_CERTIFICATE = (SSL_ERROR_BASE + 30),
|
||||
SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 31),
|
||||
SSL_ERROR_RX_MALFORMED_CERT_REQUEST = (SSL_ERROR_BASE + 32),
|
||||
SSL_ERROR_RX_MALFORMED_HELLO_DONE = (SSL_ERROR_BASE + 33),
|
||||
SSL_ERROR_RX_MALFORMED_CERT_VERIFY = (SSL_ERROR_BASE + 34),
|
||||
SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 35),
|
||||
SSL_ERROR_RX_MALFORMED_FINISHED = (SSL_ERROR_BASE + 36),
|
||||
/*
|
||||
* Received a malformed (too long or short) SSL record.
|
||||
*/
|
||||
SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER = (SSL_ERROR_BASE + 37),
|
||||
SSL_ERROR_RX_MALFORMED_ALERT = (SSL_ERROR_BASE + 38),
|
||||
SSL_ERROR_RX_MALFORMED_HANDSHAKE = (SSL_ERROR_BASE + 39),
|
||||
SSL_ERROR_RX_MALFORMED_APPLICATION_DATA = (SSL_ERROR_BASE + 40),
|
||||
/*
|
||||
* Received an SSL handshake that was inappropriate for the state we're in.
|
||||
* E.g. Server received message from server, or wrong state in state machine.
|
||||
*/
|
||||
SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST = (SSL_ERROR_BASE + 41),
|
||||
SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO = (SSL_ERROR_BASE + 42),
|
||||
SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO = (SSL_ERROR_BASE + 43),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERTIFICATE = (SSL_ERROR_BASE + 44),
|
||||
SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH = (SSL_ERROR_BASE + 45),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST = (SSL_ERROR_BASE + 46),
|
||||
SSL_ERROR_RX_UNEXPECTED_HELLO_DONE = (SSL_ERROR_BASE + 47),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY = (SSL_ERROR_BASE + 48),
|
||||
SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH = (SSL_ERROR_BASE + 49),
|
||||
SSL_ERROR_RX_UNEXPECTED_FINISHED = (SSL_ERROR_BASE + 50),
|
||||
/*
|
||||
* Received an SSL record that was inappropriate for the state we're in.
|
||||
*/
|
||||
SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER = (SSL_ERROR_BASE + 51),
|
||||
SSL_ERROR_RX_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 52),
|
||||
SSL_ERROR_RX_UNEXPECTED_HANDSHAKE = (SSL_ERROR_BASE + 53),
|
||||
SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA = (SSL_ERROR_BASE + 54),
|
||||
/*
|
||||
* Received record/message with unknown discriminant.
|
||||
*/
|
||||
SSL_ERROR_RX_UNKNOWN_RECORD_TYPE = (SSL_ERROR_BASE + 55),
|
||||
SSL_ERROR_RX_UNKNOWN_HANDSHAKE = (SSL_ERROR_BASE + 56),
|
||||
SSL_ERROR_RX_UNKNOWN_ALERT = (SSL_ERROR_BASE + 57),
|
||||
/*
|
||||
* Received an alert reporting what we did wrong. (more alerts above)
|
||||
*/
|
||||
SSL_ERROR_CLOSE_NOTIFY_ALERT = (SSL_ERROR_BASE + 58),
|
||||
SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT = (SSL_ERROR_BASE + 59),
|
||||
SSL_ERROR_DECOMPRESSION_FAILURE_ALERT = (SSL_ERROR_BASE + 60),
|
||||
SSL_ERROR_HANDSHAKE_FAILURE_ALERT = (SSL_ERROR_BASE + 61),
|
||||
SSL_ERROR_ILLEGAL_PARAMETER_ALERT = (SSL_ERROR_BASE + 62),
|
||||
SSL_ERROR_UNSUPPORTED_CERT_ALERT = (SSL_ERROR_BASE + 63),
|
||||
SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT = (SSL_ERROR_BASE + 64),
|
||||
|
||||
SSL_ERROR_GENERATE_RANDOM_FAILURE = (SSL_ERROR_BASE + 65),
|
||||
SSL_ERROR_SIGN_HASHES_FAILURE = (SSL_ERROR_BASE + 66),
|
||||
SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE = (SSL_ERROR_BASE + 67),
|
||||
SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 68),
|
||||
SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 69),
|
||||
SSL_ERROR_GENERATE_RANDOM_FAILURE = (SSL_ERROR_BASE + 65),
|
||||
SSL_ERROR_SIGN_HASHES_FAILURE = (SSL_ERROR_BASE + 66),
|
||||
SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE = (SSL_ERROR_BASE + 67),
|
||||
SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 68),
|
||||
SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 69),
|
||||
|
||||
SSL_ERROR_ENCRYPTION_FAILURE = (SSL_ERROR_BASE + 70),
|
||||
SSL_ERROR_DECRYPTION_FAILURE = (SSL_ERROR_BASE + 71), /* don't use */
|
||||
SSL_ERROR_SOCKET_WRITE_FAILURE = (SSL_ERROR_BASE + 72),
|
||||
SSL_ERROR_ENCRYPTION_FAILURE = (SSL_ERROR_BASE + 70),
|
||||
SSL_ERROR_DECRYPTION_FAILURE = (SSL_ERROR_BASE + 71), /* don't use */
|
||||
SSL_ERROR_SOCKET_WRITE_FAILURE = (SSL_ERROR_BASE + 72),
|
||||
|
||||
SSL_ERROR_MD5_DIGEST_FAILURE = (SSL_ERROR_BASE + 73),
|
||||
SSL_ERROR_SHA_DIGEST_FAILURE = (SSL_ERROR_BASE + 74),
|
||||
SSL_ERROR_MAC_COMPUTATION_FAILURE = (SSL_ERROR_BASE + 75),
|
||||
SSL_ERROR_SYM_KEY_CONTEXT_FAILURE = (SSL_ERROR_BASE + 76),
|
||||
SSL_ERROR_SYM_KEY_UNWRAP_FAILURE = (SSL_ERROR_BASE + 77),
|
||||
SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED = (SSL_ERROR_BASE + 78),
|
||||
SSL_ERROR_IV_PARAM_FAILURE = (SSL_ERROR_BASE + 79),
|
||||
SSL_ERROR_INIT_CIPHER_SUITE_FAILURE = (SSL_ERROR_BASE + 80),
|
||||
SSL_ERROR_SESSION_KEY_GEN_FAILURE = (SSL_ERROR_BASE + 81),
|
||||
SSL_ERROR_NO_SERVER_KEY_FOR_ALG = (SSL_ERROR_BASE + 82),
|
||||
SSL_ERROR_TOKEN_INSERTION_REMOVAL = (SSL_ERROR_BASE + 83),
|
||||
SSL_ERROR_TOKEN_SLOT_NOT_FOUND = (SSL_ERROR_BASE + 84),
|
||||
SSL_ERROR_NO_COMPRESSION_OVERLAP = (SSL_ERROR_BASE + 85),
|
||||
SSL_ERROR_HANDSHAKE_NOT_COMPLETED = (SSL_ERROR_BASE + 86),
|
||||
SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE = (SSL_ERROR_BASE + 87),
|
||||
SSL_ERROR_CERT_KEA_MISMATCH = (SSL_ERROR_BASE + 88),
|
||||
/* SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA became obsolete in NSS 3.14. */
|
||||
SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA = (SSL_ERROR_BASE + 89),
|
||||
SSL_ERROR_SESSION_NOT_FOUND = (SSL_ERROR_BASE + 90),
|
||||
SSL_ERROR_MD5_DIGEST_FAILURE = (SSL_ERROR_BASE + 73),
|
||||
SSL_ERROR_SHA_DIGEST_FAILURE = (SSL_ERROR_BASE + 74),
|
||||
SSL_ERROR_MAC_COMPUTATION_FAILURE = (SSL_ERROR_BASE + 75),
|
||||
SSL_ERROR_SYM_KEY_CONTEXT_FAILURE = (SSL_ERROR_BASE + 76),
|
||||
SSL_ERROR_SYM_KEY_UNWRAP_FAILURE = (SSL_ERROR_BASE + 77),
|
||||
SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED = (SSL_ERROR_BASE + 78),
|
||||
SSL_ERROR_IV_PARAM_FAILURE = (SSL_ERROR_BASE + 79),
|
||||
SSL_ERROR_INIT_CIPHER_SUITE_FAILURE = (SSL_ERROR_BASE + 80),
|
||||
SSL_ERROR_SESSION_KEY_GEN_FAILURE = (SSL_ERROR_BASE + 81),
|
||||
SSL_ERROR_NO_SERVER_KEY_FOR_ALG = (SSL_ERROR_BASE + 82),
|
||||
SSL_ERROR_TOKEN_INSERTION_REMOVAL = (SSL_ERROR_BASE + 83),
|
||||
SSL_ERROR_TOKEN_SLOT_NOT_FOUND = (SSL_ERROR_BASE + 84),
|
||||
SSL_ERROR_NO_COMPRESSION_OVERLAP = (SSL_ERROR_BASE + 85),
|
||||
SSL_ERROR_HANDSHAKE_NOT_COMPLETED = (SSL_ERROR_BASE + 86),
|
||||
SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE = (SSL_ERROR_BASE + 87),
|
||||
SSL_ERROR_CERT_KEA_MISMATCH = (SSL_ERROR_BASE + 88),
|
||||
/* SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA became obsolete in NSS 3.14. */
|
||||
SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA = (SSL_ERROR_BASE + 89),
|
||||
SSL_ERROR_SESSION_NOT_FOUND = (SSL_ERROR_BASE + 90),
|
||||
|
||||
SSL_ERROR_DECRYPTION_FAILED_ALERT = (SSL_ERROR_BASE + 91),
|
||||
SSL_ERROR_RECORD_OVERFLOW_ALERT = (SSL_ERROR_BASE + 92),
|
||||
SSL_ERROR_UNKNOWN_CA_ALERT = (SSL_ERROR_BASE + 93),
|
||||
SSL_ERROR_ACCESS_DENIED_ALERT = (SSL_ERROR_BASE + 94),
|
||||
SSL_ERROR_DECODE_ERROR_ALERT = (SSL_ERROR_BASE + 95),
|
||||
SSL_ERROR_DECRYPT_ERROR_ALERT = (SSL_ERROR_BASE + 96),
|
||||
SSL_ERROR_EXPORT_RESTRICTION_ALERT = (SSL_ERROR_BASE + 97),
|
||||
SSL_ERROR_PROTOCOL_VERSION_ALERT = (SSL_ERROR_BASE + 98),
|
||||
SSL_ERROR_INSUFFICIENT_SECURITY_ALERT = (SSL_ERROR_BASE + 99),
|
||||
SSL_ERROR_INTERNAL_ERROR_ALERT = (SSL_ERROR_BASE + 100),
|
||||
SSL_ERROR_USER_CANCELED_ALERT = (SSL_ERROR_BASE + 101),
|
||||
SSL_ERROR_NO_RENEGOTIATION_ALERT = (SSL_ERROR_BASE + 102),
|
||||
SSL_ERROR_DECRYPTION_FAILED_ALERT = (SSL_ERROR_BASE + 91),
|
||||
SSL_ERROR_RECORD_OVERFLOW_ALERT = (SSL_ERROR_BASE + 92),
|
||||
SSL_ERROR_UNKNOWN_CA_ALERT = (SSL_ERROR_BASE + 93),
|
||||
SSL_ERROR_ACCESS_DENIED_ALERT = (SSL_ERROR_BASE + 94),
|
||||
SSL_ERROR_DECODE_ERROR_ALERT = (SSL_ERROR_BASE + 95),
|
||||
SSL_ERROR_DECRYPT_ERROR_ALERT = (SSL_ERROR_BASE + 96),
|
||||
SSL_ERROR_EXPORT_RESTRICTION_ALERT = (SSL_ERROR_BASE + 97),
|
||||
SSL_ERROR_PROTOCOL_VERSION_ALERT = (SSL_ERROR_BASE + 98),
|
||||
SSL_ERROR_INSUFFICIENT_SECURITY_ALERT = (SSL_ERROR_BASE + 99),
|
||||
SSL_ERROR_INTERNAL_ERROR_ALERT = (SSL_ERROR_BASE + 100),
|
||||
SSL_ERROR_USER_CANCELED_ALERT = (SSL_ERROR_BASE + 101),
|
||||
SSL_ERROR_NO_RENEGOTIATION_ALERT = (SSL_ERROR_BASE + 102),
|
||||
|
||||
SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED = (SSL_ERROR_BASE + 103),
|
||||
SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED = (SSL_ERROR_BASE + 103),
|
||||
|
||||
SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT = (SSL_ERROR_BASE + 104),
|
||||
SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT = (SSL_ERROR_BASE + 105),
|
||||
SSL_ERROR_UNRECOGNIZED_NAME_ALERT = (SSL_ERROR_BASE + 106),
|
||||
SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT = (SSL_ERROR_BASE + 107),
|
||||
SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT = (SSL_ERROR_BASE + 108),
|
||||
SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT = (SSL_ERROR_BASE + 104),
|
||||
SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT = (SSL_ERROR_BASE + 105),
|
||||
SSL_ERROR_UNRECOGNIZED_NAME_ALERT = (SSL_ERROR_BASE + 106),
|
||||
SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT = (SSL_ERROR_BASE + 107),
|
||||
SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT = (SSL_ERROR_BASE + 108),
|
||||
|
||||
SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 109),
|
||||
SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 110),
|
||||
SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 109),
|
||||
SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 110),
|
||||
|
||||
SSL_ERROR_DECOMPRESSION_FAILURE = (SSL_ERROR_BASE + 111),
|
||||
SSL_ERROR_RENEGOTIATION_NOT_ALLOWED = (SSL_ERROR_BASE + 112),
|
||||
SSL_ERROR_UNSAFE_NEGOTIATION = (SSL_ERROR_BASE + 113),
|
||||
SSL_ERROR_DECOMPRESSION_FAILURE = (SSL_ERROR_BASE + 111),
|
||||
SSL_ERROR_RENEGOTIATION_NOT_ALLOWED = (SSL_ERROR_BASE + 112),
|
||||
SSL_ERROR_UNSAFE_NEGOTIATION = (SSL_ERROR_BASE + 113),
|
||||
|
||||
SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114),
|
||||
SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114),
|
||||
|
||||
SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115),
|
||||
SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115),
|
||||
|
||||
SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 116),
|
||||
SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 116),
|
||||
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2 = (SSL_ERROR_BASE + 117),
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS = (SSL_ERROR_BASE + 118),
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS = (SSL_ERROR_BASE + 119),
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2 = (SSL_ERROR_BASE + 117),
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SERVERS = (SSL_ERROR_BASE + 118),
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_CLIENTS = (SSL_ERROR_BASE + 119),
|
||||
|
||||
SSL_ERROR_INVALID_VERSION_RANGE = (SSL_ERROR_BASE + 120),
|
||||
SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 121),
|
||||
SSL_ERROR_INVALID_VERSION_RANGE = (SSL_ERROR_BASE + 120),
|
||||
SSL_ERROR_CIPHER_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 121),
|
||||
|
||||
SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
|
||||
SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
|
||||
SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 122),
|
||||
SSL_ERROR_RX_UNEXPECTED_HELLO_VERIFY_REQUEST = (SSL_ERROR_BASE + 123),
|
||||
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION = (SSL_ERROR_BASE + 124),
|
||||
SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION = (SSL_ERROR_BASE + 124),
|
||||
|
||||
SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 125),
|
||||
SSL_ERROR_RX_UNEXPECTED_CERT_STATUS = (SSL_ERROR_BASE + 125),
|
||||
|
||||
SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 126),
|
||||
SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 127),
|
||||
SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128),
|
||||
SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 126),
|
||||
SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 127),
|
||||
SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128),
|
||||
|
||||
SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129),
|
||||
SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
|
||||
SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129),
|
||||
SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
|
||||
|
||||
SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
|
||||
SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
|
||||
|
||||
SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132),
|
||||
SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132),
|
||||
|
||||
SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133),
|
||||
SSL_ERROR_RX_SHORT_DTLS_READ = (SSL_ERROR_BASE + 133),
|
||||
|
||||
SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134),
|
||||
SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
|
||||
SSL_ERROR_NO_SUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 134),
|
||||
SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 135),
|
||||
|
||||
SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
|
||||
SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
|
||||
SSL_ERROR_MISSING_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 136),
|
||||
SSL_ERROR_UNEXPECTED_EXTENDED_MASTER_SECRET = (SSL_ERROR_BASE + 137),
|
||||
|
||||
SSL_ERROR_RX_MALFORMED_KEY_SHARE = (SSL_ERROR_BASE + 138),
|
||||
SSL_ERROR_MISSING_KEY_SHARE = (SSL_ERROR_BASE + 139),
|
||||
SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE = (SSL_ERROR_BASE + 140),
|
||||
SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE = (SSL_ERROR_BASE + 141),
|
||||
SSL_ERROR_RX_MALFORMED_KEY_SHARE = (SSL_ERROR_BASE + 138),
|
||||
SSL_ERROR_MISSING_KEY_SHARE = (SSL_ERROR_BASE + 139),
|
||||
SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE = (SSL_ERROR_BASE + 140),
|
||||
SSL_ERROR_RX_MALFORMED_DHE_KEY_SHARE = (SSL_ERROR_BASE + 141),
|
||||
|
||||
SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS = (SSL_ERROR_BASE + 142),
|
||||
SSL_ERROR_MISSING_EXTENSION_ALERT = (SSL_ERROR_BASE + 143),
|
||||
SSL_ERROR_RX_UNEXPECTED_ENCRYPTED_EXTENSIONS = (SSL_ERROR_BASE + 142),
|
||||
SSL_ERROR_MISSING_EXTENSION_ALERT = (SSL_ERROR_BASE + 143),
|
||||
|
||||
SSL_ERROR_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 144),
|
||||
SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 145),
|
||||
|
||||
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
||||
SSL_ERROR_KEY_EXCHANGE_FAILURE = (SSL_ERROR_BASE + 144),
|
||||
SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION = (SSL_ERROR_BASE + 145),
|
||||
SSL_ERROR_RX_MALFORMED_ENCRYPTED_EXTENSIONS = (SSL_ERROR_BASE + 146),
|
||||
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
||||
} SSLErrorCodes;
|
||||
#endif /* NO_SECURITY_ERROR_ENUM */
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#endif /* __SSL_ERR_H_ */
|
||||
|
|
|
@ -7,20 +7,21 @@
|
|||
#include "nssutil.h"
|
||||
#include "ssl.h"
|
||||
|
||||
#define ER3(name, value, str) {#name, str},
|
||||
#define ER3(name, value, str) { #name, str },
|
||||
|
||||
static const struct PRErrorMessage ssltext[] = {
|
||||
#include "SSLerrs.h"
|
||||
{0,0}
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const struct PRErrorTable ssl_et = {
|
||||
ssltext, "sslerr", SSL_ERROR_BASE,
|
||||
(sizeof ssltext)/(sizeof ssltext[0])
|
||||
(sizeof ssltext) / (sizeof ssltext[0])
|
||||
};
|
||||
|
||||
static PRStatus
|
||||
ssl_InitializePRErrorTableOnce(void) {
|
||||
ssl_InitializePRErrorTableOnce(void)
|
||||
{
|
||||
return PR_ErrorInstallTable(&ssl_et);
|
||||
}
|
||||
|
||||
|
@ -30,5 +31,6 @@ SECStatus
|
|||
ssl_InitializePRErrorTable(void)
|
||||
{
|
||||
return (PR_SUCCESS == PR_CallOnce(&once, ssl_InitializePRErrorTableOnce))
|
||||
? SECSuccess : SECFailure;
|
||||
? SECSuccess
|
||||
: SECFailure;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Gather (Read) entire SSL2 records from socket into buffer.
|
||||
* Gather (Read) entire SSL2 records from socket into buffer.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
@ -20,7 +20,7 @@ static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss);
|
|||
** and is to be called multiple times until ss->sec.recordLen != 0.
|
||||
** This function decrypts the gathered record in place, in gs_buf.
|
||||
*
|
||||
* Caller must hold RecvBufLock.
|
||||
* Caller must hold RecvBufLock.
|
||||
*
|
||||
* Returns +1 when it has gathered a complete SSLV2 record.
|
||||
* Returns 0 if it hits EOF.
|
||||
|
@ -41,7 +41,7 @@ static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss);
|
|||
** advance to one of two states, depending on whether the record
|
||||
** is encrypted (GS_MAC), or unencrypted (GS_DATA).
|
||||
**
|
||||
** GS_MAC - The machine is in this state while waiting for the remainder
|
||||
** GS_MAC - The machine is in this state while waiting for the remainder
|
||||
** of the SSL2 record to be read in. When the read is completed,
|
||||
** the machine checks the record for valid length, decrypts it,
|
||||
** and checks and discards the MAC, then advances to GS_INIT.
|
||||
|
@ -50,295 +50,297 @@ static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss);
|
|||
** of the unencrypted SSL2 record to be read in. Upon completion,
|
||||
** the machine advances to the GS_INIT state and returns the data.
|
||||
*/
|
||||
int
|
||||
int
|
||||
ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags)
|
||||
{
|
||||
unsigned char * bp;
|
||||
unsigned char * pBuf;
|
||||
int nb, err, rv;
|
||||
unsigned char *bp;
|
||||
unsigned char *pBuf;
|
||||
int nb, err, rv;
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
|
||||
if (gs->state == GS_INIT) {
|
||||
/* Initialize gathering engine */
|
||||
gs->state = GS_HEADER;
|
||||
gs->remainder = 3;
|
||||
gs->count = 3;
|
||||
gs->offset = 0;
|
||||
gs->recordLen = 0;
|
||||
gs->recordPadding = 0;
|
||||
gs->hdr[2] = 0;
|
||||
/* Initialize gathering engine */
|
||||
gs->state = GS_HEADER;
|
||||
gs->remainder = 3;
|
||||
gs->count = 3;
|
||||
gs->offset = 0;
|
||||
gs->recordLen = 0;
|
||||
gs->recordPadding = 0;
|
||||
gs->hdr[2] = 0;
|
||||
|
||||
gs->writeOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->writeOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
}
|
||||
if (gs->encrypted) {
|
||||
PORT_Assert(ss->sec.hash != 0);
|
||||
PORT_Assert(ss->sec.hash != 0);
|
||||
}
|
||||
|
||||
pBuf = gs->buf.buf;
|
||||
for (;;) {
|
||||
SSL_TRC(30, ("%d: SSL[%d]: gather state %d (need %d more)",
|
||||
SSL_GETPID(), ss->fd, gs->state, gs->remainder));
|
||||
bp = ((gs->state != GS_HEADER) ? pBuf : gs->hdr) + gs->offset;
|
||||
nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
|
||||
if (nb > 0) {
|
||||
PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
|
||||
}
|
||||
if (nb == 0) {
|
||||
/* EOF */
|
||||
SSL_TRC(30, ("%d: SSL[%d]: EOF", SSL_GETPID(), ss->fd));
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
if (nb < 0) {
|
||||
SSL_DBG(("%d: SSL[%d]: recv error %d", SSL_GETPID(), ss->fd,
|
||||
PR_GetError()));
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
SSL_TRC(30, ("%d: SSL[%d]: gather state %d (need %d more)",
|
||||
SSL_GETPID(), ss->fd, gs->state, gs->remainder));
|
||||
bp = ((gs->state != GS_HEADER) ? pBuf : gs->hdr) + gs->offset;
|
||||
nb = ssl_DefRecv(ss, bp, gs->remainder, flags);
|
||||
if (nb > 0) {
|
||||
PRINT_BUF(60, (ss, "raw gather data:", bp, nb));
|
||||
}
|
||||
if (nb == 0) {
|
||||
/* EOF */
|
||||
SSL_TRC(30, ("%d: SSL[%d]: EOF", SSL_GETPID(), ss->fd));
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
if (nb < 0) {
|
||||
SSL_DBG(("%d: SSL[%d]: recv error %d", SSL_GETPID(), ss->fd,
|
||||
PR_GetError()));
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
gs->offset += nb;
|
||||
gs->remainder -= nb;
|
||||
gs->offset += nb;
|
||||
gs->remainder -= nb;
|
||||
|
||||
if (gs->remainder > 0) {
|
||||
continue;
|
||||
}
|
||||
if (gs->remainder > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Probably finished this piece */
|
||||
switch (gs->state) {
|
||||
case GS_HEADER:
|
||||
if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && !ss->firstHsDone) {
|
||||
/* Probably finished this piece */
|
||||
switch (gs->state) {
|
||||
case GS_HEADER:
|
||||
if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && !ss->firstHsDone) {
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
|
||||
|
||||
/* If this looks like an SSL3 handshake record,
|
||||
** and we're expecting an SSL2 Hello message from our peer,
|
||||
** handle it here.
|
||||
*/
|
||||
if (gs->hdr[0] == content_handshake) {
|
||||
if ((ss->nextHandshake == ssl2_HandleClientHelloMessage) ||
|
||||
(ss->nextHandshake == ssl2_HandleServerHelloMessage)) {
|
||||
rv = ssl2_HandleV3HandshakeRecord(ss);
|
||||
if (rv == SECFailure) {
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
/* XXX_1 The call stack to here is:
|
||||
* ssl_Do1stHandshake -> ssl_GatherRecord1stHandshake ->
|
||||
* ssl2_GatherRecord -> here.
|
||||
* We want to return all the way out to ssl_Do1stHandshake,
|
||||
* and have it call ssl_GatherRecord1stHandshake again.
|
||||
* ssl_GatherRecord1stHandshake will call
|
||||
* ssl3_GatherCompleteHandshake when it is called again.
|
||||
*
|
||||
* Returning SECWouldBlock here causes
|
||||
* ssl_GatherRecord1stHandshake to return without clearing
|
||||
* ss->handshake, ensuring that ssl_Do1stHandshake will
|
||||
* call it again immediately.
|
||||
*
|
||||
* If we return 1 here, ssl_GatherRecord1stHandshake will
|
||||
* clear ss->handshake before returning, and thus will not
|
||||
* be called again by ssl_Do1stHandshake.
|
||||
*/
|
||||
return SECWouldBlock;
|
||||
} else if (gs->hdr[0] == content_alert) {
|
||||
if (ss->nextHandshake == ssl2_HandleServerHelloMessage) {
|
||||
/* XXX This is a hack. We're assuming that any failure
|
||||
* XXX on the client hello is a failure to match
|
||||
* XXX ciphers.
|
||||
*/
|
||||
PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If this looks like an SSL3 handshake record,
|
||||
** and we're expecting an SSL2 Hello message from our peer,
|
||||
** handle it here.
|
||||
*/
|
||||
if (gs->hdr[0] == content_handshake) {
|
||||
if ((ss->nextHandshake == ssl2_HandleClientHelloMessage) ||
|
||||
(ss->nextHandshake == ssl2_HandleServerHelloMessage)) {
|
||||
rv = ssl2_HandleV3HandshakeRecord(ss);
|
||||
if (rv == SECFailure) {
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
/* XXX_1 The call stack to here is:
|
||||
* ssl_Do1stHandshake -> ssl_GatherRecord1stHandshake ->
|
||||
* ssl2_GatherRecord -> here.
|
||||
* We want to return all the way out to ssl_Do1stHandshake,
|
||||
* and have it call ssl_GatherRecord1stHandshake again.
|
||||
* ssl_GatherRecord1stHandshake will call
|
||||
* ssl3_GatherCompleteHandshake when it is called again.
|
||||
*
|
||||
* Returning SECWouldBlock here causes
|
||||
* ssl_GatherRecord1stHandshake to return without clearing
|
||||
* ss->handshake, ensuring that ssl_Do1stHandshake will
|
||||
* call it again immediately.
|
||||
*
|
||||
* If we return 1 here, ssl_GatherRecord1stHandshake will
|
||||
* clear ss->handshake before returning, and thus will not
|
||||
* be called again by ssl_Do1stHandshake.
|
||||
*/
|
||||
return SECWouldBlock;
|
||||
}
|
||||
else if (gs->hdr[0] == content_alert) {
|
||||
if (ss->nextHandshake == ssl2_HandleServerHelloMessage) {
|
||||
/* XXX This is a hack. We're assuming that any failure
|
||||
* XXX on the client hello is a failure to match
|
||||
* XXX ciphers.
|
||||
*/
|
||||
PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we've got the first 3 bytes. The header may be two or three. */
|
||||
if (gs->hdr[0] & 0x80) {
|
||||
/* This record has a 2-byte header, and no padding */
|
||||
gs->count = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
|
||||
gs->recordPadding = 0;
|
||||
} else {
|
||||
/* This record has a 3-byte header that is all read in now. */
|
||||
gs->count = ((gs->hdr[0] & 0x3f) << 8) | gs->hdr[1];
|
||||
/* is_escape = (gs->hdr[0] & 0x40) != 0; */
|
||||
gs->recordPadding = gs->hdr[2];
|
||||
}
|
||||
if (!gs->count) {
|
||||
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
|
||||
goto cleanup;
|
||||
}
|
||||
/* we've got the first 3 bytes. The header may be two or three. */
|
||||
if (gs->hdr[0] & 0x80) {
|
||||
/* This record has a 2-byte header, and no padding */
|
||||
gs->count = ((gs->hdr[0] & 0x7f) << 8) | gs->hdr[1];
|
||||
gs->recordPadding = 0;
|
||||
}
|
||||
else {
|
||||
/* This record has a 3-byte header that is all read in now. */
|
||||
gs->count = ((gs->hdr[0] & 0x3f) << 8) | gs->hdr[1];
|
||||
/* is_escape = (gs->hdr[0] & 0x40) != 0; */
|
||||
gs->recordPadding = gs->hdr[2];
|
||||
}
|
||||
if (!gs->count) {
|
||||
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (gs->count > gs->buf.space) {
|
||||
err = sslBuffer_Grow(&gs->buf, gs->count);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
pBuf = gs->buf.buf;
|
||||
}
|
||||
if (gs->count > gs->buf.space) {
|
||||
err = sslBuffer_Grow(&gs->buf, gs->count);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
pBuf = gs->buf.buf;
|
||||
}
|
||||
|
||||
if (gs->hdr[0] & 0x80) {
|
||||
/* we've already read in the first byte of the body.
|
||||
** Put it into the buffer.
|
||||
*/
|
||||
pBuf[0] = gs->hdr[2];
|
||||
gs->offset = 1;
|
||||
gs->remainder = gs->count - 1;
|
||||
}
|
||||
else {
|
||||
gs->offset = 0;
|
||||
gs->remainder = gs->count;
|
||||
}
|
||||
|
||||
if (gs->hdr[0] & 0x80) {
|
||||
/* we've already read in the first byte of the body.
|
||||
** Put it into the buffer.
|
||||
*/
|
||||
pBuf[0] = gs->hdr[2];
|
||||
gs->offset = 1;
|
||||
gs->remainder = gs->count - 1;
|
||||
} else {
|
||||
gs->offset = 0;
|
||||
gs->remainder = gs->count;
|
||||
}
|
||||
if (gs->encrypted) {
|
||||
gs->state = GS_MAC;
|
||||
gs->recordLen = gs->count - gs->recordPadding -
|
||||
ss->sec.hash->length;
|
||||
}
|
||||
else {
|
||||
gs->state = GS_DATA;
|
||||
gs->recordLen = gs->count;
|
||||
}
|
||||
|
||||
if (gs->encrypted) {
|
||||
gs->state = GS_MAC;
|
||||
gs->recordLen = gs->count - gs->recordPadding
|
||||
- ss->sec.hash->length;
|
||||
} else {
|
||||
gs->state = GS_DATA;
|
||||
gs->recordLen = gs->count;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case GS_MAC:
|
||||
/* Have read in entire rest of the ciphertext.
|
||||
** Check for valid length.
|
||||
** Decrypt it.
|
||||
** Check the MAC.
|
||||
*/
|
||||
PORT_Assert(gs->encrypted);
|
||||
|
||||
{
|
||||
unsigned int macLen;
|
||||
int nout;
|
||||
unsigned char mac[SSL_MAX_MAC_BYTES];
|
||||
|
||||
case GS_MAC:
|
||||
/* Have read in entire rest of the ciphertext.
|
||||
** Check for valid length.
|
||||
** Decrypt it.
|
||||
** Check the MAC.
|
||||
*/
|
||||
PORT_Assert(gs->encrypted);
|
||||
ssl_GetSpecReadLock(ss); /**********************************/
|
||||
|
||||
{
|
||||
unsigned int macLen;
|
||||
int nout;
|
||||
unsigned char mac[SSL_MAX_MAC_BYTES];
|
||||
/* If this is a stream cipher, blockSize will be 1,
|
||||
* and this test will always be false.
|
||||
* If this is a block cipher, this will detect records
|
||||
* that are not a multiple of the blocksize in length.
|
||||
*/
|
||||
if (gs->count & (ss->sec.blockSize - 1)) {
|
||||
/* This is an error. Sender is misbehaving */
|
||||
SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d",
|
||||
SSL_GETPID(), ss->fd, gs->count,
|
||||
ss->sec.blockSize));
|
||||
PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
|
||||
rv = SECFailure;
|
||||
goto spec_locked_done;
|
||||
}
|
||||
PORT_Assert(gs->count == gs->offset);
|
||||
|
||||
ssl_GetSpecReadLock(ss); /**********************************/
|
||||
if (gs->offset == 0) {
|
||||
rv = 0; /* means EOF. */
|
||||
goto spec_locked_done;
|
||||
}
|
||||
|
||||
/* If this is a stream cipher, blockSize will be 1,
|
||||
* and this test will always be false.
|
||||
* If this is a block cipher, this will detect records
|
||||
* that are not a multiple of the blocksize in length.
|
||||
*/
|
||||
if (gs->count & (ss->sec.blockSize - 1)) {
|
||||
/* This is an error. Sender is misbehaving */
|
||||
SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d",
|
||||
SSL_GETPID(), ss->fd, gs->count,
|
||||
ss->sec.blockSize));
|
||||
PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
|
||||
rv = SECFailure;
|
||||
goto spec_locked_done;
|
||||
}
|
||||
PORT_Assert(gs->count == gs->offset);
|
||||
/* Decrypt the portion of data that we just received.
|
||||
** Decrypt it in place.
|
||||
*/
|
||||
rv = (*ss->sec.dec)(ss->sec.readcx, pBuf, &nout, gs->offset,
|
||||
pBuf, gs->offset);
|
||||
if (rv != SECSuccess) {
|
||||
goto spec_locked_done;
|
||||
}
|
||||
|
||||
if (gs->offset == 0) {
|
||||
rv = 0; /* means EOF. */
|
||||
goto spec_locked_done;
|
||||
}
|
||||
/* Have read in all the MAC portion of record
|
||||
**
|
||||
** Prepare MAC by resetting it and feeding it the shared secret
|
||||
*/
|
||||
macLen = ss->sec.hash->length;
|
||||
if (gs->offset >= macLen) {
|
||||
PRUint32 sequenceNumber = ss->sec.rcvSequence++;
|
||||
unsigned char seq[4];
|
||||
|
||||
/* Decrypt the portion of data that we just received.
|
||||
** Decrypt it in place.
|
||||
*/
|
||||
rv = (*ss->sec.dec)(ss->sec.readcx, pBuf, &nout, gs->offset,
|
||||
pBuf, gs->offset);
|
||||
if (rv != SECSuccess) {
|
||||
goto spec_locked_done;
|
||||
}
|
||||
seq[0] = (unsigned char)(sequenceNumber >> 24);
|
||||
seq[1] = (unsigned char)(sequenceNumber >> 16);
|
||||
seq[2] = (unsigned char)(sequenceNumber >> 8);
|
||||
seq[3] = (unsigned char)(sequenceNumber);
|
||||
|
||||
(*ss->sec.hash->begin)(ss->sec.hashcx);
|
||||
(*ss->sec.hash->update)(ss->sec.hashcx, ss->sec.rcvSecret.data,
|
||||
ss->sec.rcvSecret.len);
|
||||
(*ss->sec.hash->update)(ss->sec.hashcx, pBuf + macLen,
|
||||
gs->offset - macLen);
|
||||
(*ss->sec.hash->update)(ss->sec.hashcx, seq, 4);
|
||||
(*ss->sec.hash->end)(ss->sec.hashcx, mac, &macLen, macLen);
|
||||
|
||||
/* Have read in all the MAC portion of record
|
||||
**
|
||||
** Prepare MAC by resetting it and feeding it the shared secret
|
||||
*/
|
||||
macLen = ss->sec.hash->length;
|
||||
if (gs->offset >= macLen) {
|
||||
PRUint32 sequenceNumber = ss->sec.rcvSequence++;
|
||||
unsigned char seq[4];
|
||||
PORT_Assert(macLen == ss->sec.hash->length);
|
||||
|
||||
seq[0] = (unsigned char) (sequenceNumber >> 24);
|
||||
seq[1] = (unsigned char) (sequenceNumber >> 16);
|
||||
seq[2] = (unsigned char) (sequenceNumber >> 8);
|
||||
seq[3] = (unsigned char) (sequenceNumber);
|
||||
ssl_ReleaseSpecReadLock(ss); /******************************/
|
||||
|
||||
(*ss->sec.hash->begin)(ss->sec.hashcx);
|
||||
(*ss->sec.hash->update)(ss->sec.hashcx, ss->sec.rcvSecret.data,
|
||||
ss->sec.rcvSecret.len);
|
||||
(*ss->sec.hash->update)(ss->sec.hashcx, pBuf + macLen,
|
||||
gs->offset - macLen);
|
||||
(*ss->sec.hash->update)(ss->sec.hashcx, seq, 4);
|
||||
(*ss->sec.hash->end)(ss->sec.hashcx, mac, &macLen, macLen);
|
||||
if (NSS_SecureMemcmp(mac, pBuf, macLen) != 0) {
|
||||
/* MAC's didn't match... */
|
||||
SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d",
|
||||
SSL_GETPID(), ss->fd, ss->sec.rcvSequence));
|
||||
PRINT_BUF(1, (ss, "computed mac:", mac, macLen));
|
||||
PRINT_BUF(1, (ss, "received mac:", pBuf, macLen));
|
||||
PORT_SetError(SSL_ERROR_BAD_MAC_READ);
|
||||
rv = SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ssl_ReleaseSpecReadLock(ss); /******************************/
|
||||
}
|
||||
|
||||
PORT_Assert(macLen == ss->sec.hash->length);
|
||||
if (gs->recordPadding + macLen <= gs->offset) {
|
||||
gs->recordOffset = macLen;
|
||||
gs->readOffset = macLen;
|
||||
gs->writeOffset = gs->offset - gs->recordPadding;
|
||||
rv = 1;
|
||||
}
|
||||
else {
|
||||
PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
|
||||
cleanup:
|
||||
/* nothing in the buffer any more. */
|
||||
gs->recordOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->writeOffset = 0;
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
ssl_ReleaseSpecReadLock(ss); /******************************/
|
||||
gs->recordLen = gs->writeOffset - gs->readOffset;
|
||||
gs->recordPadding = 0; /* forget we did any padding. */
|
||||
gs->state = GS_INIT;
|
||||
|
||||
if (NSS_SecureMemcmp(mac, pBuf, macLen) != 0) {
|
||||
/* MAC's didn't match... */
|
||||
SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d",
|
||||
SSL_GETPID(), ss->fd, ss->sec.rcvSequence));
|
||||
PRINT_BUF(1, (ss, "computed mac:", mac, macLen));
|
||||
PRINT_BUF(1, (ss, "received mac:", pBuf, macLen));
|
||||
PORT_SetError(SSL_ERROR_BAD_MAC_READ);
|
||||
rv = SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
ssl_ReleaseSpecReadLock(ss); /******************************/
|
||||
}
|
||||
if (rv > 0) {
|
||||
PRINT_BUF(50, (ss, "recv clear record:",
|
||||
pBuf + gs->recordOffset, gs->recordLen));
|
||||
}
|
||||
return rv;
|
||||
|
||||
if (gs->recordPadding + macLen <= gs->offset) {
|
||||
gs->recordOffset = macLen;
|
||||
gs->readOffset = macLen;
|
||||
gs->writeOffset = gs->offset - gs->recordPadding;
|
||||
rv = 1;
|
||||
} else {
|
||||
PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
|
||||
cleanup:
|
||||
/* nothing in the buffer any more. */
|
||||
gs->recordOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->writeOffset = 0;
|
||||
rv = SECFailure;
|
||||
}
|
||||
spec_locked_done:
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
return rv;
|
||||
}
|
||||
|
||||
gs->recordLen = gs->writeOffset - gs->readOffset;
|
||||
gs->recordPadding = 0; /* forget we did any padding. */
|
||||
gs->state = GS_INIT;
|
||||
case GS_DATA:
|
||||
/* Have read in all the DATA portion of record */
|
||||
|
||||
gs->recordOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->writeOffset = gs->offset;
|
||||
PORT_Assert(gs->recordLen == gs->writeOffset - gs->readOffset);
|
||||
gs->recordLen = gs->offset;
|
||||
gs->recordPadding = 0;
|
||||
gs->state = GS_INIT;
|
||||
|
||||
if (rv > 0) {
|
||||
PRINT_BUF(50, (ss, "recv clear record:",
|
||||
pBuf + gs->recordOffset, gs->recordLen));
|
||||
}
|
||||
return rv;
|
||||
++ss->sec.rcvSequence;
|
||||
|
||||
spec_locked_done:
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
return rv;
|
||||
}
|
||||
PRINT_BUF(50, (ss, "recv clear record:",
|
||||
pBuf + gs->recordOffset, gs->recordLen));
|
||||
return 1;
|
||||
|
||||
case GS_DATA:
|
||||
/* Have read in all the DATA portion of record */
|
||||
|
||||
gs->recordOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->writeOffset = gs->offset;
|
||||
PORT_Assert(gs->recordLen == gs->writeOffset - gs->readOffset);
|
||||
gs->recordLen = gs->offset;
|
||||
gs->recordPadding = 0;
|
||||
gs->state = GS_INIT;
|
||||
|
||||
++ss->sec.rcvSequence;
|
||||
|
||||
PRINT_BUF(50, (ss, "recv clear record:",
|
||||
pBuf + gs->recordOffset, gs->recordLen));
|
||||
return 1;
|
||||
|
||||
} /* end switch gs->state */
|
||||
} /* end gather loop. */
|
||||
} /* end switch gs->state */
|
||||
} /* end gather loop. */
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -352,13 +354,13 @@ spec_locked_done:
|
|||
* Returns +1 when it has gathered a complete SSLV2 record.
|
||||
* Returns 0 if it hits EOF.
|
||||
* Returns -1 (SECFailure) on any error
|
||||
* Returns -2 (SECWouldBlock)
|
||||
* Returns -2 (SECWouldBlock)
|
||||
*
|
||||
* Called by ssl_GatherRecord1stHandshake in sslcon.c,
|
||||
* Called by ssl_GatherRecord1stHandshake in sslcon.c,
|
||||
* and by DoRecv in sslsecur.c
|
||||
* Caller must hold RecvBufLock.
|
||||
*/
|
||||
int
|
||||
int
|
||||
ssl2_GatherRecord(sslSocket *ss, int flags)
|
||||
{
|
||||
return ssl2_GatherData(ss, &ss->gs, flags);
|
||||
|
@ -372,7 +374,7 @@ ssl_InitGather(sslGather *gs)
|
|||
|
||||
gs->state = GS_INIT;
|
||||
gs->writeOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->readOffset = 0;
|
||||
gs->dtlsPacketOffset = 0;
|
||||
gs->dtlsPacket.len = 0;
|
||||
status = sslBuffer_Grow(&gs->buf, 4096);
|
||||
|
@ -380,13 +382,13 @@ ssl_InitGather(sslGather *gs)
|
|||
}
|
||||
|
||||
/* Caller must hold RecvBufLock. */
|
||||
void
|
||||
void
|
||||
ssl_DestroyGather(sslGather *gs)
|
||||
{
|
||||
if (gs) { /* the PORT_*Free functions check for NULL pointers. */
|
||||
PORT_ZFree(gs->buf.buf, gs->buf.space);
|
||||
PORT_Free(gs->inbuf.buf);
|
||||
PORT_Free(gs->dtlsPacket.buf);
|
||||
if (gs) { /* the PORT_*Free functions check for NULL pointers. */
|
||||
PORT_ZFree(gs->buf.buf, gs->buf.space);
|
||||
PORT_Free(gs->inbuf.buf);
|
||||
PORT_Free(gs->dtlsPacket.buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,32 +396,32 @@ ssl_DestroyGather(sslGather *gs)
|
|||
static SECStatus
|
||||
ssl2_HandleV3HandshakeRecord(sslSocket *ss)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECStatus rv;
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
|
||||
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
|
||||
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
|
||||
PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
|
||||
|
||||
/* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */
|
||||
ss->gs.remainder = 2;
|
||||
ss->gs.count = 0;
|
||||
ss->gs.remainder = 2;
|
||||
ss->gs.count = 0;
|
||||
|
||||
/* Clearing these handshake pointers ensures that
|
||||
/* Clearing these handshake pointers ensures that
|
||||
* ssl_Do1stHandshake won't call ssl2_HandleMessage when we return.
|
||||
*/
|
||||
ss->nextHandshake = 0;
|
||||
ss->nextHandshake = 0;
|
||||
ss->securityHandshake = 0;
|
||||
|
||||
/* Setting ss->version to an SSL 3.x value will cause
|
||||
** ssl_GatherRecord1stHandshake to invoke ssl3_GatherCompleteHandshake()
|
||||
/* Setting ss->version to an SSL 3.x value will cause
|
||||
** ssl_GatherRecord1stHandshake to invoke ssl3_GatherCompleteHandshake()
|
||||
** the next time it is called.
|
||||
**/
|
||||
rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_MAX_SUPPORTED,
|
||||
PR_TRUE);
|
||||
PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
ss->sec.send = ssl3_SendApplicationData;
|
||||
ss->sec.send = ssl3_SendApplicationData;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -9,34 +9,37 @@ static const char *
|
|||
ssl_GetCompressionMethodName(SSLCompressionMethod compression)
|
||||
{
|
||||
switch (compression) {
|
||||
case ssl_compression_null:
|
||||
return "NULL";
|
||||
case ssl_compression_null:
|
||||
return "NULL";
|
||||
#ifdef NSS_ENABLE_ZLIB
|
||||
case ssl_compression_deflate:
|
||||
return "DEFLATE";
|
||||
case ssl_compression_deflate:
|
||||
return "DEFLATE";
|
||||
#endif
|
||||
default:
|
||||
return "???";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECStatus
|
||||
SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
|
||||
{
|
||||
sslSocket * ss;
|
||||
SSLChannelInfo inf;
|
||||
sslSessionID * sid;
|
||||
sslSocket *ss;
|
||||
SSLChannelInfo inf;
|
||||
sslSessionID *sid;
|
||||
|
||||
if (!info || len < sizeof inf.length) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
/* Check if we can properly return the length of data written and that
|
||||
* we're not asked to return more information than we know how to provide.
|
||||
*/
|
||||
if (!info || len < sizeof inf.length || len > sizeof inf) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
memset(&inf, 0, sizeof inf);
|
||||
|
@ -44,45 +47,48 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
|
|||
|
||||
if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
|
||||
sid = ss->sec.ci.sid;
|
||||
inf.protocolVersion = ss->version;
|
||||
inf.authKeyBits = ss->sec.authKeyBits;
|
||||
inf.keaKeyBits = ss->sec.keaKeyBits;
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
|
||||
inf.cipherSuite = ss->sec.cipherType | 0xff00;
|
||||
inf.compressionMethod = ssl_compression_null;
|
||||
inf.compressionMethodName = "N/A";
|
||||
} else if (ss->ssl3.initialized) { /* SSL3 and TLS */
|
||||
ssl_GetSpecReadLock(ss);
|
||||
/* XXX The cipher suite should be in the specs and this
|
||||
* function should get it from cwSpec rather than from the "hs".
|
||||
* See bug 275744 comment 69 and bug 766137.
|
||||
*/
|
||||
inf.cipherSuite = ss->ssl3.hs.cipher_suite;
|
||||
inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
inf.compressionMethodName =
|
||||
ssl_GetCompressionMethodName(inf.compressionMethod);
|
||||
}
|
||||
if (sid) {
|
||||
inf.creationTime = sid->creationTime;
|
||||
inf.lastAccessTime = sid->lastAccessTime;
|
||||
inf.expirationTime = sid->expirationTime;
|
||||
inf.protocolVersion = ss->version;
|
||||
inf.authKeyBits = ss->sec.authKeyBits;
|
||||
inf.keaKeyBits = ss->sec.keaKeyBits;
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
|
||||
inf.cipherSuite = ss->sec.cipherType | 0xff00;
|
||||
inf.compressionMethod = ssl_compression_null;
|
||||
inf.compressionMethodName = "N/A";
|
||||
}
|
||||
else if (ss->ssl3.initialized) { /* SSL3 and TLS */
|
||||
ssl_GetSpecReadLock(ss);
|
||||
/* XXX The cipher suite should be in the specs and this
|
||||
* function should get it from cwSpec rather than from the "hs".
|
||||
* See bug 275744 comment 69 and bug 766137.
|
||||
*/
|
||||
inf.cipherSuite = ss->ssl3.hs.cipher_suite;
|
||||
inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
inf.compressionMethodName =
|
||||
ssl_GetCompressionMethodName(inf.compressionMethod);
|
||||
}
|
||||
if (sid) {
|
||||
inf.creationTime = sid->creationTime;
|
||||
inf.lastAccessTime = sid->lastAccessTime;
|
||||
inf.expirationTime = sid->expirationTime;
|
||||
inf.extendedMasterSecretUsed =
|
||||
(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ||
|
||||
sid->u.ssl3.keys.extendedMasterSecretUsed) ?
|
||||
PR_TRUE: PR_FALSE;
|
||||
(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ||
|
||||
sid->u.ssl3.keys.extendedMasterSecretUsed)
|
||||
? PR_TRUE
|
||||
: PR_FALSE;
|
||||
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
|
||||
inf.sessionIDLength = SSL2_SESSIONID_BYTES;
|
||||
memcpy(inf.sessionID, sid->u.ssl2.sessionID,
|
||||
SSL2_SESSIONID_BYTES);
|
||||
} else {
|
||||
unsigned int sidLen = sid->u.ssl3.sessionIDLength;
|
||||
sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
|
||||
inf.sessionIDLength = sidLen;
|
||||
memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
|
||||
}
|
||||
}
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
|
||||
inf.sessionIDLength = SSL2_SESSIONID_BYTES;
|
||||
memcpy(inf.sessionID, sid->u.ssl2.sessionID,
|
||||
SSL2_SESSIONID_BYTES);
|
||||
}
|
||||
else {
|
||||
unsigned int sidLen = sid->u.ssl3.sessionIDLength;
|
||||
sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
|
||||
inf.sessionIDLength = sidLen;
|
||||
memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(info, &inf, inf.length);
|
||||
|
@ -98,7 +104,10 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
|
|||
sslSocket *ss;
|
||||
SSLPreliminaryChannelInfo inf;
|
||||
|
||||
if (!info || len < sizeof inf.length) {
|
||||
/* Check if we can properly return the length of data written and that
|
||||
* we're not asked to return more information than we know how to provide.
|
||||
*/
|
||||
if (!info || len < sizeof inf.length || len > sizeof inf) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -126,197 +135,206 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
||||
#define CS(x) x, #x
|
||||
#define CK(x) x | 0xff00, #x
|
||||
|
||||
#define S_DSA "DSA", ssl_auth_dsa
|
||||
#define S_RSA "RSA", ssl_auth_rsa
|
||||
#define S_KEA "KEA", ssl_auth_kea
|
||||
#define S_DSA "DSA", ssl_auth_dsa
|
||||
#define S_RSA "RSA", ssl_auth_rsa
|
||||
#define S_KEA "KEA", ssl_auth_kea
|
||||
#define S_ECDSA "ECDSA", ssl_auth_ecdsa
|
||||
|
||||
#define K_DHE "DHE", kt_dh
|
||||
#define K_RSA "RSA", kt_rsa
|
||||
#define K_KEA "KEA", kt_kea
|
||||
#define K_ECDH "ECDH", kt_ecdh
|
||||
#define K_ECDHE "ECDHE", kt_ecdh
|
||||
#define K_DHE "DHE", kt_dh
|
||||
#define K_RSA "RSA", kt_rsa
|
||||
#define K_KEA "KEA", kt_kea
|
||||
#define K_ECDH "ECDH", kt_ecdh
|
||||
#define K_ECDHE "ECDHE", kt_ecdh
|
||||
|
||||
#define C_SEED "SEED", calg_seed
|
||||
#define C_SEED "SEED", calg_seed
|
||||
#define C_CAMELLIA "CAMELLIA", calg_camellia
|
||||
#define C_AES "AES", calg_aes
|
||||
#define C_RC4 "RC4", calg_rc4
|
||||
#define C_RC2 "RC2", calg_rc2
|
||||
#define C_DES "DES", calg_des
|
||||
#define C_3DES "3DES", calg_3des
|
||||
#define C_NULL "NULL", calg_null
|
||||
#define C_SJ "SKIPJACK", calg_sj
|
||||
#define C_AES "AES", calg_aes
|
||||
#define C_RC4 "RC4", calg_rc4
|
||||
#define C_RC2 "RC2", calg_rc2
|
||||
#define C_DES "DES", calg_des
|
||||
#define C_3DES "3DES", calg_3des
|
||||
#define C_NULL "NULL", calg_null
|
||||
#define C_SJ "SKIPJACK", calg_sj
|
||||
#define C_AESGCM "AES-GCM", calg_aes_gcm
|
||||
#define C_CHACHA20 "CHACHA20POLY1305", calg_chacha20
|
||||
|
||||
#define B_256 256, 256, 256
|
||||
#define B_128 128, 128, 128
|
||||
#define B_3DES 192, 156, 112
|
||||
#define B_SJ 96, 80, 80
|
||||
#define B_DES 64, 56, 56
|
||||
#define B_56 128, 56, 56
|
||||
#define B_40 128, 40, 40
|
||||
#define B_0 0, 0, 0
|
||||
#define B_256 256, 256, 256
|
||||
#define B_128 128, 128, 128
|
||||
#define B_3DES 192, 156, 112
|
||||
#define B_SJ 96, 80, 80
|
||||
#define B_DES 64, 56, 56
|
||||
#define B_56 128, 56, 56
|
||||
#define B_40 128, 40, 40
|
||||
#define B_0 0, 0, 0
|
||||
|
||||
#define M_AEAD_128 "AEAD", ssl_mac_aead, 128
|
||||
#define M_SHA256 "SHA256", ssl_hmac_sha256, 256
|
||||
#define M_SHA "SHA1", ssl_mac_sha, 160
|
||||
#define M_MD5 "MD5", ssl_mac_md5, 128
|
||||
#define M_NULL "NULL", ssl_mac_null, 0
|
||||
#define M_SHA "SHA1", ssl_mac_sha, 160
|
||||
#define M_MD5 "MD5", ssl_mac_md5, 128
|
||||
#define M_NULL "NULL", ssl_mac_null, 0
|
||||
|
||||
/* clang-format off */
|
||||
static const SSLCipherSuiteInfo suiteInfo[] = {
|
||||
/* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
|
||||
{0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
/* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */
|
||||
{0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_DHE, C_CHACHA20, B_256, M_AEAD_128, 0, 0, 0 },
|
||||
|
||||
{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA), S_DSA, K_DHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256), S_DSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_256, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_RSA, C_AES, B_256, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_RSA, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
|
||||
{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, 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_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_RSA, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, 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_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256), S_DSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256), S_DSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_CAMELLIA_128_CBC_SHA), S_RSA, K_RSA, C_CAMELLIA, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_RC4_128_SHA), S_RSA, K_RSA, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_RC4_128_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_RSA, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_RSA, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
|
||||
{0,CS(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0 },
|
||||
{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(TLS_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA), S_DSA, K_DHE, C_3DES,B_3DES,M_SHA, 1, 0, 0 },
|
||||
{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(TLS_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_RSA, C_3DES,B_3DES,M_SHA, 1, 0, 0 },
|
||||
|
||||
{0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_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, 0, 0, 1 },
|
||||
{0,CS(TLS_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_DHE_RSA_WITH_DES_CBC_SHA), S_RSA, K_DHE, C_DES, B_DES, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_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, 0, 0, 1 },
|
||||
{0,CS(TLS_RSA_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 0, 0 },
|
||||
|
||||
{0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_SHA, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL,B_0, M_SHA256, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA), S_RSA, K_RSA, C_RC4, B_56, M_SHA, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA), S_RSA, K_RSA, C_DES, B_DES, M_SHA, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT_WITH_RC4_40_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_WITH_NULL_SHA256), S_RSA, K_RSA, C_NULL,B_0, M_SHA256, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_WITH_NULL_SHA), S_RSA, K_RSA, C_NULL,B_0, M_SHA, 0, 1, 0 },
|
||||
{0,CS(TLS_RSA_WITH_NULL_MD5), S_RSA, K_RSA, C_NULL,B_0, M_MD5, 0, 1, 0 },
|
||||
|
||||
#ifndef NSS_DISABLE_ECC
|
||||
/* ECC cipher suites */
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
#ifndef NSS_DISABLE_ECC
|
||||
/* ECC cipher suites */
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0 },
|
||||
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256), S_ECDSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, 0, 0, 0 },
|
||||
|
||||
{0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
#endif /* NSS_DISABLE_ECC */
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0 },
|
||||
{0,CS(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256), S_RSA, K_ECDHE, C_CHACHA20, B_256, M_AEAD_128, 0, 0, 0 },
|
||||
#endif /* NSS_DISABLE_ECC */
|
||||
|
||||
/* SSL 2 table */
|
||||
{0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5), S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_DES_64_CBC_WITH_MD5), S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0 },
|
||||
{0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0 }
|
||||
/* SSL 2 table */
|
||||
{0,CK(SSL_CK_RC4_128_WITH_MD5), S_RSA, K_RSA, C_RC4, B_128, M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_RC2_128_CBC_WITH_MD5), S_RSA, K_RSA, C_RC2, B_128, M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_DES_192_EDE3_CBC_WITH_MD5), S_RSA, K_RSA, C_3DES,B_3DES,M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_DES_64_CBC_WITH_MD5), S_RSA, K_RSA, C_DES, B_DES, M_MD5, 0, 0, 0 },
|
||||
{0,CK(SSL_CK_RC4_128_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC4, B_40, M_MD5, 0, 1, 0 },
|
||||
{0,CK(SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5), S_RSA, K_RSA, C_RC2, B_40, M_MD5, 0, 1, 0 }
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
#define NUM_SUITEINFOS ((sizeof suiteInfo) / (sizeof suiteInfo[0]))
|
||||
|
||||
|
||||
SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
|
||||
SSLCipherSuiteInfo *info, PRUintn len)
|
||||
SECStatus
|
||||
SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,
|
||||
SSLCipherSuiteInfo *info, PRUintn len)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
len = PR_MIN(len, sizeof suiteInfo[0]);
|
||||
if (!info || len < sizeof suiteInfo[0].length) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
/* Check if we can properly return the length of data written and that
|
||||
* we're not asked to return more information than we know how to provide.
|
||||
*/
|
||||
if (!info || len < sizeof suiteInfo[0].length ||
|
||||
len > sizeof suiteInfo[0]) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
len = PR_MIN(len, sizeof suiteInfo[0]);
|
||||
for (i = 0; i < NUM_SUITEINFOS; i++) {
|
||||
if (suiteInfo[i].cipherSuite == cipherSuite) {
|
||||
memcpy(info, &suiteInfo[i], len);
|
||||
info->length = len;
|
||||
return SECSuccess;
|
||||
}
|
||||
if (suiteInfo[i].cipherSuite == cipherSuite) {
|
||||
memcpy(info, &suiteInfo[i], len);
|
||||
info->length = len;
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* This function might be a candidate to be public.
|
||||
/* This function might be a candidate to be public.
|
||||
* Disables all export ciphers in the default set of enabled ciphers.
|
||||
*/
|
||||
SECStatus
|
||||
SECStatus
|
||||
SSL_DisableDefaultExportCipherSuites(void)
|
||||
{
|
||||
const SSLCipherSuiteInfo * pInfo = suiteInfo;
|
||||
const SSLCipherSuiteInfo *pInfo = suiteInfo;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
|
||||
if (pInfo->isExportable) {
|
||||
PORT_CheckSuccess(SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE));
|
||||
}
|
||||
if (pInfo->isExportable) {
|
||||
PORT_CheckSuccess(SSL_CipherPrefSetDefault(pInfo->cipherSuite, PR_FALSE));
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* This function might be a candidate to be public,
|
||||
/* This function might be a candidate to be public,
|
||||
* except that it takes an sslSocket pointer as an argument.
|
||||
* A Public version would take a PRFileDesc pointer.
|
||||
* Disables all export ciphers in the default set of enabled ciphers.
|
||||
*/
|
||||
SECStatus
|
||||
SSL_DisableExportCipherSuites(PRFileDesc * fd)
|
||||
SECStatus
|
||||
SSL_DisableExportCipherSuites(PRFileDesc *fd)
|
||||
{
|
||||
const SSLCipherSuiteInfo * pInfo = suiteInfo;
|
||||
const SSLCipherSuiteInfo *pInfo = suiteInfo;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NUM_SUITEINFOS; ++i, ++pInfo) {
|
||||
if (pInfo->isExportable) {
|
||||
PORT_CheckSuccess(SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE));
|
||||
}
|
||||
if (pInfo->isExportable) {
|
||||
PORT_CheckSuccess(SSL_CipherPrefSet(fd, pInfo->cipherSuite, PR_FALSE));
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Tells us if the named suite is exportable
|
||||
/* Tells us if the named suite is exportable
|
||||
* returns false for unknown suites.
|
||||
*/
|
||||
PRBool
|
||||
|
@ -324,14 +342,14 @@ SSL_IsExportCipherSuite(PRUint16 cipherSuite)
|
|||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < NUM_SUITEINFOS; i++) {
|
||||
if (suiteInfo[i].cipherSuite == cipherSuite) {
|
||||
return (PRBool)(suiteInfo[i].isExportable);
|
||||
}
|
||||
if (suiteInfo[i].cipherSuite == cipherSuite) {
|
||||
return (PRBool)(suiteInfo[i].isExportable);
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
SECItem*
|
||||
SECItem *
|
||||
SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
|
||||
{
|
||||
SECItem *sniName = NULL;
|
||||
|
@ -340,9 +358,9 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
|
|||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
|
||||
SSL_GETPID(), fd));
|
||||
return NULL;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo",
|
||||
SSL_GETPID(), fd));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ss->sec.isServer) {
|
||||
|
@ -357,7 +375,7 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
|
|||
ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
|
||||
}
|
||||
return sniName;
|
||||
}
|
||||
}
|
||||
name = SSL_RevealURL(fd);
|
||||
if (name) {
|
||||
sniName = PORT_ZNew(SECItem);
|
||||
|
@ -365,8 +383,8 @@ SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
|
|||
PORT_Free(name);
|
||||
return NULL;
|
||||
}
|
||||
sniName->data = (void*)name;
|
||||
sniName->len = PORT_Strlen(name);
|
||||
sniName->data = (void *)name;
|
||||
sniName->len = PORT_Strlen(name);
|
||||
}
|
||||
return sniName;
|
||||
}
|
||||
|
@ -385,24 +403,24 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
|
|||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
|
||||
PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
|
||||
return SECFailure;
|
||||
PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* construct PRF arguments */
|
||||
valLen = SSL3_RANDOM_LENGTH * 2;
|
||||
if (hasContext) {
|
||||
valLen += 2 /* PRUint16 length */ + contextLen;
|
||||
valLen += 2 /* PRUint16 length */ + contextLen;
|
||||
}
|
||||
val = PORT_Alloc(valLen);
|
||||
if (!val) {
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
i = 0;
|
||||
PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
|
||||
|
@ -410,10 +428,10 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
|
|||
PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
|
||||
i += SSL3_RANDOM_LENGTH;
|
||||
if (hasContext) {
|
||||
val[i++] = contextLen >> 8;
|
||||
val[i++] = contextLen;
|
||||
PORT_Memcpy(val + i, context, contextLen);
|
||||
i += contextLen;
|
||||
val[i++] = contextLen >> 8;
|
||||
val[i++] = contextLen;
|
||||
PORT_Memcpy(val + i, context, contextLen);
|
||||
i += contextLen;
|
||||
}
|
||||
PORT_Assert(i == valLen);
|
||||
|
||||
|
@ -422,11 +440,12 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd,
|
|||
*/
|
||||
ssl_GetSpecReadLock(ss);
|
||||
if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
|
||||
PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
|
||||
valLen, out, outLen);
|
||||
PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
|
||||
rv = SECFailure;
|
||||
}
|
||||
else {
|
||||
rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
|
||||
valLen, out, outLen);
|
||||
}
|
||||
ssl_ReleaseSpecReadLock(ss);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
static int ssl_isInited = 0;
|
||||
static PRCallOnceType ssl_init = { 0 };
|
||||
static PRCallOnceType ssl_init = { 0 };
|
||||
|
||||
PRStatus
|
||||
ssl_InitCallOnce(void *arg)
|
||||
|
@ -24,22 +24,21 @@ ssl_InitCallOnce(void *arg)
|
|||
|
||||
rv = ssl_InitializePRErrorTable();
|
||||
if (rv != SECSuccess) {
|
||||
*error = SEC_ERROR_NO_MEMORY;
|
||||
return PR_FAILURE;
|
||||
*error = SEC_ERROR_NO_MEMORY;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
ssl3_CheckCipherSuiteOrderConsistency();
|
||||
ssl3_CheckCipherSuiteOrderConsistency();
|
||||
#endif
|
||||
|
||||
rv = ssl3_ApplyNSSPolicy();
|
||||
if (rv != SECSuccess) {
|
||||
*error = PORT_GetError();
|
||||
return PR_FAILURE;
|
||||
*error = PORT_GetError();
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
ssl_Init(void)
|
||||
{
|
||||
|
@ -47,14 +46,14 @@ ssl_Init(void)
|
|||
|
||||
/* short circuit test if we are already inited */
|
||||
if (!ssl_isInited) {
|
||||
int error;
|
||||
/* only do this once at init time, block all others until we are done */
|
||||
nrv = PR_CallOnceWithArg(&ssl_init, ssl_InitCallOnce, &error);
|
||||
if (nrv != PR_SUCCESS) {
|
||||
PORT_SetError(error);
|
||||
return SECFailure;
|
||||
}
|
||||
ssl_isInited = 1;
|
||||
int error;
|
||||
/* only do this once at init time, block all others until we are done */
|
||||
nrv = PR_CallOnceWithArg(&ssl_init, ssl_InitCallOnce, &error);
|
||||
if (nrv != PR_SUCCESS) {
|
||||
PORT_SetError(error);
|
||||
return SECFailure;
|
||||
}
|
||||
ssl_isInited = 1;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
|
@ -4,15 +4,16 @@
|
|||
|
||||
#include "seccomon.h"
|
||||
/* This ifdef should match the one in sslsnce.c */
|
||||
#if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
|
||||
#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_OS2) || defined(XP_BEOS)
|
||||
|
||||
#include "sslmutex.h"
|
||||
#include "prerr.h"
|
||||
|
||||
static SECStatus single_process_sslMutex_Init(sslMutex* pMutex)
|
||||
static SECStatus
|
||||
single_process_sslMutex_Init(sslMutex* pMutex)
|
||||
{
|
||||
PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0 );
|
||||
|
||||
PR_ASSERT(pMutex != 0 && pMutex->u.sslLock == 0);
|
||||
|
||||
pMutex->u.sslLock = PR_NewLock();
|
||||
if (!pMutex->u.sslLock) {
|
||||
return SECFailure;
|
||||
|
@ -20,10 +21,11 @@ static SECStatus single_process_sslMutex_Init(sslMutex* pMutex)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex)
|
||||
static SECStatus
|
||||
single_process_sslMutex_Destroy(sslMutex* pMutex)
|
||||
{
|
||||
PR_ASSERT(pMutex != 0);
|
||||
PR_ASSERT(pMutex->u.sslLock!= 0);
|
||||
PR_ASSERT(pMutex->u.sslLock != 0);
|
||||
if (!pMutex->u.sslLock) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
|
@ -32,10 +34,11 @@ static SECStatus single_process_sslMutex_Destroy(sslMutex* pMutex)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex)
|
||||
static SECStatus
|
||||
single_process_sslMutex_Unlock(sslMutex* pMutex)
|
||||
{
|
||||
PR_ASSERT(pMutex != 0 );
|
||||
PR_ASSERT(pMutex->u.sslLock !=0);
|
||||
PR_ASSERT(pMutex != 0);
|
||||
PR_ASSERT(pMutex->u.sslLock != 0);
|
||||
if (!pMutex->u.sslLock) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
|
@ -44,10 +47,11 @@ static SECStatus single_process_sslMutex_Unlock(sslMutex* pMutex)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
|
||||
static SECStatus
|
||||
single_process_sslMutex_Lock(sslMutex* pMutex)
|
||||
{
|
||||
PR_ASSERT(pMutex != 0);
|
||||
PR_ASSERT(pMutex->u.sslLock != 0 );
|
||||
PR_ASSERT(pMutex->u.sslLock != 0);
|
||||
if (!pMutex->u.sslLock) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
|
@ -66,7 +70,7 @@ static SECStatus single_process_sslMutex_Lock(sslMutex* pMutex)
|
|||
#include "pratom.h"
|
||||
|
||||
#define SSL_MUTEX_MAGIC 0xfeedfd
|
||||
#define NONBLOCKING_POSTS 1 /* maybe this is faster */
|
||||
#define NONBLOCKING_POSTS 1 /* maybe this is faster */
|
||||
|
||||
#if NONBLOCKING_POSTS
|
||||
|
||||
|
@ -82,20 +86,20 @@ setNonBlocking(int fd, int nonBlocking)
|
|||
|
||||
flags = fcntl(fd, F_GETFL, 0);
|
||||
if (0 > flags)
|
||||
return flags;
|
||||
return flags;
|
||||
if (nonBlocking)
|
||||
flags |= FNONBLOCK;
|
||||
flags |= FNONBLOCK;
|
||||
else
|
||||
flags &= ~FNONBLOCK;
|
||||
flags &= ~FNONBLOCK;
|
||||
err = fcntl(fd, F_SETFL, flags);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
SECStatus
|
||||
sslMutex_Init(sslMutex *pMutex, int shared)
|
||||
sslMutex_Init(sslMutex* pMutex, int shared)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
PR_ASSERT(pMutex);
|
||||
pMutex->isMultiProcess = (PRBool)(shared != 0);
|
||||
if (!shared) {
|
||||
|
@ -104,17 +108,17 @@ sslMutex_Init(sslMutex *pMutex, int shared)
|
|||
pMutex->u.pipeStr.mPipes[0] = -1;
|
||||
pMutex->u.pipeStr.mPipes[1] = -1;
|
||||
pMutex->u.pipeStr.mPipes[2] = -1;
|
||||
pMutex->u.pipeStr.nWaiters = 0;
|
||||
pMutex->u.pipeStr.nWaiters = 0;
|
||||
|
||||
err = pipe(pMutex->u.pipeStr.mPipes);
|
||||
if (err) {
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return err;
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return err;
|
||||
}
|
||||
#if NONBLOCKING_POSTS
|
||||
err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1);
|
||||
if (err)
|
||||
goto loser;
|
||||
goto loser;
|
||||
#endif
|
||||
|
||||
pMutex->u.pipeStr.mPipes[2] = SSL_MUTEX_MAGIC;
|
||||
|
@ -135,26 +139,26 @@ loser:
|
|||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
||||
sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal)
|
||||
{
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Destroy(pMutex);
|
||||
}
|
||||
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
close(pMutex->u.pipeStr.mPipes[0]);
|
||||
close(pMutex->u.pipeStr.mPipes[1]);
|
||||
|
||||
if (processLocal) {
|
||||
return SECSuccess;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
pMutex->u.pipeStr.mPipes[0] = -1;
|
||||
pMutex->u.pipeStr.mPipes[1] = -1;
|
||||
pMutex->u.pipeStr.mPipes[2] = -1;
|
||||
pMutex->u.pipeStr.nWaiters = 0;
|
||||
pMutex->u.pipeStr.nWaiters = 0;
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -164,13 +168,12 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
|||
|
||||
/* nWaiters includes the holder of the lock (if any) and the number
|
||||
** threads waiting for it. After incrementing nWaiters, if the count
|
||||
** is exactly 1, then you have the lock and may proceed. If the
|
||||
** is exactly 1, then you have the lock and may proceed. If the
|
||||
** count is greater than 1, then you must wait on the pipe.
|
||||
*/
|
||||
*/
|
||||
|
||||
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex* pMutex)
|
||||
{
|
||||
PRInt32 newValue;
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
|
@ -178,30 +181,30 @@ sslMutex_Unlock(sslMutex *pMutex)
|
|||
}
|
||||
|
||||
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
/* Do Memory Barrier here. */
|
||||
newValue = PR_ATOMIC_DECREMENT(&pMutex->u.pipeStr.nWaiters);
|
||||
if (newValue > 0) {
|
||||
int cc;
|
||||
char c = 1;
|
||||
do {
|
||||
cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
|
||||
} while (cc < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (cc != 1) {
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
int cc;
|
||||
char c = 1;
|
||||
do {
|
||||
cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
|
||||
} while (cc < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (cc != 1) {
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex* pMutex)
|
||||
{
|
||||
PRInt32 newValue;
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
|
@ -209,88 +212,88 @@ sslMutex_Lock(sslMutex *pMutex)
|
|||
}
|
||||
|
||||
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
newValue = PR_ATOMIC_INCREMENT(&pMutex->u.pipeStr.nWaiters);
|
||||
/* Do Memory Barrier here. */
|
||||
if (newValue > 1) {
|
||||
int cc;
|
||||
char c;
|
||||
do {
|
||||
cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
|
||||
} while (cc < 0 && errno == EINTR);
|
||||
if (cc != 1) {
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
int cc;
|
||||
char c;
|
||||
do {
|
||||
cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
|
||||
} while (cc < 0 && errno == EINTR);
|
||||
if (cc != 1) {
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Using Atomic operations requires the use of a memory barrier instruction
|
||||
/* Using Atomic operations requires the use of a memory barrier instruction
|
||||
** on PowerPC, Sparc, and Alpha. NSPR's PR_Atomic functions do not perform
|
||||
** them, and NSPR does not provide a function that does them (e.g. PR_Barrier).
|
||||
** So, we don't use them on those platforms.
|
||||
** So, we don't use them on those platforms.
|
||||
*/
|
||||
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex* pMutex)
|
||||
{
|
||||
int cc;
|
||||
char c = 1;
|
||||
int cc;
|
||||
char c = 1;
|
||||
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Unlock(pMutex);
|
||||
}
|
||||
|
||||
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
do {
|
||||
cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
|
||||
cc = write(pMutex->u.pipeStr.mPipes[1], &c, 1);
|
||||
} while (cc < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
if (cc != 1) {
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex* pMutex)
|
||||
{
|
||||
int cc;
|
||||
char c;
|
||||
int cc;
|
||||
char c;
|
||||
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Lock(pMutex);
|
||||
}
|
||||
|
||||
|
||||
if (pMutex->u.pipeStr.mPipes[2] != SSL_MUTEX_MAGIC) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
do {
|
||||
cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
|
||||
cc = read(pMutex->u.pipeStr.mPipes[0], &c, 1);
|
||||
} while (cc < 0 && errno == EINTR);
|
||||
if (cc != 1) {
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
if (cc < 0)
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
else
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
|
@ -314,7 +317,8 @@ sslMutex_Lock(sslMutex *pMutex)
|
|||
|
||||
#ifdef WINNT
|
||||
|
||||
SECStatus sslMutex_2LevelInit(sslMutex *sem)
|
||||
SECStatus
|
||||
sslMutex_2LevelInit(sslMutex *sem)
|
||||
{
|
||||
/* the following adds a PRLock to sslMutex . This is done in each
|
||||
process of a multi-process server and is only needed on WINNT, if
|
||||
|
@ -330,7 +334,8 @@ SECStatus sslMutex_2LevelInit(sslMutex *sem)
|
|||
return single_process_sslMutex_Init(sem);
|
||||
}
|
||||
|
||||
static SECStatus sslMutex_2LevelDestroy(sslMutex *sem)
|
||||
static SECStatus
|
||||
sslMutex_2LevelDestroy(sslMutex *sem)
|
||||
{
|
||||
return single_process_sslMutex_Destroy(sem);
|
||||
}
|
||||
|
@ -345,26 +350,28 @@ sslMutex_Init(sslMutex *pMutex, int shared)
|
|||
#endif
|
||||
HANDLE hMutex;
|
||||
SECURITY_ATTRIBUTES attributes =
|
||||
{ sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
|
||||
{ sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
|
||||
|
||||
PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 ||
|
||||
pMutex->u.sslMutx ==
|
||||
INVALID_HANDLE_VALUE));
|
||||
|
||||
PR_ASSERT(pMutex != 0 && (pMutex->u.sslMutx == 0 ||
|
||||
pMutex->u.sslMutx == INVALID_HANDLE_VALUE) );
|
||||
|
||||
pMutex->isMultiProcess = (PRBool)(shared != 0);
|
||||
|
||||
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Init(pMutex);
|
||||
}
|
||||
|
||||
|
||||
#ifdef WINNT
|
||||
/* we need a lock on WINNT for fibers in the parent process */
|
||||
retvalue = sslMutex_2LevelInit(pMutex);
|
||||
if (SECSuccess != retvalue)
|
||||
return SECFailure;
|
||||
#endif
|
||||
|
||||
if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 &&
|
||||
hMutex != INVALID_HANDLE_VALUE)) {
|
||||
|
||||
if (!pMutex || ((hMutex = pMutex->u.sslMutx) != 0 &&
|
||||
hMutex !=
|
||||
INVALID_HANDLE_VALUE)) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -383,7 +390,7 @@ SECStatus
|
|||
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
||||
{
|
||||
HANDLE hMutex;
|
||||
int rv;
|
||||
int rv;
|
||||
int retvalue = SECSuccess;
|
||||
|
||||
PR_ASSERT(pMutex != 0);
|
||||
|
@ -391,20 +398,20 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
|||
return single_process_sslMutex_Destroy(pMutex);
|
||||
}
|
||||
|
||||
/* multi-process mode */
|
||||
/* multi-process mode */
|
||||
#ifdef WINNT
|
||||
/* on NT, get rid of the PRLock used for fibers within a process */
|
||||
retvalue = sslMutex_2LevelDestroy(pMutex);
|
||||
#endif
|
||||
|
||||
PR_ASSERT( pMutex->u.sslMutx != 0 &&
|
||||
pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
|
||||
if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0
|
||||
|| hMutex == INVALID_HANDLE_VALUE) {
|
||||
|
||||
PR_ASSERT(pMutex->u.sslMutx != 0 &&
|
||||
pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
|
||||
if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
|
||||
hMutex == INVALID_HANDLE_VALUE) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
rv = CloseHandle(hMutex); /* ignore error */
|
||||
if (!processLocal && rv) {
|
||||
pMutex->u.sslMutx = hMutex = INVALID_HANDLE_VALUE;
|
||||
|
@ -416,18 +423,18 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
|||
return retvalue;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
sslMutex_Unlock(sslMutex *pMutex)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
BOOL success = FALSE;
|
||||
HANDLE hMutex;
|
||||
|
||||
PR_ASSERT(pMutex != 0 );
|
||||
PR_ASSERT(pMutex != 0);
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Unlock(pMutex);
|
||||
}
|
||||
|
||||
PR_ASSERT(pMutex->u.sslMutx != 0 &&
|
||||
|
||||
PR_ASSERT(pMutex->u.sslMutx != 0 &&
|
||||
pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
|
||||
if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
|
||||
hMutex == INVALID_HANDLE_VALUE) {
|
||||
|
@ -447,12 +454,12 @@ sslMutex_Unlock(sslMutex *pMutex)
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
sslMutex_Lock(sslMutex *pMutex)
|
||||
{
|
||||
HANDLE hMutex;
|
||||
DWORD event;
|
||||
DWORD lastError;
|
||||
HANDLE hMutex;
|
||||
DWORD event;
|
||||
DWORD lastError;
|
||||
SECStatus rv;
|
||||
SECStatus retvalue = SECSuccess;
|
||||
PR_ASSERT(pMutex != 0);
|
||||
|
@ -465,42 +472,42 @@ sslMutex_Lock(sslMutex *pMutex)
|
|||
in the same process */
|
||||
retvalue = single_process_sslMutex_Lock(pMutex);
|
||||
#endif
|
||||
PR_ASSERT(pMutex->u.sslMutx != 0 &&
|
||||
PR_ASSERT(pMutex->u.sslMutx != 0 &&
|
||||
pMutex->u.sslMutx != INVALID_HANDLE_VALUE);
|
||||
if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
|
||||
if (!pMutex || (hMutex = pMutex->u.sslMutx) == 0 ||
|
||||
hMutex == INVALID_HANDLE_VALUE) {
|
||||
PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
|
||||
return SECFailure; /* what else ? */
|
||||
return SECFailure; /* what else ? */
|
||||
}
|
||||
/* acquire the mutex to be the only owner accross all other processes */
|
||||
event = WaitForSingleObject(hMutex, INFINITE);
|
||||
switch (event) {
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED:
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
case WAIT_OBJECT_0:
|
||||
case WAIT_ABANDONED:
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
|
||||
case WAIT_TIMEOUT:
|
||||
case WAIT_TIMEOUT:
|
||||
#if defined(WAIT_IO_COMPLETION)
|
||||
case WAIT_IO_COMPLETION:
|
||||
case WAIT_IO_COMPLETION:
|
||||
#endif
|
||||
default: /* should never happen. nothing we can do. */
|
||||
PR_ASSERT(!("WaitForSingleObject returned invalid value."));
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
default: /* should never happen. nothing we can do. */
|
||||
PR_ASSERT(!("WaitForSingleObject returned invalid value."));
|
||||
PORT_SetError(PR_UNKNOWN_ERROR);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
|
||||
case WAIT_FAILED: /* failure returns this */
|
||||
rv = SECFailure;
|
||||
lastError = GetLastError(); /* for debugging */
|
||||
nss_MD_win32_map_default_error(lastError);
|
||||
break;
|
||||
case WAIT_FAILED: /* failure returns this */
|
||||
rv = SECFailure;
|
||||
lastError = GetLastError(); /* for debugging */
|
||||
nss_MD_win32_map_default_error(lastError);
|
||||
break;
|
||||
}
|
||||
|
||||
if (! (SECSuccess == retvalue && SECSuccess == rv)) {
|
||||
if (!(SECSuccess == retvalue && SECSuccess == rv)) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -509,8 +516,8 @@ sslMutex_Lock(sslMutex *pMutex)
|
|||
#include <errno.h>
|
||||
#include "unix_err.h"
|
||||
|
||||
SECStatus
|
||||
sslMutex_Init(sslMutex *pMutex, int shared)
|
||||
SECStatus
|
||||
sslMutex_Init(sslMutex* pMutex, int shared)
|
||||
{
|
||||
int rv;
|
||||
PR_ASSERT(pMutex);
|
||||
|
@ -528,8 +535,8 @@ sslMutex_Init(sslMutex *pMutex, int shared)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
||||
SECStatus
|
||||
sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal)
|
||||
{
|
||||
int rv;
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
|
@ -538,56 +545,56 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
|||
|
||||
/* semaphores are global resources. See SEM_DESTROY(3) man page */
|
||||
if (processLocal) {
|
||||
return SECSuccess;
|
||||
return SECSuccess;
|
||||
}
|
||||
do {
|
||||
rv = sem_destroy(&pMutex->u.sem);
|
||||
rv = sem_destroy(&pMutex->u.sem);
|
||||
} while (rv < 0 && errno == EINTR);
|
||||
if (rv < 0) {
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return SECFailure;
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex* pMutex)
|
||||
{
|
||||
int rv;
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Unlock(pMutex);
|
||||
}
|
||||
do {
|
||||
rv = sem_post(&pMutex->u.sem);
|
||||
rv = sem_post(&pMutex->u.sem);
|
||||
} while (rv < 0 && errno == EINTR);
|
||||
if (rv < 0) {
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return SECFailure;
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex* pMutex)
|
||||
{
|
||||
int rv;
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
return single_process_sslMutex_Lock(pMutex);
|
||||
}
|
||||
do {
|
||||
rv = sem_wait(&pMutex->u.sem);
|
||||
rv = sem_wait(&pMutex->u.sem);
|
||||
} while (rv < 0 && errno == EINTR);
|
||||
if (rv < 0) {
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return SECFailure;
|
||||
nss_MD_unix_map_default_error(errno);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SECStatus
|
||||
sslMutex_Init(sslMutex *pMutex, int shared)
|
||||
SECStatus
|
||||
sslMutex_Init(sslMutex* pMutex, int shared)
|
||||
{
|
||||
PR_ASSERT(pMutex);
|
||||
pMutex->isMultiProcess = (PRBool)(shared != 0);
|
||||
|
@ -599,8 +606,8 @@ sslMutex_Init(sslMutex *pMutex, int shared)
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
||||
SECStatus
|
||||
sslMutex_Destroy(sslMutex* pMutex, PRBool processLocal)
|
||||
{
|
||||
PR_ASSERT(pMutex);
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
|
@ -611,8 +618,8 @@ sslMutex_Destroy(sslMutex *pMutex, PRBool processLocal)
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Unlock(sslMutex* pMutex)
|
||||
{
|
||||
PR_ASSERT(pMutex);
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
|
@ -623,8 +630,8 @@ sslMutex_Unlock(sslMutex *pMutex)
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex *pMutex)
|
||||
SECStatus
|
||||
sslMutex_Lock(sslMutex* pMutex)
|
||||
{
|
||||
PR_ASSERT(pMutex);
|
||||
if (PR_FALSE == pMutex->isMultiProcess) {
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
#ifndef __SSLMUTEX_H_
|
||||
#define __SSLMUTEX_H_ 1
|
||||
|
||||
/* What SSL really wants is portable process-shared unnamed mutexes in
|
||||
/* What SSL really wants is portable process-shared unnamed mutexes in
|
||||
* shared memory, that have the property that if the process that holds
|
||||
* them dies, they are released automatically, and that (unlike fcntl
|
||||
* record locking) lock to the thread, not to the process.
|
||||
* NSPR doesn't provide that.
|
||||
* Windows has mutexes that meet that description, but they're not portable.
|
||||
* POSIX mutexes are not automatically released when the holder dies,
|
||||
* and other processes/threads cannot release the mutex on behalf of the
|
||||
* dead holder.
|
||||
* POSIX semaphores can be used to accomplish this on systems that implement
|
||||
* process-shared unnamed POSIX semaphores, because a watchdog thread can
|
||||
* discover and release semaphores that were held by a dead process.
|
||||
* On systems that do not support process-shared POSIX unnamed semaphores,
|
||||
* they can be emulated using pipes.
|
||||
* them dies, they are released automatically, and that (unlike fcntl
|
||||
* record locking) lock to the thread, not to the process.
|
||||
* NSPR doesn't provide that.
|
||||
* Windows has mutexes that meet that description, but they're not portable.
|
||||
* POSIX mutexes are not automatically released when the holder dies,
|
||||
* and other processes/threads cannot release the mutex on behalf of the
|
||||
* dead holder.
|
||||
* POSIX semaphores can be used to accomplish this on systems that implement
|
||||
* process-shared unnamed POSIX semaphores, because a watchdog thread can
|
||||
* discover and release semaphores that were held by a dead process.
|
||||
* On systems that do not support process-shared POSIX unnamed semaphores,
|
||||
* they can be emulated using pipes.
|
||||
* The performance cost of doing that is not yet measured.
|
||||
*
|
||||
* So, this API looks a lot like POSIX pthread mutexes.
|
||||
|
@ -34,8 +34,8 @@
|
|||
|
||||
#include <wtypes.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
PRBool isMultiProcess;
|
||||
#ifdef WINNT
|
||||
/* on WINNT we need both the PRLock and the Win32 mutex for fibers */
|
||||
|
@ -43,25 +43,25 @@ typedef struct
|
|||
#else
|
||||
union {
|
||||
#endif
|
||||
PRLock* sslLock;
|
||||
PRLock *sslLock;
|
||||
HANDLE sslMutx;
|
||||
} u;
|
||||
} sslMutex;
|
||||
|
||||
typedef int sslPID;
|
||||
typedef int sslPID;
|
||||
|
||||
#elif defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prtypes.h"
|
||||
|
||||
typedef struct {
|
||||
typedef struct {
|
||||
PRBool isMultiProcess;
|
||||
union {
|
||||
PRLock* sslLock;
|
||||
PRLock *sslLock;
|
||||
struct {
|
||||
int mPipes[3];
|
||||
PRInt32 nWaiters;
|
||||
int mPipes[3];
|
||||
PRInt32 nWaiters;
|
||||
} pipeStr;
|
||||
} u;
|
||||
} sslMutex;
|
||||
|
@ -70,15 +70,15 @@ typedef pid_t sslPID;
|
|||
/* other types of unix, except OS X */
|
||||
#elif defined(XP_UNIX) && !defined(DARWIN)
|
||||
|
||||
#include <sys/types.h> /* for pid_t */
|
||||
#include <semaphore.h> /* for sem_t, and sem_* functions */
|
||||
#include <sys/types.h> /* for pid_t */
|
||||
#include <semaphore.h> /* for sem_t, and sem_* functions */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
{
|
||||
PRBool isMultiProcess;
|
||||
union {
|
||||
PRLock* sslLock;
|
||||
sem_t sem;
|
||||
PRLock *sslLock;
|
||||
sem_t sem;
|
||||
} u;
|
||||
} sslMutex;
|
||||
|
||||
|
@ -88,10 +88,10 @@ typedef pid_t sslPID;
|
|||
|
||||
/* what platform is this ?? */
|
||||
|
||||
typedef struct {
|
||||
typedef struct {
|
||||
PRBool isMultiProcess;
|
||||
union {
|
||||
PRLock* sslLock;
|
||||
PRLock *sslLock;
|
||||
/* include cross-process locking mechanism here */
|
||||
} u;
|
||||
} sslMutex;
|
||||
|
@ -111,7 +111,7 @@ SEC_BEGIN_PROTOS
|
|||
extern SECStatus sslMutex_Init(sslMutex *sem, int shared);
|
||||
|
||||
/* 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
|
||||
* with the current process. Leave any shared resources (including the state of
|
||||
* shared memory) intact. */
|
||||
extern SECStatus sslMutex_Destroy(sslMutex *sem, PRBool processLocal);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* This file implements the CLIENT Session ID cache.
|
||||
/*
|
||||
* This file implements the CLIENT Session ID cache.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|
@ -22,18 +22,18 @@ PRUint32 ssl_sid_timeout = 100;
|
|||
PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
|
||||
|
||||
static sslSessionID *cache = NULL;
|
||||
static PZLock * cacheLock = NULL;
|
||||
static PZLock *cacheLock = NULL;
|
||||
|
||||
/* sids can be in one of 4 states:
|
||||
*
|
||||
* never_cached, created, but not yet put into cache.
|
||||
* in_client_cache, in the client cache's linked list.
|
||||
* in_server_cache, entry came from the server's cache file.
|
||||
* invalid_cache has been removed from the cache.
|
||||
* never_cached, created, but not yet put into cache.
|
||||
* in_client_cache, in the client cache's linked list.
|
||||
* in_server_cache, entry came from the server's cache file.
|
||||
* invalid_cache has been removed from the cache.
|
||||
*/
|
||||
|
||||
#define LOCK_CACHE lock_cache()
|
||||
#define UNLOCK_CACHE PZ_Unlock(cacheLock)
|
||||
#define LOCK_CACHE lock_cache()
|
||||
#define UNLOCK_CACHE PZ_Unlock(cacheLock)
|
||||
|
||||
static SECStatus
|
||||
ssl_InitClientSessionCacheLock(void)
|
||||
|
@ -62,7 +62,7 @@ FreeSessionCacheLocks()
|
|||
SECStatus rv1, rv2;
|
||||
rv1 = ssl_FreeSymWrapKeysLock();
|
||||
rv2 = ssl_FreeClientSessionCacheLock();
|
||||
if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) {
|
||||
if ((SECSuccess == rv1) && (SECSuccess == rv2)) {
|
||||
return SECSuccess;
|
||||
}
|
||||
return SECFailure;
|
||||
|
@ -75,7 +75,7 @@ InitSessionCacheLocks(void)
|
|||
PRErrorCode rc;
|
||||
rv1 = ssl_InitSymWrapKeysLock();
|
||||
rv2 = ssl_InitClientSessionCacheLock();
|
||||
if ( (SECSuccess == rv1) && (SECSuccess == rv2) ) {
|
||||
if ((SECSuccess == rv1) && (SECSuccess == rv2)) {
|
||||
return SECSuccess;
|
||||
}
|
||||
rc = PORT_GetError();
|
||||
|
@ -101,7 +101,8 @@ ssl_FreeSessionCacheLocks()
|
|||
static PRCallOnceType lockOnce;
|
||||
|
||||
/* free the session cache locks if they were initialized lazily */
|
||||
static SECStatus ssl_ShutdownLocks(void* appData, void* nssData)
|
||||
static SECStatus
|
||||
ssl_ShutdownLocks(void *appData, void *nssData)
|
||||
{
|
||||
PORT_Assert(PR_FALSE == LocksInitializedEarly);
|
||||
if (LocksInitializedEarly) {
|
||||
|
@ -113,7 +114,8 @@ static SECStatus ssl_ShutdownLocks(void* appData, void* nssData)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRStatus initSessionCacheLocksLazily(void)
|
||||
static PRStatus
|
||||
initSessionCacheLocksLazily(void)
|
||||
{
|
||||
SECStatus rv = InitSessionCacheLocks();
|
||||
if (SECSuccess != rv) {
|
||||
|
@ -139,10 +141,11 @@ ssl_InitSessionCacheLocks(PRBool lazyInit)
|
|||
|
||||
if (lazyInit) {
|
||||
return (PR_SUCCESS ==
|
||||
PR_CallOnce(&lockOnce, initSessionCacheLocksLazily)) ?
|
||||
SECSuccess : SECFailure;
|
||||
PR_CallOnce(&lockOnce, initSessionCacheLocksLazily))
|
||||
? SECSuccess
|
||||
: SECFailure;
|
||||
}
|
||||
|
||||
|
||||
if (SECSuccess == InitSessionCacheLocks()) {
|
||||
LocksInitializedEarly = PR_TRUE;
|
||||
return SECSuccess;
|
||||
|
@ -151,7 +154,7 @@ ssl_InitSessionCacheLocks(PRBool lazyInit)
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
lock_cache(void)
|
||||
{
|
||||
ssl_InitSessionCacheLocks(PR_TRUE);
|
||||
|
@ -169,9 +172,10 @@ ssl_DestroySID(sslSessionID *sid)
|
|||
PORT_Assert(sid->cached != in_client_cache);
|
||||
|
||||
if (sid->version < SSL_LIBRARY_VERSION_3_0) {
|
||||
SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
|
||||
} else {
|
||||
SECITEM_ZfreeItem(&sid->u.ssl2.masterKey, PR_FALSE);
|
||||
SECITEM_ZfreeItem(&sid->u.ssl2.cipherArg, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
|
||||
SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
|
||||
PR_FALSE);
|
||||
|
@ -189,45 +193,45 @@ ssl_DestroySID(sslSessionID *sid)
|
|||
}
|
||||
|
||||
if (sid->peerID != NULL)
|
||||
PORT_Free((void *)sid->peerID); /* CONST */
|
||||
PORT_Free((void *)sid->peerID); /* CONST */
|
||||
|
||||
if (sid->urlSvrName != NULL)
|
||||
PORT_Free((void *)sid->urlSvrName); /* CONST */
|
||||
PORT_Free((void *)sid->urlSvrName); /* CONST */
|
||||
|
||||
if ( sid->peerCert ) {
|
||||
CERT_DestroyCertificate(sid->peerCert);
|
||||
if (sid->peerCert) {
|
||||
CERT_DestroyCertificate(sid->peerCert);
|
||||
}
|
||||
if (sid->peerCertStatus.items) {
|
||||
SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
|
||||
}
|
||||
|
||||
if ( sid->localCert ) {
|
||||
CERT_DestroyCertificate(sid->localCert);
|
||||
if (sid->localCert) {
|
||||
CERT_DestroyCertificate(sid->localCert);
|
||||
}
|
||||
|
||||
|
||||
PORT_ZFree(sid, sizeof(sslSessionID));
|
||||
}
|
||||
|
||||
/* BEWARE: This function gets called for both client and server SIDs !!
|
||||
* Decrement reference count, and
|
||||
* free sid if ref count is zero, and sid is not in the cache.
|
||||
* Does NOT remove from the cache first.
|
||||
* Decrement reference count, and
|
||||
* free sid if ref count is zero, and sid is not in the cache.
|
||||
* Does NOT remove from the cache first.
|
||||
* If the sid is still in the cache, it is left there until next time
|
||||
* the cache list is traversed.
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
ssl_FreeLockedSID(sslSessionID *sid)
|
||||
{
|
||||
PORT_Assert(sid->references >= 1);
|
||||
if (--sid->references == 0) {
|
||||
ssl_DestroySID(sid);
|
||||
ssl_DestroySID(sid);
|
||||
}
|
||||
}
|
||||
|
||||
/* BEWARE: This function gets called for both client and server SIDs !!
|
||||
* Decrement reference count, and
|
||||
* free sid if ref count is zero, and sid is not in the cache.
|
||||
* Does NOT remove from the cache first.
|
||||
* Decrement reference count, and
|
||||
* free sid if ref count is zero, and sid is not in the cache.
|
||||
* Does NOT remove from the cache first.
|
||||
* These locks are necessary because the sid _might_ be in the cache list.
|
||||
*/
|
||||
void
|
||||
|
@ -247,55 +251,56 @@ ssl_FreeSID(sslSessionID *sid)
|
|||
*/
|
||||
|
||||
sslSessionID *
|
||||
ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
|
||||
const char * urlSvrName)
|
||||
ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
|
||||
const char *urlSvrName)
|
||||
{
|
||||
sslSessionID **sidp;
|
||||
sslSessionID * sid;
|
||||
PRUint32 now;
|
||||
sslSessionID *sid;
|
||||
PRUint32 now;
|
||||
|
||||
if (!urlSvrName)
|
||||
return NULL;
|
||||
return NULL;
|
||||
now = ssl_Time();
|
||||
LOCK_CACHE;
|
||||
sidp = &cache;
|
||||
while ((sid = *sidp) != 0) {
|
||||
PORT_Assert(sid->cached == in_client_cache);
|
||||
PORT_Assert(sid->references >= 1);
|
||||
PORT_Assert(sid->cached == in_client_cache);
|
||||
PORT_Assert(sid->references >= 1);
|
||||
|
||||
SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid));
|
||||
SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid));
|
||||
|
||||
if (sid->expirationTime < now) {
|
||||
/*
|
||||
** This session-id timed out.
|
||||
** Don't even care who it belongs to, blow it out of our cache.
|
||||
*/
|
||||
SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d",
|
||||
now - sid->creationTime, sid->references));
|
||||
if (sid->expirationTime < now) {
|
||||
/*
|
||||
** This session-id timed out.
|
||||
** Don't even care who it belongs to, blow it out of our cache.
|
||||
*/
|
||||
SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d",
|
||||
now - sid->creationTime, sid->references));
|
||||
|
||||
*sidp = sid->next; /* delink it from the list. */
|
||||
sid->cached = invalid_cache; /* mark not on list. */
|
||||
ssl_FreeLockedSID(sid); /* drop ref count, free. */
|
||||
} else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */
|
||||
(sid->port == port) && /* server port matches */
|
||||
/* proxy (peerID) matches */
|
||||
(((peerID == NULL) && (sid->peerID == NULL)) ||
|
||||
((peerID != NULL) && (sid->peerID != NULL) &&
|
||||
PORT_Strcmp(sid->peerID, peerID) == 0)) &&
|
||||
/* is cacheable */
|
||||
(sid->version < SSL_LIBRARY_VERSION_3_0 ||
|
||||
sid->u.ssl3.keys.resumable) &&
|
||||
/* server hostname matches. */
|
||||
(sid->urlSvrName != NULL) &&
|
||||
(0 == PORT_Strcmp(urlSvrName, sid->urlSvrName))
|
||||
) {
|
||||
/* Hit */
|
||||
sid->lastAccessTime = now;
|
||||
sid->references++;
|
||||
break;
|
||||
} else {
|
||||
sidp = &sid->next;
|
||||
}
|
||||
*sidp = sid->next; /* delink it from the list. */
|
||||
sid->cached = invalid_cache; /* mark not on list. */
|
||||
ssl_FreeLockedSID(sid); /* drop ref count, free. */
|
||||
}
|
||||
else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */
|
||||
(sid->port == port) && /* server port matches */
|
||||
/* proxy (peerID) matches */
|
||||
(((peerID == NULL) && (sid->peerID == NULL)) ||
|
||||
((peerID != NULL) && (sid->peerID != NULL) &&
|
||||
PORT_Strcmp(sid->peerID, peerID) == 0)) &&
|
||||
/* is cacheable */
|
||||
(sid->version < SSL_LIBRARY_VERSION_3_0 ||
|
||||
sid->u.ssl3.keys.resumable) &&
|
||||
/* server hostname matches. */
|
||||
(sid->urlSvrName != NULL) &&
|
||||
(0 == PORT_Strcmp(urlSvrName, sid->urlSvrName))) {
|
||||
/* Hit */
|
||||
sid->lastAccessTime = now;
|
||||
sid->references++;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
sidp = &sid->next;
|
||||
}
|
||||
}
|
||||
UNLOCK_CACHE;
|
||||
return sid;
|
||||
|
@ -305,19 +310,19 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
|
|||
** Add an sid to the cache or return a previously cached entry to the cache.
|
||||
** Although this is static, it is called via ss->sec.cache().
|
||||
*/
|
||||
static void
|
||||
static void
|
||||
CacheSID(sslSessionID *sid)
|
||||
{
|
||||
PRUint32 expirationPeriod;
|
||||
PRUint32 expirationPeriod;
|
||||
|
||||
PORT_Assert(sid->cached == never_cached);
|
||||
|
||||
SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
|
||||
"time=%x cached=%d",
|
||||
sid, sid->cached, sid->addr.pr_s6_addr32[0],
|
||||
sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2],
|
||||
sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime,
|
||||
sid->cached));
|
||||
"time=%x cached=%d",
|
||||
sid, sid->cached, sid->addr.pr_s6_addr32[0],
|
||||
sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2],
|
||||
sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime,
|
||||
sid->cached));
|
||||
|
||||
if (!sid->urlSvrName) {
|
||||
/* don't cache this SID because it can never be matched */
|
||||
|
@ -326,41 +331,42 @@ CacheSID(sslSessionID *sid)
|
|||
|
||||
/* XXX should be different trace for version 2 vs. version 3 */
|
||||
if (sid->version < SSL_LIBRARY_VERSION_3_0) {
|
||||
expirationPeriod = ssl_sid_timeout;
|
||||
PRINT_BUF(8, (0, "sessionID:",
|
||||
sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)));
|
||||
PRINT_BUF(8, (0, "masterKey:",
|
||||
sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len));
|
||||
PRINT_BUF(8, (0, "cipherArg:",
|
||||
sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len));
|
||||
} else {
|
||||
if (sid->u.ssl3.sessionIDLength == 0 &&
|
||||
sid->u.ssl3.locked.sessionTicket.ticket.data == NULL)
|
||||
return;
|
||||
expirationPeriod = ssl_sid_timeout;
|
||||
PRINT_BUF(8, (0, "sessionID:",
|
||||
sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)));
|
||||
PRINT_BUF(8, (0, "masterKey:",
|
||||
sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len));
|
||||
PRINT_BUF(8, (0, "cipherArg:",
|
||||
sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len));
|
||||
}
|
||||
else {
|
||||
if (sid->u.ssl3.sessionIDLength == 0 &&
|
||||
sid->u.ssl3.locked.sessionTicket.ticket.data == NULL)
|
||||
return;
|
||||
|
||||
/* Client generates the SessionID if this was a stateless resume. */
|
||||
if (sid->u.ssl3.sessionIDLength == 0) {
|
||||
SECStatus rv;
|
||||
rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
|
||||
SSL3_SESSIONID_BYTES);
|
||||
if (rv != SECSuccess)
|
||||
return;
|
||||
sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
|
||||
}
|
||||
expirationPeriod = ssl3_sid_timeout;
|
||||
PRINT_BUF(8, (0, "sessionID:",
|
||||
sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
|
||||
/* Client generates the SessionID if this was a stateless resume. */
|
||||
if (sid->u.ssl3.sessionIDLength == 0) {
|
||||
SECStatus rv;
|
||||
rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
|
||||
SSL3_SESSIONID_BYTES);
|
||||
if (rv != SECSuccess)
|
||||
return;
|
||||
sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
|
||||
}
|
||||
expirationPeriod = ssl3_sid_timeout;
|
||||
PRINT_BUF(8, (0, "sessionID:",
|
||||
sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));
|
||||
|
||||
sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
|
||||
if (!sid->u.ssl3.lock) {
|
||||
return;
|
||||
}
|
||||
sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
|
||||
if (!sid->u.ssl3.lock) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0);
|
||||
if (!sid->creationTime)
|
||||
sid->lastAccessTime = sid->creationTime = ssl_Time();
|
||||
sid->lastAccessTime = sid->creationTime = ssl_Time();
|
||||
if (!sid->expirationTime)
|
||||
sid->expirationTime = sid->creationTime + expirationPeriod;
|
||||
sid->expirationTime = sid->creationTime + expirationPeriod;
|
||||
|
||||
/*
|
||||
* Put sid into the cache. Bump reference count to indicate that
|
||||
|
@ -370,12 +376,12 @@ CacheSID(sslSessionID *sid)
|
|||
LOCK_CACHE;
|
||||
sid->references++;
|
||||
sid->cached = in_client_cache;
|
||||
sid->next = cache;
|
||||
cache = sid;
|
||||
sid->next = cache;
|
||||
cache = sid;
|
||||
UNLOCK_CACHE;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* If sid "zap" is in the cache,
|
||||
* removes sid from cache, and decrements reference count.
|
||||
* Caller must hold cache lock.
|
||||
|
@ -387,43 +393,43 @@ UncacheSID(sslSessionID *zap)
|
|||
sslSessionID *sid;
|
||||
|
||||
if (zap->cached != in_client_cache) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
SSL_TRC(8,("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
|
||||
"time=%x cipher=%d",
|
||||
zap, zap->cached, zap->addr.pr_s6_addr32[0],
|
||||
zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
|
||||
zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
|
||||
zap->u.ssl2.cipherType));
|
||||
SSL_TRC(8, ("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
|
||||
"time=%x cipher=%d",
|
||||
zap, zap->cached, zap->addr.pr_s6_addr32[0],
|
||||
zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
|
||||
zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
|
||||
zap->u.ssl2.cipherType));
|
||||
if (zap->version < SSL_LIBRARY_VERSION_3_0) {
|
||||
PRINT_BUF(8, (0, "sessionID:",
|
||||
zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
|
||||
PRINT_BUF(8, (0, "masterKey:",
|
||||
zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
|
||||
PRINT_BUF(8, (0, "cipherArg:",
|
||||
zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
|
||||
PRINT_BUF(8, (0, "sessionID:",
|
||||
zap->u.ssl2.sessionID, sizeof(zap->u.ssl2.sessionID)));
|
||||
PRINT_BUF(8, (0, "masterKey:",
|
||||
zap->u.ssl2.masterKey.data, zap->u.ssl2.masterKey.len));
|
||||
PRINT_BUF(8, (0, "cipherArg:",
|
||||
zap->u.ssl2.cipherArg.data, zap->u.ssl2.cipherArg.len));
|
||||
}
|
||||
|
||||
/* See if it's in the cache, if so nuke it */
|
||||
while ((sid = *sidp) != 0) {
|
||||
if (sid == zap) {
|
||||
/*
|
||||
** Bingo. Reduce reference count by one so that when
|
||||
** everyone is done with the sid we can free it up.
|
||||
*/
|
||||
*sidp = zap->next;
|
||||
zap->cached = invalid_cache;
|
||||
ssl_FreeLockedSID(zap);
|
||||
return;
|
||||
}
|
||||
sidp = &sid->next;
|
||||
if (sid == zap) {
|
||||
/*
|
||||
** Bingo. Reduce reference count by one so that when
|
||||
** everyone is done with the sid we can free it up.
|
||||
*/
|
||||
*sidp = zap->next;
|
||||
zap->cached = invalid_cache;
|
||||
ssl_FreeLockedSID(zap);
|
||||
return;
|
||||
}
|
||||
sidp = &sid->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* If sid "zap" is in the cache,
|
||||
* removes sid from cache, and decrements reference count.
|
||||
* Although this function is static, it is called externally via
|
||||
* Although this function is static, it is called externally via
|
||||
* ss->sec.uncache().
|
||||
*/
|
||||
static void
|
||||
|
@ -432,19 +438,19 @@ LockAndUncacheSID(sslSessionID *zap)
|
|||
LOCK_CACHE;
|
||||
UncacheSID(zap);
|
||||
UNLOCK_CACHE;
|
||||
|
||||
}
|
||||
|
||||
/* choose client or server cache functions for this sslsocket. */
|
||||
void
|
||||
void
|
||||
ssl_ChooseSessionIDProcs(sslSecurityInfo *sec)
|
||||
{
|
||||
if (sec->isServer) {
|
||||
sec->cache = ssl_sid_cache;
|
||||
sec->uncache = ssl_sid_uncache;
|
||||
} else {
|
||||
sec->cache = CacheSID;
|
||||
sec->uncache = LockAndUncacheSID;
|
||||
sec->cache = ssl_sid_cache;
|
||||
sec->uncache = ssl_sid_uncache;
|
||||
}
|
||||
else {
|
||||
sec->cache = CacheSID;
|
||||
sec->uncache = LockAndUncacheSID;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,8 +459,8 @@ void
|
|||
SSL_ClearSessionCache(void)
|
||||
{
|
||||
LOCK_CACHE;
|
||||
while(cache != NULL)
|
||||
UncacheSID(cache);
|
||||
while (cache != NULL)
|
||||
UncacheSID(cache);
|
||||
UNLOCK_CACHE;
|
||||
}
|
||||
|
||||
|
@ -464,7 +470,7 @@ ssl_Time(void)
|
|||
{
|
||||
PRUint32 myTime;
|
||||
#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
|
||||
myTime = time(NULL); /* accurate until the year 2038. */
|
||||
myTime = time(NULL); /* accurate until the year 2038. */
|
||||
#else
|
||||
/* portable, but possibly slower */
|
||||
PRTime now;
|
||||
|
@ -493,11 +499,11 @@ ssl3_SetSIDSessionTicket(sslSessionID *sid,
|
|||
* yet, so no locking is needed.
|
||||
*/
|
||||
if (sid->u.ssl3.lock) {
|
||||
PR_RWLock_Wlock(sid->u.ssl3.lock);
|
||||
if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
|
||||
SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
|
||||
PR_FALSE);
|
||||
}
|
||||
PR_RWLock_Wlock(sid->u.ssl3.lock);
|
||||
if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
|
||||
SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
|
||||
PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data);
|
||||
|
@ -508,6 +514,6 @@ ssl3_SetSIDSessionTicket(sslSessionID *sid,
|
|||
newSessionTicket->ticket.len = 0;
|
||||
|
||||
if (sid->u.ssl3.lock) {
|
||||
PR_RWLock_Unlock(sid->u.ssl3.lock);
|
||||
PR_RWLock_Unlock(sid->u.ssl3.lock);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#ifndef __sslproto_h_
|
||||
#define __sslproto_h_
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
/* All versions less than 3_0 are treated as SSL version 2 */
|
||||
#define SSL_LIBRARY_VERSION_2 0x0002
|
||||
#define SSL_LIBRARY_VERSION_3_0 0x0300
|
||||
|
@ -260,6 +262,10 @@
|
|||
#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F
|
||||
#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031
|
||||
|
||||
#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8
|
||||
#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9
|
||||
#define TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA
|
||||
|
||||
/* Netscape "experimental" cipher suites. */
|
||||
#define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0
|
||||
#define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1
|
||||
|
@ -275,4 +281,6 @@
|
|||
#define SRTP_NULL_HMAC_SHA1_80 0x0005
|
||||
#define SRTP_NULL_HMAC_SHA1_32 0x0006
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#endif /* __sslproto_h_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Accessor functions for SSLSocket private members.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|
@ -13,100 +13,98 @@
|
|||
/* given PRFileDesc, returns a copy of certificate associated with the socket
|
||||
* the caller should delete the cert when done with SSL_DestroyCertificate
|
||||
*/
|
||||
CERTCertificate *
|
||||
SSL_RevealCert(PRFileDesc * fd)
|
||||
CERTCertificate *
|
||||
SSL_RevealCert(PRFileDesc *fd)
|
||||
{
|
||||
CERTCertificate * cert = NULL;
|
||||
sslSocket * sslsocket = NULL;
|
||||
CERTCertificate *cert = NULL;
|
||||
sslSocket *sslsocket = NULL;
|
||||
|
||||
sslsocket = ssl_FindSocket(fd);
|
||||
|
||||
/* CERT_DupCertificate increases reference count and returns pointer to
|
||||
* the same cert
|
||||
*/
|
||||
if (sslsocket && sslsocket->sec.peerCert)
|
||||
cert = CERT_DupCertificate(sslsocket->sec.peerCert);
|
||||
|
||||
return cert;
|
||||
sslsocket = ssl_FindSocket(fd);
|
||||
|
||||
/* CERT_DupCertificate increases reference count and returns pointer to
|
||||
* the same cert
|
||||
*/
|
||||
if (sslsocket && sslsocket->sec.peerCert)
|
||||
cert = CERT_DupCertificate(sslsocket->sec.peerCert);
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
/* given PRFileDesc, returns a pointer to PinArg associated with the socket
|
||||
*/
|
||||
void *
|
||||
SSL_RevealPinArg(PRFileDesc * fd)
|
||||
void *
|
||||
SSL_RevealPinArg(PRFileDesc *fd)
|
||||
{
|
||||
sslSocket * sslsocket = NULL;
|
||||
void * PinArg = NULL;
|
||||
|
||||
sslsocket = ssl_FindSocket(fd);
|
||||
|
||||
/* is pkcs11PinArg part of the sslSocket or sslSecurityInfo ? */
|
||||
if (sslsocket)
|
||||
PinArg = sslsocket->pkcs11PinArg;
|
||||
|
||||
return PinArg;
|
||||
}
|
||||
sslSocket *sslsocket = NULL;
|
||||
void *PinArg = NULL;
|
||||
|
||||
sslsocket = ssl_FindSocket(fd);
|
||||
|
||||
/* is pkcs11PinArg part of the sslSocket or sslSecurityInfo ? */
|
||||
if (sslsocket)
|
||||
PinArg = sslsocket->pkcs11PinArg;
|
||||
|
||||
return PinArg;
|
||||
}
|
||||
|
||||
/* given PRFileDesc, returns a pointer to the URL associated with the socket
|
||||
* the caller should free url when done
|
||||
*/
|
||||
char *
|
||||
SSL_RevealURL(PRFileDesc * fd)
|
||||
char *
|
||||
SSL_RevealURL(PRFileDesc *fd)
|
||||
{
|
||||
sslSocket * sslsocket = NULL;
|
||||
char * url = NULL;
|
||||
sslSocket *sslsocket = NULL;
|
||||
char *url = NULL;
|
||||
|
||||
sslsocket = ssl_FindSocket(fd);
|
||||
|
||||
if (sslsocket && sslsocket->url)
|
||||
url = PL_strdup(sslsocket->url);
|
||||
|
||||
return url;
|
||||
sslsocket = ssl_FindSocket(fd);
|
||||
|
||||
if (sslsocket && sslsocket->url)
|
||||
url = PL_strdup(sslsocket->url);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
/* given PRFileDesc, returns status information related to extensions
|
||||
/* given PRFileDesc, returns status information related to extensions
|
||||
* negotiated with peer during the handshake.
|
||||
*/
|
||||
|
||||
SECStatus
|
||||
SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
|
||||
SSL_HandshakeNegotiatedExtension(PRFileDesc *socket,
|
||||
SSLExtensionType extId,
|
||||
PRBool *pYes)
|
||||
{
|
||||
/* some decisions derived from SSL_GetChannelInfo */
|
||||
sslSocket * sslsocket = NULL;
|
||||
/* some decisions derived from SSL_GetChannelInfo */
|
||||
sslSocket *sslsocket = NULL;
|
||||
|
||||
if (!pYes) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
sslsocket = ssl_FindSocket(socket);
|
||||
if (!sslsocket) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeNegotiatedExtension",
|
||||
SSL_GETPID(), socket));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*pYes = PR_FALSE;
|
||||
|
||||
/* according to public API SSL_GetChannelInfo, this doesn't need a lock */
|
||||
if (sslsocket->opt.useSecurity) {
|
||||
if (sslsocket->ssl3.initialized) { /* SSL3 and TLS */
|
||||
/* now we know this socket went through ssl3_InitState() and
|
||||
* ss->xtnData got initialized, which is the only member accessed by
|
||||
* ssl3_ExtensionNegotiated();
|
||||
* Member xtnData appears to get accessed in functions that handle
|
||||
* the handshake (hello messages and extension sending),
|
||||
* therefore the handshake lock should be sufficient.
|
||||
*/
|
||||
ssl_GetSSL3HandshakeLock(sslsocket);
|
||||
*pYes = ssl3_ExtensionNegotiated(sslsocket, extId);
|
||||
ssl_ReleaseSSL3HandshakeLock(sslsocket);
|
||||
if (!pYes) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
sslsocket = ssl_FindSocket(socket);
|
||||
if (!sslsocket) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeNegotiatedExtension",
|
||||
SSL_GETPID(), socket));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*pYes = PR_FALSE;
|
||||
|
||||
/* according to public API SSL_GetChannelInfo, this doesn't need a lock */
|
||||
if (sslsocket->opt.useSecurity) {
|
||||
if (sslsocket->ssl3.initialized) { /* SSL3 and TLS */
|
||||
/* now we know this socket went through ssl3_InitState() and
|
||||
* ss->xtnData got initialized, which is the only member accessed by
|
||||
* ssl3_ExtensionNegotiated();
|
||||
* Member xtnData appears to get accessed in functions that handle
|
||||
* the handshake (hello messages and extension sending),
|
||||
* therefore the handshake lock should be sufficient.
|
||||
*/
|
||||
ssl_GetSSL3HandshakeLock(sslsocket);
|
||||
*pYes = ssl3_ExtensionNegotiated(sslsocket, extId);
|
||||
ssl_ReleaseSSL3HandshakeLock(sslsocket);
|
||||
}
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -36,12 +36,12 @@ typedef struct SSL3StatisticsStr {
|
|||
|
||||
/* Key Exchange algorithm values */
|
||||
typedef enum {
|
||||
ssl_kea_null = 0,
|
||||
ssl_kea_rsa = 1,
|
||||
ssl_kea_dh = 2,
|
||||
ssl_kea_fortezza = 3, /* deprecated, now unused */
|
||||
ssl_kea_ecdh = 4,
|
||||
ssl_kea_size /* number of ssl_kea_ algorithms */
|
||||
ssl_kea_null = 0,
|
||||
ssl_kea_rsa = 1,
|
||||
ssl_kea_dh = 2,
|
||||
ssl_kea_fortezza = 3, /* deprecated, now unused */
|
||||
ssl_kea_ecdh = 4,
|
||||
ssl_kea_size /* number of ssl_kea_ algorithms */
|
||||
} SSLKEAType;
|
||||
|
||||
/* The following defines are for backwards compatibility.
|
||||
|
@ -49,21 +49,20 @@ typedef enum {
|
|||
** programs that use the kt_ symbols should convert to the ssl_kt_ symbols
|
||||
** soon.
|
||||
*/
|
||||
#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_ecdh ssl_kea_ecdh
|
||||
#define kt_kea_size ssl_kea_size
|
||||
|
||||
#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_ecdh ssl_kea_ecdh
|
||||
#define kt_kea_size ssl_kea_size
|
||||
|
||||
/* Values of this enum match the SignatureAlgorithm enum from
|
||||
* https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
|
||||
typedef enum {
|
||||
ssl_sign_null = 0, /* "anonymous" in TLS */
|
||||
ssl_sign_rsa = 1,
|
||||
ssl_sign_dsa = 2,
|
||||
ssl_sign_ecdsa = 3
|
||||
ssl_sign_null = 0, /* "anonymous" in TLS */
|
||||
ssl_sign_rsa = 1,
|
||||
ssl_sign_dsa = 2,
|
||||
ssl_sign_ecdsa = 3
|
||||
} SSLSignType;
|
||||
|
||||
/* Values of this enum match the HashAlgorithm enum from
|
||||
|
@ -86,80 +85,86 @@ typedef struct SSLSignatureAndHashAlgStr {
|
|||
} SSLSignatureAndHashAlg;
|
||||
|
||||
typedef enum {
|
||||
ssl_auth_null = 0,
|
||||
ssl_auth_rsa = 1,
|
||||
ssl_auth_dsa = 2,
|
||||
ssl_auth_kea = 3,
|
||||
ssl_auth_ecdsa = 4
|
||||
ssl_auth_null = 0,
|
||||
ssl_auth_rsa = 1,
|
||||
ssl_auth_dsa = 2,
|
||||
ssl_auth_kea = 3,
|
||||
ssl_auth_ecdsa = 4
|
||||
} SSLAuthType;
|
||||
|
||||
typedef enum {
|
||||
ssl_calg_null = 0,
|
||||
ssl_calg_rc4 = 1,
|
||||
ssl_calg_rc2 = 2,
|
||||
ssl_calg_des = 3,
|
||||
ssl_calg_3des = 4,
|
||||
ssl_calg_idea = 5,
|
||||
ssl_calg_fortezza = 6, /* deprecated, now unused */
|
||||
ssl_calg_aes = 7,
|
||||
ssl_calg_null = 0,
|
||||
ssl_calg_rc4 = 1,
|
||||
ssl_calg_rc2 = 2,
|
||||
ssl_calg_des = 3,
|
||||
ssl_calg_3des = 4,
|
||||
ssl_calg_idea = 5,
|
||||
ssl_calg_fortezza = 6, /* deprecated, now unused */
|
||||
ssl_calg_aes = 7,
|
||||
ssl_calg_camellia = 8,
|
||||
ssl_calg_seed = 9,
|
||||
ssl_calg_aes_gcm = 10
|
||||
ssl_calg_seed = 9,
|
||||
ssl_calg_aes_gcm = 10,
|
||||
ssl_calg_chacha20 = 11
|
||||
} SSLCipherAlgorithm;
|
||||
|
||||
typedef enum {
|
||||
ssl_mac_null = 0,
|
||||
ssl_mac_md5 = 1,
|
||||
ssl_mac_sha = 2,
|
||||
ssl_hmac_md5 = 3, /* TLS HMAC version of mac_md5 */
|
||||
ssl_hmac_sha = 4, /* TLS HMAC version of mac_sha */
|
||||
ssl_hmac_sha256 = 5,
|
||||
ssl_mac_aead = 6
|
||||
typedef enum {
|
||||
ssl_mac_null = 0,
|
||||
ssl_mac_md5 = 1,
|
||||
ssl_mac_sha = 2,
|
||||
ssl_hmac_md5 = 3, /* TLS HMAC version of mac_md5 */
|
||||
ssl_hmac_sha = 4, /* TLS HMAC version of mac_sha */
|
||||
ssl_hmac_sha256 = 5,
|
||||
ssl_mac_aead = 6
|
||||
} SSLMACAlgorithm;
|
||||
|
||||
typedef enum {
|
||||
ssl_compression_null = 0,
|
||||
ssl_compression_deflate = 1 /* RFC 3749 */
|
||||
ssl_compression_deflate = 1 /* RFC 3749 */
|
||||
} SSLCompressionMethod;
|
||||
|
||||
typedef struct SSLChannelInfoStr {
|
||||
PRUint32 length;
|
||||
PRUint16 protocolVersion;
|
||||
PRUint16 cipherSuite;
|
||||
/* |length| is obsolete. On return, SSL_GetChannelInfo sets |length| to the
|
||||
* smaller of the |len| argument and the length of the struct. The caller
|
||||
* may ignore |length|. */
|
||||
PRUint32 length;
|
||||
PRUint16 protocolVersion;
|
||||
PRUint16 cipherSuite;
|
||||
|
||||
/* server authentication info */
|
||||
PRUint32 authKeyBits;
|
||||
PRUint32 authKeyBits;
|
||||
|
||||
/* key exchange algorithm info */
|
||||
PRUint32 keaKeyBits;
|
||||
PRUint32 keaKeyBits;
|
||||
|
||||
/* session info */
|
||||
PRUint32 creationTime; /* seconds since Jan 1, 1970 */
|
||||
PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */
|
||||
PRUint32 expirationTime; /* seconds since Jan 1, 1970 */
|
||||
PRUint32 sessionIDLength; /* up to 32 */
|
||||
PRUint8 sessionID [32];
|
||||
PRUint32 creationTime; /* seconds since Jan 1, 1970 */
|
||||
PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */
|
||||
PRUint32 expirationTime; /* seconds since Jan 1, 1970 */
|
||||
PRUint32 sessionIDLength; /* up to 32 */
|
||||
PRUint8 sessionID[32];
|
||||
|
||||
/* The following fields are added in NSS 3.12.5. */
|
||||
|
||||
/* compression method info */
|
||||
const char * compressionMethodName;
|
||||
const char* compressionMethodName;
|
||||
SSLCompressionMethod compressionMethod;
|
||||
|
||||
/* The following fields are added in NSS 3.21.
|
||||
* This field only has meaning in TLS < 1.3 and will be set to
|
||||
* PR_FALSE in TLS 1.3.
|
||||
*/
|
||||
PRBool extendedMasterSecretUsed;
|
||||
PRBool extendedMasterSecretUsed;
|
||||
} SSLChannelInfo;
|
||||
|
||||
/* Preliminary channel info */
|
||||
#define ssl_preinfo_version (1U << 0)
|
||||
#define ssl_preinfo_cipher_suite (1U << 1)
|
||||
#define ssl_preinfo_all (ssl_preinfo_version|ssl_preinfo_cipher_suite)
|
||||
#define ssl_preinfo_all (ssl_preinfo_version | ssl_preinfo_cipher_suite)
|
||||
|
||||
typedef struct SSLPreliminaryChannelInfoStr {
|
||||
/* This is set to the length of the struct. */
|
||||
/* |length| is obsolete. On return, SSL_GetPreliminaryChannelInfo sets
|
||||
* |length| to the smaller of the |len| argument and the length of the
|
||||
* struct. The caller may ignore |length|. */
|
||||
PRUint32 length;
|
||||
/* A bitfield over SSLPreliminaryValueSet that describes which
|
||||
* preliminary values are set (see ssl_preinfo_*). */
|
||||
|
@ -171,39 +176,42 @@ typedef struct SSLPreliminaryChannelInfoStr {
|
|||
} SSLPreliminaryChannelInfo;
|
||||
|
||||
typedef struct SSLCipherSuiteInfoStr {
|
||||
PRUint16 length;
|
||||
PRUint16 cipherSuite;
|
||||
/* |length| is obsolete. On return, SSL_GetCipherSuitelInfo sets |length|
|
||||
* to the smaller of the |len| argument and the length of the struct. The
|
||||
* caller may ignore |length|. */
|
||||
PRUint16 length;
|
||||
PRUint16 cipherSuite;
|
||||
|
||||
/* Cipher Suite Name */
|
||||
const char * cipherSuiteName;
|
||||
const char* cipherSuiteName;
|
||||
|
||||
/* server authentication info */
|
||||
const char * authAlgorithmName;
|
||||
SSLAuthType authAlgorithm;
|
||||
const char* authAlgorithmName;
|
||||
SSLAuthType authAlgorithm;
|
||||
|
||||
/* key exchange algorithm info */
|
||||
const char * keaTypeName;
|
||||
SSLKEAType keaType;
|
||||
const char* keaTypeName;
|
||||
SSLKEAType keaType;
|
||||
|
||||
/* symmetric encryption info */
|
||||
const char * symCipherName;
|
||||
SSLCipherAlgorithm symCipher;
|
||||
PRUint16 symKeyBits;
|
||||
PRUint16 symKeySpace;
|
||||
PRUint16 effectiveKeyBits;
|
||||
const char* symCipherName;
|
||||
SSLCipherAlgorithm symCipher;
|
||||
PRUint16 symKeyBits;
|
||||
PRUint16 symKeySpace;
|
||||
PRUint16 effectiveKeyBits;
|
||||
|
||||
/* MAC info */
|
||||
/* AEAD ciphers don't have a MAC. For an AEAD cipher, macAlgorithmName
|
||||
* is "AEAD", macAlgorithm is ssl_mac_aead, and macBits is the length in
|
||||
* bits of the authentication tag. */
|
||||
const char * macAlgorithmName;
|
||||
SSLMACAlgorithm macAlgorithm;
|
||||
PRUint16 macBits;
|
||||
const char* macAlgorithmName;
|
||||
SSLMACAlgorithm macAlgorithm;
|
||||
PRUint16 macBits;
|
||||
|
||||
PRUintn isFIPS : 1;
|
||||
PRUintn isExportable : 1;
|
||||
PRUintn nonStandard : 1;
|
||||
PRUintn reservedBits :29;
|
||||
PRUintn isFIPS : 1;
|
||||
PRUintn isExportable : 1;
|
||||
PRUintn nonStandard : 1;
|
||||
PRUintn reservedBits : 29;
|
||||
|
||||
} SSLCipherSuiteInfo;
|
||||
|
||||
|
@ -218,34 +226,34 @@ typedef struct SSLVersionRangeStr {
|
|||
} SSLVersionRange;
|
||||
|
||||
typedef enum {
|
||||
SSL_sni_host_name = 0,
|
||||
SSL_sni_host_name = 0,
|
||||
SSL_sni_type_total
|
||||
} SSLSniNameType;
|
||||
|
||||
/* Supported extensions. */
|
||||
/* Update SSL_MAX_EXTENSIONS whenever a new extension type is added. */
|
||||
typedef enum {
|
||||
ssl_server_name_xtn = 0,
|
||||
ssl_cert_status_xtn = 5,
|
||||
ssl_server_name_xtn = 0,
|
||||
ssl_cert_status_xtn = 5,
|
||||
#ifndef NSS_DISABLE_ECC
|
||||
ssl_elliptic_curves_xtn = 10,
|
||||
ssl_ec_point_formats_xtn = 11,
|
||||
ssl_elliptic_curves_xtn = 10,
|
||||
ssl_ec_point_formats_xtn = 11,
|
||||
#endif
|
||||
ssl_signature_algorithms_xtn = 13,
|
||||
ssl_use_srtp_xtn = 14,
|
||||
ssl_app_layer_protocol_xtn = 16,
|
||||
ssl_signature_algorithms_xtn = 13,
|
||||
ssl_use_srtp_xtn = 14,
|
||||
ssl_app_layer_protocol_xtn = 16,
|
||||
/* signed_certificate_timestamp extension, RFC 6962 */
|
||||
ssl_signed_cert_timestamp_xtn = 18,
|
||||
ssl_padding_xtn = 21,
|
||||
ssl_extended_master_secret_xtn = 23,
|
||||
ssl_session_ticket_xtn = 35,
|
||||
ssl_tls13_key_share_xtn = 40, /* unofficial TODO(ekr) */
|
||||
ssl_next_proto_nego_xtn = 13172,
|
||||
ssl_renegotiation_info_xtn = 0xff01,
|
||||
ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
|
||||
ssl_signed_cert_timestamp_xtn = 18,
|
||||
ssl_padding_xtn = 21,
|
||||
ssl_extended_master_secret_xtn = 23,
|
||||
ssl_session_ticket_xtn = 35,
|
||||
ssl_tls13_key_share_xtn = 40, /* unofficial TODO(ekr) */
|
||||
ssl_next_proto_nego_xtn = 13172,
|
||||
ssl_renegotiation_info_xtn = 0xff01,
|
||||
ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */
|
||||
} SSLExtensionType;
|
||||
|
||||
#define SSL_MAX_EXTENSIONS 14 /* doesn't include ssl_padding_xtn. */
|
||||
#define SSL_MAX_EXTENSIONS 14 /* doesn't include ssl_padding_xtn. */
|
||||
|
||||
typedef enum {
|
||||
ssl_dhe_group_none = 0,
|
||||
|
|
|
@ -15,25 +15,26 @@
|
|||
static const char *hex = "0123456789abcdef";
|
||||
|
||||
static const char printable[257] = {
|
||||
"................" /* 0x */
|
||||
"................" /* 1x */
|
||||
" !\"#$%&'()*+,-./" /* 2x */
|
||||
"0123456789:;<=>?" /* 3x */
|
||||
"@ABCDEFGHIJKLMNO" /* 4x */
|
||||
"PQRSTUVWXYZ[\\]^_" /* 5x */
|
||||
"`abcdefghijklmno" /* 6x */
|
||||
"pqrstuvwxyz{|}~." /* 7x */
|
||||
"................" /* 8x */
|
||||
"................" /* 9x */
|
||||
"................" /* ax */
|
||||
"................" /* bx */
|
||||
"................" /* cx */
|
||||
"................" /* dx */
|
||||
"................" /* ex */
|
||||
"................" /* fx */
|
||||
"................" /* 0x */
|
||||
"................" /* 1x */
|
||||
" !\"#$%&'()*+,-./" /* 2x */
|
||||
"0123456789:;<=>?" /* 3x */
|
||||
"@ABCDEFGHIJKLMNO" /* 4x */
|
||||
"PQRSTUVWXYZ[\\]^_" /* 5x */
|
||||
"`abcdefghijklmno" /* 6x */
|
||||
"pqrstuvwxyz{|}~." /* 7x */
|
||||
"................" /* 8x */
|
||||
"................" /* 9x */
|
||||
"................" /* ax */
|
||||
"................" /* bx */
|
||||
"................" /* cx */
|
||||
"................" /* dx */
|
||||
"................" /* ex */
|
||||
"................" /* fx */
|
||||
};
|
||||
|
||||
void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
|
||||
void
|
||||
ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
|
||||
{
|
||||
const unsigned char *cp = (const unsigned char *)vp;
|
||||
char buf[80];
|
||||
|
@ -41,53 +42,56 @@ void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
|
|||
char *ap;
|
||||
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
|
||||
msg, len));
|
||||
} else {
|
||||
SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
|
||||
SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
|
||||
msg, len));
|
||||
}
|
||||
else {
|
||||
SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
|
||||
}
|
||||
memset(buf, ' ', sizeof buf);
|
||||
bp = buf;
|
||||
ap = buf + 50;
|
||||
while (--len >= 0) {
|
||||
unsigned char ch = *cp++;
|
||||
*bp++ = hex[(ch >> 4) & 0xf];
|
||||
*bp++ = hex[ch & 0xf];
|
||||
*bp++ = ' ';
|
||||
*ap++ = printable[ch];
|
||||
if (ap - buf >= 66) {
|
||||
*ap = 0;
|
||||
SSL_TRACE((" %s", buf));
|
||||
memset(buf, ' ', sizeof buf);
|
||||
bp = buf;
|
||||
ap = buf + 50;
|
||||
}
|
||||
unsigned char ch = *cp++;
|
||||
*bp++ = hex[(ch >> 4) & 0xf];
|
||||
*bp++ = hex[ch & 0xf];
|
||||
*bp++ = ' ';
|
||||
*ap++ = printable[ch];
|
||||
if (ap - buf >= 66) {
|
||||
*ap = 0;
|
||||
SSL_TRACE((" %s", buf));
|
||||
memset(buf, ' ', sizeof buf);
|
||||
bp = buf;
|
||||
ap = buf + 50;
|
||||
}
|
||||
}
|
||||
if (bp > buf) {
|
||||
*ap = 0;
|
||||
SSL_TRACE((" %s", buf));
|
||||
*ap = 0;
|
||||
SSL_TRACE((" %s", buf));
|
||||
}
|
||||
}
|
||||
|
||||
#define LEN(cp) (((cp)[0] << 8) | ((cp)[1]))
|
||||
#define LEN(cp) (((cp)[0] << 8) | ((cp)[1]))
|
||||
|
||||
static void PrintType(sslSocket *ss, char *msg)
|
||||
static void
|
||||
PrintType(sslSocket *ss, char *msg)
|
||||
{
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd,
|
||||
msg));
|
||||
} else {
|
||||
SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
|
||||
SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd, msg));
|
||||
}
|
||||
else {
|
||||
SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintInt(sslSocket *ss, char *msg, unsigned v)
|
||||
static void
|
||||
PrintInt(sslSocket *ss, char *msg, unsigned v)
|
||||
{
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s=%u", SSL_GETPID(), ss->fd,
|
||||
msg, v));
|
||||
} else {
|
||||
SSL_TRACE(("%d: SSL: %s=%u", SSL_GETPID(), msg, v));
|
||||
SSL_TRACE(("%d: SSL[%d]: %s=%u", SSL_GETPID(), ss->fd, msg, v));
|
||||
}
|
||||
else {
|
||||
SSL_TRACE(("%d: SSL: %s=%u", SSL_GETPID(), msg, v));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,149 +99,146 @@ static void PrintInt(sslSocket *ss, char *msg, unsigned v)
|
|||
* a) It prefixes each line of the buffer with "XX: SSL[xxx] "
|
||||
* b) It dumps only hex, not ASCII.
|
||||
*/
|
||||
static void PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
|
||||
static void
|
||||
PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
|
||||
{
|
||||
char buf[80];
|
||||
char *bp;
|
||||
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]",
|
||||
SSL_GETPID(), ss->fd, msg, len));
|
||||
} else {
|
||||
SSL_TRACE(("%d: SSL: %s [Len: %d]",
|
||||
SSL_GETPID(), msg, len));
|
||||
SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]",
|
||||
SSL_GETPID(), ss->fd, msg, len));
|
||||
}
|
||||
else {
|
||||
SSL_TRACE(("%d: SSL: %s [Len: %d]",
|
||||
SSL_GETPID(), msg, len));
|
||||
}
|
||||
bp = buf;
|
||||
while (--len >= 0) {
|
||||
unsigned char ch = *cp++;
|
||||
*bp++ = hex[(ch >> 4) & 0xf];
|
||||
*bp++ = hex[ch & 0xf];
|
||||
*bp++ = ' ';
|
||||
if (bp + 4 > buf + 50) {
|
||||
*bp = 0;
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s",
|
||||
SSL_GETPID(), ss->fd, buf));
|
||||
} else {
|
||||
SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
|
||||
}
|
||||
bp = buf;
|
||||
}
|
||||
unsigned char ch = *cp++;
|
||||
*bp++ = hex[(ch >> 4) & 0xf];
|
||||
*bp++ = hex[ch & 0xf];
|
||||
*bp++ = ' ';
|
||||
if (bp + 4 > buf + 50) {
|
||||
*bp = 0;
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s",
|
||||
SSL_GETPID(), ss->fd, buf));
|
||||
}
|
||||
else {
|
||||
SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
|
||||
}
|
||||
bp = buf;
|
||||
}
|
||||
}
|
||||
if (bp > buf) {
|
||||
*bp = 0;
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s",
|
||||
SSL_GETPID(), ss->fd, buf));
|
||||
} else {
|
||||
SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
|
||||
{
|
||||
switch (bp[0]) {
|
||||
case SSL_MT_ERROR:
|
||||
PrintType(ss, "Error");
|
||||
PrintInt(ss, "error", LEN(bp+1));
|
||||
break;
|
||||
|
||||
case SSL_MT_CLIENT_HELLO:
|
||||
{
|
||||
unsigned lcs = LEN(bp+3);
|
||||
unsigned ls = LEN(bp+5);
|
||||
unsigned lc = LEN(bp+7);
|
||||
|
||||
PrintType(ss, "Client-Hello");
|
||||
|
||||
PrintInt(ss, "version (Major)", bp[1]);
|
||||
PrintInt(ss, "version (minor)", bp[2]);
|
||||
|
||||
PrintBuf(ss, "cipher-specs", bp+9, lcs);
|
||||
PrintBuf(ss, "session-id", bp+9+lcs, ls);
|
||||
PrintBuf(ss, "challenge", bp+9+lcs+ls, lc);
|
||||
}
|
||||
break;
|
||||
case SSL_MT_CLIENT_MASTER_KEY:
|
||||
{
|
||||
unsigned lck = LEN(bp+4);
|
||||
unsigned lek = LEN(bp+6);
|
||||
unsigned lka = LEN(bp+8);
|
||||
|
||||
PrintType(ss, "Client-Master-Key");
|
||||
|
||||
PrintInt(ss, "cipher-choice", bp[1]);
|
||||
PrintInt(ss, "key-length", LEN(bp+2));
|
||||
|
||||
PrintBuf(ss, "clear-key", bp+10, lck);
|
||||
PrintBuf(ss, "encrypted-key", bp+10+lck, lek);
|
||||
PrintBuf(ss, "key-arg", bp+10+lck+lek, lka);
|
||||
}
|
||||
break;
|
||||
case SSL_MT_CLIENT_FINISHED:
|
||||
PrintType(ss, "Client-Finished");
|
||||
PrintBuf(ss, "connection-id", bp+1, len-1);
|
||||
break;
|
||||
case SSL_MT_SERVER_HELLO:
|
||||
{
|
||||
unsigned lc = LEN(bp+5);
|
||||
unsigned lcs = LEN(bp+7);
|
||||
unsigned lci = LEN(bp+9);
|
||||
|
||||
PrintType(ss, "Server-Hello");
|
||||
|
||||
PrintInt(ss, "session-id-hit", bp[1]);
|
||||
PrintInt(ss, "certificate-type", bp[2]);
|
||||
PrintInt(ss, "version (Major)", bp[3]);
|
||||
PrintInt(ss, "version (minor)", bp[3]);
|
||||
PrintBuf(ss, "certificate", bp+11, lc);
|
||||
PrintBuf(ss, "cipher-specs", bp+11+lc, lcs);
|
||||
PrintBuf(ss, "connection-id", bp+11+lc+lcs, lci);
|
||||
}
|
||||
break;
|
||||
case SSL_MT_SERVER_VERIFY:
|
||||
PrintType(ss, "Server-Verify");
|
||||
PrintBuf(ss, "challenge", bp+1, len-1);
|
||||
break;
|
||||
case SSL_MT_SERVER_FINISHED:
|
||||
PrintType(ss, "Server-Finished");
|
||||
PrintBuf(ss, "session-id", bp+1, len-1);
|
||||
break;
|
||||
case SSL_MT_REQUEST_CERTIFICATE:
|
||||
PrintType(ss, "Request-Certificate");
|
||||
PrintInt(ss, "authentication-type", bp[1]);
|
||||
PrintBuf(ss, "certificate-challenge", bp+2, len-2);
|
||||
break;
|
||||
case SSL_MT_CLIENT_CERTIFICATE:
|
||||
{
|
||||
unsigned lc = LEN(bp+2);
|
||||
unsigned lr = LEN(bp+4);
|
||||
PrintType(ss, "Client-Certificate");
|
||||
PrintInt(ss, "certificate-type", bp[1]);
|
||||
PrintBuf(ss, "certificate", bp+6, lc);
|
||||
PrintBuf(ss, "response", bp+6+lc, lr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
|
||||
return;
|
||||
*bp = 0;
|
||||
if (ss) {
|
||||
SSL_TRACE(("%d: SSL[%d]: %s",
|
||||
SSL_GETPID(), ss->fd, buf));
|
||||
}
|
||||
else {
|
||||
SSL_TRACE(("%d: SSL: %s", SSL_GETPID(), buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ssl_Trace(const char *format, ... )
|
||||
ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
|
||||
{
|
||||
char buf[2000];
|
||||
switch (bp[0]) {
|
||||
case SSL_MT_ERROR:
|
||||
PrintType(ss, "Error");
|
||||
PrintInt(ss, "error", LEN(bp + 1));
|
||||
break;
|
||||
|
||||
case SSL_MT_CLIENT_HELLO: {
|
||||
unsigned lcs = LEN(bp + 3);
|
||||
unsigned ls = LEN(bp + 5);
|
||||
unsigned lc = LEN(bp + 7);
|
||||
|
||||
PrintType(ss, "Client-Hello");
|
||||
|
||||
PrintInt(ss, "version (Major)", bp[1]);
|
||||
PrintInt(ss, "version (minor)", bp[2]);
|
||||
|
||||
PrintBuf(ss, "cipher-specs", bp + 9, lcs);
|
||||
PrintBuf(ss, "session-id", bp + 9 + lcs, ls);
|
||||
PrintBuf(ss, "challenge", bp + 9 + lcs + ls, lc);
|
||||
} break;
|
||||
case SSL_MT_CLIENT_MASTER_KEY: {
|
||||
unsigned lck = LEN(bp + 4);
|
||||
unsigned lek = LEN(bp + 6);
|
||||
unsigned lka = LEN(bp + 8);
|
||||
|
||||
PrintType(ss, "Client-Master-Key");
|
||||
|
||||
PrintInt(ss, "cipher-choice", bp[1]);
|
||||
PrintInt(ss, "key-length", LEN(bp + 2));
|
||||
|
||||
PrintBuf(ss, "clear-key", bp + 10, lck);
|
||||
PrintBuf(ss, "encrypted-key", bp + 10 + lck, lek);
|
||||
PrintBuf(ss, "key-arg", bp + 10 + lck + lek, lka);
|
||||
} break;
|
||||
case SSL_MT_CLIENT_FINISHED:
|
||||
PrintType(ss, "Client-Finished");
|
||||
PrintBuf(ss, "connection-id", bp + 1, len - 1);
|
||||
break;
|
||||
case SSL_MT_SERVER_HELLO: {
|
||||
unsigned lc = LEN(bp + 5);
|
||||
unsigned lcs = LEN(bp + 7);
|
||||
unsigned lci = LEN(bp + 9);
|
||||
|
||||
PrintType(ss, "Server-Hello");
|
||||
|
||||
PrintInt(ss, "session-id-hit", bp[1]);
|
||||
PrintInt(ss, "certificate-type", bp[2]);
|
||||
PrintInt(ss, "version (Major)", bp[3]);
|
||||
PrintInt(ss, "version (minor)", bp[3]);
|
||||
PrintBuf(ss, "certificate", bp + 11, lc);
|
||||
PrintBuf(ss, "cipher-specs", bp + 11 + lc, lcs);
|
||||
PrintBuf(ss, "connection-id", bp + 11 + lc + lcs, lci);
|
||||
} break;
|
||||
case SSL_MT_SERVER_VERIFY:
|
||||
PrintType(ss, "Server-Verify");
|
||||
PrintBuf(ss, "challenge", bp + 1, len - 1);
|
||||
break;
|
||||
case SSL_MT_SERVER_FINISHED:
|
||||
PrintType(ss, "Server-Finished");
|
||||
PrintBuf(ss, "session-id", bp + 1, len - 1);
|
||||
break;
|
||||
case SSL_MT_REQUEST_CERTIFICATE:
|
||||
PrintType(ss, "Request-Certificate");
|
||||
PrintInt(ss, "authentication-type", bp[1]);
|
||||
PrintBuf(ss, "certificate-challenge", bp + 2, len - 2);
|
||||
break;
|
||||
case SSL_MT_CLIENT_CERTIFICATE: {
|
||||
unsigned lc = LEN(bp + 2);
|
||||
unsigned lr = LEN(bp + 4);
|
||||
PrintType(ss, "Client-Certificate");
|
||||
PrintInt(ss, "certificate-type", bp[1]);
|
||||
PrintBuf(ss, "certificate", bp + 6, lc);
|
||||
PrintBuf(ss, "response", bp + 6 + lc, lr);
|
||||
} break;
|
||||
default:
|
||||
ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ssl_Trace(const char *format, ...)
|
||||
{
|
||||
char buf[2000];
|
||||
va_list args;
|
||||
|
||||
if (ssl_trace_iob) {
|
||||
va_start(args, format);
|
||||
PR_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
va_start(args, format);
|
||||
PR_vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
|
||||
fputs(buf, ssl_trace_iob);
|
||||
fputs("\n", ssl_trace_iob);
|
||||
fputs(buf, ssl_trace_iob);
|
||||
fputs("\n", ssl_trace_iob);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,7 +15,7 @@ typedef enum {
|
|||
} SharedSecretType;
|
||||
|
||||
SECStatus tls13_UnprotectRecord(
|
||||
sslSocket* ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
|
||||
sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext,
|
||||
SSL3AlertDescription *alert);
|
||||
unsigned char *
|
||||
tls13_EncodeUintX(PRUint32 value, unsigned int bytes, unsigned char *to);
|
||||
|
|
|
@ -32,7 +32,7 @@ static const struct {
|
|||
};
|
||||
|
||||
SECStatus
|
||||
tls13_HkdfExtract(PK11SymKey* ikm1, PK11SymKey* ikm2, SSLHashType baseHash,
|
||||
tls13_HkdfExtract(PK11SymKey *ikm1, PK11SymKey *ikm2, SSLHashType baseHash,
|
||||
PK11SymKey **prkp)
|
||||
{
|
||||
CK_NSS_HKDFParams params;
|
||||
|
@ -60,7 +60,8 @@ tls13_HkdfExtract(PK11SymKey* ikm1, PK11SymKey* ikm2, SSLHashType baseHash,
|
|||
params.pSalt = salt->data;
|
||||
params.ulSaltLen = salt->len;
|
||||
PORT_Assert(salt->len > 0);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Per documentation for CKM_NSS_HKDF_*:
|
||||
*
|
||||
* If the optional salt is given, it is used; otherwise, the salt is
|
||||
|
@ -74,7 +75,7 @@ tls13_HkdfExtract(PK11SymKey* ikm1, PK11SymKey* ikm2, SSLHashType baseHash,
|
|||
|
||||
PORT_Assert(kTlsHkdfInfo[baseHash].pkcs11Mech);
|
||||
PORT_Assert(kTlsHkdfInfo[baseHash].hashSize);
|
||||
PORT_Assert(kTlsHkdfInfo[baseHash].hash==baseHash);
|
||||
PORT_Assert(kTlsHkdfInfo[baseHash].hash == baseHash);
|
||||
prk = PK11_Derive(ikm2, kTlsHkdfInfo[baseHash].pkcs11Mech,
|
||||
¶msi, kTlsHkdfInfo[baseHash].pkcs11Mech,
|
||||
CKA_DERIVE, kTlsHkdfInfo[baseHash].hashSize);
|
||||
|
@ -86,14 +87,14 @@ tls13_HkdfExtract(PK11SymKey* ikm1, PK11SymKey* ikm2, SSLHashType baseHash,
|
|||
}
|
||||
|
||||
SECStatus
|
||||
tls13_HkdfExpandLabel(PK11SymKey* prk, SSLHashType baseHash,
|
||||
tls13_HkdfExpandLabel(PK11SymKey *prk, SSLHashType baseHash,
|
||||
const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
|
||||
const char *label, unsigned int labelLen,
|
||||
CK_MECHANISM_TYPE algorithm, unsigned int keySize,
|
||||
PK11SymKey **keyp)
|
||||
{
|
||||
CK_NSS_HKDFParams params;
|
||||
SECItem paramsi = {siBuffer, NULL, 0};
|
||||
SECItem paramsi = { siBuffer, NULL, 0 };
|
||||
PRUint8 info[100];
|
||||
PRUint8 *ptr = info;
|
||||
unsigned int infoLen;
|
||||
|
@ -103,7 +104,8 @@ tls13_HkdfExpandLabel(PK11SymKey* prk, SSLHashType baseHash,
|
|||
|
||||
if (handshakeHash) {
|
||||
PORT_Assert(handshakeHashLen == kTlsHkdfInfo[baseHash].hashSize);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PORT_Assert(!handshakeHashLen);
|
||||
}
|
||||
|
||||
|
@ -169,9 +171,8 @@ abort:
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
tls13_HkdfExpandLabelRaw(PK11SymKey* prk, SSLHashType baseHash,
|
||||
tls13_HkdfExpandLabelRaw(PK11SymKey *prk, SSLHashType baseHash,
|
||||
const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
|
||||
const char *label, unsigned int labelLen,
|
||||
unsigned char *output, unsigned int outputLen)
|
||||
|
|
|
@ -17,15 +17,15 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
SECStatus tls13_HkdfExtract(
|
||||
PK11SymKey* ikm1, PK11SymKey* ikm2, SSLHashType baseHash,
|
||||
PK11SymKey *ikm1, PK11SymKey *ikm2, SSLHashType baseHash,
|
||||
PK11SymKey **prkp);
|
||||
SECStatus tls13_HkdfExpandLabelRaw(
|
||||
PK11SymKey* prk, SSLHashType baseHash,
|
||||
PK11SymKey *prk, SSLHashType baseHash,
|
||||
const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
|
||||
const char *label, unsigned int labelLen,
|
||||
unsigned char *output, unsigned int outputLen);
|
||||
SECStatus tls13_HkdfExpandLabel(
|
||||
PK11SymKey* prk, SSLHashType baseHash,
|
||||
PK11SymKey *prk, SSLHashType baseHash,
|
||||
const PRUint8 *handshakeHash, unsigned int handshakeHashLen,
|
||||
const char *label, unsigned int labelLen,
|
||||
CK_MECHANISM_TYPE algorithm, unsigned int keySize,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file essentially replicates NSPR's source for the functions that
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* NSPR's functions, instead of duplicating them, but they're private.
|
||||
* As long as SSL's server session cache code must do platform native I/O
|
||||
* to accomplish its job, and NSPR's error mapping functions remain private,
|
||||
* this code will continue to need to be replicated.
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* This file essentially replicates NSPR's source for the functions that
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* NSPR's functions, instead of duplicating them, but they're private.
|
||||
* As long as SSL's server session cache code must do platform native I/O
|
||||
* to accomplish its job, and NSPR's error mapping functions remain private,
|
||||
* this code will continue to need to be replicated.
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -33,79 +33,94 @@
|
|||
/* forward declaration. */
|
||||
void nss_MD_win32_map_default_error(PRInt32 err);
|
||||
|
||||
void nss_MD_win32_map_opendir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_opendir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_closedir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_closedir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_readdir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_readdir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_delete_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_delete_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
/* The error code for stat() is in errno. */
|
||||
void nss_MD_win32_map_stat_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_stat_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_fstat_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_fstat_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_rename_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_rename_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
/* The error code for access() is in errno. */
|
||||
void nss_MD_win32_map_access_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_access_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_mkdir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_mkdir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_rmdir_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_rmdir_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_read_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_read_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_transmitfile_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_transmitfile_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_write_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_write_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_lseek_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_lseek_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_fsync_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_fsync_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
@ -113,231 +128,423 @@ void nss_MD_win32_map_fsync_error(PRInt32 err)
|
|||
/*
|
||||
* For both CloseHandle() and closesocket().
|
||||
*/
|
||||
void nss_MD_win32_map_close_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_close_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_socket_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_socket_error(PRInt32 err)
|
||||
{
|
||||
PR_ASSERT(err != WSANOTINITIALISED);
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_recv_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_recv_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_recvfrom_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_recvfrom_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_send_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_send_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEMSGSIZE:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_sendto_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_sendto_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEMSGSIZE:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_accept_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_accept_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
|
||||
case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEOPNOTSUPP:
|
||||
prError = PR_NOT_TCP_SOCKET_ERROR;
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
prError = PR_INVALID_STATE_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_acceptex_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_acceptex_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_connect_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_connect_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEWOULDBLOCK: prError = PR_IN_PROGRESS_ERROR; break;
|
||||
case WSAEINVAL: prError = PR_ALREADY_INITIATED_ERROR; break;
|
||||
case WSAETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEWOULDBLOCK:
|
||||
prError = PR_IN_PROGRESS_ERROR;
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
prError = PR_ALREADY_INITIATED_ERROR;
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
prError = PR_IO_TIMEOUT_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_bind_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_bind_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEINVAL:
|
||||
prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_listen_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_listen_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
|
||||
case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEOPNOTSUPP:
|
||||
prError = PR_NOT_TCP_SOCKET_ERROR;
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
prError = PR_INVALID_STATE_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_shutdown_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_shutdown_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_getsockname_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_getsockname_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAEINVAL: prError = PR_INVALID_STATE_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAEINVAL:
|
||||
prError = PR_INVALID_STATE_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_getpeername_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_getpeername_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_getsockopt_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_getsockopt_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_setsockopt_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_setsockopt_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_open_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_open_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_gethostname_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_gethostname_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
/* Win32 select() only works on sockets. So in this
|
||||
** context, WSAENOTSOCK is equivalent to EBADF on Unix.
|
||||
** context, WSAENOTSOCK is equivalent to EBADF on Unix.
|
||||
*/
|
||||
void nss_MD_win32_map_select_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_select_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
switch (err) {
|
||||
case WSAENOTSOCK: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
default: nss_MD_win32_map_default_error(err); return;
|
||||
case WSAENOTSOCK:
|
||||
prError = PR_BAD_DESCRIPTOR_ERROR;
|
||||
break;
|
||||
default:
|
||||
nss_MD_win32_map_default_error(err);
|
||||
return;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
void nss_MD_win32_map_lockf_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_lockf_error(PRInt32 err)
|
||||
{
|
||||
nss_MD_win32_map_default_error(err);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void nss_MD_win32_map_default_error(PRInt32 err)
|
||||
void
|
||||
nss_MD_win32_map_default_error(PRInt32 err)
|
||||
{
|
||||
PRErrorCode prError;
|
||||
|
||||
switch (err) {
|
||||
case EACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
|
||||
case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
case ERROR_ACCESS_DENIED: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
|
||||
case ERROR_ALREADY_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
|
||||
case ERROR_DISK_CORRUPT: prError = PR_IO_ERROR; break;
|
||||
case ERROR_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
|
||||
case ERROR_DISK_OPERATION_FAILED: prError = PR_IO_ERROR; break;
|
||||
case ERROR_DRIVE_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
|
||||
case ERROR_FILENAME_EXCED_RANGE: prError = PR_NAME_TOO_LONG_ERROR; break;
|
||||
case ERROR_FILE_CORRUPT: prError = PR_IO_ERROR; break;
|
||||
case ERROR_FILE_EXISTS: prError = PR_FILE_EXISTS_ERROR; break;
|
||||
case ERROR_FILE_INVALID: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
case EACCES:
|
||||
prError = PR_NO_ACCESS_RIGHTS_ERROR;
|
||||
break;
|
||||
case ENOENT:
|
||||
prError = PR_FILE_NOT_FOUND_ERROR;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
prError = PR_NO_ACCESS_RIGHTS_ERROR;
|
||||
break;
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
prError = PR_FILE_EXISTS_ERROR;
|
||||
break;
|
||||
case ERROR_DISK_CORRUPT:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_DISK_FULL:
|
||||
prError = PR_NO_DEVICE_SPACE_ERROR;
|
||||
break;
|
||||
case ERROR_DISK_OPERATION_FAILED:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_DRIVE_LOCKED:
|
||||
prError = PR_FILE_IS_LOCKED_ERROR;
|
||||
break;
|
||||
case ERROR_FILENAME_EXCED_RANGE:
|
||||
prError = PR_NAME_TOO_LONG_ERROR;
|
||||
break;
|
||||
case ERROR_FILE_CORRUPT:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_FILE_EXISTS:
|
||||
prError = PR_FILE_EXISTS_ERROR;
|
||||
break;
|
||||
case ERROR_FILE_INVALID:
|
||||
prError = PR_BAD_DESCRIPTOR_ERROR;
|
||||
break;
|
||||
#if ERROR_FILE_NOT_FOUND != ENOENT
|
||||
case ERROR_FILE_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
prError = PR_FILE_NOT_FOUND_ERROR;
|
||||
break;
|
||||
#endif
|
||||
case ERROR_HANDLE_DISK_FULL: prError = PR_NO_DEVICE_SPACE_ERROR; break;
|
||||
case ERROR_INVALID_ADDRESS: prError = PR_ACCESS_FAULT_ERROR; break;
|
||||
case ERROR_INVALID_HANDLE: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
case ERROR_INVALID_NAME: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case ERROR_INVALID_PARAMETER: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case ERROR_INVALID_USER_BUFFER: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
|
||||
case ERROR_LOCKED: prError = PR_FILE_IS_LOCKED_ERROR; break;
|
||||
case ERROR_NETNAME_DELETED: prError = PR_CONNECT_RESET_ERROR; break;
|
||||
case ERROR_NOACCESS: prError = PR_ACCESS_FAULT_ERROR; break;
|
||||
case ERROR_NOT_ENOUGH_MEMORY: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
|
||||
case ERROR_NOT_ENOUGH_QUOTA: prError = PR_OUT_OF_MEMORY_ERROR; break;
|
||||
case ERROR_NOT_READY: prError = PR_IO_ERROR; break;
|
||||
case ERROR_NO_MORE_FILES: prError = PR_NO_MORE_FILES_ERROR; break;
|
||||
case ERROR_OPEN_FAILED: prError = PR_IO_ERROR; break;
|
||||
case ERROR_OPEN_FILES: prError = PR_IO_ERROR; break;
|
||||
case ERROR_OUTOFMEMORY: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
|
||||
case ERROR_PATH_BUSY: prError = PR_IO_ERROR; break;
|
||||
case ERROR_PATH_NOT_FOUND: prError = PR_FILE_NOT_FOUND_ERROR; break;
|
||||
case ERROR_SEEK_ON_DEVICE: prError = PR_IO_ERROR; break;
|
||||
case ERROR_SHARING_VIOLATION: prError = PR_FILE_IS_BUSY_ERROR; break;
|
||||
case ERROR_STACK_OVERFLOW: prError = PR_ACCESS_FAULT_ERROR; break;
|
||||
case ERROR_TOO_MANY_OPEN_FILES: prError = PR_SYS_DESC_TABLE_FULL_ERROR; break;
|
||||
case ERROR_WRITE_PROTECT: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
|
||||
case WSAEACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
|
||||
case WSAEADDRINUSE: prError = PR_ADDRESS_IN_USE_ERROR; break;
|
||||
case WSAEADDRNOTAVAIL: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; break;
|
||||
case WSAEAFNOSUPPORT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
|
||||
case WSAEALREADY: prError = PR_ALREADY_INITIATED_ERROR; break;
|
||||
case WSAEBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
|
||||
case WSAECONNABORTED: prError = PR_CONNECT_ABORTED_ERROR; break;
|
||||
case WSAECONNREFUSED: prError = PR_CONNECT_REFUSED_ERROR; break;
|
||||
case WSAECONNRESET: prError = PR_CONNECT_RESET_ERROR; break;
|
||||
case WSAEDESTADDRREQ: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case WSAEFAULT: prError = PR_ACCESS_FAULT_ERROR; break;
|
||||
case WSAEHOSTUNREACH: prError = PR_HOST_UNREACHABLE_ERROR; break;
|
||||
case WSAEINVAL: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case WSAEISCONN: prError = PR_IS_CONNECTED_ERROR; break;
|
||||
case WSAEMFILE: prError = PR_PROC_DESC_TABLE_FULL_ERROR; break;
|
||||
case WSAEMSGSIZE: prError = PR_BUFFER_OVERFLOW_ERROR; break;
|
||||
case WSAENETDOWN: prError = PR_NETWORK_DOWN_ERROR; break;
|
||||
case WSAENETRESET: prError = PR_CONNECT_ABORTED_ERROR; break;
|
||||
case WSAENETUNREACH: prError = PR_NETWORK_UNREACHABLE_ERROR; break;
|
||||
case WSAENOBUFS: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
|
||||
case WSAENOPROTOOPT: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case WSAENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break;
|
||||
case WSAENOTSOCK: prError = PR_NOT_SOCKET_ERROR; break;
|
||||
case WSAEOPNOTSUPP: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; break;
|
||||
case WSAEPROTONOSUPPORT: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; break;
|
||||
case WSAEPROTOTYPE: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case WSAESHUTDOWN: prError = PR_SOCKET_SHUTDOWN_ERROR; break;
|
||||
case WSAESOCKTNOSUPPORT: prError = PR_INVALID_ARGUMENT_ERROR; break;
|
||||
case WSAETIMEDOUT: prError = PR_CONNECT_ABORTED_ERROR; break;
|
||||
case WSAEWOULDBLOCK: prError = PR_WOULD_BLOCK_ERROR; break;
|
||||
default: prError = PR_UNKNOWN_ERROR; break;
|
||||
case ERROR_HANDLE_DISK_FULL:
|
||||
prError = PR_NO_DEVICE_SPACE_ERROR;
|
||||
break;
|
||||
case ERROR_INVALID_ADDRESS:
|
||||
prError = PR_ACCESS_FAULT_ERROR;
|
||||
break;
|
||||
case ERROR_INVALID_HANDLE:
|
||||
prError = PR_BAD_DESCRIPTOR_ERROR;
|
||||
break;
|
||||
case ERROR_INVALID_NAME:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case ERROR_INVALID_USER_BUFFER:
|
||||
prError = PR_INSUFFICIENT_RESOURCES_ERROR;
|
||||
break;
|
||||
case ERROR_LOCKED:
|
||||
prError = PR_FILE_IS_LOCKED_ERROR;
|
||||
break;
|
||||
case ERROR_NETNAME_DELETED:
|
||||
prError = PR_CONNECT_RESET_ERROR;
|
||||
break;
|
||||
case ERROR_NOACCESS:
|
||||
prError = PR_ACCESS_FAULT_ERROR;
|
||||
break;
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
prError = PR_INSUFFICIENT_RESOURCES_ERROR;
|
||||
break;
|
||||
case ERROR_NOT_ENOUGH_QUOTA:
|
||||
prError = PR_OUT_OF_MEMORY_ERROR;
|
||||
break;
|
||||
case ERROR_NOT_READY:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_NO_MORE_FILES:
|
||||
prError = PR_NO_MORE_FILES_ERROR;
|
||||
break;
|
||||
case ERROR_OPEN_FAILED:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_OPEN_FILES:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_OUTOFMEMORY:
|
||||
prError = PR_INSUFFICIENT_RESOURCES_ERROR;
|
||||
break;
|
||||
case ERROR_PATH_BUSY:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
prError = PR_FILE_NOT_FOUND_ERROR;
|
||||
break;
|
||||
case ERROR_SEEK_ON_DEVICE:
|
||||
prError = PR_IO_ERROR;
|
||||
break;
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
prError = PR_FILE_IS_BUSY_ERROR;
|
||||
break;
|
||||
case ERROR_STACK_OVERFLOW:
|
||||
prError = PR_ACCESS_FAULT_ERROR;
|
||||
break;
|
||||
case ERROR_TOO_MANY_OPEN_FILES:
|
||||
prError = PR_SYS_DESC_TABLE_FULL_ERROR;
|
||||
break;
|
||||
case ERROR_WRITE_PROTECT:
|
||||
prError = PR_NO_ACCESS_RIGHTS_ERROR;
|
||||
break;
|
||||
case WSAEACCES:
|
||||
prError = PR_NO_ACCESS_RIGHTS_ERROR;
|
||||
break;
|
||||
case WSAEADDRINUSE:
|
||||
prError = PR_ADDRESS_IN_USE_ERROR;
|
||||
break;
|
||||
case WSAEADDRNOTAVAIL:
|
||||
prError = PR_ADDRESS_NOT_AVAILABLE_ERROR;
|
||||
break;
|
||||
case WSAEAFNOSUPPORT:
|
||||
prError = PR_ADDRESS_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
case WSAEALREADY:
|
||||
prError = PR_ALREADY_INITIATED_ERROR;
|
||||
break;
|
||||
case WSAEBADF:
|
||||
prError = PR_BAD_DESCRIPTOR_ERROR;
|
||||
break;
|
||||
case WSAECONNABORTED:
|
||||
prError = PR_CONNECT_ABORTED_ERROR;
|
||||
break;
|
||||
case WSAECONNREFUSED:
|
||||
prError = PR_CONNECT_REFUSED_ERROR;
|
||||
break;
|
||||
case WSAECONNRESET:
|
||||
prError = PR_CONNECT_RESET_ERROR;
|
||||
break;
|
||||
case WSAEDESTADDRREQ:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case WSAEFAULT:
|
||||
prError = PR_ACCESS_FAULT_ERROR;
|
||||
break;
|
||||
case WSAEHOSTUNREACH:
|
||||
prError = PR_HOST_UNREACHABLE_ERROR;
|
||||
break;
|
||||
case WSAEINVAL:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case WSAEISCONN:
|
||||
prError = PR_IS_CONNECTED_ERROR;
|
||||
break;
|
||||
case WSAEMFILE:
|
||||
prError = PR_PROC_DESC_TABLE_FULL_ERROR;
|
||||
break;
|
||||
case WSAEMSGSIZE:
|
||||
prError = PR_BUFFER_OVERFLOW_ERROR;
|
||||
break;
|
||||
case WSAENETDOWN:
|
||||
prError = PR_NETWORK_DOWN_ERROR;
|
||||
break;
|
||||
case WSAENETRESET:
|
||||
prError = PR_CONNECT_ABORTED_ERROR;
|
||||
break;
|
||||
case WSAENETUNREACH:
|
||||
prError = PR_NETWORK_UNREACHABLE_ERROR;
|
||||
break;
|
||||
case WSAENOBUFS:
|
||||
prError = PR_INSUFFICIENT_RESOURCES_ERROR;
|
||||
break;
|
||||
case WSAENOPROTOOPT:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case WSAENOTCONN:
|
||||
prError = PR_NOT_CONNECTED_ERROR;
|
||||
break;
|
||||
case WSAENOTSOCK:
|
||||
prError = PR_NOT_SOCKET_ERROR;
|
||||
break;
|
||||
case WSAEOPNOTSUPP:
|
||||
prError = PR_OPERATION_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
case WSAEPROTONOSUPPORT:
|
||||
prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR;
|
||||
break;
|
||||
case WSAEPROTOTYPE:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case WSAESHUTDOWN:
|
||||
prError = PR_SOCKET_SHUTDOWN_ERROR;
|
||||
break;
|
||||
case WSAESOCKTNOSUPPORT:
|
||||
prError = PR_INVALID_ARGUMENT_ERROR;
|
||||
break;
|
||||
case WSAETIMEDOUT:
|
||||
prError = PR_CONNECT_ABORTED_ERROR;
|
||||
break;
|
||||
case WSAEWOULDBLOCK:
|
||||
prError = PR_WOULD_BLOCK_ERROR;
|
||||
break;
|
||||
default:
|
||||
prError = PR_UNKNOWN_ERROR;
|
||||
break;
|
||||
}
|
||||
PR_SetError(prError, err);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*
|
||||
* This file essentially replicates NSPR's source for the functions that
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* map system-specific error codes to NSPR error codes. We would use
|
||||
* NSPR's functions, instead of duplicating them, but they're private.
|
||||
* As long as SSL's server session cache code must do platform native I/O
|
||||
* to accomplish its job, and NSPR's error mapping functions remain private,
|
||||
* This code will continue to need to be replicated.
|
||||
*
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
|
@ -51,6 +51,8 @@
|
|||
#define CKK_NSS_JPAKE_ROUND1 (CKK_NSS + 2)
|
||||
#define CKK_NSS_JPAKE_ROUND2 (CKK_NSS + 3)
|
||||
|
||||
#define CKK_NSS_CHACHA20 (CKK_NSS + 4)
|
||||
|
||||
/*
|
||||
* NSS-defined certificate types
|
||||
*
|
||||
|
@ -218,6 +220,9 @@
|
|||
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE (CKM_NSS + 25)
|
||||
#define CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH (CKM_NSS + 26)
|
||||
|
||||
#define CKM_NSS_CHACHA20_KEY_GEN (CKM_NSS + 27)
|
||||
#define CKM_NSS_CHACHA20_POLY1305 (CKM_NSS + 28)
|
||||
|
||||
/*
|
||||
* HISTORICAL:
|
||||
* Do not attempt to use these. They are only used by NETSCAPE's internal
|
||||
|
@ -285,6 +290,14 @@ typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {
|
|||
CK_ULONG ulHeaderLen; /* in */
|
||||
} CK_NSS_MAC_CONSTANT_TIME_PARAMS;
|
||||
|
||||
typedef struct CK_NSS_AEAD_PARAMS {
|
||||
CK_BYTE_PTR pNonce;
|
||||
CK_ULONG ulNonceLen;
|
||||
CK_BYTE_PTR pAAD;
|
||||
CK_ULONG ulAADLen;
|
||||
CK_ULONG ulTagLen;
|
||||
} CK_NSS_AEAD_PARAMS;
|
||||
|
||||
/*
|
||||
* NSS-defined return values
|
||||
*
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define PR_Assert sec_asn1d_Assert
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
|
||||
|
@ -1593,6 +1595,7 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
|
|||
|
||||
item = (SECItem *)(state->dest);
|
||||
if (item != NULL && item->data != NULL) {
|
||||
unsigned long offset;
|
||||
/* Strip leading zeroes when target is unsigned integer */
|
||||
if (state->underlying_kind == SEC_ASN1_INTEGER && /* INTEGER */
|
||||
item->len == 0 && /* MSB */
|
||||
|
@ -1603,8 +1606,42 @@ sec_asn1d_parse_leaf (sec_asn1d_state *state,
|
|||
len--;
|
||||
}
|
||||
}
|
||||
PORT_Memcpy (item->data + item->len, buf, len);
|
||||
item->len += len;
|
||||
offset = item->len;
|
||||
if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
|
||||
// The previous bit string must have no unused bits.
|
||||
if (item->len & 0x7) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
// If this is a bit string, the length is bits, not bytes.
|
||||
offset = item->len >> 3;
|
||||
}
|
||||
if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
|
||||
unsigned long len_in_bits;
|
||||
// Protect against overflow during the bytes-to-bits conversion.
|
||||
if (len >= (ULONG_MAX >> 3) + 1) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
len_in_bits = (len << 3) - state->bit_string_unused_bits;
|
||||
// Protect against overflow when computing the total length in bits.
|
||||
if (UINT_MAX - item->len < len_in_bits) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
item->len += len_in_bits;
|
||||
} else {
|
||||
if (UINT_MAX - item->len < len) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
return 0;
|
||||
}
|
||||
item->len += len;
|
||||
}
|
||||
PORT_Memcpy (item->data + offset, buf, len);
|
||||
}
|
||||
state->pending -= bufLen;
|
||||
if (state->pending == 0)
|
||||
|
@ -1671,14 +1708,6 @@ sec_asn1d_parse_more_bit_string (sec_asn1d_state *state,
|
|||
}
|
||||
|
||||
len = sec_asn1d_parse_leaf (state, buf, len);
|
||||
if (state->place == beforeEndOfContents && state->dest != NULL) {
|
||||
SECItem *item;
|
||||
|
||||
item = (SECItem *)(state->dest);
|
||||
if (item->len)
|
||||
item->len = (item->len << 3) - state->bit_string_unused_bits;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -2208,7 +2237,7 @@ sec_asn1d_concat_substrings (sec_asn1d_state *state)
|
|||
* All bit-string substrings except the last one should be
|
||||
* a clean multiple of 8 bits.
|
||||
*/
|
||||
if (is_bit_string && (substring->next == NULL)
|
||||
if (is_bit_string && (substring->next != NULL)
|
||||
&& (substring->len & 0x7)) {
|
||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
||||
state->top->status = decodeError;
|
||||
|
|
|
@ -1652,7 +1652,6 @@ const static SECOidData oids[SEC_OID_TOTAL] = {
|
|||
OD( x520Name, SEC_OID_AVA_NAME,
|
||||
"X520 Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
|
||||
|
||||
|
||||
OD( aes128_GCM, SEC_OID_AES_128_GCM,
|
||||
"AES-128-GCM", CKM_AES_GCM, INVALID_CERT_EXTENSION ),
|
||||
OD( aes192_GCM, SEC_OID_AES_192_GCM,
|
||||
|
@ -1710,6 +1709,8 @@ const static SECOidData oids[SEC_OID_TOTAL] = {
|
|||
"TLS DH-ANON-EXPORT key exchange", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
|
||||
ODE( SEC_OID_APPLY_SSL_POLICY,
|
||||
"Apply SSL policy (pseudo-OID)", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
|
||||
ODE( SEC_OID_CHACHA20_POLY1305,
|
||||
"ChaCha20-Poly1305", CKM_NSS_CHACHA20_POLY1305, INVALID_CERT_EXTENSION ),
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -479,6 +479,8 @@ typedef enum {
|
|||
SEC_OID_TLS_DH_ANON_EXPORT = 344,
|
||||
SEC_OID_APPLY_SSL_POLICY = 345,
|
||||
|
||||
SEC_OID_CHACHA20_POLY1305 = 346,
|
||||
|
||||
SEC_OID_TOTAL
|
||||
} SECOidTag;
|
||||
|
||||
|
|
|
@ -321,8 +321,8 @@ sec_port_ucs2_utf8_conversion_function
|
|||
for( i = 0; i < inBufLen; i += 2 ) {
|
||||
if( (inBuf[i+H_0] == 0x00) && ((inBuf[i+H_1] & 0x80) == 0x00) ) len += 1;
|
||||
else if( inBuf[i+H_0] < 0x08 ) len += 2;
|
||||
else if( ((inBuf[i+0+H_0] & 0xDC) == 0xD8) ) {
|
||||
if( ((inBufLen - i) > 2) && ((inBuf[i+2+H_0] & 0xDC) == 0xDC) ) {
|
||||
else if( ((inBuf[i+0+H_0] & 0xFC) == 0xD8) ) {
|
||||
if( ((inBufLen - i) > 2) && ((inBuf[i+2+H_0] & 0xFC) == 0xDC) ) {
|
||||
i += 2;
|
||||
len += 4;
|
||||
} else {
|
||||
|
@ -356,10 +356,10 @@ sec_port_ucs2_utf8_conversion_function
|
|||
outBuf[len+1] = 0x80 | ((inBuf[i+H_1] & 0x3F) >> 0);
|
||||
|
||||
len += 2;
|
||||
} else if( (inBuf[i+H_0] & 0xDC) == 0xD8 ) {
|
||||
} else if( (inBuf[i+H_0] & 0xFC) == 0xD8 ) {
|
||||
int abcde, BCDE;
|
||||
|
||||
PORT_Assert(((inBufLen - i) > 2) && ((inBuf[i+2+H_0] & 0xDC) == 0xDC) );
|
||||
PORT_Assert(((inBufLen - i) > 2) && ((inBuf[i+2+H_0] & 0xFC) == 0xDC) );
|
||||
|
||||
/* D800-DBFF DC00-DFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||
/* 110110BC DEfghijk 110111lm nopqrstu ->
|
||||
|
@ -852,6 +852,7 @@ struct ucs2 ucs2[] = {
|
|||
{ 0x9000, "\xE9\x80\x80" },
|
||||
{ 0xA000, "\xEA\x80\x80" },
|
||||
{ 0xC000, "\xEC\x80\x80" },
|
||||
{ 0xFB01, "\xEF\xAC\x81" },
|
||||
{ 0xFFFF, "\xEF\xBF\xBF" }
|
||||
|
||||
};
|
||||
|
@ -1161,6 +1162,8 @@ uint16_t utf16_bad[][3] = {
|
|||
{ 0xD800, 0xfe, 0 },
|
||||
{ 0xD800, 0x3bb, 0 },
|
||||
{ 0xD800, 0xD800, 0 },
|
||||
{ 0xD800, 0xFEFF, 0 },
|
||||
{ 0xD800, 0xFFFD, 0 },
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
0 seed_ecb_-D SEED_ECB_Decrypt
|
||||
0 seed_cbc_-E SEED_CBC_Encrypt
|
||||
0 seed_cbc_-D SEED_CBC_Decrypt
|
||||
0 chacha20_poly1305_-E ChaCha20_Poly1305_Encrypt
|
||||
0 chacha20_poly1305_-D ChaCha20_Poly1305_Decrypt
|
||||
0 rc2_ecb_-E RC2_ECB_Encrypt
|
||||
0 rc2_ecb_-D RC2_ECB_Decrypt
|
||||
0 rc2_cbc_-E RC2_CBC_Encrypt
|
||||
|
|
|
@ -85,12 +85,14 @@ ssl_init()
|
|||
|
||||
if [ -z "$NSS_DISABLE_ECC" ] ; then
|
||||
ECC_STRING=" - with ECC"
|
||||
# List of cipher suites to test, including ECC cipher suites.
|
||||
CIPHER_SUITES="-c ABCDEF:C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D:C00E:C00F:C010:C011:C012:C013:C014:C023:C027:C02B:C02F:CCA8:CCA9:CCAA:0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B:0084:009C:009E:00A2cdefgijklmnvyz"
|
||||
else
|
||||
ECC_STRING=""
|
||||
# List of cipher suites to test, excluding ECC cipher suites.
|
||||
CIPHER_SUITES="-c ABCDEF:0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B:0084:009C:009E:00A2:CCAAcdefgijklmnvyz"
|
||||
fi
|
||||
|
||||
CSHORT="-c ABCDEF:0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B:0084:009C:009E:00A2cdefgijklmnvyz"
|
||||
CLONG="-c ABCDEF:C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D:C00E:C00F:C010:C011:C012:C013:C014:C023:C027:C02B:C02F:0016:0032:0033:0038:0039:003B:003C:003D:0040:0041:0067:006A:006B:0084:009C:009E:00A2cdefgijklmnvyz"
|
||||
|
||||
if [ "${OS_ARCH}" != "WINNT" ]; then
|
||||
ulimit -n 1000 # make sure we have enough file descriptors
|
||||
|
@ -260,11 +262,7 @@ ssl_cov()
|
|||
html_head "SSL Cipher Coverage $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING"
|
||||
|
||||
testname=""
|
||||
if [ -z "$NSS_DISABLE_ECC" ] ; then
|
||||
sparam="$CLONG"
|
||||
else
|
||||
sparam="$CSHORT"
|
||||
fi
|
||||
sparam="$CIPHER_SUITES"
|
||||
|
||||
mixed=0
|
||||
start_selfserv # Launch the server
|
||||
|
@ -731,11 +729,7 @@ ssl_policy()
|
|||
html_head "SSL POLICY $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE $ECC_STRING"
|
||||
|
||||
testname=""
|
||||
if [ -z "$NSS_DISABLE_ECC" ] ; then
|
||||
sparam="$CLONG"
|
||||
else
|
||||
sparam="$CSHORT"
|
||||
fi
|
||||
sparam="$CIPHER_SUITES"
|
||||
|
||||
if [ ! -f "${P_R_CLIENTDIR}/pkcs11.txt" ] ; then
|
||||
return;
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
noECC TLS12 :009C TLS12_RSA_WITH_AES_128_GCM_SHA256
|
||||
noECC TLS12 :009E TLS12_DHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
noECC TLS12 :00A2 TLS12_DHE_DSS_WITH_AES_128_GCM_SHA256
|
||||
noECC TLS12 :CCAA TLS12_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
#
|
||||
# ECC ciphers (TLS)
|
||||
#
|
||||
|
@ -170,3 +171,5 @@
|
|||
ECC TLS12 :C027 TLS12_ECDHE_RSA_WITH_AES_128_CBC_SHA256
|
||||
ECC TLS12 :C02B TLS12_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||
ECC TLS12 :C02F TLS12_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||
ECC TLS12 :CCA8 TLS12_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
ECC TLS12 :CCA9 TLS12_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||
|
|
Загрузка…
Ссылка в новой задаче