Bug 1245053, landing NSS_3_23_BETA5, r=mt

This commit is contained in:
Kai Engert 2016-02-23 00:50:19 +01:00
Родитель e97ffb64eb
Коммит 5553a6adbf
100 изменённых файлов: 20559 добавлений и 16601 удалений

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

@ -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, &params->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タチツテトナニヌ

Двоичные данные
security/nss/cmd/bltest/tests/chacha20_poly1305/aad1 Normal file

Двоичный файл не отображается.

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

@ -0,0 +1 @@
0xqNNGSOYNt7hq+8U+9+wqSt7VEpbgj+qeK1pzbuYtY9vqRejKlnEoL6+2naknKLGnHeCp4GCykF1qW2fs07NpLdvX8td4uMmAOu4ygJG1j6syTk+tZ1lFWFgItIMde8P/Te8I5Lep3ldtJlhs7GS2EWGuELWU8J4mp+kC7L0GAGkQ==

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

@ -0,0 +1 @@
ZKCGFXWGGvRg8GLHm+ZDvV6AXP00XPOJ8QhnCsdsjLJMbPwYdV1D7qCe6U44LSawvbe3PDIbAQDU8Dt/NViUzzMvgw5xC5fOmMioSr0LlIEUrRduAI0zvWD5grH/N8hVl5egbvTw72HBhjJOKzUGODYGkHtqfAKw+fYVe1PIZ+S5Fmx2e4BNRqWbUhbN56TpkEDFpAQzIl7igqGwoGxSPq9FNNf4P6EVWwBHcYy8VGoNBysEs1ZO6htCInP1SCcaC7IxYFP6dpkZVevWMVlDTs67TkZtrloQc6ZydicJehBJ5hfZHTYQlPpo8P93mHEwMFvqui7aBN+Ze3FNbG8sKaatXLQCKwJwm+6tnWeJDLsiOSM2/qGFHzg=

Двоичные данные
security/nss/cmd/bltest/tests/chacha20_poly1305/iv0 Normal file

Двоичный файл не отображается.

Двоичные данные
security/nss/cmd/bltest/tests/chacha20_poly1305/iv1 Normal file

Двоичный файл не отображается.

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

@ -0,0 +1 @@
€≠ヤ<EFBFBD>㊧炎旧克署葬灯楓利劒屆撼<EFBFBD>

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

@ -0,0 +1 @@
<1C>@<40><><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, &params, &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, &params, &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, &params, &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, &params, &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,
&paramsi, 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