mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
nss: update to 3.44.1, with vc2013 fix and gyp fix
This commit is contained in:
parent
a2ef5fcde7
commit
d4b834111b
553 changed files with 1515569 additions and 1130 deletions
|
|
@ -21,10 +21,12 @@ tasks:
|
|||
$if: 'repository.url[-1] == "/"'
|
||||
then: {$eval: 'repository.url[:-1]'}
|
||||
else: {$eval: 'repository.url'}
|
||||
# scheduler id
|
||||
schedulerId: 'nss-level-${repository.level}'
|
||||
in:
|
||||
taskId: '${ownTaskId}'
|
||||
taskGroupId: '${ownTaskId}'
|
||||
schedulerId: 'nss-level-${repository.level}'
|
||||
schedulerId: '${schedulerId}'
|
||||
created: {$fromNow: ''}
|
||||
deadline: {$fromNow: '1 day'}
|
||||
expires: {$fromNow: '14 days'}
|
||||
|
|
@ -56,6 +58,7 @@ tasks:
|
|||
TC_OWNER: "${push.owner}"
|
||||
TC_SOURCE: "${repository.url}"
|
||||
TC_PROJECT: ${repository.project}
|
||||
TC_SCHEDULER_ID: "${schedulerId}"
|
||||
NSS_PUSHLOG_ID: '${push.pushlog_id}'
|
||||
NSS_HEAD_REPOSITORY: '${repository.url}'
|
||||
NSS_HEAD_REVISION: '${push.revision}'
|
||||
|
|
|
|||
|
|
@ -87,10 +87,10 @@ ifdef NS_USE_GCC
|
|||
NSPR_CONFIGURE_ENV = CC=gcc CXX=g++
|
||||
endif
|
||||
ifdef CC
|
||||
NSPR_CONFIGURE_ENV = CC=$(CC)
|
||||
NSPR_CONFIGURE_ENV = CC="$(CC)"
|
||||
endif
|
||||
ifdef CCC
|
||||
NSPR_CONFIGURE_ENV += CXX=$(CCC)
|
||||
NSPR_CONFIGURE_ENV += CXX="$(CCC)"
|
||||
endif
|
||||
# Remove -arch definitions. NSPR can't handle that.
|
||||
NSPR_CONFIGURE_ENV := $(filter-out -arch x86_64,$(NSPR_CONFIGURE_ENV))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
|
||||
1 Added function:
|
||||
|
||||
'function SECOidTag HASH_GetHashOidTagByHashType(HASH_HashType)' {HASH_GetHashOidTagByHashType@@NSS_3.43}
|
||||
'function SECStatus CERT_GetCertificateDer(const CERTCertificate*, SECItem*)' {CERT_GetCertificateDer@@NSS_3.44}
|
||||
|
||||
1 function with some indirect sub-type change:
|
||||
|
||||
[C]'function SECStatus CERT_AddOCSPAcceptableResponses(CERTOCSPRequest*, SECOidTag, ...)' at ocsp.c:2203:1 has some indirect sub-type changes:
|
||||
parameter 2 of type 'typedef SECOidTag' has sub-type changes:
|
||||
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
|
||||
type size hasn't changed
|
||||
3 enumerator insertions:
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_END' value '361'
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL' value '362'
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_USER' value '363'
|
||||
|
||||
1 enumerator change:
|
||||
'__anonymous_enum__::SEC_OID_TOTAL' from value '361' to '364' at secoidt.h:34:1
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
1 function with some indirect sub-type change:
|
||||
|
||||
[C]'function SECStatus NSS_GetAlgorithmPolicy(SECOidTag, PRUint32*)' at secoid.c:2234:1 has some indirect sub-type changes:
|
||||
parameter 1 of type 'typedef SECOidTag' has sub-type changes:
|
||||
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
|
||||
type size hasn't changed
|
||||
3 enumerator insertions:
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_END' value '361'
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL' value '362'
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_USER' value '363'
|
||||
|
||||
1 enumerator change:
|
||||
'__anonymous_enum__::SEC_OID_TOTAL' from value '361' to '364' at secoidt.h:34:1
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
1 function with some indirect sub-type change:
|
||||
|
||||
[C]'function PK11SymKey* NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo*)' at cmscinfo.c:426:1 has some indirect sub-type changes:
|
||||
parameter 1 of type 'NSSCMSContentInfo*' has sub-type changes:
|
||||
in pointed to type 'typedef NSSCMSContentInfo' at cmst.h:54:1:
|
||||
underlying type 'struct NSSCMSContentInfoStr' at cmst.h:126:1 changed:
|
||||
type size hasn't changed
|
||||
1 data member changes (2 filtered):
|
||||
type of 'NSSCMSContent NSSCMSContentInfoStr::content' changed:
|
||||
underlying type 'union NSSCMSContentUnion' at cmst.h:113:1 changed:
|
||||
type size hasn't changed
|
||||
1 data member changes (3 filtered):
|
||||
type of 'NSSCMSEncryptedData* NSSCMSContentUnion::encryptedData' changed:
|
||||
in pointed to type 'typedef NSSCMSEncryptedData' at cmst.h:65:1:
|
||||
underlying type 'struct NSSCMSEncryptedDataStr' at cmst.h:463:1 changed:
|
||||
type size hasn't changed
|
||||
1 data member changes (1 filtered):
|
||||
type of 'NSSCMSAttribute** NSSCMSEncryptedDataStr::unprotectedAttr' changed:
|
||||
in pointed to type 'NSSCMSAttribute*':
|
||||
in pointed to type 'typedef NSSCMSAttribute' at cmst.h:69:1:
|
||||
underlying type 'struct NSSCMSAttributeStr' at cmst.h:482:1 changed:
|
||||
type size hasn't changed
|
||||
1 data member change:
|
||||
type of 'SECOidData* NSSCMSAttributeStr::typeTag' changed:
|
||||
in pointed to type 'typedef SECOidData' at secoidt.h:16:1:
|
||||
underlying type 'struct SECOidDataStr' at secoidt.h:518:1 changed:
|
||||
type size hasn't changed
|
||||
1 data member change:
|
||||
type of 'SECOidTag SECOidDataStr::offset' changed:
|
||||
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
|
||||
type size hasn't changed
|
||||
3 enumerator insertions:
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_END' value '361'
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL' value '362'
|
||||
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_USER' value '363'
|
||||
|
||||
1 enumerator change:
|
||||
'__anonymous_enum__::SEC_OID_TOTAL' from value '361' to '364' at secoidt.h:34:1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
2 functions with some indirect sub-type change:
|
||||
|
||||
[C]'function SECStatus SSL_GetCipherSuiteInfo(PRUint16, SSLCipherSuiteInfo*, PRUintn)' at sslinfo.c:326:1 has some indirect sub-type changes:
|
||||
parameter 2 of type 'SSLCipherSuiteInfo*' has sub-type changes:
|
||||
in pointed to type 'typedef SSLCipherSuiteInfo' at sslt.h:433:1:
|
||||
underlying type 'struct SSLCipherSuiteInfoStr' at sslt.h:366:1 changed:
|
||||
type size changed from 768 to 832 (in bits)
|
||||
1 data member insertion:
|
||||
'SSLHashType SSLCipherSuiteInfoStr::kdfHash', at offset 768 (in bits) at sslt.h:429:1
|
||||
|
||||
[C]'function SECStatus SSL_GetPreliminaryChannelInfo(PRFileDesc*, SSLPreliminaryChannelInfo*, PRUintn)' at sslinfo.c:111:1 has some indirect sub-type changes:
|
||||
parameter 2 of type 'SSLPreliminaryChannelInfo*' has sub-type changes:
|
||||
in pointed to type 'typedef SSLPreliminaryChannelInfo' at sslt.h:379:1:
|
||||
underlying type 'struct SSLPreliminaryChannelInfoStr' at sslt.h:333:1 changed:
|
||||
type size changed from 160 to 192 (in bits)
|
||||
1 data member insertion:
|
||||
'PRUint16 SSLPreliminaryChannelInfoStr::zeroRttCipherSuite', at offset 160 (in bits) at sslt.h:375:1
|
||||
|
||||
|
||||
|
|
@ -1 +1 @@
|
|||
NSS_3_42_BRANCH
|
||||
NSS_3_43_BRANCH
|
||||
|
|
|
|||
|
|
@ -924,9 +924,13 @@ async function scheduleWindows(name, base, build_script) {
|
|||
|
||||
function scheduleTests(task_build, task_cert, test_base) {
|
||||
test_base = merge(test_base, {kind: "test"});
|
||||
|
||||
// Schedule tests that do NOT need certificates.
|
||||
let no_cert_base = merge(test_base, {parent: task_build});
|
||||
let cert_base = merge(test_base, {parent: task_cert});
|
||||
let cert_base_long = merge(cert_base, {maxRunTime: 7200});
|
||||
|
||||
// Schedule tests that do NOT need certificates. This is defined as
|
||||
// the test itself not needing certs AND not running under the upgradedb
|
||||
// cycle (which itself needs certs). If cycle is not defined, default is all.
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "Gtests", symbol: "Gtest", tests: "ssl_gtests gtests", cycle: "standard"
|
||||
}));
|
||||
|
|
@ -947,46 +951,45 @@ function scheduleTests(task_build, task_cert, test_base) {
|
|||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "tlsfuzzer tests", symbol: "tlsfuzzer", tests: "tlsfuzzer", cycle: "standard"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base, {
|
||||
name: "Chains tests", symbol: "Chains", tests: "chains"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base_long, {
|
||||
name: "Cipher tests", symbol: "Default", tests: "cipher", group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base_long, {
|
||||
name: "Cipher tests", symbol: "NoAESNI", tests: "cipher",
|
||||
env: {NSS_DISABLE_HW_AES: "1"}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base_long, {
|
||||
name: "Cipher tests", symbol: "NoPCLMUL", tests: "cipher",
|
||||
env: {NSS_DISABLE_PCLMUL: "1"}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base_long, {
|
||||
name: "Cipher tests", symbol: "NoAVX", tests: "cipher",
|
||||
env: {NSS_DISABLE_AVX: "1"}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base_long, {
|
||||
name: "Cipher tests", symbol: "NoSSSE3|NEON", tests: "cipher",
|
||||
env: {
|
||||
NSS_DISABLE_ARM_NEON: "1",
|
||||
NSS_DISABLE_SSSE3: "1"
|
||||
}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base, {
|
||||
name: "EC tests", symbol: "EC", tests: "ec"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base, {
|
||||
name: "Lowhash tests", symbol: "Lowhash", tests: "lowhash"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base, {
|
||||
name: "SDR tests", symbol: "SDR", tests: "sdr"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
queue.scheduleTask(merge(cert_base, {
|
||||
name: "Policy tests", symbol: "Policy", tests: "policy"
|
||||
}));
|
||||
|
||||
// Schedule tests that need certificates.
|
||||
let cert_base = merge(test_base, {parent: task_cert});
|
||||
queue.scheduleTask(merge(cert_base, {
|
||||
name: "CRMF tests", symbol: "CRMF", tests: "crmf"
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -135,7 +135,8 @@ function convertTask(def) {
|
|||
return {
|
||||
provisionerId: def.provisioner || "aws-provisioner-v1",
|
||||
workerType: def.workerType || "hg-worker",
|
||||
schedulerId: "task-graph-scheduler",
|
||||
schedulerId: process.env.TC_SCHEDULER_ID,
|
||||
taskGroupId: process.env.TASK_ID,
|
||||
|
||||
scopes,
|
||||
created: fromNow(0),
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ export async function initFilter() {
|
|||
let comment = await getCommitComment();
|
||||
|
||||
// Check for try syntax in changeset comment.
|
||||
let match = comment.match(/^\s*try:\s*(.*)\s*$/);
|
||||
let match = comment.match(/\btry:\s*(.*)\s*$/m);
|
||||
|
||||
// Add try syntax filter.
|
||||
if (match) {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ abi_diff()
|
|||
cat ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt \
|
||||
| grep -v "^Functions changes summary:" \
|
||||
| grep -v "^Variables changes summary:" \
|
||||
| sed -e 's/__anonymous_enum__[0-9]*/__anonymous_enum__/g' \
|
||||
> ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt
|
||||
rm -f ${HGDIR}/nss/automation/abi-check/new-report-temp$SO.txt
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ fuzz=0
|
|||
fuzz_tls=0
|
||||
fuzz_oss=0
|
||||
no_local_nspr=0
|
||||
sslkeylogfile=1
|
||||
|
||||
gyp_params=(--depth="$cwd" --generator-output=".")
|
||||
ninja_params=()
|
||||
|
|
@ -94,7 +95,8 @@ while [ $# -gt 0 ]; do
|
|||
--sancov=?*) enable_sancov "${1#*=}" ;;
|
||||
--emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
|
||||
--no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
|
||||
--test) gyp_params+=(-Dtest_build=1) ;;
|
||||
--test) gyp_params+=(-Dtest_build=1 -Dstatic_libs=1) ;;
|
||||
--static) gyp_params+=(-Dstatic_libs=1) ;;
|
||||
--ct-verif) gyp_params+=(-Dct_verif=1) ;;
|
||||
--nspr) nspr_clean; rebuild_nspr=1 ;;
|
||||
--with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;;
|
||||
|
|
@ -103,6 +105,7 @@ while [ $# -gt 0 ]; do
|
|||
--enable-fips) gyp_params+=(-Ddisable_fips=0) ;;
|
||||
--enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;;
|
||||
--mozpkix-only) gyp_params+=(-Dmozpkix_only=1 -Ddisable_tests=1 -Dsign_libs=0) ;;
|
||||
--disable-keylog) sslkeylogfile=0 ;;
|
||||
-D*) gyp_params+=("$1") ;;
|
||||
*) show_help; exit 2 ;;
|
||||
esac
|
||||
|
|
@ -117,6 +120,8 @@ else
|
|||
target=Debug
|
||||
fi
|
||||
|
||||
#gyp_params+=(-Denable_sslkeylogfile="$sslkeylogfile")
|
||||
|
||||
# Do special setup.
|
||||
if [ "$fuzz" = 1 ]; then
|
||||
source "$cwd"/coreconf/fuzz.sh
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ main(int argc, char **argv)
|
|||
|
||||
/* Parse command line arguments */
|
||||
optstate = PL_CreateOptState(argc, argv, "i:o:w:");
|
||||
PORT_Assert(optstate);
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch (optstate->option) {
|
||||
default:
|
||||
|
|
@ -203,9 +204,7 @@ main(int argc, char **argv)
|
|||
}
|
||||
exitCode = 0;
|
||||
loser:
|
||||
if (optstate) {
|
||||
PL_DestroyOptState(optstate);
|
||||
}
|
||||
PL_DestroyOptState(optstate);
|
||||
if (inFile && closeIn) {
|
||||
fclose(inFile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -497,6 +497,13 @@ static const char *const
|
|||
"ocspResponder",
|
||||
"stepUp",
|
||||
"msTrustListSigning",
|
||||
"x509Any",
|
||||
"ipsecIKE",
|
||||
"ipsecIKEEnd",
|
||||
"ipsecIKEIntermediate",
|
||||
"ipsecEnd",
|
||||
"ipsecTunnel",
|
||||
"ipsecUser",
|
||||
NULL };
|
||||
|
||||
static SECStatus
|
||||
|
|
@ -517,6 +524,10 @@ AddExtKeyUsage(void *extHandle, const char *userSuppliedValue)
|
|||
|
||||
while (1) {
|
||||
if (!userSuppliedValue) {
|
||||
/*
|
||||
* none of the 'new' extended key usage options work with the prompted menu. This is so
|
||||
* old scripts can continue to work.
|
||||
*/
|
||||
if (PrintChoicesAndGetAnswer(
|
||||
"\t\t0 - Server Auth\n"
|
||||
"\t\t1 - Client Auth\n"
|
||||
|
|
@ -572,6 +583,45 @@ AddExtKeyUsage(void *extHandle, const char *userSuppliedValue)
|
|||
case 7:
|
||||
rv = AddOidToSequence(os, SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING);
|
||||
break;
|
||||
/*
|
||||
* These new usages can only be added explicitly by the userSuppliedValues. This allows old
|
||||
* scripts which used '>7' as an exit value to continue to work.
|
||||
*/
|
||||
case 8:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_X509_ANY_EXT_KEY_USAGE);
|
||||
break;
|
||||
case 9:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_IKE);
|
||||
break;
|
||||
case 10:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_IPSEC_IKE_END);
|
||||
break;
|
||||
case 11:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_IPSEC_IKE_INTERMEDIATE);
|
||||
break;
|
||||
case 12:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_END);
|
||||
break;
|
||||
case 13:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL);
|
||||
break;
|
||||
case 14:
|
||||
if (!userSuppliedValue)
|
||||
goto endloop;
|
||||
rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_IPSEC_USER);
|
||||
break;
|
||||
default:
|
||||
goto endloop;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1362,8 +1362,11 @@ luC(enum usage_level ul, const char *command)
|
|||
"%-20s Create extended key usage extension. Possible keywords:\n"
|
||||
"%-20s \"serverAuth\", \"clientAuth\",\"codeSigning\",\n"
|
||||
"%-20s \"emailProtection\", \"timeStamp\",\"ocspResponder\",\n"
|
||||
"%-20s \"stepUp\", \"msTrustListSign\", \"critical\"\n",
|
||||
" -6 | --extKeyUsage keyword,keyword,...", "", "", "", "");
|
||||
"%-20s \"stepUp\", \"msTrustListSign\", \"x509Any\",\n"
|
||||
"%-20s \"ipsecIKE\", \"ipsecIKEEnd\", \"ipsecIKEIntermediate\",\n"
|
||||
"%-20s \"ipsecEnd\", \"ipsecTunnel\", \"ipsecUser\",\n"
|
||||
"%-20s \"critical\"\n",
|
||||
" -6 | --extKeyUsage keyword,keyword,...", "", "", "", "", "", "", "");
|
||||
FPS "%-20s Create an email subject alt name extension\n",
|
||||
" -7 emailAddrs");
|
||||
FPS "%-20s Create an dns subject alt name extension\n",
|
||||
|
|
@ -3120,7 +3123,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
|||
PR_fprintf(PR_STDERR,
|
||||
"%s -%c: specify a nickname (-n) or\n"
|
||||
" a key ID (-k).\n",
|
||||
commandToRun, progName);
|
||||
progName, commandToRun);
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
|
|
|||
1
security/nss/cmd/fipstest/README
Normal file
1
security/nss/cmd/fipstest/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
The scripts have been moved to tests/fips/cavs_scripts
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -185,7 +185,7 @@ cleanup:
|
|||
}
|
||||
|
||||
static const char *const usageInfo[] = {
|
||||
"pk11import - test PK11_PrivateKeyImport()"
|
||||
"pk11import - test PK11_PrivateKeyImport()",
|
||||
"Options:",
|
||||
" -d certdir directory containing cert database",
|
||||
" -k keysize size of the rsa, dh, and dsa key to test (default 1024)",
|
||||
|
|
|
|||
|
|
@ -233,7 +233,9 @@ PrintParameterUsage()
|
|||
" ecdsa_secp521r1_sha512,\n"
|
||||
" rsa_pss_rsae_sha256, rsa_pss_rsae_sha384, rsa_pss_rsae_sha512,\n"
|
||||
" rsa_pss_pss_sha256, rsa_pss_pss_sha384, rsa_pss_pss_sha512,\n"
|
||||
"-Z enable 0-RTT (for TLS 1.3; also use -u)\n",
|
||||
"-Z enable 0-RTT (for TLS 1.3; also use -u)\n"
|
||||
"-E enable post-handshake authentication\n"
|
||||
" (for TLS 1.3; only has an effect with 3 or more -r options)\n",
|
||||
stderr);
|
||||
}
|
||||
|
||||
|
|
@ -804,6 +806,7 @@ PRBool failedToNegotiateName = PR_FALSE;
|
|||
PRBool enableExtendedMasterSecret = PR_FALSE;
|
||||
PRBool zeroRTT = PR_FALSE;
|
||||
PRBool enableALPN = PR_FALSE;
|
||||
PRBool enablePostHandshakeAuth = PR_FALSE;
|
||||
SSLNamedGroup *enabledGroups = NULL;
|
||||
unsigned int enabledGroupsCount = 0;
|
||||
const SSLSignatureScheme *enabledSigSchemes = NULL;
|
||||
|
|
@ -1431,15 +1434,28 @@ handle_connection(PRFileDesc *tcp_sock, PRFileDesc *model_sock)
|
|||
errWarn("second SSL_OptionSet SSL_REQUIRE_CERTIFICATE");
|
||||
break;
|
||||
}
|
||||
rv = SSL_ReHandshake(ssl_sock, PR_TRUE);
|
||||
if (rv != 0) {
|
||||
errWarn("SSL_ReHandshake");
|
||||
break;
|
||||
}
|
||||
rv = SSL_ForceHandshake(ssl_sock);
|
||||
if (rv < 0) {
|
||||
errWarn("SSL_ForceHandshake");
|
||||
break;
|
||||
if (enablePostHandshakeAuth) {
|
||||
rv = SSL_SendCertificateRequest(ssl_sock);
|
||||
if (rv != SECSuccess) {
|
||||
errWarn("SSL_SendCertificateRequest");
|
||||
break;
|
||||
}
|
||||
rv = SSL_ForceHandshake(ssl_sock);
|
||||
if (rv != SECSuccess) {
|
||||
errWarn("SSL_ForceHandshake");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rv = SSL_ReHandshake(ssl_sock, PR_TRUE);
|
||||
if (rv != 0) {
|
||||
errWarn("SSL_ReHandshake");
|
||||
break;
|
||||
}
|
||||
rv = SSL_ForceHandshake(ssl_sock);
|
||||
if (rv < 0) {
|
||||
errWarn("SSL_ForceHandshake");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1948,6 +1964,16 @@ server_main(
|
|||
}
|
||||
}
|
||||
|
||||
if (enablePostHandshakeAuth) {
|
||||
if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
errExit("You tried enabling post-handshake auth without enabling TLS 1.3!");
|
||||
}
|
||||
rv = SSL_OptionSet(model_sock, SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling post-handshake auth");
|
||||
}
|
||||
}
|
||||
|
||||
if (enableALPN) {
|
||||
PRUint8 alpnVal[] = { 0x08,
|
||||
0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31 };
|
||||
|
|
@ -2223,7 +2249,7 @@ main(int argc, char **argv)
|
|||
** in 3.28, please leave some time before resuing those.
|
||||
** 'z' was removed in 3.39. */
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"2:A:C:DGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y");
|
||||
"2:A:C:DEGH:I:J:L:M:NP:QRS:T:U:V:W:YZa:bc:d:e:f:g:hi:jk:lmn:op:rst:uvw:y");
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
++optionsFound;
|
||||
switch (optstate->option) {
|
||||
|
|
@ -2243,6 +2269,11 @@ main(int argc, char **argv)
|
|||
case 'D':
|
||||
noDelay = PR_TRUE;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
enablePostHandshakeAuth = PR_TRUE;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
configureDHE = (PORT_Atoi(optstate->value) != 0);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ PrintUsageHeader()
|
|||
fprintf(stderr,
|
||||
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
|
||||
" [-D | -d certdir] [-C] [-b | -R root-module] \n"
|
||||
" [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n"
|
||||
" [-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z] [-E]\n"
|
||||
" [-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
|
||||
" [-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n"
|
||||
" [-I groups] [-J signatureschemes]\n"
|
||||
|
|
@ -311,6 +311,9 @@ PrintParameterUsage()
|
|||
fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}");
|
||||
fprintf(stderr, "%-20s Exit after handshake\n", "-Q");
|
||||
fprintf(stderr, "%-20s Encrypted SNI Keys\n", "-N");
|
||||
fprintf(stderr, "%-20s Enable post-handshake authentication\n"
|
||||
"%-20s for TLS 1.3; need to specify -n\n",
|
||||
"-E", "");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -989,6 +992,7 @@ PRBool requestToExit = PR_FALSE;
|
|||
char *versionString = NULL;
|
||||
PRBool handshakeComplete = PR_FALSE;
|
||||
char *encryptedSNIKeys = NULL;
|
||||
PRBool enablePostHandshakeAuth = PR_FALSE;
|
||||
|
||||
static int
|
||||
writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb)
|
||||
|
|
@ -1410,6 +1414,15 @@ run()
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (enablePostHandshakeAuth) {
|
||||
rv = SSL_OptionSet(s, SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "error enabling post-handshake auth");
|
||||
error = 1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabledGroups) {
|
||||
rv = SSL_NamedGroupConfig(s, enabledGroups, enabledGroupsCount);
|
||||
if (rv < 0) {
|
||||
|
|
@ -1707,7 +1720,7 @@ main(int argc, char **argv)
|
|||
* Please leave some time before reusing these.
|
||||
*/
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"46A:CDFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
|
||||
"46A:CDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
|
||||
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
|
|
@ -1738,6 +1751,10 @@ main(int argc, char **argv)
|
|||
openDB = PR_FALSE;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
enablePostHandshakeAuth = PR_TRUE;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
if (serverCertAuth.testFreshStatusFromSideChannel) {
|
||||
/* parameter given twice or more */
|
||||
|
|
@ -1988,6 +2005,11 @@ main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (enablePostHandshakeAuth && !nickname) {
|
||||
fprintf(stderr, "%s: -E requires the use of -n\n", progName);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
|
||||
|
||||
PK11_SetPasswordFunc(SECU_GetModulePassword);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,10 @@ ifeq ($(KERNEL),Linux)
|
|||
endif
|
||||
OS_LIBS = $(OS_PTHREAD) -ldl -lc
|
||||
|
||||
ifeq ($(OS_TARGET),Android)
|
||||
OS_LIBS += -llog
|
||||
endif
|
||||
|
||||
ifdef USE_PTHREADS
|
||||
DEFINES += -D_REENTRANT
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -5,17 +5,18 @@ import subprocess
|
|||
import sys
|
||||
|
||||
def main():
|
||||
if sys.platform == 'win32':
|
||||
if sys.platform == 'win32' or len(sys.argv) < 2:
|
||||
print(0)
|
||||
else:
|
||||
cc = os.environ.get('CC', 'cc')
|
||||
try:
|
||||
cc_is_clang = 'clang' in subprocess.check_output(
|
||||
cc_is_arg = sys.argv[1] in subprocess.check_output(
|
||||
[cc, '--version'], universal_newlines=True)
|
||||
except OSError:
|
||||
# We probably just don't have CC/cc.
|
||||
cc_is_clang = False
|
||||
print(int(cc_is_clang))
|
||||
cc_is_arg = False
|
||||
print(int(cc_is_arg))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
'conditions': [
|
||||
['OS=="android"', {
|
||||
'target_arch%': 'arm',
|
||||
}, 'OS=="ios"', {
|
||||
'target_arch%': 'arm64',
|
||||
}, {
|
||||
# Default architecture we're building for is the architecture we're
|
||||
# building on.
|
||||
|
|
@ -35,7 +37,7 @@
|
|||
},{
|
||||
'use_system_sqlite%': 0,
|
||||
}],
|
||||
['OS=="mac" or OS=="win"', {
|
||||
['OS=="mac" or OS=="ios" or OS=="win"', {
|
||||
'cc_use_gnu_ld%': 0,
|
||||
}, {
|
||||
'cc_use_gnu_ld%': 1,
|
||||
|
|
@ -54,7 +56,7 @@
|
|||
'zlib_libs%': ['-lz'],
|
||||
'dll_prefix': 'lib',
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
['OS=="mac" or OS=="ios"', {
|
||||
'moz_debug_flags%': '-gdwarf-2 -gfull',
|
||||
'dll_suffix': 'dylib',
|
||||
}, {
|
||||
|
|
@ -64,10 +66,15 @@
|
|||
],
|
||||
}],
|
||||
['"<(GENERATOR)"=="ninja"', {
|
||||
'cc_is_clang%': '<!(<(python) <(DEPTH)/coreconf/check_cc_clang.py)',
|
||||
'cc_is_clang%': '<!(<(python) <(DEPTH)/coreconf/check_cc.py clang)',
|
||||
}, {
|
||||
'cc_is_clang%': '0',
|
||||
}],
|
||||
['"<(GENERATOR)"=="ninja"', {
|
||||
'cc_is_gcc%': '<!(<(python) <(DEPTH)/coreconf/check_cc.py gcc)',
|
||||
}, {
|
||||
'cc_is_gcc%': '0',
|
||||
}],
|
||||
],
|
||||
},
|
||||
# Copy conditionally-set variables out one scope.
|
||||
|
|
@ -86,6 +93,7 @@
|
|||
'dll_suffix': '<(dll_suffix)',
|
||||
'freebl_name': '<(freebl_name)',
|
||||
'cc_is_clang%': '<(cc_is_clang)',
|
||||
'cc_is_gcc%': '<(cc_is_gcc)',
|
||||
'cc_use_gnu_ld%': '<(cc_use_gnu_ld)',
|
||||
# Some defaults
|
||||
'disable_tests%': 0,
|
||||
|
|
@ -99,6 +107,7 @@
|
|||
'moz_folded_library_name%': '',
|
||||
'sanitizer_flags%': 0,
|
||||
'test_build%': 0,
|
||||
'static_libs%': 0,
|
||||
'no_zdefs%': 0,
|
||||
'fuzz%': 0,
|
||||
'fuzz_tls%': 0,
|
||||
|
|
@ -122,6 +131,7 @@
|
|||
'variables': {
|
||||
'mapfile%': '',
|
||||
'test_build%': 0,
|
||||
'static_libs%': 0,
|
||||
'debug_optimization_level%': '0',
|
||||
'release_optimization_level%': '2',
|
||||
},
|
||||
|
|
@ -142,7 +152,12 @@
|
|||
'NSS_NO_INIT_SUPPORT',
|
||||
],
|
||||
}],
|
||||
[ 'OS!="android" and OS!="mac" and OS!="win"', {
|
||||
[ 'static_libs==1', {
|
||||
'variables': {
|
||||
'standalone_static_library': '1',
|
||||
},
|
||||
}],
|
||||
[ 'OS!="android" and OS!="mac" and OS!="ios" and OS!="win"', {
|
||||
'libraries': [
|
||||
'-lpthread',
|
||||
],
|
||||
|
|
@ -153,6 +168,11 @@
|
|||
'-lc',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="android"', {
|
||||
'libraries': [
|
||||
'-llog',
|
||||
],
|
||||
}],
|
||||
[ 'fuzz==1', {
|
||||
'variables': {
|
||||
'debug_optimization_level%': '1',
|
||||
|
|
@ -257,7 +277,7 @@
|
|||
}],
|
||||
}]
|
||||
],
|
||||
}, 'test_build==1 and _type=="shared_library"', {
|
||||
}, 'static_libs==1 and _type=="shared_library"', {
|
||||
# When linking a shared lib against a static one, XCode doesn't
|
||||
# export the latter's symbols by default. -all_load fixes that.
|
||||
'xcode_settings': {
|
||||
|
|
@ -355,7 +375,7 @@
|
|||
'OPENBSD',
|
||||
],
|
||||
}],
|
||||
['OS=="mac" or OS=="dragonfly" or OS=="freebsd" or OS=="netbsd" or OS=="openbsd"', {
|
||||
['OS=="mac" or OS=="ios" or OS=="dragonfly" or OS=="freebsd" or OS=="netbsd" or OS=="openbsd"', {
|
||||
'defines': [
|
||||
'HAVE_BSD_FLOCK',
|
||||
],
|
||||
|
|
@ -367,7 +387,7 @@
|
|||
'_REENTRANT',
|
||||
],
|
||||
}],
|
||||
[ 'OS!="mac" and OS!="win"', {
|
||||
[ 'OS!="mac" and OS!="ios" and OS!="win"', {
|
||||
'cflags': [
|
||||
'-fPIC',
|
||||
'-pipe',
|
||||
|
|
@ -393,7 +413,7 @@
|
|||
}],
|
||||
[ 'use_pprof==1 and OS!="android" and OS!="win"', {
|
||||
'conditions': [
|
||||
[ 'OS=="mac"', {
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_LDFLAGS': [ '-lprofiler' ],
|
||||
},
|
||||
|
|
@ -453,7 +473,7 @@
|
|||
'ANDROID',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="mac"', {
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'defines': [
|
||||
'DARWIN',
|
||||
],
|
||||
|
|
@ -468,8 +488,18 @@
|
|||
'ARCHS': ['x86_64'],
|
||||
},
|
||||
}],
|
||||
[ 'target_arch=="arm64"', {
|
||||
'xcode_settings': {
|
||||
'ARCHS': ['arm64'],
|
||||
},
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'OS=="ios"', {
|
||||
'xcode_settings': {
|
||||
'IPHONEOS_DEPLOYMENT_TARGET': '<(iphone_deployment_target)',
|
||||
},
|
||||
}],
|
||||
[ 'OS=="win"', {
|
||||
'defines': [
|
||||
'_WINDOWS',
|
||||
|
|
@ -537,7 +567,7 @@
|
|||
'Debug': {
|
||||
'inherit_from': ['Common'],
|
||||
'conditions': [
|
||||
[ 'OS!="mac" and OS!="win"', {
|
||||
[ 'OS!="mac" and OS!="ios" and OS!="win"', {
|
||||
'cflags': [
|
||||
'-g',
|
||||
'<(moz_debug_flags)',
|
||||
|
|
@ -607,7 +637,7 @@
|
|||
'process_map_file': ['/bin/sh', '-c', '/usr/bin/env grep -v ";-" >(mapfile) | sed -e "s,;+,," -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,;," > >@(_outputs)'],
|
||||
},
|
||||
}],
|
||||
[ 'OS=="mac"', {
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'variables': {
|
||||
'process_map_file': ['/bin/sh', '-c', '/usr/bin/grep -v ";+" >(mapfile) | grep -v ";-" | sed -e "s; DATA ;;" -e "s,;;,," -e "s,;.*,," -e "s,^,_," > >@(_outputs)'],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ if [ -z "$CC" ]; then
|
|||
export CXX=clang++
|
||||
fi
|
||||
|
||||
gyp_params+=(-Dtest_build=1 -Dfuzz=1 -Dsign_libs=0)
|
||||
gyp_params+=(-Dtest_build=1 -Dstatic_libs=1 -Dfuzz=1 -Dsign_libs=0)
|
||||
|
||||
# Add debug symbols even for opt builds.
|
||||
nspr_params+=(--enable-debug-symbols)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ const uint8_t kTlsAlertInappropriateFallback = 86;
|
|||
const uint8_t kTlsAlertMissingExtension = 109;
|
||||
const uint8_t kTlsAlertUnsupportedExtension = 110;
|
||||
const uint8_t kTlsAlertUnrecognizedName = 112;
|
||||
const uint8_t kTlsAlertCertificateRequired = 116;
|
||||
const uint8_t kTlsAlertNoApplicationProtocol = 120;
|
||||
|
||||
const uint8_t kTlsFakeChangeCipherSpec[] = {
|
||||
|
|
|
|||
|
|
@ -427,6 +427,9 @@ of the attribute codes:
|
|||
</listitem>
|
||||
<listitem>
|
||||
<para><command>J</command> (as an object signer)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><command>I</command> (as an IPSEC user)</para>
|
||||
</listitem>
|
||||
</itemizedlist></listitem>
|
||||
</varlistentry>
|
||||
|
|
@ -662,6 +665,41 @@ of the attribute codes:
|
|||
critical
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
x509Any
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ipsecIKE
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ipsecIKEEnd
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ipsecIKEIntermediate
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ipsecEnd
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ipsecTunnel
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
ipsecUser
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>X.509 certificate extensions are described in RFC 5280.</para></listitem>
|
||||
</varlistentry>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
'type': 'executable',
|
||||
'sources': [
|
||||
'alg1485_unittest.cc',
|
||||
'cert_unittest.cc',
|
||||
'decode_certs_unittest.cc',
|
||||
'<(DEPTH)/gtests/common/gtests.cc'
|
||||
],
|
||||
'dependencies': [
|
||||
|
|
@ -20,6 +22,7 @@
|
|||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss3',
|
||||
'<(DEPTH)/lib/smime/smime.gyp:smime3',
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ MODULE = nss
|
|||
|
||||
CPPSRCS = \
|
||||
alg1485_unittest.cc \
|
||||
cert_unittest.cc \
|
||||
decode_certs_unittest.cc \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
|
||||
|
|
|
|||
|
|
@ -1,172 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef gcm_vectors_h__
|
||||
#define gcm_vectors_h__
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef struct gcm_kat_str {
|
||||
std::string key;
|
||||
std::string plaintext;
|
||||
std::string additional_data;
|
||||
std::string iv;
|
||||
std::string hash_key;
|
||||
std::string ghash;
|
||||
std::string result;
|
||||
} gcm_kat_value;
|
||||
|
||||
/*
|
||||
* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf
|
||||
*/
|
||||
const gcm_kat_value kGcmKatValues[] = {
|
||||
{"00000000000000000000000000000000", "", "", "000000000000000000000000",
|
||||
"66e94bd4ef8a2c3b884cfa59ca342b2e", "00000000000000000000000000000000",
|
||||
"58e2fccefa7e3061367f1d57a4e7455a"},
|
||||
|
||||
{"00000000000000000000000000000000", "00000000000000000000000000000000", "",
|
||||
"000000000000000000000000", "66e94bd4ef8a2c3b884cfa59ca342b2e",
|
||||
"f38cbb1ad69223dcc3457ae5b6b0f885",
|
||||
"0388dace60b6a392f328c2b971b2fe78ab6e47d42cec13bdf53a67b21257bddf"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
|
||||
"", "cafebabefacedbaddecaf888", "b83b533708bf535d0aa6e52980d53b78",
|
||||
"7f1b32b81b820d02614f8895ac1d4eac",
|
||||
"42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25"
|
||||
"466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62c"
|
||||
"f35abd2ba6fab4"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2", "cafebabefacedbaddecaf888",
|
||||
"b83b533708bf535d0aa6e52980d53b78", "698e57f70e6ecc7fd9463b7260a9ae5f",
|
||||
"42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25"
|
||||
"466931c7d8f6a5aac84aa051ba30b396a0aac973d58e0915bc94fbc3221a5db94fae95ae7"
|
||||
"121a47"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2", "cafebabefacedbad",
|
||||
"b83b533708bf535d0aa6e52980d53b78", "df586bb4c249b92cb6922877e444d37b",
|
||||
"61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e"
|
||||
"49f24b22b097544d4896b424989b5e1ebac0f07c23f45983612d2e79e3b0785561be14aac"
|
||||
"a2fccb"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c9515"
|
||||
"6809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
||||
"b83b533708bf535d0aa6e52980d53b78", "1c5afe9760d3932f3c9a878aac3dc3de",
|
||||
"8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4f"
|
||||
"ba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5619cc5aefffe0bfa462af43c16"
|
||||
"99d050"},
|
||||
|
||||
{"000000000000000000000000000000000000000000000000", "", "",
|
||||
"000000000000000000000000", "aae06992acbf52a3e8f4a96ec9300bd7",
|
||||
"00000000000000000000000000000000", "cd33b28ac773f74ba00ed1f312572435"},
|
||||
|
||||
{"000000000000000000000000000000000000000000000000",
|
||||
"00000000000000000000000000000000", "", "000000000000000000000000",
|
||||
"aae06992acbf52a3e8f4a96ec9300bd7", "e2c63f0ac44ad0e02efa05ab6743d4ce",
|
||||
"98e7247c07f0fe411c267e4384b0f6002ff58d80033927ab8ef4d4587514f0fb"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
|
||||
"", "cafebabefacedbaddecaf888", "466923ec9ae682214f2c082badb39249",
|
||||
"51110d40f6c8fff0eb1ae33445a889f0",
|
||||
"3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c"
|
||||
"144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade2569924a7c8587336bfb1"
|
||||
"18024db8674a14"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2", "cafebabefacedbaddecaf888",
|
||||
"466923ec9ae682214f2c082badb39249", "ed2ce3062e4a8ec06db8b4c490e8a268",
|
||||
"3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c"
|
||||
"144c525ac619d18c84a3f4718e2448b2fe324d9ccda27102519498e80f1478f37ba55bd6d"
|
||||
"27618c"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2", "cafebabefacedbad",
|
||||
"466923ec9ae682214f2c082badb39249", "1e6a133806607858ee80eaf237064089",
|
||||
"0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9"
|
||||
"a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f765dcc57fcf623a24094fcca40d"
|
||||
"3533f8"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c9515"
|
||||
"6809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
||||
"466923ec9ae682214f2c082badb39249", "82567fb0b4cc371801eadec005968e94",
|
||||
"d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012a"
|
||||
"f34ddd9e2f037589b292db3e67c036745fa22e7e9b7373bdcf566ff291c25bbb8568fc3d3"
|
||||
"76a6d9"},
|
||||
|
||||
{"0000000000000000000000000000000000000000000000000000000000000000", "", "",
|
||||
"000000000000000000000000", "dc95c078a2408989ad48a21492842087",
|
||||
"00000000000000000000000000000000", "530f8afbc74536b9a963b4f1c4cb738b"},
|
||||
|
||||
{"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"00000000000000000000000000000000", "", "000000000000000000000000",
|
||||
"dc95c078a2408989ad48a21492842087", "83de425c5edc5d498f382c441041ca92",
|
||||
"cea7403d4d606b6e074ec5d3baf39d18d0d1c8a799996bf0265b98b5d48ab919"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
|
||||
"", "cafebabefacedbaddecaf888", "acbef20579b4b8ebce889bac8732dad7",
|
||||
"4db870d37cb75fcb46097c36230d1612",
|
||||
"522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e485"
|
||||
"90dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015adb094dac5d93471bdec"
|
||||
"1a502270e3cc6c"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2", "cafebabefacedbaddecaf888",
|
||||
"acbef20579b4b8ebce889bac8732dad7", "8bd0c4d8aacd391e67cca447e8c38f65",
|
||||
"522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e485"
|
||||
"90dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f66276fc6ece0f4e1768cddf8853bb"
|
||||
"2d551b"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2", "cafebabefacedbad",
|
||||
"acbef20579b4b8ebce889bac8732dad7", "75a34288b8c68f811c52b2e9a2f97f63",
|
||||
"c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33"
|
||||
"934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f3a337dbf46a792c45e454913fe"
|
||||
"2ea8f2"},
|
||||
|
||||
{"feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
|
||||
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c959"
|
||||
"56809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||
"9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c9515"
|
||||
"6809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
|
||||
"acbef20579b4b8ebce889bac8732dad7", "d5ffcf6fc5ac4d69722187421a7f170b",
|
||||
"5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b78"
|
||||
"0f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3fa44a8266ee1c8eb0c8b5d4cf5a"
|
||||
"e9f19a"},
|
||||
|
||||
/* Extra, non-NIST, test case to test 64-bit binary multiplication carry
|
||||
* correctness. This is a GHASH-only test. */
|
||||
{"", "", "", "", "0000000000000000fcefef64ffc4766c",
|
||||
"3561e34e52d8b598f9937982512fff27",
|
||||
"0000000000000000ffcef9ebbffdbd8b00000000000000000000000000000000"}};
|
||||
|
||||
#endif // gcm_vectors_h__
|
||||
|
|
@ -40,6 +40,13 @@
|
|||
'freebl_gtest_deps',
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'cc_is_gcc==1 and (target_arch=="ia32" or target_arch=="x64")', {
|
||||
'cflags_cc': [
|
||||
'-msse2',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'prng_gtest',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <memory>
|
||||
|
||||
#ifdef __MACH__
|
||||
#include <mach/clock.h>
|
||||
|
|
@ -27,7 +28,7 @@ void gettime(struct timespec* tp) {
|
|||
tp->tv_sec = mts.tv_sec;
|
||||
tp->tv_nsec = mts.tv_nsec;
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, tp);
|
||||
ASSERT_NE(0, timespec_get(tp, TIME_UTC));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -84,8 +85,9 @@ class MPITest : public ::testing::Test {
|
|||
mp_int a;
|
||||
ASSERT_EQ(MP_OKAY, mp_init(&a));
|
||||
ASSERT_EQ(MP_OKAY, mp_read_unsigned_octets(&a, ref.data(), ref.size()));
|
||||
uint8_t buf[len];
|
||||
ASSERT_EQ(MP_OKAY, mp_to_fixlen_octets(&a, buf, len));
|
||||
std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
|
||||
ASSERT_NE(buf, nullptr);
|
||||
ASSERT_EQ(MP_OKAY, mp_to_fixlen_octets(&a, buf.get(), len));
|
||||
size_t compare;
|
||||
if (len > ref.size()) {
|
||||
for (size_t i = 0; i < len - ref.size(); ++i) {
|
||||
|
|
@ -96,9 +98,9 @@ class MPITest : public ::testing::Test {
|
|||
compare = len;
|
||||
}
|
||||
dump("value", ref.data(), ref.size());
|
||||
dump("output", buf, len);
|
||||
ASSERT_EQ(0, memcmp(buf + len - compare, ref.data() + ref.size() - compare,
|
||||
compare))
|
||||
dump("output", buf.get(), len);
|
||||
ASSERT_EQ(0, memcmp(buf.get() + len - compare,
|
||||
ref.data() + ref.size() - compare, compare))
|
||||
<< "comparing " << compare << " octets";
|
||||
mp_clear(&a);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "gtest/gtest.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
|
||||
#include "blapi.h"
|
||||
#include "secitem.h"
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ TEST_F(pkixder_input_tests, Skip_WrapAroundPointer)
|
|||
// but this should catch the problem on at least some compilers, if not all of
|
||||
// them.
|
||||
const uint8_t* der = nullptr;
|
||||
// coverity[FORWARD_NULL]
|
||||
--der;
|
||||
Input buf;
|
||||
ASSERT_EQ(Success, buf.Init(der, 0));
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ MODULE = nss
|
|||
|
||||
CPPSRCS = \
|
||||
pk11_aeskeywrap_unittest.cc \
|
||||
pk11_aes_gcm_unittest.cc \
|
||||
pk11_chacha20poly1305_unittest.cc \
|
||||
pk11_curve25519_unittest.cc \
|
||||
pk11_ecdsa_unittest.cc \
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "nss.h"
|
||||
#include "pk11pub.h"
|
||||
#include "sechash.h"
|
||||
#include "secerr.h"
|
||||
|
||||
#include "cpputil.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
|
|
@ -17,10 +18,17 @@
|
|||
|
||||
namespace nss_test {
|
||||
|
||||
static const CK_MECHANISM_TYPE kMech = CKM_NSS_CHACHA20_POLY1305;
|
||||
static const CK_MECHANISM_TYPE kMechXor = CKM_NSS_CHACHA20_CTR;
|
||||
// Some test data for simple tests.
|
||||
static const uint8_t kKeyData[32] = {'k'};
|
||||
static const uint8_t kCtrNonce[16] = {'c', 0, 0, 0, 'n'};
|
||||
static const uint8_t kData[16] = {'d'};
|
||||
|
||||
class Pkcs11ChaCha20Poly1305Test
|
||||
: public ::testing::TestWithParam<chacha_testvector> {
|
||||
public:
|
||||
void EncryptDecrypt(PK11SymKey* symKey, const bool invalid_iv,
|
||||
void EncryptDecrypt(const ScopedPK11SymKey& key, const bool invalid_iv,
|
||||
const bool invalid_tag, const uint8_t* data,
|
||||
size_t data_len, const uint8_t* aad, size_t aad_len,
|
||||
const uint8_t* iv, size_t iv_len,
|
||||
|
|
@ -39,7 +47,7 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
// Encrypt.
|
||||
unsigned int outputLen = 0;
|
||||
std::vector<uint8_t> output(data_len + aead_params.ulTagLen);
|
||||
SECStatus rv = PK11_Encrypt(symKey, mech, ¶ms, output.data(),
|
||||
SECStatus rv = PK11_Encrypt(key.get(), kMech, ¶ms, output.data(),
|
||||
&outputLen, output.size(), data, data_len);
|
||||
|
||||
// Return if encryption failure was expected due to invalid IV.
|
||||
|
|
@ -60,8 +68,9 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
// Decrypt.
|
||||
unsigned int decryptedLen = 0;
|
||||
std::vector<uint8_t> decrypted(data_len);
|
||||
rv = PK11_Decrypt(symKey, mech, ¶ms, decrypted.data(), &decryptedLen,
|
||||
decrypted.size(), output.data(), outputLen);
|
||||
rv =
|
||||
PK11_Decrypt(key.get(), kMech, ¶ms, decrypted.data(), &decryptedLen,
|
||||
decrypted.size(), output.data(), outputLen);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Check the plaintext.
|
||||
|
|
@ -73,8 +82,9 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
if (outputLen != 0) {
|
||||
std::vector<uint8_t> bogusCiphertext(output);
|
||||
bogusCiphertext[0] ^= 0xff;
|
||||
rv = PK11_Decrypt(symKey, mech, ¶ms, decrypted.data(), &decryptedLen,
|
||||
decrypted.size(), bogusCiphertext.data(), outputLen);
|
||||
rv = PK11_Decrypt(key.get(), kMech, ¶ms, decrypted.data(),
|
||||
&decryptedLen, decrypted.size(), bogusCiphertext.data(),
|
||||
outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
||||
|
|
@ -83,8 +93,9 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
if (outputLen != 0) {
|
||||
std::vector<uint8_t> bogusTag(output);
|
||||
bogusTag[outputLen - 1] ^= 0xff;
|
||||
rv = PK11_Decrypt(symKey, mech, ¶ms, decrypted.data(), &decryptedLen,
|
||||
decrypted.size(), bogusTag.data(), outputLen);
|
||||
rv = PK11_Decrypt(key.get(), kMech, ¶ms, decrypted.data(),
|
||||
&decryptedLen, decrypted.size(), bogusTag.data(),
|
||||
outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +111,7 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
bogusAeadParams.pNonce = toUcharPtr(bogusIV.data());
|
||||
bogusIV[0] ^= 0xff;
|
||||
|
||||
rv = PK11_Decrypt(symKey, mech, &bogusParams, decrypted.data(),
|
||||
rv = PK11_Decrypt(key.get(), kMech, &bogusParams, decrypted.data(),
|
||||
&decryptedLen, data_len, output.data(), outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
|
@ -117,7 +128,7 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
bogusAeadParams.pAAD = toUcharPtr(bogusAAD.data());
|
||||
bogusAAD[0] ^= 0xff;
|
||||
|
||||
rv = PK11_Decrypt(symKey, mech, &bogusParams, decrypted.data(),
|
||||
rv = PK11_Decrypt(key.get(), kMech, &bogusParams, decrypted.data(),
|
||||
&decryptedLen, data_len, output.data(), outputLen);
|
||||
EXPECT_NE(rv, SECSuccess);
|
||||
}
|
||||
|
|
@ -125,16 +136,16 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
|
||||
void EncryptDecrypt(const chacha_testvector testvector) {
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
SECItem keyItem = {siBuffer, toUcharPtr(testvector.Key.data()),
|
||||
static_cast<unsigned int>(testvector.Key.size())};
|
||||
SECItem key_item = {siBuffer, toUcharPtr(testvector.Key.data()),
|
||||
static_cast<unsigned int>(testvector.Key.size())};
|
||||
|
||||
// Import key.
|
||||
ScopedPK11SymKey symKey(PK11_ImportSymKey(
|
||||
slot.get(), mech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr));
|
||||
EXPECT_TRUE(!!symKey);
|
||||
ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), kMech, PK11_OriginUnwrap,
|
||||
CKA_ENCRYPT, &key_item, nullptr));
|
||||
EXPECT_TRUE(!!key);
|
||||
|
||||
// Check.
|
||||
EncryptDecrypt(symKey.get(), testvector.invalid_iv, testvector.invalid_tag,
|
||||
EncryptDecrypt(key, testvector.invalid_iv, testvector.invalid_tag,
|
||||
testvector.Data.data(), testvector.Data.size(),
|
||||
testvector.AAD.data(), testvector.AAD.size(),
|
||||
testvector.IV.data(), testvector.IV.size(),
|
||||
|
|
@ -142,14 +153,13 @@ class Pkcs11ChaCha20Poly1305Test
|
|||
}
|
||||
|
||||
protected:
|
||||
CK_MECHANISM_TYPE mech = CKM_NSS_CHACHA20_POLY1305;
|
||||
};
|
||||
|
||||
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);
|
||||
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
|
||||
EXPECT_TRUE(!!key);
|
||||
|
||||
// Generate random data.
|
||||
std::vector<uint8_t> data(512);
|
||||
|
|
@ -168,8 +178,85 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateEncryptDecrypt) {
|
|||
EXPECT_EQ(rv, SECSuccess);
|
||||
|
||||
// Check.
|
||||
EncryptDecrypt(symKey.get(), false, false, data.data(), data.size(),
|
||||
aad.data(), aad.size(), iv.data(), iv.size());
|
||||
EncryptDecrypt(key, false, false, data.data(), data.size(), aad.data(),
|
||||
aad.size(), iv.data(), iv.size());
|
||||
}
|
||||
|
||||
TEST_F(Pkcs11ChaCha20Poly1305Test, Xor) {
|
||||
static const uint8_t kExpected[sizeof(kData)] = {
|
||||
0xd8, 0x15, 0xd3, 0xb3, 0xe9, 0x34, 0x3b, 0x7a,
|
||||
0x24, 0xf6, 0x5f, 0xd7, 0x95, 0x3d, 0xd3, 0x51};
|
||||
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
SECItem keyItem = {siBuffer, toUcharPtr(kKeyData),
|
||||
static_cast<unsigned int>(sizeof(kKeyData))};
|
||||
ScopedPK11SymKey key(PK11_ImportSymKey(
|
||||
slot.get(), kMechXor, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr));
|
||||
EXPECT_TRUE(!!key);
|
||||
|
||||
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce),
|
||||
static_cast<unsigned int>(sizeof(kCtrNonce))};
|
||||
uint8_t output[sizeof(kData)];
|
||||
unsigned int output_len = 88; // This should be overwritten.
|
||||
SECStatus rv =
|
||||
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
|
||||
sizeof(output), kData, sizeof(kData));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(output_len));
|
||||
EXPECT_EQ(0, memcmp(kExpected, output, sizeof(kExpected)));
|
||||
|
||||
// Decrypting has the same effect.
|
||||
rv = PK11_Decrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
|
||||
sizeof(output), kData, sizeof(kData));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ASSERT_EQ(sizeof(kData), static_cast<size_t>(output_len));
|
||||
EXPECT_EQ(0, memcmp(kExpected, output, sizeof(kExpected)));
|
||||
|
||||
// Operating in reverse too.
|
||||
rv = PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
|
||||
sizeof(output), kExpected, sizeof(kExpected));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(output_len));
|
||||
EXPECT_EQ(0, memcmp(kData, output, sizeof(kData)));
|
||||
}
|
||||
|
||||
// This test just ensures that a key can be generated for use with the XOR
|
||||
// function. The result is random and therefore cannot be checked.
|
||||
TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateXor) {
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
|
||||
EXPECT_TRUE(!!key);
|
||||
|
||||
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce),
|
||||
static_cast<unsigned int>(sizeof(kCtrNonce))};
|
||||
uint8_t output[sizeof(kData)];
|
||||
unsigned int output_len = 88; // This should be overwritten.
|
||||
SECStatus rv =
|
||||
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
|
||||
sizeof(output), kData, sizeof(kData));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ASSERT_EQ(sizeof(kData), static_cast<size_t>(output_len));
|
||||
}
|
||||
|
||||
TEST_F(Pkcs11ChaCha20Poly1305Test, XorInvalidParams) {
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
|
||||
EXPECT_TRUE(!!key);
|
||||
|
||||
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce),
|
||||
static_cast<unsigned int>(sizeof(kCtrNonce)) - 1};
|
||||
uint8_t output[sizeof(kData)];
|
||||
unsigned int output_len = 88;
|
||||
SECStatus rv =
|
||||
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
|
||||
sizeof(output), kData, sizeof(kData));
|
||||
EXPECT_EQ(SECFailure, rv);
|
||||
|
||||
ctr_nonce_item.data = nullptr;
|
||||
rv = PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len,
|
||||
sizeof(output), kData, sizeof(kData));
|
||||
EXPECT_EQ(SECFailure, rv);
|
||||
EXPECT_EQ(SEC_ERROR_BAD_DATA, PORT_GetError());
|
||||
}
|
||||
|
||||
TEST_P(Pkcs11ChaCha20Poly1305Test, TestVectors) { EncryptDecrypt(GetParam()); }
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ class Pkcs11Curve25519Test
|
|||
|
||||
ScopedCERTSubjectPublicKeyInfo certSpki(
|
||||
SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
|
||||
if (!expect_success && !certSpki) {
|
||||
return;
|
||||
}
|
||||
ASSERT_TRUE(certSpki);
|
||||
|
||||
ScopedSECKEYPublicKey pubKey(SECKEY_ExtractPublicKey(certSpki.get()));
|
||||
|
|
|
|||
|
|
@ -29,20 +29,20 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
|
||||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==1', {
|
||||
[ 'static_libs==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -48,8 +48,15 @@ class Pk11KeyImportTestBase : public ::testing::Test {
|
|||
ScopedSECKEYEncryptedPrivateKeyInfo key_info;
|
||||
ScopedSECItem public_value;
|
||||
GenerateAndExport(&key_type, &key_info, &public_value);
|
||||
ASSERT_NE(nullptr, key_info);
|
||||
|
||||
ASSERT_NE(nullptr, public_value);
|
||||
// Note: NSS is currently unable export wrapped DH keys, so this doesn't
|
||||
// test
|
||||
// CKM_DH_PKCS_KEY_PAIR_GEN beyond generate and verify
|
||||
if (key_type == dhKey) {
|
||||
return;
|
||||
}
|
||||
ASSERT_NE(nullptr, key_info);
|
||||
|
||||
// Now import the encrypted key.
|
||||
static const uint8_t nick[] = "nick";
|
||||
|
|
@ -78,17 +85,41 @@ class Pk11KeyImportTestBase : public ::testing::Test {
|
|||
CK_MECHANISM_TYPE mech_;
|
||||
|
||||
private:
|
||||
SECItem GetPublicComponent(ScopedSECKEYPublicKey& pub_key) {
|
||||
SECItem null = {siBuffer, NULL, 0};
|
||||
switch (SECKEY_GetPublicKeyType(pub_key.get())) {
|
||||
case rsaKey:
|
||||
case rsaPssKey:
|
||||
case rsaOaepKey:
|
||||
return pub_key->u.rsa.modulus;
|
||||
case keaKey:
|
||||
return pub_key->u.kea.publicValue;
|
||||
case dsaKey:
|
||||
return pub_key->u.dsa.publicValue;
|
||||
case dhKey:
|
||||
return pub_key->u.dh.publicValue;
|
||||
case ecKey:
|
||||
return pub_key->u.ec.publicValue;
|
||||
case fortezzaKey: /* depricated */
|
||||
case nullKey:
|
||||
/* didn't use default here so we can catch new key types at compile time
|
||||
*/
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
void CheckForPublicKey(const ScopedSECKEYPrivateKey& priv_key,
|
||||
const SECItem* expected_public) {
|
||||
// Verify the public key exists.
|
||||
StackSECItem priv_id;
|
||||
KeyType type = SECKEY_GetPrivateKeyType(priv_key.get());
|
||||
SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, priv_key.get(),
|
||||
CKA_ID, &priv_id);
|
||||
ASSERT_EQ(SECSuccess, rv) << "Couldn't read CKA_ID from private key: "
|
||||
<< PORT_ErrorToName(PORT_GetError());
|
||||
|
||||
CK_ATTRIBUTE_TYPE value_type = CKA_VALUE;
|
||||
switch (SECKEY_GetPrivateKeyType(priv_key.get())) {
|
||||
switch (type) {
|
||||
case rsaKey:
|
||||
value_type = CKA_MODULUS;
|
||||
break;
|
||||
|
|
@ -106,6 +137,8 @@ class Pk11KeyImportTestBase : public ::testing::Test {
|
|||
FAIL() << "unknown key type";
|
||||
}
|
||||
|
||||
// Scan public key objects until we find one with the same CKA_ID as
|
||||
// priv_key
|
||||
std::unique_ptr<PK11GenericObject, PK11GenericObjectsDeleter> objs(
|
||||
PK11_FindGenericObjects(slot_.get(), CKO_PUBLIC_KEY));
|
||||
ASSERT_NE(nullptr, objs);
|
||||
|
|
@ -128,20 +161,44 @@ class Pk11KeyImportTestBase : public ::testing::Test {
|
|||
ASSERT_EQ(1U, token.len);
|
||||
ASSERT_NE(0, token.data[0]);
|
||||
|
||||
StackSECItem value;
|
||||
rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, value_type, &value);
|
||||
StackSECItem raw_value;
|
||||
SECItem decoded_value;
|
||||
rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, value_type, &raw_value);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
SECItem value = raw_value;
|
||||
|
||||
// Decode the EC_POINT and check the output against expected.
|
||||
// CKA_EC_POINT isn't stable, see Bug 1520649.
|
||||
ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
|
||||
ASSERT_TRUE(arena);
|
||||
if (value_type == CKA_EC_POINT) {
|
||||
continue;
|
||||
// If this fails due to the noted inconsistency, we may need to
|
||||
// check the whole raw_value, or remove a leading UNCOMPRESSED_POINT tag
|
||||
rv = SEC_QuickDERDecodeItem(arena.get(), &decoded_value,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
&raw_value);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
value = decoded_value;
|
||||
}
|
||||
|
||||
ASSERT_TRUE(SECITEM_ItemsAreEqual(expected_public, &value))
|
||||
<< "expected: "
|
||||
<< DataBuffer(expected_public->data, expected_public->len)
|
||||
<< std::endl
|
||||
<< "actual: " << DataBuffer(value.data, value.len) << std::endl;
|
||||
|
||||
// Finally, convert the private to public and ensure it matches.
|
||||
ScopedSECKEYPublicKey pub_key(SECKEY_ConvertToPublicKey(priv_key.get()));
|
||||
ASSERT_TRUE(pub_key);
|
||||
SECItem converted_public = GetPublicComponent(pub_key);
|
||||
ASSERT_TRUE(converted_public.len != 0);
|
||||
|
||||
ASSERT_TRUE(SECITEM_ItemsAreEqual(expected_public, &converted_public))
|
||||
<< "expected: "
|
||||
<< DataBuffer(expected_public->data, expected_public->len)
|
||||
<< std::endl
|
||||
<< "actual: "
|
||||
<< DataBuffer(converted_public.data, converted_public.len)
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,13 +217,6 @@ class Pk11KeyImportTestBase : public ::testing::Test {
|
|||
ScopedSECKEYPublicKey pub_key(pub_tmp);
|
||||
ASSERT_NE(nullptr, pub_key);
|
||||
|
||||
// Wrap and export the key.
|
||||
ScopedSECKEYEncryptedPrivateKeyInfo epki(PK11_ExportEncryptedPrivKeyInfo(
|
||||
slot_.get(), SEC_OID_AES_256_CBC, password_.get(), priv_key.get(), 1,
|
||||
nullptr));
|
||||
ASSERT_NE(nullptr, epki) << "PK11_ExportEncryptedPrivKeyInfo failed: "
|
||||
<< PORT_ErrorToName(PORT_GetError());
|
||||
|
||||
// Save the public value, which we will need on import */
|
||||
SECItem* pub_val;
|
||||
KeyType t = SECKEY_GetPublicKeyType(pub_key.get());
|
||||
|
|
@ -190,8 +240,22 @@ class Pk11KeyImportTestBase : public ::testing::Test {
|
|||
CheckForPublicKey(priv_key, pub_val);
|
||||
|
||||
*key_type = t;
|
||||
key_info->swap(epki);
|
||||
public_value->reset(SECITEM_DupItem(pub_val));
|
||||
|
||||
// Note: NSS is currently unable export wrapped DH keys, so this doesn't
|
||||
// test
|
||||
// CKM_DH_PKCS_KEY_PAIR_GEN beyond generate and verify
|
||||
if (mech_ == CKM_DH_PKCS_KEY_PAIR_GEN) {
|
||||
return;
|
||||
}
|
||||
// Wrap and export the key.
|
||||
ScopedSECKEYEncryptedPrivateKeyInfo epki(PK11_ExportEncryptedPrivKeyInfo(
|
||||
slot_.get(), SEC_OID_AES_256_CBC, password_.get(), priv_key.get(), 1,
|
||||
nullptr));
|
||||
ASSERT_NE(nullptr, epki) << "PK11_ExportEncryptedPrivKeyInfo failed: "
|
||||
<< PORT_ErrorToName(PORT_GetError());
|
||||
|
||||
key_info->swap(epki);
|
||||
}
|
||||
|
||||
ScopedPK11SlotInfo slot_;
|
||||
|
|
@ -281,9 +345,8 @@ TEST_P(Pk11KeyImportTest, GenerateExportImport) { Test(); }
|
|||
|
||||
INSTANTIATE_TEST_CASE_P(Pk11KeyImportTest, Pk11KeyImportTest,
|
||||
::testing::Values(CKM_RSA_PKCS_KEY_PAIR_GEN,
|
||||
CKM_DSA_KEY_PAIR_GEN));
|
||||
// Note: NSS is currently unable export wrapped DH keys, so this doesn't test
|
||||
// CKM_DH_PKCS_KEY_PAIR_GEN.
|
||||
CKM_DSA_KEY_PAIR_GEN,
|
||||
CKM_DH_PKCS_KEY_PAIR_GEN));
|
||||
|
||||
class Pk11KeyImportTestEC : public Pk11KeyImportTestBase,
|
||||
public ::testing::WithParamInterface<SECOidTag> {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==1', {
|
||||
[ 'static_libs==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ CPPSRCS := $(filter-out $(shell grep -l '^TEST_F' $(CPPSRCS)), $(CPPSRCS))
|
|||
CFLAGS += -DNSS_DISABLE_TLS_1_3
|
||||
endif
|
||||
|
||||
ifdef NSS_ALLOW_SSLKEYLOGFILE
|
||||
SSLKEYLOGFILE_FILES = ssl_keylog_unittest.cc
|
||||
else
|
||||
SSLKEYLOGFILE_FILES = $(NULL)
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ CPPSRCS = \
|
|||
ssl_gather_unittest.cc \
|
||||
ssl_gtest.cc \
|
||||
ssl_hrr_unittest.cc \
|
||||
ssl_keylog_unittest.cc \
|
||||
ssl_keyupdate_unittest.cc \
|
||||
ssl_loopback_unittest.cc \
|
||||
ssl_misc_unittest.cc \
|
||||
|
|
@ -55,6 +54,7 @@ CPPSRCS = \
|
|||
tls_filter.cc \
|
||||
tls_protect.cc \
|
||||
tls_esni_unittest.cc \
|
||||
$(SSLKEYLOGFILE_FILES) \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
|
||||
|
|
|
|||
|
|
@ -649,6 +649,227 @@ TEST_P(TlsConnectTls13, ZeroRttOrdering) {
|
|||
EXPECT_EQ(2U, step);
|
||||
}
|
||||
|
||||
// Early data remains available after the handshake completes for TLS.
|
||||
TEST_F(TlsConnectStreamTls13, ZeroRttLateReadTls) {
|
||||
SetupForZeroRtt();
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->Handshake(); // ClientHello
|
||||
|
||||
// Write some early data.
|
||||
const uint8_t data[] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
PRInt32 rv = PR_Write(client_->ssl_fd(), data, sizeof(data));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), rv);
|
||||
|
||||
// Consume the ClientHello and generate ServerHello..Finished.
|
||||
server_->Handshake();
|
||||
|
||||
// Read some of the data.
|
||||
std::vector<uint8_t> small_buffer(1 + sizeof(data) / 2);
|
||||
rv = PR_Read(server_->ssl_fd(), small_buffer.data(), small_buffer.size());
|
||||
EXPECT_EQ(static_cast<PRInt32>(small_buffer.size()), rv);
|
||||
EXPECT_EQ(0, memcmp(data, small_buffer.data(), small_buffer.size()));
|
||||
|
||||
Handshake(); // Complete the handshake.
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
|
||||
// After the handshake, it should be possible to read the remainder.
|
||||
uint8_t big_buf[100];
|
||||
rv = PR_Read(server_->ssl_fd(), big_buf, sizeof(big_buf));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data) - small_buffer.size()), rv);
|
||||
EXPECT_EQ(0, memcmp(&data[small_buffer.size()], big_buf,
|
||||
sizeof(data) - small_buffer.size()));
|
||||
|
||||
// And that's all there is to read.
|
||||
rv = PR_Read(server_->ssl_fd(), big_buf, sizeof(big_buf));
|
||||
EXPECT_GT(0, rv);
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
}
|
||||
|
||||
// Early data that arrives before the handshake can be read after the handshake
|
||||
// is complete.
|
||||
TEST_F(TlsConnectDatagram13, ZeroRttLateReadDtls) {
|
||||
SetupForZeroRtt();
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->Handshake(); // ClientHello
|
||||
|
||||
// Write some early data.
|
||||
const uint8_t data[] = {1, 2, 3};
|
||||
PRInt32 written = PR_Write(client_->ssl_fd(), data, sizeof(data));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), written);
|
||||
|
||||
Handshake(); // Complete the handshake.
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
|
||||
// Reading at the server should return the early data, which was buffered.
|
||||
uint8_t buf[sizeof(data) + 1] = {0};
|
||||
PRInt32 read = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), read);
|
||||
EXPECT_EQ(0, memcmp(data, buf, sizeof(data)));
|
||||
}
|
||||
|
||||
class PacketHolder : public PacketFilter {
|
||||
public:
|
||||
PacketHolder() = default;
|
||||
|
||||
virtual Action Filter(const DataBuffer& input, DataBuffer* output) {
|
||||
packet_ = input;
|
||||
Disable();
|
||||
return DROP;
|
||||
}
|
||||
|
||||
const DataBuffer& packet() const { return packet_; }
|
||||
|
||||
private:
|
||||
DataBuffer packet_;
|
||||
};
|
||||
|
||||
// Early data that arrives late is discarded for DTLS.
|
||||
TEST_F(TlsConnectDatagram13, ZeroRttLateArrivalDtls) {
|
||||
SetupForZeroRtt();
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->Handshake(); // ClientHello
|
||||
|
||||
// Write some early data. Twice, so that we can read bits of it.
|
||||
const uint8_t data[] = {1, 2, 3};
|
||||
PRInt32 written = PR_Write(client_->ssl_fd(), data, sizeof(data));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), written);
|
||||
|
||||
// Block and capture the next packet.
|
||||
auto holder = std::make_shared<PacketHolder>();
|
||||
client_->SetFilter(holder);
|
||||
written = PR_Write(client_->ssl_fd(), data, sizeof(data));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), written);
|
||||
EXPECT_FALSE(holder->enabled()) << "the filter should disable itself";
|
||||
|
||||
// Consume the ClientHello and generate ServerHello..Finished.
|
||||
server_->Handshake();
|
||||
|
||||
// Read some of the data.
|
||||
std::vector<uint8_t> small_buffer(sizeof(data));
|
||||
PRInt32 read =
|
||||
PR_Read(server_->ssl_fd(), small_buffer.data(), small_buffer.size());
|
||||
|
||||
EXPECT_EQ(static_cast<PRInt32>(small_buffer.size()), read);
|
||||
EXPECT_EQ(0, memcmp(data, small_buffer.data(), small_buffer.size()));
|
||||
|
||||
Handshake(); // Complete the handshake.
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
|
||||
server_->SendDirect(holder->packet());
|
||||
|
||||
// Reading now should return nothing, even though a valid packet was
|
||||
// delivered.
|
||||
read = PR_Read(server_->ssl_fd(), small_buffer.data(), small_buffer.size());
|
||||
EXPECT_GT(0, read);
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
}
|
||||
|
||||
// Early data reads in TLS should be coalesced.
|
||||
TEST_F(TlsConnectStreamTls13, ZeroRttCoalesceReadTls) {
|
||||
SetupForZeroRtt();
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->Handshake(); // ClientHello
|
||||
|
||||
// Write some early data. In two writes.
|
||||
const uint8_t data[] = {1, 2, 3, 4, 5, 6};
|
||||
PRInt32 written = PR_Write(client_->ssl_fd(), data, 1);
|
||||
EXPECT_EQ(1, written);
|
||||
|
||||
written = PR_Write(client_->ssl_fd(), data + 1, sizeof(data) - 1);
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data) - 1), written);
|
||||
|
||||
// Consume the ClientHello and generate ServerHello..Finished.
|
||||
server_->Handshake();
|
||||
|
||||
// Read all of the data.
|
||||
std::vector<uint8_t> buffer(sizeof(data));
|
||||
PRInt32 read = PR_Read(server_->ssl_fd(), buffer.data(), buffer.size());
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), read);
|
||||
EXPECT_EQ(0, memcmp(data, buffer.data(), sizeof(data)));
|
||||
|
||||
Handshake(); // Complete the handshake.
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
}
|
||||
|
||||
// Early data reads in DTLS should not be coalesced.
|
||||
TEST_F(TlsConnectDatagram13, ZeroRttNoCoalesceReadDtls) {
|
||||
SetupForZeroRtt();
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->Handshake(); // ClientHello
|
||||
|
||||
// Write some early data. In two writes.
|
||||
const uint8_t data[] = {1, 2, 3, 4, 5, 6};
|
||||
PRInt32 written = PR_Write(client_->ssl_fd(), data, 1);
|
||||
EXPECT_EQ(1, written);
|
||||
|
||||
written = PR_Write(client_->ssl_fd(), data + 1, sizeof(data) - 1);
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data) - 1), written);
|
||||
|
||||
// Consume the ClientHello and generate ServerHello..Finished.
|
||||
server_->Handshake();
|
||||
|
||||
// Try to read all of the data.
|
||||
std::vector<uint8_t> buffer(sizeof(data));
|
||||
PRInt32 read = PR_Read(server_->ssl_fd(), buffer.data(), buffer.size());
|
||||
EXPECT_EQ(1, read);
|
||||
EXPECT_EQ(0, memcmp(data, buffer.data(), 1));
|
||||
|
||||
// Read the remainder.
|
||||
read = PR_Read(server_->ssl_fd(), buffer.data(), buffer.size());
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data) - 1), read);
|
||||
EXPECT_EQ(0, memcmp(data + 1, buffer.data(), sizeof(data) - 1));
|
||||
|
||||
Handshake(); // Complete the handshake.
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
}
|
||||
|
||||
// Early data reads in DTLS should fail if the buffer is too small.
|
||||
TEST_F(TlsConnectDatagram13, ZeroRttShortReadDtls) {
|
||||
SetupForZeroRtt();
|
||||
client_->Set0RttEnabled(true);
|
||||
server_->Set0RttEnabled(true);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
client_->Handshake(); // ClientHello
|
||||
|
||||
// Write some early data. In two writes.
|
||||
const uint8_t data[] = {1, 2, 3, 4, 5, 6};
|
||||
PRInt32 written = PR_Write(client_->ssl_fd(), data, sizeof(data));
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), written);
|
||||
|
||||
// Consume the ClientHello and generate ServerHello..Finished.
|
||||
server_->Handshake();
|
||||
|
||||
// Try to read all of the data into a small buffer.
|
||||
std::vector<uint8_t> buffer(sizeof(data));
|
||||
PRInt32 read = PR_Read(server_->ssl_fd(), buffer.data(), 1);
|
||||
EXPECT_GT(0, read);
|
||||
EXPECT_EQ(SSL_ERROR_RX_SHORT_DTLS_READ, PORT_GetError());
|
||||
|
||||
// Read again with more space.
|
||||
read = PR_Read(server_->ssl_fd(), buffer.data(), buffer.size());
|
||||
EXPECT_EQ(static_cast<PRInt32>(sizeof(data)), read);
|
||||
EXPECT_EQ(0, memcmp(data, buffer.data(), sizeof(data)));
|
||||
|
||||
Handshake(); // Complete the handshake.
|
||||
ExpectEarlyDataAccepted(true);
|
||||
CheckConnected();
|
||||
}
|
||||
|
||||
#ifndef NSS_DISABLE_TLS_1_3
|
||||
INSTANTIATE_TEST_CASE_P(Tls13ZeroRttReplayTest, TlsZeroRttReplayTest,
|
||||
TlsConnectTestBase::kTlsVariantsAll);
|
||||
|
|
|
|||
|
|
@ -320,6 +320,46 @@ TEST_F(TlsConnectStreamTls13, PostHandshakeAuthConcurrent) {
|
|||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, PostHandshakeAuthBeforeKeyUpdate) {
|
||||
client_->SetupClientAuth();
|
||||
EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
|
||||
SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
|
||||
Connect();
|
||||
// Send CertificateRequest.
|
||||
EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
|
||||
<< "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
|
||||
// Send KeyUpdate.
|
||||
EXPECT_EQ(SECFailure, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, PostHandshakeAuthDuringClientKeyUpdate) {
|
||||
client_->SetupClientAuth();
|
||||
EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
|
||||
SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
|
||||
Connect();
|
||||
CheckEpochs(3, 3);
|
||||
// Send CertificateRequest from server.
|
||||
EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
|
||||
<< "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
|
||||
// Send KeyUpdate from client.
|
||||
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
|
||||
server_->SendData(50); // server sends CertificateRequest
|
||||
client_->SendData(50); // client sends KeyUpdate
|
||||
server_->ReadBytes(50); // server receives KeyUpdate and defers response
|
||||
CheckEpochs(4, 3);
|
||||
client_->ReadBytes(50); // client receives CertificateRequest
|
||||
client_->SendData(
|
||||
50); // client sends Certificate, CertificateVerify, Finished
|
||||
server_->ReadBytes(
|
||||
50); // server receives Certificate, CertificateVerify, Finished
|
||||
client_->CheckEpochs(3, 4);
|
||||
server_->CheckEpochs(4, 4);
|
||||
server_->SendData(50); // server sends KeyUpdate
|
||||
client_->ReadBytes(50); // client receives KeyUpdate
|
||||
client_->CheckEpochs(4, 4);
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, PostHandshakeAuthMissingExtension) {
|
||||
client_->SetupClientAuth();
|
||||
Connect();
|
||||
|
|
@ -454,6 +494,9 @@ TEST_F(TlsConnectStreamTls13, PostHandshakeAuthDecline) {
|
|||
client_->SetupClientAuth();
|
||||
EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
|
||||
SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_OptionSet(server_->ssl_fd(), SSL_REQUIRE_CERTIFICATE,
|
||||
SSL_REQUIRE_ALWAYS));
|
||||
// Client to decline the certificate request.
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_GetClientAuthDataHook(
|
||||
|
|
@ -472,10 +515,13 @@ TEST_F(TlsConnectStreamTls13, PostHandshakeAuthDecline) {
|
|||
// Send CertificateRequest.
|
||||
EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
|
||||
<< "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
|
||||
server_->SendData(50);
|
||||
client_->ReadBytes(50);
|
||||
client_->SendData(50);
|
||||
server_->ReadBytes(50);
|
||||
server_->SendData(50); // send Certificate Request
|
||||
client_->ReadBytes(50); // read Certificate Request
|
||||
client_->SendData(50); // send empty Certificate+Finished
|
||||
server_->ExpectSendAlert(kTlsAlertCertificateRequired);
|
||||
server_->ReadBytes(50); // read empty Certificate+Finished
|
||||
server_->ExpectReadWriteError();
|
||||
server_->SendData(50); // send alert
|
||||
// AuthCertificateCallback is not called, because the client sends
|
||||
// an empty certificate_list.
|
||||
EXPECT_EQ(0U, called);
|
||||
|
|
@ -655,6 +701,44 @@ TEST_P(TlsConnectTls12, ClientAuthInconsistentPssSignatureScheme) {
|
|||
ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ClientAuthPkcs1SignatureScheme) {
|
||||
static const SSLSignatureScheme kSignatureScheme[] = {
|
||||
ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pss_rsae_sha256};
|
||||
|
||||
Reset(TlsAgent::kServerRsa, "rsa");
|
||||
client_->SetSignatureSchemes(kSignatureScheme,
|
||||
PR_ARRAY_SIZE(kSignatureScheme));
|
||||
server_->SetSignatureSchemes(kSignatureScheme,
|
||||
PR_ARRAY_SIZE(kSignatureScheme));
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
||||
auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>(
|
||||
client_, kTlsHandshakeCertificateVerify);
|
||||
capture_cert_verify->EnableDecryption();
|
||||
|
||||
Connect();
|
||||
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_rsae_sha256,
|
||||
1024);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ClientAuthPkcs1SignatureSchemeOnly) {
|
||||
static const SSLSignatureScheme kSignatureScheme[] = {
|
||||
ssl_sig_rsa_pkcs1_sha256};
|
||||
|
||||
Reset(TlsAgent::kServerRsa, "rsa");
|
||||
client_->SetSignatureSchemes(kSignatureScheme,
|
||||
PR_ARRAY_SIZE(kSignatureScheme));
|
||||
server_->SetSignatureSchemes(kSignatureScheme,
|
||||
PR_ARRAY_SIZE(kSignatureScheme));
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
||||
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
}
|
||||
|
||||
class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& a)
|
||||
|
|
@ -887,7 +971,7 @@ TEST_P(TlsConnectTls13, InconsistentSignatureSchemeAlert) {
|
|||
client_->CheckErrorCode(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
|
||||
TEST_P(TlsConnectTls12, RequestClientAuthWithSha384) {
|
||||
server_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
|
||||
server_->RequestClientAuth(false);
|
||||
|
|
@ -1349,12 +1433,21 @@ TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigBoth) {
|
|||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeRsa, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus,
|
||||
TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12,
|
||||
::testing::Values(TlsAgent::kServerRsaSign),
|
||||
::testing::Values(ssl_auth_rsa_sign),
|
||||
::testing::Values(ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384,
|
||||
ssl_sig_rsa_pkcs1_sha512, ssl_sig_rsa_pss_rsae_sha256,
|
||||
ssl_sig_rsa_pss_rsae_sha384)));
|
||||
// RSASSA-PKCS1-v1_5 is not allowed to be used in TLS 1.3
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeRsaTls13, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
|
||||
TlsConnectTestBase::kTlsV13,
|
||||
::testing::Values(TlsAgent::kServerRsaSign),
|
||||
::testing::Values(ssl_auth_rsa_sign),
|
||||
::testing::Values(ssl_sig_rsa_pss_rsae_sha256,
|
||||
ssl_sig_rsa_pss_rsae_sha384)));
|
||||
// PSS with SHA-512 needs a bigger key to work.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeBigRsa, TlsSignatureSchemeConfiguration,
|
||||
|
|
|
|||
|
|
@ -68,12 +68,6 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase {
|
|||
virtual void SetupCertificate() {
|
||||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
switch (sig_scheme_) {
|
||||
case ssl_sig_rsa_pkcs1_sha256:
|
||||
case ssl_sig_rsa_pkcs1_sha384:
|
||||
case ssl_sig_rsa_pkcs1_sha512:
|
||||
Reset(TlsAgent::kServerRsaSign);
|
||||
auth_type_ = ssl_auth_rsa_sign;
|
||||
break;
|
||||
case ssl_sig_rsa_pss_rsae_sha256:
|
||||
case ssl_sig_rsa_pss_rsae_sha384:
|
||||
Reset(TlsAgent::kServerRsaSign);
|
||||
|
|
@ -330,6 +324,12 @@ static SSLSignatureScheme kSignatureSchemesParamsArr[] = {
|
|||
ssl_sig_rsa_pss_pss_sha256, ssl_sig_rsa_pss_pss_sha384,
|
||||
ssl_sig_rsa_pss_pss_sha512};
|
||||
|
||||
static SSLSignatureScheme kSignatureSchemesParamsArrTls13[] = {
|
||||
ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384,
|
||||
ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_rsae_sha384,
|
||||
ssl_sig_rsa_pss_rsae_sha512, ssl_sig_rsa_pss_pss_sha256,
|
||||
ssl_sig_rsa_pss_pss_sha384, ssl_sig_rsa_pss_pss_sha512};
|
||||
|
||||
INSTANTIATE_CIPHER_TEST_P(RC4, Stream, V10ToV12, kDummyNamedGroupParams,
|
||||
kDummySignatureSchemesParams,
|
||||
TLS_RSA_WITH_RC4_128_SHA,
|
||||
|
|
@ -394,7 +394,7 @@ INSTANTIATE_CIPHER_TEST_P(
|
|||
#ifndef NSS_DISABLE_TLS_1_3
|
||||
INSTANTIATE_CIPHER_TEST_P(TLS13, All, V13,
|
||||
::testing::ValuesIn(kFasterDHEGroups),
|
||||
::testing::ValuesIn(kSignatureSchemesParamsArr),
|
||||
::testing::ValuesIn(kSignatureSchemesParamsArrTls13),
|
||||
TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256,
|
||||
TLS_AES_256_GCM_SHA384);
|
||||
INSTANTIATE_CIPHER_TEST_P(TLS13AllGroups, All, V13,
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- 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 <cstdlib>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "tls_connect.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
extern "C" {
|
||||
extern FILE* ssl_trace_iob;
|
||||
|
||||
#ifdef NSS_ALLOW_SSLKEYLOGFILE
|
||||
extern FILE* ssl_keylog_iob;
|
||||
#endif
|
||||
}
|
||||
|
||||
// These tests ensure that when the associated environment variables are unset
|
||||
// that the lazily-initialized defaults are what they are supposed to be.
|
||||
|
||||
#ifdef DEBUG
|
||||
TEST_P(TlsConnectGeneric, DebugEnvTraceFileNotSet) {
|
||||
char* ev = PR_GetEnvSecure("SSLDEBUGFILE");
|
||||
if (ev && ev[0]) {
|
||||
// note: should use GTEST_SKIP when GTest gets updated to support it
|
||||
return;
|
||||
}
|
||||
|
||||
Connect();
|
||||
EXPECT_EQ(stderr, ssl_trace_iob);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NSS_ALLOW_SSLKEYLOGFILE
|
||||
TEST_P(TlsConnectGeneric, DebugEnvKeylogFileNotSet) {
|
||||
char* ev = PR_GetEnvSecure("SSLKEYLOGFILE");
|
||||
if (ev && ev[0]) {
|
||||
// note: should use GTEST_SKIP when GTest gets updated to support it
|
||||
return;
|
||||
}
|
||||
|
||||
Connect();
|
||||
EXPECT_EQ(nullptr, ssl_keylog_iob);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace nss_test
|
||||
|
|
@ -436,14 +436,14 @@ TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsOddLength) {
|
|||
}
|
||||
|
||||
TEST_F(TlsExtensionTest13Stream, SignatureAlgorithmsPrecedingGarbage) {
|
||||
// 31 unknown signature algorithms followed by sha-256, rsa
|
||||
// 31 unknown signature algorithms followed by sha-256, rsa-pss
|
||||
const uint8_t val[] = {
|
||||
0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x01};
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x04};
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
MakeTlsFilter<TlsExtensionReplacer>(client_, ssl_signature_algorithms_xtn,
|
||||
extension);
|
||||
|
|
@ -482,6 +482,73 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) {
|
|||
client_, ssl_elliptic_curves_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTest12, SupportedCurvesDisableX25519) {
|
||||
// Disable session resumption.
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
|
||||
|
||||
// Ensure that we can enable its use in the key exchange.
|
||||
SECStatus rv =
|
||||
NSS_SetAlgorithmPolicy(SEC_OID_CURVE25519, NSS_USE_ALG_IN_SSL_KX, 0);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
|
||||
0);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
|
||||
auto capture1 =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_elliptic_curves_xtn);
|
||||
Connect();
|
||||
|
||||
EXPECT_TRUE(capture1->captured());
|
||||
const DataBuffer& ext1 = capture1->extension();
|
||||
|
||||
uint32_t count;
|
||||
ASSERT_TRUE(ext1.Read(0, 2, &count));
|
||||
|
||||
// Whether or not we've seen x25519 offered in this handshake.
|
||||
bool seen1_x25519 = false;
|
||||
for (size_t offset = 2; offset <= count; offset++) {
|
||||
uint32_t val;
|
||||
ASSERT_TRUE(ext1.Read(offset, 2, &val));
|
||||
if (val == ssl_grp_ec_curve25519) {
|
||||
seen1_x25519 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ASSERT_TRUE(seen1_x25519);
|
||||
|
||||
// Ensure that we can disable its use in the key exchange.
|
||||
rv = NSS_SetAlgorithmPolicy(SEC_OID_CURVE25519, 0, NSS_USE_ALG_IN_SSL_KX);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL,
|
||||
0);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
|
||||
// Clean up after the last run.
|
||||
Reset();
|
||||
auto capture2 =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_elliptic_curves_xtn);
|
||||
Connect();
|
||||
|
||||
EXPECT_TRUE(capture2->captured());
|
||||
const DataBuffer& ext2 = capture2->extension();
|
||||
|
||||
ASSERT_TRUE(ext2.Read(0, 2, &count));
|
||||
|
||||
// Whether or not we've seen x25519 offered in this handshake.
|
||||
bool seen2_x25519 = false;
|
||||
for (size_t offset = 2; offset <= count; offset++) {
|
||||
uint32_t val;
|
||||
ASSERT_TRUE(ext2.Read(offset, 2, &val));
|
||||
|
||||
if (val == ssl_grp_ec_curve25519) {
|
||||
seen2_x25519 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_FALSE(seen2_x25519);
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestPre13, SupportedPointsEmpty) {
|
||||
const uint8_t val[] = {0x00};
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
'ssl_gather_unittest.cc',
|
||||
'ssl_gtest.cc',
|
||||
'ssl_hrr_unittest.cc',
|
||||
'ssl_keylog_unittest.cc',
|
||||
'ssl_keyupdate_unittest.cc',
|
||||
'ssl_loopback_unittest.cc',
|
||||
'ssl_misc_unittest.cc',
|
||||
|
|
@ -76,7 +75,7 @@
|
|||
'<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==1', {
|
||||
[ 'static_libs==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
],
|
||||
|
|
@ -93,6 +92,14 @@
|
|||
'<(DEPTH)/lib/dbm/src/src.gyp:dbm',
|
||||
],
|
||||
}],
|
||||
[ 'enable_sslkeylogfile==1 and sanitizer_flags==0', {
|
||||
'sources': [
|
||||
'ssl_keylog_unittest.cc',
|
||||
],
|
||||
'defines': [
|
||||
'NSS_ALLOW_SSLKEYLOGFILE',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@
|
|||
* 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 NSS_ALLOW_SSLKEYLOGFILE
|
||||
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
|
@ -114,5 +112,3 @@ INSTANTIATE_TEST_CASE_P(
|
|||
#endif
|
||||
|
||||
} // namespace nss_test
|
||||
|
||||
#endif // NSS_ALLOW_SSLKEYLOGFILE
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class AeadTest : public ::testing::Test {
|
|||
static const size_t kMaxSize = 32;
|
||||
|
||||
ASSERT_GE(kMaxSize, ciphertext_len);
|
||||
ASSERT_LT(0U, ciphertext_len);
|
||||
|
||||
uint8_t output[kMaxSize];
|
||||
unsigned int output_len = 0;
|
||||
|
|
@ -191,7 +192,7 @@ TEST_F(AeadTest, AeadAes128Gcm) {
|
|||
}
|
||||
|
||||
TEST_F(AeadTest, AeadAes256Gcm) {
|
||||
SSLAeadContext *ctxInit;
|
||||
SSLAeadContext *ctxInit = nullptr;
|
||||
ASSERT_EQ(SECSuccess,
|
||||
SSL_MakeAead(SSL_LIBRARY_VERSION_TLS_1_3, TLS_AES_256_GCM_SHA384,
|
||||
secret_.get(), kLabel, strlen(kLabel), &ctxInit));
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@ class BadPrSocket : public DummyIOLayerMethods {
|
|||
// NSPR method vtable with the ones from this object.
|
||||
dummy_layer_ =
|
||||
PR_GetIdentitiesLayer(agent->ssl_fd(), DummyPrSocket::LayerId());
|
||||
EXPECT_TRUE(dummy_layer_);
|
||||
original_methods_ = dummy_layer_->methods;
|
||||
original_secret_ = dummy_layer_->secret;
|
||||
dummy_layer_->methods = fd_->methods;
|
||||
|
|
@ -442,6 +443,48 @@ TEST_P(TlsConnectStream, ReplaceRecordLayerAsyncLateAuth) {
|
|||
SendForwardReceive(client_, client_stage, server_);
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, ReplaceRecordLayerAsyncPostHandshake) {
|
||||
StartConnect();
|
||||
client_->SetServerKeyBits(server_->server_key_bits());
|
||||
|
||||
BadPrSocket bad_layer_client(client_);
|
||||
BadPrSocket bad_layer_server(server_);
|
||||
StagedRecords client_stage(client_);
|
||||
StagedRecords server_stage(server_);
|
||||
|
||||
client_->SetAuthCertificateCallback(AuthCompleteBlock);
|
||||
|
||||
server_stage.ForwardAll(client_, TlsAgent::STATE_CONNECTING);
|
||||
client_stage.ForwardAll(server_, TlsAgent::STATE_CONNECTING);
|
||||
server_stage.ForwardAll(client_, TlsAgent::STATE_CONNECTING);
|
||||
|
||||
ASSERT_TRUE(client_stage.empty());
|
||||
client_->Handshake();
|
||||
ASSERT_TRUE(client_stage.empty());
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
|
||||
|
||||
// Now declare the certificate good.
|
||||
EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
|
||||
client_->Handshake();
|
||||
ASSERT_FALSE(client_stage.empty());
|
||||
|
||||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
|
||||
client_stage.ForwardAll(server_, TlsAgent::STATE_CONNECTED);
|
||||
} else {
|
||||
client_stage.ForwardAll(server_, TlsAgent::STATE_CONNECTED);
|
||||
server_stage.ForwardAll(client_, TlsAgent::STATE_CONNECTED);
|
||||
}
|
||||
CheckKeys();
|
||||
|
||||
// Reading and writing application data should work.
|
||||
SendForwardReceive(client_, client_stage, server_);
|
||||
|
||||
// Post-handshake messages should work here.
|
||||
EXPECT_EQ(SECSuccess, SSL_SendSessionTicket(server_->ssl_fd(), nullptr, 0));
|
||||
SendForwardReceive(server_, server_stage, client_);
|
||||
}
|
||||
|
||||
// This test ensures that data is correctly forwarded when the handshake is
|
||||
// resumed after asynchronous server certificate authentication, when
|
||||
// SSL_AuthCertificateComplete() is called. The logic for resuming the
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@ class PacketFilter {
|
|||
CHANGE, // change the packet to a different value
|
||||
DROP // drop the packet
|
||||
};
|
||||
PacketFilter(bool enabled = true) : enabled_(enabled) {}
|
||||
explicit PacketFilter(bool on = true) : enabled_(on) {}
|
||||
virtual ~PacketFilter() {}
|
||||
|
||||
bool enabled() const { return enabled_; }
|
||||
|
||||
virtual Action Process(const DataBuffer& input, DataBuffer* output) {
|
||||
if (!enabled_) {
|
||||
return KEEP;
|
||||
|
|
|
|||
|
|
@ -250,6 +250,7 @@ void TlsConnectTestBase::Reset(const std::string& server_name,
|
|||
server_->SkipVersionChecks();
|
||||
}
|
||||
|
||||
std::cerr << "Reset" << std::endl;
|
||||
Init();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ class TlsConnectTestBase : public ::testing::Test {
|
|||
// around test cases. In particular, DSA is checked in
|
||||
// ssl_extension_unittest.cc.
|
||||
const std::vector<SECOidTag> algorithms_ = {SEC_OID_APPLY_SSL_POLICY,
|
||||
SEC_OID_ANSIX9_DSA_SIGNATURE};
|
||||
SEC_OID_ANSIX9_DSA_SIGNATURE,
|
||||
SEC_OID_CURVE25519};
|
||||
std::vector<std::tuple<SECOidTag, uint32_t>> saved_policies_;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ static void GenerateEsniKey(time_t windowStart, SSLNamedGroup group,
|
|||
ASSERT_NE(nullptr, priv);
|
||||
SECITEM_FreeItem(&ecParams, PR_FALSE);
|
||||
PRUint8 encoded[1024];
|
||||
unsigned int encoded_len;
|
||||
unsigned int encoded_len = 0;
|
||||
|
||||
SECStatus rv = SSL_EncodeESNIKeys(
|
||||
&cipher_suites[0], cipher_suites.size(), group, pub, 100, windowStart,
|
||||
|
|
@ -375,11 +375,13 @@ TEST_P(TlsConnectTls13, ConnectEsniCSMismatch) {
|
|||
GenerateEsniKey(time(nullptr), ssl_grp_ec_curve25519, kDefaultSuites, &record,
|
||||
&pub, &priv);
|
||||
PRUint8 encoded[1024];
|
||||
unsigned int encoded_len;
|
||||
unsigned int encoded_len = 0;
|
||||
|
||||
SECStatus rv = SSL_EncodeESNIKeys(
|
||||
&kChaChaSuite[0], kChaChaSuite.size(), ssl_grp_ec_curve25519, pub.get(),
|
||||
100, time(0), time(0) + 10, encoded, &encoded_len, sizeof(encoded));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ASSERT_LT(0U, encoded_len);
|
||||
rv = SSL_SetESNIKeyPair(server_->ssl_fd(), priv.get(), encoded, encoded_len);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = SSL_EnableESNI(client_->ssl_fd(), record.data(), record.len(), "");
|
||||
|
|
|
|||
|
|
@ -549,9 +549,9 @@ class SelectiveDropFilter : public PacketFilter {
|
|||
class SelectiveRecordDropFilter : public TlsRecordFilter {
|
||||
public:
|
||||
SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& a,
|
||||
uint32_t pattern, bool enabled = true)
|
||||
uint32_t pattern, bool on = true)
|
||||
: TlsRecordFilter(a), pattern_(pattern), counter_(0) {
|
||||
if (!enabled) {
|
||||
if (!on) {
|
||||
Disable();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ NSS build tool options:
|
|||
(requires the gold linker, use clang-3.8 for SAW)
|
||||
--no-zdefs don't set -Wl,-z,defs
|
||||
--test ignore map files and export everything we have
|
||||
--static create static libraries and use static linking
|
||||
--ct-verif build with valgrind for ct-verif
|
||||
--nspr force a rebuild of NSPR
|
||||
--with-nspr use the NSPR build at the given locations
|
||||
|
|
@ -51,4 +52,6 @@ NSS build tool options:
|
|||
--enable-libpkix make libpkix part of the build
|
||||
--mozpkix-only build only static mozpkix and mozpkix-test libraries
|
||||
support for this build option is limited
|
||||
--disable-keylog disable support for logging key data to a file specified
|
||||
by the SSLKEYLOGFILE environment variable
|
||||
-D<gyp-option> pass an option directly to gyp
|
||||
|
|
|
|||
|
|
@ -215,6 +215,12 @@ extern void CERT_DestroyCertificate(CERTCertificate *cert);
|
|||
*/
|
||||
extern CERTCertificate *CERT_DupCertificate(CERTCertificate *c);
|
||||
|
||||
/* Access the DER of the certificate. This only creates a reference to the DER
|
||||
* in the outparam not a copy. To avoid the pointer becoming invalid, use
|
||||
* CERT_DupCertificate() and keep a reference to the duplicate alive.
|
||||
*/
|
||||
extern SECStatus CERT_GetCertificateDer(const CERTCertificate *c, SECItem *der);
|
||||
|
||||
/*
|
||||
** Create a new certificate request. This result must be wrapped with an
|
||||
** CERTSignedData to create a signed certificate request.
|
||||
|
|
|
|||
|
|
@ -447,71 +447,39 @@ cert_GetCertType(CERTCertificate *cert)
|
|||
}
|
||||
|
||||
PRBool
|
||||
cert_EKUAllowsIPsecIKE(CERTCertificate *cert, PRBool *isCritical)
|
||||
cert_IsIPsecOID(CERTOidSequence *extKeyUsage)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECItem encodedExtKeyUsage;
|
||||
CERTOidSequence *extKeyUsage = NULL;
|
||||
PRBool result = PR_FALSE;
|
||||
|
||||
rv = CERT_GetExtenCriticality(cert->extensions,
|
||||
SEC_OID_X509_EXT_KEY_USAGE,
|
||||
isCritical);
|
||||
if (rv != SECSuccess) {
|
||||
*isCritical = PR_FALSE;
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_IPSEC_IKE) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
encodedExtKeyUsage.data = NULL;
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE,
|
||||
&encodedExtKeyUsage);
|
||||
if (rv != SECSuccess) {
|
||||
/* EKU not present, allowed. */
|
||||
result = PR_TRUE;
|
||||
goto done;
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_IPSEC_IKE_END) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
|
||||
if (!extKeyUsage) {
|
||||
/* failure */
|
||||
goto done;
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_IPSEC_IKE_INTERMEDIATE) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_X509_ANY_EXT_KEY_USAGE) ==
|
||||
SECSuccess) {
|
||||
result = PR_TRUE;
|
||||
goto done;
|
||||
/* these are now deprecated, but may show up. Treat them the same as IKE */
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_IPSEC_END) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_EXT_KEY_USAGE_IPSEC_IKE) ==
|
||||
SECSuccess) {
|
||||
result = PR_TRUE;
|
||||
goto done;
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_IPSEC_IKE_END) ==
|
||||
SECSuccess) {
|
||||
result = PR_TRUE;
|
||||
goto done;
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_IPSEC_USER) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_IPSEC_IKE_INTERMEDIATE) ==
|
||||
SECSuccess) {
|
||||
result = PR_TRUE;
|
||||
goto done;
|
||||
/* this one should probably be in cert_ComputeCertType and set all usages? */
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_X509_ANY_EXT_KEY_USAGE) == SECSuccess) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
done:
|
||||
if (encodedExtKeyUsage.data != NULL) {
|
||||
PORT_Free(encodedExtKeyUsage.data);
|
||||
}
|
||||
if (extKeyUsage != NULL) {
|
||||
CERT_DestroyOidSequence(extKeyUsage);
|
||||
}
|
||||
return result;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
|
@ -521,9 +489,9 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
SECItem tmpitem;
|
||||
SECItem encodedExtKeyUsage;
|
||||
CERTOidSequence *extKeyUsage = NULL;
|
||||
PRBool basicConstraintPresent = PR_FALSE;
|
||||
CERTBasicConstraints basicConstraint;
|
||||
PRUint32 nsCertType = 0;
|
||||
PRBool isCA = PR_FALSE;
|
||||
|
||||
tmpitem.data = NULL;
|
||||
CERT_FindNSCertTypeExtension(cert, &tmpitem);
|
||||
|
|
@ -535,7 +503,7 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
}
|
||||
rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
|
||||
if (rv == SECSuccess) {
|
||||
basicConstraintPresent = PR_TRUE;
|
||||
isCA = basicConstraint.isCA;
|
||||
}
|
||||
if (tmpitem.data != NULL || extKeyUsage != NULL) {
|
||||
if (tmpitem.data == NULL) {
|
||||
|
|
@ -571,19 +539,11 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) ==
|
||||
SECSuccess) {
|
||||
if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
|
||||
nsCertType |= NS_CERT_TYPE_EMAIL_CA;
|
||||
} else {
|
||||
nsCertType |= NS_CERT_TYPE_EMAIL;
|
||||
}
|
||||
nsCertType |= isCA ? NS_CERT_TYPE_EMAIL_CA : NS_CERT_TYPE_EMAIL;
|
||||
}
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == SECSuccess) {
|
||||
if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_CA;
|
||||
} else {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_SERVER;
|
||||
}
|
||||
nsCertType |= isCA ? NS_CERT_TYPE_SSL_CA : NS_CERT_TYPE_SSL_SERVER;
|
||||
}
|
||||
/*
|
||||
* Treat certs with step-up OID as also having SSL server type.
|
||||
|
|
@ -592,27 +552,18 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
if (findOIDinOIDSeqByTagNum(extKeyUsage,
|
||||
SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==
|
||||
SECSuccess) {
|
||||
if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_CA;
|
||||
} else {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_SERVER;
|
||||
}
|
||||
nsCertType |= isCA ? NS_CERT_TYPE_SSL_CA : NS_CERT_TYPE_SSL_SERVER;
|
||||
}
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == SECSuccess) {
|
||||
if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_CA;
|
||||
} else {
|
||||
nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
|
||||
}
|
||||
nsCertType |= isCA ? NS_CERT_TYPE_SSL_CA : NS_CERT_TYPE_SSL_CLIENT;
|
||||
}
|
||||
if (cert_IsIPsecOID(extKeyUsage)) {
|
||||
nsCertType |= isCA ? NS_CERT_TYPE_IPSEC_CA : NS_CERT_TYPE_IPSEC;
|
||||
}
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == SECSuccess) {
|
||||
if (basicConstraintPresent == PR_TRUE && (basicConstraint.isCA)) {
|
||||
nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
|
||||
} else {
|
||||
nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING;
|
||||
}
|
||||
nsCertType |= isCA ? NS_CERT_TYPE_OBJECT_SIGNING_CA : NS_CERT_TYPE_OBJECT_SIGNING;
|
||||
}
|
||||
if (findOIDinOIDSeqByTagNum(
|
||||
extKeyUsage, SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == SECSuccess) {
|
||||
|
|
@ -629,7 +580,7 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
|
||||
/* if the basic constraint extension says the cert is a CA, then
|
||||
allow SSL CA and EMAIL CA and Status Responder */
|
||||
if (basicConstraintPresent && basicConstraint.isCA) {
|
||||
if (isCA) {
|
||||
nsCertType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
|
||||
EXT_KEY_USAGE_STATUS_RESPONDER);
|
||||
}
|
||||
|
|
@ -638,6 +589,14 @@ cert_ComputeCertType(CERTCertificate *cert)
|
|||
NS_CERT_TYPE_EMAIL;
|
||||
}
|
||||
|
||||
/* IPSEC is allowed to use SSL client and server certs as well as email certs */
|
||||
if (nsCertType & (NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | NS_CERT_TYPE_EMAIL)) {
|
||||
nsCertType |= NS_CERT_TYPE_IPSEC;
|
||||
}
|
||||
if (nsCertType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA)) {
|
||||
nsCertType |= NS_CERT_TYPE_IPSEC_CA;
|
||||
}
|
||||
|
||||
if (encodedExtKeyUsage.data != NULL) {
|
||||
PORT_Free(encodedExtKeyUsage.data);
|
||||
}
|
||||
|
|
@ -1153,7 +1112,7 @@ CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, PRBool ca,
|
|||
break;
|
||||
case certUsageIPsec:
|
||||
requiredKeyUsage = KU_KEY_CERT_SIGN;
|
||||
requiredCertType = NS_CERT_TYPE_SSL_CA;
|
||||
requiredCertType = NS_CERT_TYPE_IPSEC_CA;
|
||||
break;
|
||||
case certUsageSSLCA:
|
||||
requiredKeyUsage = KU_KEY_CERT_SIGN;
|
||||
|
|
@ -1200,7 +1159,7 @@ CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, PRBool ca,
|
|||
case certUsageIPsec:
|
||||
/* RFC 4945 Section 5.1.3.2 */
|
||||
requiredKeyUsage = KU_DIGITAL_SIGNATURE_OR_NON_REPUDIATION;
|
||||
requiredCertType = 0;
|
||||
requiredCertType = NS_CERT_TYPE_IPSEC;
|
||||
break;
|
||||
case certUsageSSLServerWithStepUp:
|
||||
requiredKeyUsage =
|
||||
|
|
@ -1314,6 +1273,17 @@ CERT_DupCertificate(CERTCertificate *c)
|
|||
return c;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_GetCertificateDer(const CERTCertificate *c, SECItem *der)
|
||||
{
|
||||
if (!c || !der) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
*der = c->derCert;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow use of default cert database, so that apps(such as mozilla) don't
|
||||
* have to pass the handle all over the place.
|
||||
|
|
|
|||
|
|
@ -416,6 +416,19 @@ struct CERTDistNamesStr {
|
|||
void *head; /* private */
|
||||
};
|
||||
|
||||
/*
|
||||
* NS_CERT_TYPE defines are used in two areas:
|
||||
* 1) The old NSS Cert Type Extension, which is a certificate extension in the
|
||||
* actual cert. It was created before the x509 Extended Key Usage Extension,
|
||||
* which has now taken over it's function. This field is only 8 bits wide
|
||||
* 2) The nsCertType entry in the CERTCertificate structure. This field is
|
||||
* 32 bits wide.
|
||||
* Any entries in this table greater than 0x80 will not be able to be encoded
|
||||
* in an NSS Cert Type Extension, but can still be represented internally in
|
||||
* the nsCertType field.
|
||||
*/
|
||||
#define NS_CERT_TYPE_IPSEC_CA (0x200) /* outside the NS Cert Type Extenstion */
|
||||
#define NS_CERT_TYPE_IPSEC (0x100) /* outside the NS Cert Type Extenstion */
|
||||
#define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */
|
||||
#define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */
|
||||
#define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */
|
||||
|
|
@ -430,11 +443,12 @@ struct CERTDistNamesStr {
|
|||
|
||||
#define NS_CERT_TYPE_APP \
|
||||
(NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | NS_CERT_TYPE_EMAIL | \
|
||||
NS_CERT_TYPE_OBJECT_SIGNING)
|
||||
NS_CERT_TYPE_IPSEC | NS_CERT_TYPE_OBJECT_SIGNING)
|
||||
|
||||
#define NS_CERT_TYPE_CA \
|
||||
(NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | \
|
||||
NS_CERT_TYPE_OBJECT_SIGNING_CA | EXT_KEY_USAGE_STATUS_RESPONDER)
|
||||
#define NS_CERT_TYPE_CA \
|
||||
(NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | \
|
||||
NS_CERT_TYPE_OBJECT_SIGNING_CA | EXT_KEY_USAGE_STATUS_RESPONDER | \
|
||||
NS_CERT_TYPE_IPSEC_CA)
|
||||
typedef enum SECCertUsageEnum {
|
||||
certUsageSSLClient = 0,
|
||||
certUsageSSLServer = 1,
|
||||
|
|
|
|||
|
|
@ -1401,7 +1401,6 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
|
||||
for (i = 1; i <= certificateUsageHighest &&
|
||||
(SECSuccess == valid || returnedUsages || log);) {
|
||||
PRBool typeAndEKUAllowed = PR_TRUE;
|
||||
PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE;
|
||||
if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) {
|
||||
NEXT_USAGE();
|
||||
|
|
@ -1451,19 +1450,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
LOG_ERROR(log, cert, 0, requiredKeyUsage);
|
||||
INVALID_USAGE();
|
||||
}
|
||||
if (certUsage != certUsageIPsec) {
|
||||
if (!(certType & requiredCertType)) {
|
||||
typeAndEKUAllowed = PR_FALSE;
|
||||
}
|
||||
} else {
|
||||
PRBool isCritical;
|
||||
PRBool allowed = cert_EKUAllowsIPsecIKE(cert, &isCritical);
|
||||
/* If the extension isn't critical, we allow any EKU value. */
|
||||
if (isCritical && !allowed) {
|
||||
typeAndEKUAllowed = PR_FALSE;
|
||||
}
|
||||
}
|
||||
if (!typeAndEKUAllowed) {
|
||||
if (!(certType & requiredCertType)) {
|
||||
if (PR_TRUE == requiredUsage) {
|
||||
PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -639,6 +639,11 @@ seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki)
|
|||
return pubk;
|
||||
break;
|
||||
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
|
||||
/* A basic sanity check on inputs. */
|
||||
if (spki->algorithm.parameters.len == 0 || newOs.len == 0) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
break;
|
||||
}
|
||||
pubk->keyType = ecKey;
|
||||
pubk->u.ec.size = 0;
|
||||
|
||||
|
|
@ -1206,6 +1211,37 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the private key to find a public key handle. The handle will be on
|
||||
* the same slot as the private key.
|
||||
*/
|
||||
static CK_OBJECT_HANDLE
|
||||
seckey_FindPublicKeyHandle(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk)
|
||||
{
|
||||
CK_OBJECT_HANDLE keyID;
|
||||
|
||||
/* this helper function is only used below. If we want to make this more
|
||||
* general, we would need to free up any already cached handles if the
|
||||
* slot doesn't match up with the private key slot */
|
||||
PORT_Assert(pubk->pkcs11ID == CK_INVALID_HANDLE);
|
||||
|
||||
/* first look for a matching public key */
|
||||
keyID = PK11_MatchItem(privk->pkcs11Slot, privk->pkcs11ID, CKO_PUBLIC_KEY);
|
||||
if (keyID != CK_INVALID_HANDLE) {
|
||||
return keyID;
|
||||
}
|
||||
|
||||
/* none found, create a temp one, make the pubk the owner */
|
||||
pubk->pkcs11ID = PK11_DerivePubKeyFromPrivKey(privk);
|
||||
if (pubk->pkcs11ID == CK_INVALID_HANDLE) {
|
||||
/* end of the road. Token doesn't have matching public key, nor can
|
||||
* token regenerate a new public key from and existing private key. */
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
pubk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot);
|
||||
return pubk->pkcs11ID;
|
||||
}
|
||||
|
||||
SECKEYPublicKey *
|
||||
SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
|
||||
{
|
||||
|
|
@ -1213,6 +1249,8 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
|
|||
PLArenaPool *arena;
|
||||
CERTCertificate *cert;
|
||||
SECStatus rv;
|
||||
CK_OBJECT_HANDLE pubKeyHandle;
|
||||
SECItem decodedPoint;
|
||||
|
||||
/*
|
||||
* First try to look up the cert.
|
||||
|
|
@ -1243,11 +1281,47 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
|
|||
|
||||
switch (privk->keyType) {
|
||||
case nullKey:
|
||||
case dhKey:
|
||||
case dsaKey:
|
||||
/* Nothing to query, if the cert isn't there, we're done -- no way
|
||||
* to get the public key */
|
||||
break;
|
||||
case dsaKey:
|
||||
pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
|
||||
if (pubKeyHandle == CK_INVALID_HANDLE)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_BASE, arena, &pubk->u.dsa.params.base);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_PRIME, arena, &pubk->u.dsa.params.prime);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_SUBPRIME, arena, &pubk->u.dsa.params.subPrime);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_VALUE, arena, &pubk->u.dsa.publicValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
return pubk;
|
||||
case dhKey:
|
||||
pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
|
||||
if (pubKeyHandle == CK_INVALID_HANDLE)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_BASE, arena, &pubk->u.dh.base);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_PRIME, arena, &pubk->u.dh.prime);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_VALUE, arena, &pubk->u.dh.publicValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
return pubk;
|
||||
case rsaKey:
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
|
||||
CKA_MODULUS, arena, &pubk->u.rsa.modulus);
|
||||
|
|
@ -1258,7 +1332,6 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
|
|||
if (rv != SECSuccess)
|
||||
break;
|
||||
return pubk;
|
||||
break;
|
||||
case ecKey:
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
|
||||
CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams);
|
||||
|
|
@ -1268,7 +1341,23 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
|
|||
rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID,
|
||||
CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
|
||||
if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) {
|
||||
break;
|
||||
pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk);
|
||||
if (pubKeyHandle == CK_INVALID_HANDLE)
|
||||
break;
|
||||
rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle,
|
||||
CKA_EC_POINT, arena, &pubk->u.ec.publicValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
/* ec.publicValue should be decoded, PKCS #11 defines CKA_EC_POINT
|
||||
* as encoded, but it's not always. try do decoded it and if it
|
||||
* succeeds store the decoded value */
|
||||
rv = SEC_QuickDERDecodeItem(arena, &decodedPoint,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate), &pubk->u.ec.publicValue);
|
||||
if (rv == SECSuccess) {
|
||||
/* both values are in the public key arena, so it's safe to
|
||||
* overwrite the old value */
|
||||
pubk->u.ec.publicValue = decodedPoint;
|
||||
}
|
||||
pubk->u.ec.encoding = ECPoint_Undefined;
|
||||
return pubk;
|
||||
|
|
@ -1276,7 +1365,9 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
|
|||
break;
|
||||
}
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
/* must use Destroy public key here, because some paths create temporary
|
||||
* PKCS #11 objects which need to be freed */
|
||||
SECKEY_DestroyPublicKey(pubk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1013,6 +1013,10 @@ extern SECStatus ChaCha20Poly1305_Open(
|
|||
const unsigned char *nonce, unsigned int nonceLen,
|
||||
const unsigned char *ad, unsigned int adLen);
|
||||
|
||||
extern SECStatus ChaCha20_Xor(
|
||||
unsigned char *output, const unsigned char *block, unsigned int len,
|
||||
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr);
|
||||
|
||||
/******************************************/
|
||||
/*
|
||||
** MD5 secure hash function
|
||||
|
|
|
|||
|
|
@ -92,23 +92,32 @@ CheckX86CPUSupport()
|
|||
#endif /* NSS_X86_OR_X64 */
|
||||
|
||||
/* clang-format off */
|
||||
#if (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__)
|
||||
#if defined(__aarch64__) || defined(__arm__)
|
||||
#ifndef __has_include
|
||||
#define __has_include(x) 0
|
||||
#endif
|
||||
#if (__has_include(<sys/auxv.h>) || defined(__linux__)) && \
|
||||
defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)
|
||||
/* This might be conflict with host compiler */
|
||||
#if !defined(__ANDROID__)
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
extern unsigned long getauxval(unsigned long type) __attribute__((weak));
|
||||
#else
|
||||
static unsigned long (*getauxval)(unsigned long) = NULL;
|
||||
#define AT_HWCAP2 0
|
||||
#define AT_HWCAP 0
|
||||
#endif /* defined(__GNUC__) && __GNUC__ >= 2 && defined(__ELF__)*/
|
||||
#endif /* (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__) */
|
||||
|
||||
#ifndef AT_HWCAP2
|
||||
#define AT_HWCAP2 26
|
||||
#endif
|
||||
#ifndef AT_HWCAP
|
||||
#define AT_HWCAP 16
|
||||
#endif
|
||||
|
||||
#endif /* defined(__aarch64__) || defined(__arm__) */
|
||||
/* clang-format on */
|
||||
|
||||
#if defined(__aarch64__) && !defined(__ANDROID__)
|
||||
#if defined(__aarch64__)
|
||||
// Defines from hwcap.h in Linux kernel - ARM64
|
||||
#ifndef HWCAP_AES
|
||||
#define HWCAP_AES (1 << 3)
|
||||
|
|
@ -138,9 +147,9 @@ CheckARMSupport()
|
|||
/* aarch64 must support NEON. */
|
||||
arm_neon_support_ = disable_arm_neon == NULL;
|
||||
}
|
||||
#endif /* defined(__aarch64__) && !defined(__ANDROID__) */
|
||||
#endif /* defined(__aarch64__) */
|
||||
|
||||
#if defined(__arm__) && !defined(__ANDROID__)
|
||||
#if defined(__arm__)
|
||||
// Defines from hwcap.h in Linux kernel - ARM
|
||||
/*
|
||||
* HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
|
||||
|
|
@ -165,23 +174,58 @@ CheckARMSupport()
|
|||
#define HWCAP2_SHA2 (1 << 3)
|
||||
#endif
|
||||
|
||||
PRBool
|
||||
GetNeonSupport()
|
||||
{
|
||||
char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
|
||||
if (disable_arm_neon) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
|
||||
// Compiler generates NEON instruction as default option.
|
||||
// If no getauxval, compiler generate NEON instruction by default,
|
||||
// we should allow NOEN support.
|
||||
return PR_TRUE;
|
||||
#elif !defined(__ANDROID__)
|
||||
// Android's cpu-features.c detects features by the following logic
|
||||
//
|
||||
// - Call getauxval(AT_HWCAP)
|
||||
// - Parse /proc/self/auxv if getauxval is nothing or returns 0
|
||||
// - Parse /proc/cpuinfo if both cannot detect features
|
||||
//
|
||||
// But we don't use it for Android since Android document
|
||||
// (https://developer.android.com/ndk/guides/cpu-features) says
|
||||
// one problem with AT_HWCAP sometimes devices (Nexus 4 and emulator)
|
||||
// are mistaken for IDIV.
|
||||
if (getauxval) {
|
||||
return (getauxval(AT_HWCAP) & HWCAP_NEON);
|
||||
}
|
||||
#endif /* defined(__ARM_NEON) || defined(__ARM_NEON__) */
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
CheckARMSupport()
|
||||
{
|
||||
char *disable_arm_neon = PR_GetEnvSecure("NSS_DISABLE_ARM_NEON");
|
||||
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
||||
if (getauxval) {
|
||||
// Android's cpu-features.c uses AT_HWCAP2 for newer features.
|
||||
// AT_HWCAP2 is implemented on newer devices / kernel, so we can trust
|
||||
// it since cpu-features.c doesn't have workaround / fallback.
|
||||
// Also, AT_HWCAP2 is supported by glibc 2.18+ on Linux/arm, If
|
||||
// AT_HWCAP2 isn't supported by glibc or Linux kernel, getauxval will
|
||||
// returns 0.
|
||||
long hwcaps = getauxval(AT_HWCAP2);
|
||||
arm_aes_support_ = hwcaps & HWCAP2_AES && disable_hw_aes == NULL;
|
||||
arm_pmull_support_ = hwcaps & HWCAP2_PMULL;
|
||||
arm_sha1_support_ = hwcaps & HWCAP2_SHA1;
|
||||
arm_sha2_support_ = hwcaps & HWCAP2_SHA2;
|
||||
arm_neon_support_ = hwcaps & HWCAP_NEON && disable_arm_neon == NULL;
|
||||
}
|
||||
arm_neon_support_ = GetNeonSupport();
|
||||
}
|
||||
#endif /* defined(__arm__) && !defined(__ANDROID__) */
|
||||
#endif /* defined(__arm__) */
|
||||
|
||||
// Enable when Firefox can use it.
|
||||
// Enable when Firefox can use it for Android API 16 and 17.
|
||||
// #if defined(__ANDROID__) && (defined(__arm__) || defined(__aarch64__))
|
||||
// #include <cpu-features.h>
|
||||
// void
|
||||
|
|
@ -262,7 +306,7 @@ FreeblInit(void)
|
|||
{
|
||||
#ifdef NSS_X86_OR_X64
|
||||
CheckX86CPUSupport();
|
||||
#elif (defined(__aarch64__) || defined(__arm__)) && !defined(__ANDROID__)
|
||||
#elif (defined(__aarch64__) || defined(__arm__))
|
||||
CheckARMSupport();
|
||||
#endif
|
||||
return PR_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ ChaCha20Poly1305_DestroyContext(ChaCha20Poly1305Context *ctx, PRBool freeit)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef NSS_DISABLE_CHACHAPOLY
|
||||
void
|
||||
ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
|
||||
uint8_t *nonce, uint32_t ctr)
|
||||
|
|
@ -167,6 +168,25 @@ ChaCha20Xor(uint8_t *output, uint8_t *block, uint32_t len, uint8_t *k,
|
|||
Hacl_Chacha20_chacha20(output, block, len, k, nonce, ctr);
|
||||
}
|
||||
}
|
||||
#endif /* NSS_DISABLE_CHACHAPOLY */
|
||||
|
||||
SECStatus
|
||||
ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len,
|
||||
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr)
|
||||
{
|
||||
#ifdef NSS_DISABLE_CHACHAPOLY
|
||||
return SECFailure;
|
||||
#else
|
||||
// ChaCha has a 64 octet block, with a 32-bit block counter.
|
||||
if (sizeof(len) > 4 && len >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
ChaCha20Xor(output, (uint8_t *)block, len, (uint8_t *)k,
|
||||
(uint8_t *)nonce, ctr);
|
||||
return SECSuccess;
|
||||
#endif
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
||||
|
|
@ -185,6 +205,11 @@ ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
|
|||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
// ChaCha has a 64 octet block, with a 32-bit block counter.
|
||||
if (sizeof(inputLen) > 4 && inputLen >= (1ULL << (6 + 32))) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = inputLen + ctx->tagLen;
|
||||
if (maxOutputLen < *outputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ swap8b(PRUint64 value)
|
|||
return (value);
|
||||
}
|
||||
|
||||
#elif !defined(_MSC_VER)
|
||||
#elif defined(IS_LITTLE_ENDIAN) && !defined(_MSC_VER) && !__has_builtin(__builtin_bswap64) && !((defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))))
|
||||
|
||||
PRUint64
|
||||
swap8b(PRUint64 x)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@
|
|||
#include <stdlib.h>
|
||||
#include "prtypes.h"
|
||||
|
||||
/* For non-clang platform */
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
/* Unfortunately this isn't always set when it should be. */
|
||||
#if defined(HAVE_LONG_LONG)
|
||||
|
||||
|
|
@ -29,11 +34,17 @@
|
|||
/*
|
||||
* FREEBL_HTONLL(x): swap bytes in a 64-bit integer.
|
||||
*/
|
||||
#if defined(IS_LITTLE_ENDIAN)
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define FREEBL_HTONLL(x) _byteswap_uint64(x)
|
||||
|
||||
/* gcc doesn't have __has_builtin, but it does have __builtin_bswap64 */
|
||||
#elif __has_builtin(__builtin_bswap64) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||
|
||||
#define FREEBL_HTONLL(x) __builtin_bswap64(x)
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__x86_64))
|
||||
|
||||
PRUint64 swap8b(PRUint64 value);
|
||||
|
|
@ -48,4 +59,8 @@ PRUint64 swap8b(PRUint64 x);
|
|||
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif /* HAVE_LONG_LONG */
|
||||
#else /* IS_LITTLE_ENDIAN */
|
||||
#define FREEBL_HTONLL(x) (x)
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_LONG_LONG */
|
||||
|
|
|
|||
|
|
@ -210,7 +210,8 @@ DH_Derive(SECItem *publicValue,
|
|||
unsigned int len = 0;
|
||||
unsigned int nb;
|
||||
unsigned char *secret = NULL;
|
||||
if (!publicValue || !prime || !privateValue || !derivedSecret) {
|
||||
if (!publicValue || !publicValue->len || !prime || !prime->len ||
|
||||
!privateValue || !privateValue->len || !derivedSecret) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,8 +202,8 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey,
|
|||
#endif
|
||||
MP_DIGITS(&k) = 0;
|
||||
|
||||
if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0) ||
|
||||
!ecParams->name) {
|
||||
if (!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!privKey || !privKeyBytes || privKeyLen <= 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -391,7 +391,7 @@ EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey)
|
|||
int len;
|
||||
unsigned char *privKeyBytes = NULL;
|
||||
|
||||
if (!ecParams) {
|
||||
if (!ecParams || ecParams->name == ECCurve_noName || !privKey) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -430,7 +430,8 @@ EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
|
|||
mp_err err = MP_OKAY;
|
||||
int len;
|
||||
|
||||
if (!ecParams || !publicValue || !ecParams->name) {
|
||||
if (!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!publicValue || !publicValue->len) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -536,8 +537,9 @@ ECDH_Derive(SECItem *publicValue,
|
|||
int i;
|
||||
#endif
|
||||
|
||||
if (!publicValue || !ecParams || !privateValue || !derivedSecret ||
|
||||
!ecParams->name) {
|
||||
if (!publicValue || !publicValue->len ||
|
||||
!ecParams || ecParams->name == ECCurve_noName ||
|
||||
!privateValue || !privateValue->len || !derivedSecret) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,9 @@ ec_Curve25519_pt_mul(SECItem *X, SECItem *k, SECItem *P)
|
|||
}
|
||||
px = P->data;
|
||||
}
|
||||
if (k->len != 32) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus rv = ec_Curve25519_mul(X->data, k->data, px);
|
||||
if (NSS_SecureMemcmpZero(X->data, X->len) == 0) {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@
|
|||
#include "seccomon.h" /* Required for RSA and DSA. */
|
||||
#include "secerr.h"
|
||||
#include "prtypes.h"
|
||||
#include "secitem.h"
|
||||
#include "pkcs11t.h"
|
||||
|
||||
#include "ec.h" /* Required for ECDSA */
|
||||
#include "ec.h" /* Required for EC */
|
||||
|
||||
/*
|
||||
* different platforms have different ways of calling and initial entry point
|
||||
|
|
@ -288,6 +290,8 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
/* AES Known Plaintext (128-bits). (blocksize is 128-bits) */
|
||||
static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" };
|
||||
|
||||
static const PRUint8 aes_gcm_known_aad[] = { "MozillaallizoM" };
|
||||
|
||||
/* AES Known Ciphertext (128-bit key). */
|
||||
static const PRUint8 aes_ecb128_known_ciphertext[] = {
|
||||
0x3c, 0xa5, 0x96, 0xf3, 0x34, 0x6a, 0x96, 0xc1,
|
||||
|
|
@ -299,6 +303,13 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0x15, 0x54, 0x14, 0x1d, 0x4e, 0xd8, 0xd5, 0xea
|
||||
};
|
||||
|
||||
static const PRUint8 aes_gcm128_known_ciphertext[] = {
|
||||
0x63, 0xf4, 0x95, 0x28, 0xe6, 0x78, 0xee, 0x6e,
|
||||
0x4f, 0xe0, 0xfc, 0x8d, 0xd7, 0xa2, 0xb1, 0xff,
|
||||
0x0c, 0x97, 0x1b, 0x0a, 0xdd, 0x97, 0x75, 0xed,
|
||||
0x8b, 0xde, 0xbf, 0x16, 0x5e, 0x57, 0x6b, 0x4f
|
||||
};
|
||||
|
||||
/* AES Known Ciphertext (192-bit key). */
|
||||
static const PRUint8 aes_ecb192_known_ciphertext[] = {
|
||||
0xa0, 0x18, 0x62, 0xed, 0x88, 0x19, 0xcb, 0x62,
|
||||
|
|
@ -310,6 +321,13 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0x07, 0xbc, 0x43, 0x2f, 0x6d, 0xad, 0x29, 0xe1
|
||||
};
|
||||
|
||||
static const PRUint8 aes_gcm192_known_ciphertext[] = {
|
||||
0xc1, 0x0b, 0x92, 0x1d, 0x68, 0x21, 0xf4, 0x25,
|
||||
0x41, 0x61, 0x20, 0x2d, 0x59, 0x7f, 0x53, 0xde,
|
||||
0x93, 0x39, 0xab, 0x09, 0x76, 0x41, 0x57, 0x2b,
|
||||
0x90, 0x2e, 0x44, 0xbb, 0x52, 0x03, 0xe9, 0x07
|
||||
};
|
||||
|
||||
/* AES Known Ciphertext (256-bit key). */
|
||||
static const PRUint8 aes_ecb256_known_ciphertext[] = {
|
||||
0xdb, 0xa6, 0x52, 0x01, 0x8a, 0x70, 0xae, 0x66,
|
||||
|
|
@ -321,18 +339,29 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
0xc5, 0xc5, 0x68, 0x71, 0x6e, 0x34, 0x40, 0x16
|
||||
};
|
||||
|
||||
static const PRUint8 aes_gcm256_known_ciphertext[] = {
|
||||
0x5d, 0x9e, 0xd2, 0xa2, 0x74, 0x9c, 0xd9, 0x1c,
|
||||
0xd1, 0xc9, 0xee, 0x5d, 0xb6, 0xf2, 0xc9, 0xb6,
|
||||
0x79, 0x27, 0x53, 0x02, 0xa3, 0xdc, 0x22, 0xce,
|
||||
0xf4, 0xb0, 0xc1, 0x8c, 0x86, 0x51, 0xf5, 0xa1
|
||||
};
|
||||
|
||||
const PRUint8 *aes_ecb_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext : aes_ecb256_known_ciphertext;
|
||||
|
||||
const PRUint8 *aes_cbc_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cbc128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cbc192_known_ciphertext : aes_cbc256_known_ciphertext;
|
||||
|
||||
const PRUint8 *aes_gcm_known_ciphertext =
|
||||
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_gcm128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_gcm192_known_ciphertext : aes_gcm256_known_ciphertext;
|
||||
|
||||
/* AES variables. */
|
||||
PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH];
|
||||
PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH];
|
||||
PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH * 2];
|
||||
PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH * 2];
|
||||
AESContext *aes_context;
|
||||
unsigned int aes_bytes_encrypted;
|
||||
unsigned int aes_bytes_decrypted;
|
||||
CK_GCM_PARAMS gcmParams;
|
||||
SECStatus aes_status;
|
||||
|
||||
/*check if aes_key_size is 128, 192, or 256 bits */
|
||||
|
|
@ -455,6 +484,69 @@ freebl_fips_AES_PowerUpSelfTest(int aes_key_size)
|
|||
return (SECFailure);
|
||||
}
|
||||
|
||||
/******************************************************/
|
||||
/* AES-GCM Single-Round Known Answer Encryption Test. */
|
||||
/******************************************************/
|
||||
|
||||
gcmParams.pIv = (PRUint8 *)aes_cbc_known_initialization_vector;
|
||||
gcmParams.ulIvLen = FIPS_AES_BLOCK_SIZE;
|
||||
gcmParams.pAAD = (PRUint8 *)aes_gcm_known_aad;
|
||||
gcmParams.ulAADLen = sizeof(aes_gcm_known_aad);
|
||||
gcmParams.ulTagBits = FIPS_AES_BLOCK_SIZE * 8;
|
||||
aes_context = AES_CreateContext(aes_known_key,
|
||||
(PRUint8 *)&gcmParams,
|
||||
NSS_AES_GCM, PR_TRUE, aes_key_size,
|
||||
FIPS_AES_BLOCK_SIZE);
|
||||
|
||||
if (aes_context == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = AES_Encrypt(aes_context, aes_computed_ciphertext,
|
||||
&aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH * 2,
|
||||
aes_known_plaintext,
|
||||
FIPS_AES_DECRYPT_LENGTH);
|
||||
|
||||
AES_DestroyContext(aes_context, PR_TRUE);
|
||||
|
||||
if ((aes_status != SECSuccess) ||
|
||||
(aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH * 2) ||
|
||||
(PORT_Memcmp(aes_computed_ciphertext, aes_gcm_known_ciphertext,
|
||||
FIPS_AES_ENCRYPT_LENGTH * 2) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/******************************************************/
|
||||
/* AES-GCM Single-Round Known Answer Decryption Test. */
|
||||
/******************************************************/
|
||||
|
||||
aes_context = AES_CreateContext(aes_known_key,
|
||||
(PRUint8 *)&gcmParams,
|
||||
NSS_AES_GCM, PR_FALSE, aes_key_size,
|
||||
FIPS_AES_BLOCK_SIZE);
|
||||
|
||||
if (aes_context == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
aes_status = AES_Decrypt(aes_context, aes_computed_plaintext,
|
||||
&aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH * 2,
|
||||
aes_gcm_known_ciphertext,
|
||||
FIPS_AES_ENCRYPT_LENGTH * 2);
|
||||
|
||||
AES_DestroyContext(aes_context, PR_TRUE);
|
||||
|
||||
if ((aes_status != SECSuccess) ||
|
||||
(aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) ||
|
||||
(PORT_Memcmp(aes_computed_plaintext, aes_known_plaintext,
|
||||
FIPS_AES_DECRYPT_LENGTH) != 0)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
|
|
@ -1094,7 +1186,7 @@ freebl_fips_ECDSA_Test(ECParams *ecparams,
|
|||
"Firefox and ThunderBird are awesome!"
|
||||
};
|
||||
|
||||
unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */
|
||||
unsigned char sha256[SHA256_LENGTH]; /* SHA-256 hash (256 bits) */
|
||||
unsigned char sig[2 * MAX_ECKEY_LEN];
|
||||
SECItem signature, digest;
|
||||
ECPrivateKey *ecdsa_private_key = NULL;
|
||||
|
|
@ -1136,13 +1228,13 @@ freebl_fips_ECDSA_Test(ECParams *ecparams,
|
|||
/* ECDSA Single-Round Known Answer Signature Test. */
|
||||
/***************************************************/
|
||||
|
||||
ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg);
|
||||
ecdsaStatus = SHA256_HashBuf(sha256, msg, sizeof msg);
|
||||
if (ecdsaStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
digest.type = siBuffer;
|
||||
digest.data = sha1;
|
||||
digest.len = SHA1_LENGTH;
|
||||
digest.data = sha256;
|
||||
digest.len = SHA256_LENGTH;
|
||||
|
||||
memset(sig, 0, sizeof sig);
|
||||
signature.type = siBuffer;
|
||||
|
|
@ -1181,10 +1273,83 @@ loser:
|
|||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_ECDSA_PowerUpSelfTest()
|
||||
freebl_fips_ECDH_Test(ECParams *ecparams)
|
||||
{
|
||||
|
||||
/* ECDSA Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */
|
||||
/* ECDH Known result (reused old CAVS vector) */
|
||||
static const PRUint8 ecdh_known_pub_key_1[] = {
|
||||
EC_POINT_FORM_UNCOMPRESSED,
|
||||
/* pubX */
|
||||
0x16, 0x81, 0x32, 0x86, 0xc8, 0xe4, 0x3a, 0x1f,
|
||||
0x5d, 0xe3, 0x06, 0x22, 0x8b, 0x99, 0x14, 0x25,
|
||||
0xf7, 0x9c, 0x5b, 0x1e, 0x96, 0x84, 0x85, 0x3b,
|
||||
0x17, 0xfe, 0xf3, 0x1c, 0x0e, 0xed, 0xc4, 0xce,
|
||||
/* pubY */
|
||||
0x7a, 0x44, 0xfe, 0xbd, 0x91, 0x71, 0x7d, 0x73,
|
||||
0xd9, 0x45, 0xea, 0xae, 0x66, 0x78, 0xfa, 0x6e,
|
||||
0x46, 0xcd, 0xfa, 0x95, 0x15, 0x47, 0x62, 0x5d,
|
||||
0xbb, 0x1b, 0x9f, 0xe6, 0x39, 0xfc, 0xfd, 0x47
|
||||
};
|
||||
static const PRUint8 ecdh_known_priv_key_2[] = {
|
||||
0xb4, 0x2a, 0xe3, 0x69, 0x19, 0xec, 0xf0, 0x42,
|
||||
0x6d, 0x45, 0x8c, 0x94, 0x4a, 0x26, 0xa7, 0x5c,
|
||||
0xea, 0x9d, 0xd9, 0x0f, 0x59, 0xe0, 0x1a, 0x9d,
|
||||
0x7c, 0xb7, 0x1c, 0x04, 0x53, 0xb8, 0x98, 0x5a
|
||||
};
|
||||
static const PRUint8 ecdh_known_hash_result[] = {
|
||||
0x16, 0xf3, 0x85, 0xa2, 0x41, 0xf3, 0x7f, 0xc4,
|
||||
0x0b, 0x56, 0x47, 0xee, 0xa7, 0x74, 0xb9, 0xdb,
|
||||
0xe1, 0xfa, 0x22, 0xe9, 0x04, 0xf1, 0xb6, 0x12,
|
||||
0x4b, 0x44, 0x8a, 0xbb, 0xbc, 0x08, 0x2b, 0xa7,
|
||||
};
|
||||
|
||||
SECItem ecdh_priv_2, ecdh_pub_1;
|
||||
SECItem ZZ = { 0, 0, 0 };
|
||||
SECStatus ecdhStatus = SECSuccess;
|
||||
PRUint8 computed_hash_result[HASH_LENGTH_MAX];
|
||||
|
||||
ecdh_priv_2.data = (PRUint8 *)ecdh_known_priv_key_2;
|
||||
ecdh_priv_2.len = sizeof(ecdh_known_priv_key_2);
|
||||
ecdh_pub_1.data = (PRUint8 *)ecdh_known_pub_key_1;
|
||||
ecdh_pub_1.len = sizeof(ecdh_known_pub_key_1);
|
||||
|
||||
/* Generates a new EC key pair. The private key is a supplied
|
||||
* random value (in seed) and the public key is the result of
|
||||
* performing a scalar point multiplication of that value with
|
||||
* the curve's base point.
|
||||
*/
|
||||
ecdhStatus = ECDH_Derive(&ecdh_pub_1, ecparams, &ecdh_priv_2, PR_FALSE, &ZZ);
|
||||
if (ecdhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
ecdhStatus = SHA256_HashBuf(computed_hash_result, ZZ.data, ZZ.len);
|
||||
if (ecdhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (PORT_Memcmp(computed_hash_result, ecdh_known_hash_result,
|
||||
sizeof(ecdh_known_hash_result)) != 0) {
|
||||
ecdhStatus = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (ZZ.data) {
|
||||
SECITEM_FreeItem(&ZZ, PR_FALSE);
|
||||
}
|
||||
|
||||
if (ecdhStatus != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_EC_PowerUpSelfTest()
|
||||
{
|
||||
|
||||
/* EC Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */
|
||||
static const unsigned char p256_prime[] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
|
|
@ -1217,7 +1382,7 @@ freebl_fips_ECDSA_PowerUpSelfTest()
|
|||
static const unsigned char p256_encoding[] = {
|
||||
0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
|
||||
};
|
||||
static const ECParams ecdsa_known_P256_Params = {
|
||||
static const ECParams ec_known_P256_Params = {
|
||||
NULL, ec_params_named, /* arena, type */
|
||||
/* fieldID */
|
||||
{ 256, ec_field_GFp, /* size and type */
|
||||
|
|
@ -1250,10 +1415,10 @@ freebl_fips_ECDSA_PowerUpSelfTest()
|
|||
0x9d, 0x37, 0x4b, 0x1c, 0xdc, 0x35, 0x90, 0xff,
|
||||
0x1a, 0x2d, 0x98, 0x95, 0x1b, 0x2f, 0xeb, 0x7f,
|
||||
0xbb, 0x81, 0xca, 0xc0, 0x69, 0x75, 0xea, 0xc5,
|
||||
0x59, 0x6a, 0x62, 0x49, 0x3d, 0x50, 0xc9, 0xe1,
|
||||
0x27, 0x3b, 0xff, 0x9b, 0x13, 0x66, 0x67, 0xdd,
|
||||
0x7d, 0xd1, 0x0d, 0x2d, 0x7c, 0x44, 0x04, 0x1b,
|
||||
0x16, 0x21, 0x12, 0xc5, 0xcb, 0xbd, 0x9e, 0x75
|
||||
0xa7, 0xd2, 0x20, 0xdd, 0x45, 0xf9, 0x2b, 0xdd,
|
||||
0xda, 0x98, 0x99, 0x5b, 0x1c, 0x02, 0x3a, 0x27,
|
||||
0x8b, 0x7d, 0xb6, 0xed, 0x0e, 0xe0, 0xa7, 0xac,
|
||||
0xaa, 0x36, 0x2c, 0xfa, 0x1a, 0xdf, 0x0d, 0xe1,
|
||||
};
|
||||
|
||||
ECParams ecparams;
|
||||
|
|
@ -1261,13 +1426,18 @@ freebl_fips_ECDSA_PowerUpSelfTest()
|
|||
SECStatus rv;
|
||||
|
||||
/* ECDSA GF(p) prime field curve test */
|
||||
ecparams = ecdsa_known_P256_Params;
|
||||
ecparams = ec_known_P256_Params;
|
||||
rv = freebl_fips_ECDSA_Test(&ecparams,
|
||||
ecdsa_known_P256_signature,
|
||||
sizeof ecdsa_known_P256_signature);
|
||||
if (rv != SECSuccess) {
|
||||
return (SECFailure);
|
||||
}
|
||||
/* ECDH GF(p) prime field curve test */
|
||||
rv = freebl_fips_ECDH_Test(&ecparams);
|
||||
if (rv != SECSuccess) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
|
@ -1417,6 +1587,138 @@ freebl_fips_DSA_PowerUpSelfTest(void)
|
|||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_DH_PowerUpSelfTest(void)
|
||||
{
|
||||
/* DH Known P (2048-bits) */
|
||||
static const PRUint8 dh_known_P[] = {
|
||||
0xc2, 0x79, 0xbb, 0x76, 0x32, 0x0d, 0x43, 0xfd,
|
||||
0x1b, 0x8c, 0xa2, 0x3c, 0x00, 0xdd, 0x6d, 0xef,
|
||||
0xf8, 0x1a, 0xd9, 0xc1, 0xa2, 0xf5, 0x73, 0x2b,
|
||||
0xdb, 0x1a, 0x3e, 0x84, 0x90, 0xeb, 0xe7, 0x8e,
|
||||
0x5f, 0x5c, 0x6b, 0xb6, 0x61, 0x89, 0xd1, 0x03,
|
||||
0xb0, 0x5f, 0x91, 0xe4, 0xd2, 0x82, 0x90, 0xfc,
|
||||
0x3c, 0x49, 0x69, 0x59, 0xc1, 0x51, 0x6a, 0x85,
|
||||
0x71, 0xe7, 0x5d, 0x72, 0x5a, 0x45, 0xad, 0x01,
|
||||
0x6f, 0x82, 0xae, 0xec, 0x91, 0x08, 0x2e, 0x7c,
|
||||
0x64, 0x93, 0x46, 0x1c, 0x68, 0xef, 0xc2, 0x03,
|
||||
0x28, 0x1d, 0x75, 0x3a, 0xeb, 0x9c, 0x46, 0xf0,
|
||||
0xc9, 0xdb, 0x99, 0x95, 0x13, 0x66, 0x4d, 0xd5,
|
||||
0x1a, 0x78, 0x92, 0x51, 0x89, 0x72, 0x28, 0x7f,
|
||||
0x20, 0x70, 0x41, 0x49, 0xa2, 0x86, 0xe9, 0xf9,
|
||||
0x78, 0x5f, 0x8d, 0x2e, 0x5d, 0xfa, 0xdb, 0x57,
|
||||
0xd4, 0x71, 0xdf, 0x66, 0xe3, 0x9e, 0x88, 0x70,
|
||||
0xa4, 0x21, 0x44, 0x6a, 0xc7, 0xae, 0x30, 0x2c,
|
||||
0x9c, 0x1f, 0x91, 0x57, 0xc8, 0x24, 0x34, 0x2d,
|
||||
0x7a, 0x4a, 0x43, 0xc2, 0x5f, 0xab, 0x64, 0x2e,
|
||||
0xaa, 0x28, 0x32, 0x95, 0x42, 0x7b, 0xa0, 0xcc,
|
||||
0xdf, 0xfd, 0x22, 0xc8, 0x56, 0x84, 0xc1, 0x62,
|
||||
0x15, 0xb2, 0x77, 0x86, 0x81, 0xfc, 0xa5, 0x12,
|
||||
0x3c, 0xca, 0x28, 0x17, 0x8f, 0x03, 0x16, 0x6e,
|
||||
0xb8, 0x24, 0xfa, 0x1b, 0x15, 0x02, 0xfd, 0x8b,
|
||||
0xb6, 0x0a, 0x1a, 0xf7, 0x47, 0x41, 0xc5, 0x2b,
|
||||
0x37, 0x3e, 0xa1, 0xbf, 0x68, 0xda, 0x1c, 0x55,
|
||||
0x44, 0xc3, 0xee, 0xa1, 0x63, 0x07, 0x11, 0x3b,
|
||||
0x5f, 0x00, 0x84, 0xb4, 0xc4, 0xe4, 0xa7, 0x97,
|
||||
0x29, 0xf8, 0xce, 0xab, 0xfc, 0x27, 0x3e, 0x34,
|
||||
0xe4, 0xc7, 0x81, 0x52, 0x32, 0x0e, 0x27, 0x3c,
|
||||
0xa6, 0x70, 0x3f, 0x4a, 0x54, 0xda, 0xdd, 0x60,
|
||||
0x26, 0xb3, 0x6e, 0x45, 0x26, 0x19, 0x41, 0x6f
|
||||
};
|
||||
|
||||
static const PRUint8 dh_known_Y_1[] = {
|
||||
0xb4, 0xc7, 0x85, 0xba, 0xa6, 0x98, 0xb3, 0x77,
|
||||
0x41, 0x2b, 0xd9, 0x9a, 0x72, 0x90, 0xa4, 0xac,
|
||||
0xc4, 0xf7, 0xc2, 0x23, 0x9a, 0x68, 0xe2, 0x7d,
|
||||
0x3a, 0x54, 0x45, 0x91, 0xc1, 0xd7, 0x8a, 0x17,
|
||||
0x54, 0xd3, 0x37, 0xaa, 0x0c, 0xcd, 0x0b, 0xe2,
|
||||
0xf2, 0x34, 0x0f, 0x17, 0xa8, 0x07, 0x88, 0xaf,
|
||||
0xed, 0xc1, 0x02, 0xd4, 0xdb, 0xdc, 0x0f, 0x22,
|
||||
0x51, 0x23, 0x40, 0xb9, 0x65, 0x6d, 0x39, 0xf4,
|
||||
0xe1, 0x8b, 0x57, 0x7d, 0xb6, 0xd3, 0xf2, 0x6b,
|
||||
0x02, 0xa9, 0x36, 0xf0, 0x0d, 0xe3, 0xdb, 0x9a,
|
||||
0xbf, 0x20, 0x00, 0x4d, 0xec, 0x6f, 0x68, 0x95,
|
||||
0xee, 0x59, 0x4e, 0x3c, 0xb6, 0xda, 0x7b, 0x19,
|
||||
0x08, 0x9a, 0xef, 0x61, 0x43, 0xf5, 0xfb, 0x25,
|
||||
0x70, 0x19, 0xc1, 0x5f, 0x0e, 0x0f, 0x6a, 0x63,
|
||||
0x44, 0xe9, 0xcf, 0x33, 0xce, 0x13, 0x4f, 0x34,
|
||||
0x3c, 0x94, 0x40, 0x8d, 0xf2, 0x65, 0x42, 0xef,
|
||||
0x70, 0x54, 0xdd, 0x5f, 0xc1, 0xd7, 0x0b, 0xa6,
|
||||
0x06, 0xd5, 0xa6, 0x47, 0xae, 0x2c, 0x1f, 0x5a,
|
||||
0xa6, 0xb3, 0xc1, 0x38, 0x3a, 0x3b, 0x60, 0x94,
|
||||
0xa2, 0x95, 0xab, 0xb2, 0x86, 0x82, 0xc5, 0x3b,
|
||||
0xb8, 0x6f, 0x3e, 0x55, 0x86, 0x84, 0xe0, 0x00,
|
||||
0xe5, 0xef, 0xca, 0x5c, 0xec, 0x7e, 0x38, 0x0f,
|
||||
0x82, 0xa2, 0xb1, 0xee, 0x48, 0x1b, 0x32, 0xbb,
|
||||
0x5a, 0x33, 0xa5, 0x01, 0xba, 0xca, 0xa6, 0x64,
|
||||
0x61, 0xb6, 0xe5, 0x5c, 0x0e, 0x5f, 0x2c, 0x66,
|
||||
0x0d, 0x01, 0x6a, 0x20, 0x04, 0x70, 0x68, 0x82,
|
||||
0x93, 0x29, 0x15, 0x3b, 0x7a, 0x06, 0xb2, 0x92,
|
||||
0x61, 0xcd, 0x7e, 0xa4, 0xc1, 0x15, 0x64, 0x3b,
|
||||
0x3c, 0x51, 0x10, 0x4c, 0x87, 0xa6, 0xaf, 0x07,
|
||||
0xce, 0x46, 0x82, 0x75, 0xf3, 0x90, 0xf3, 0x21,
|
||||
0x55, 0x74, 0xc2, 0xe4, 0x96, 0x7d, 0xc3, 0xe6,
|
||||
0x33, 0xa5, 0xc6, 0x51, 0xef, 0xec, 0x90, 0x08
|
||||
};
|
||||
|
||||
static const PRUint8 dh_known_x_2[] = {
|
||||
0x9e, 0x9b, 0xc3, 0x25, 0x53, 0xf9, 0xfc, 0x92,
|
||||
0xb6, 0xae, 0x54, 0x8e, 0x23, 0x4c, 0x94, 0xba,
|
||||
0x41, 0xe6, 0x29, 0x33, 0xb9, 0xdb, 0xff, 0x6d,
|
||||
0xa8, 0xb8, 0x48, 0x49, 0x66, 0x11, 0xa6, 0x13
|
||||
};
|
||||
|
||||
static const PRUint8 dh_known_hash_result[] = {
|
||||
0x93, 0xa2, 0x89, 0x1c, 0x8a, 0xc3, 0x70, 0xbf,
|
||||
0xa7, 0xdf, 0xb6, 0xd7, 0x82, 0xfb, 0x87, 0x81,
|
||||
0x09, 0x47, 0xf3, 0x9f, 0x5a, 0xbf, 0x4f, 0x3f,
|
||||
0x8e, 0x5e, 0x06, 0xca, 0x30, 0xa7, 0xaf, 0x10
|
||||
};
|
||||
|
||||
/* DH variables. */
|
||||
SECStatus dhStatus;
|
||||
SECItem dh_prime;
|
||||
SECItem dh_pub_key_1;
|
||||
SECItem dh_priv_key_2;
|
||||
SECItem ZZ = { 0, 0, 0 };
|
||||
PRUint8 computed_hash_result[HASH_LENGTH_MAX];
|
||||
|
||||
dh_prime.data = (PRUint8 *)dh_known_P;
|
||||
dh_prime.len = sizeof(dh_known_P);
|
||||
dh_pub_key_1.data = (PRUint8 *)dh_known_Y_1;
|
||||
dh_pub_key_1.len = sizeof(dh_known_Y_1);
|
||||
dh_priv_key_2.data = (PRUint8 *)dh_known_x_2;
|
||||
dh_priv_key_2.len = sizeof(dh_known_x_2);
|
||||
|
||||
/* execute the derive */
|
||||
dhStatus = DH_Derive(&dh_pub_key_1, &dh_prime, &dh_priv_key_2, &ZZ, dh_prime.len);
|
||||
if (dhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
dhStatus = SHA256_HashBuf(computed_hash_result, ZZ.data, ZZ.len);
|
||||
if (dhStatus != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (PORT_Memcmp(computed_hash_result, dh_known_hash_result,
|
||||
sizeof(dh_known_hash_result)) != 0) {
|
||||
dhStatus = SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (ZZ.data) {
|
||||
SECITEM_FreeItem(&ZZ, PR_FALSE);
|
||||
}
|
||||
|
||||
if (dhStatus != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return (SECFailure);
|
||||
}
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
freebl_fips_RNG_PowerUpSelfTest(void)
|
||||
{
|
||||
|
|
@ -1541,7 +1843,7 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
return rv;
|
||||
|
||||
/* NOTE: RSA can only be tested in full freebl. It requires access to
|
||||
* the locking primitives */
|
||||
* the locking primitives */
|
||||
/* RSA Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_RSA_PowerUpSelfTest();
|
||||
|
||||
|
|
@ -1554,8 +1856,14 @@ freebl_fipsPowerUpSelfTest(unsigned int tests)
|
|||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* ECDSA Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_ECDSA_PowerUpSelfTest();
|
||||
/* DH Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_DH_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
/* EC Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_EC_PowerUpSelfTest();
|
||||
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
|
|
|||
|
|
@ -76,11 +76,11 @@
|
|||
'__SSSE3__',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="android"', {
|
||||
# On Android we can't use any of the hardware acceleration :(
|
||||
'defines!': [
|
||||
'__ARM_NEON__',
|
||||
'__ARM_NEON',
|
||||
[ 'target_arch=="arm"', {
|
||||
# Gecko doesn't support non-NEON platform on Android, but tier-3
|
||||
# platform such as Linux/arm will need it
|
||||
'cflags_mozilla': [
|
||||
'-mfpu=neon'
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
],
|
||||
}],
|
||||
# macOS build doesn't use cflags.
|
||||
[ 'OS=="mac"', {
|
||||
[ 'OS=="mac" or OS=="ios"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [
|
||||
'-mpclmul', '-maes'
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ loser:
|
|||
void
|
||||
intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
|
||||
{
|
||||
PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext));
|
||||
if (freeit) {
|
||||
PORT_Free(gcm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -313,10 +313,14 @@ static const struct FREEBLVectorStr vector =
|
|||
BLAKE2B_End,
|
||||
BLAKE2B_FlattenSize,
|
||||
BLAKE2B_Flatten,
|
||||
BLAKE2B_Resurrect
|
||||
BLAKE2B_Resurrect,
|
||||
|
||||
/* End of Version 3.020 */
|
||||
|
||||
ChaCha20_Xor
|
||||
|
||||
/* End of version 3.021 */
|
||||
|
||||
};
|
||||
|
||||
const FREEBLVector*
|
||||
|
|
|
|||
|
|
@ -2060,6 +2060,16 @@ EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
|
|||
return (vector->p_EC_CopyParams)(arena, dstParams, srcParams);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20_Xor(unsigned char *output, const unsigned char *block, unsigned int len,
|
||||
const unsigned char *k, const unsigned char *nonce, PRUint32 ctr)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
|
||||
return SECFailure;
|
||||
}
|
||||
return (vector->p_ChaCha20_Xor)(output, block, len, k, nonce, ctr);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,
|
||||
const unsigned char *key, unsigned int keyLen,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "blapi.h"
|
||||
|
||||
#define FREEBL_VERSION 0x0314
|
||||
#define FREEBL_VERSION 0x0315
|
||||
|
||||
struct FREEBLVectorStr {
|
||||
|
||||
|
|
@ -759,6 +759,12 @@ struct FREEBLVectorStr {
|
|||
|
||||
/* Version 3.020 came to here */
|
||||
|
||||
SECStatus (*p_ChaCha20_Xor)(unsigned char *output, const unsigned char *block,
|
||||
unsigned int len, const unsigned char *k,
|
||||
const unsigned char *nonce, PRUint32 ctr);
|
||||
|
||||
/* Version 3.021 came to here */
|
||||
|
||||
/* Add new function pointers at the end of this struct and bump
|
||||
* FREEBL_VERSION at the beginning of this file. */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2063,7 +2063,10 @@ s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
|
|||
}
|
||||
}
|
||||
if (res >= 0) {
|
||||
while (MP_SIGN(c) != MP_ZPOS) {
|
||||
if (mp_cmp_mag(c, p) >= 0) {
|
||||
MP_CHECKOK(mp_div(c, p, NULL, c));
|
||||
}
|
||||
if (MP_SIGN(c) != MP_ZPOS) {
|
||||
MP_CHECKOK(mp_add(c, p, c));
|
||||
}
|
||||
res = k;
|
||||
|
|
|
|||
|
|
@ -491,11 +491,11 @@ cleanup:
|
|||
** This implments steps 4 thorough 22 of FIPS 186-3 A.1.2.1 and
|
||||
** steps 16 through 34 of FIPS 186-2 C.6
|
||||
*/
|
||||
#define MAX_ST_SEED_BITS (HASH_LENGTH_MAX * PR_BITS_PER_BYTE)
|
||||
static SECStatus
|
||||
makePrimefromPrimesShaweTaylor(
|
||||
HASH_HashType hashtype, /* selected Hashing algorithm */
|
||||
unsigned int length, /* input. Length of prime in bits. */
|
||||
unsigned int seedlen, /* input seed length in bits */
|
||||
mp_int *c0, /* seed prime */
|
||||
mp_int *q, /* sub prime, can be 1 */
|
||||
mp_int *prime, /* output. */
|
||||
|
|
@ -557,7 +557,7 @@ makePrimefromPrimesShaweTaylor(
|
|||
old_counter = *prime_gen_counter;
|
||||
/*
|
||||
** Comment: Generate a pseudorandom integer x in the interval
|
||||
** [2**(lenght-1), 2**length].
|
||||
** [2**(length-1), 2**length].
|
||||
**
|
||||
** Step 6/18 x = 0
|
||||
*/
|
||||
|
|
@ -569,11 +569,10 @@ makePrimefromPrimesShaweTaylor(
|
|||
for (i = 0; i < iterations; i++) {
|
||||
/* is bigger than prime_seed should get to */
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i,
|
||||
MAX_ST_SEED_BITS, &x[(iterations - i - 1) * hashlen]));
|
||||
seedlen, &x[(iterations - i - 1) * hashlen]));
|
||||
}
|
||||
/* Step 8/20 prime_seed = prime_seed + iterations + 1 */
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS,
|
||||
prime_seed));
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, seedlen, prime_seed));
|
||||
/*
|
||||
** Step 9/21 x = 2 ** (length-1) + x mod 2 ** (length-1)
|
||||
**
|
||||
|
|
@ -595,7 +594,7 @@ makePrimefromPrimesShaweTaylor(
|
|||
x[offset] = (mask & x[offset]) | bit;
|
||||
/*
|
||||
** Comment: Generate a candidate prime c in the interval
|
||||
** [2**(lenght-1), 2**length].
|
||||
** [2**(length-1), 2**length].
|
||||
**
|
||||
** Step 10 t = ceiling(x/(2q(p0)))
|
||||
** Step 22 t = ceiling(x/(2(c0)))
|
||||
|
|
@ -624,7 +623,7 @@ step_23:
|
|||
/* t = 2**(length-1) + 2qc0 -1 */
|
||||
CHECK_MPI_OK(mp_add(&two_length_minus_1, &t, &t));
|
||||
/* t = floor((2**(length-1)+2qc0 -1)/2qco)
|
||||
* = ceil(2**(lenght-2)/2qc0) */
|
||||
* = ceil(2**(length-2)/2qc0) */
|
||||
CHECK_MPI_OK(mp_div(&t, &c0_2, &t, NULL));
|
||||
CHECK_MPI_OK(mp_mul(&t, &c0_2, &c));
|
||||
CHECK_MPI_OK(mp_add_d(&c, (mp_digit)1, &c)); /* c= 2tqc0 + 1*/
|
||||
|
|
@ -645,13 +644,11 @@ step_23:
|
|||
** NOTE: we reuse the x array for 'a' initially.
|
||||
*/
|
||||
for (i = 0; i < iterations; i++) {
|
||||
/* MAX_ST_SEED_BITS is bigger than prime_seed should get to */
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i,
|
||||
MAX_ST_SEED_BITS, &x[(iterations - i - 1) * hashlen]));
|
||||
seedlen, &x[(iterations - i - 1) * hashlen]));
|
||||
}
|
||||
/* Step 16/28 prime_seed = prime_seed + iterations + 1 */
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS,
|
||||
prime_seed));
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, iterations, seedlen, prime_seed));
|
||||
/* Step 17/29 a = 2 + (a mod (c-3)). */
|
||||
CHECK_MPI_OK(mp_read_unsigned_octets(&a, x, iterations * hashlen));
|
||||
CHECK_MPI_OK(mp_sub_d(&c, (mp_digit)3, &z)); /* z = c -3 */
|
||||
|
|
@ -742,6 +739,7 @@ makePrimefromSeedShaweTaylor(
|
|||
int hashlen = HASH_ResultLen(hashtype);
|
||||
int outlen = hashlen * PR_BITS_PER_BYTE;
|
||||
int offset;
|
||||
int seedlen = input_seed->len * 8; /*seedlen is in bits */
|
||||
unsigned char bit, mask;
|
||||
unsigned char x[HASH_LENGTH_MAX * 2];
|
||||
mp_digit dummy;
|
||||
|
|
@ -775,7 +773,7 @@ makePrimefromSeedShaweTaylor(
|
|||
goto cleanup;
|
||||
}
|
||||
/* Steps 16-34 */
|
||||
rv = makePrimefromPrimesShaweTaylor(hashtype, length, &c0, &one,
|
||||
rv = makePrimefromPrimesShaweTaylor(hashtype, length, seedlen, &c0, &one,
|
||||
prime, prime_seed, prime_gen_counter);
|
||||
goto cleanup; /* we're done, one way or the other */
|
||||
}
|
||||
|
|
@ -787,8 +785,7 @@ makePrimefromSeedShaweTaylor(
|
|||
step_5:
|
||||
/* Step 5 c = Hash(prime_seed) xor Hash(prime_seed+1). */
|
||||
CHECK_SEC_OK(HASH_HashBuf(hashtype, x, prime_seed->data, prime_seed->len));
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1,
|
||||
MAX_ST_SEED_BITS, &x[hashlen]));
|
||||
CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1, seedlen, &x[hashlen]));
|
||||
for (i = 0; i < hashlen; i++) {
|
||||
x[i] = x[i] ^ x[i + hashlen];
|
||||
}
|
||||
|
|
@ -817,7 +814,7 @@ step_5:
|
|||
/* Step 8 prime_gen_counter = prime_gen_counter + 1 */
|
||||
(*prime_gen_counter)++;
|
||||
/* Step 9 prime_seed = prime_seed + 2 */
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, 2, MAX_ST_SEED_BITS, prime_seed));
|
||||
CHECK_SEC_OK(addToSeed(prime_seed, 2, seedlen, prime_seed));
|
||||
/* Step 10 Perform deterministic primality test on c. For example, since
|
||||
** c is small, it's primality can be tested by trial division, See
|
||||
** See Appendic C.7.
|
||||
|
|
@ -890,7 +887,8 @@ findQfromSeed(
|
|||
mp_int *Q_, /* output. */
|
||||
unsigned int *qseed_len, /* output */
|
||||
HASH_HashType *hashtypePtr, /* output. Hash uses */
|
||||
pqgGenType *typePtr) /* output. Generation Type used */
|
||||
pqgGenType *typePtr, /* output. Generation Type used */
|
||||
unsigned int *qgen_counter) /* output. q_counter */
|
||||
{
|
||||
HASH_HashType hashtype;
|
||||
SECItem firstseed = { 0, 0, 0 };
|
||||
|
|
@ -964,6 +962,7 @@ findQfromSeed(
|
|||
*qseed_len = qseed.len;
|
||||
*hashtypePtr = hashtype;
|
||||
*typePtr = FIPS186_3_ST_TYPE;
|
||||
*qgen_counter = count;
|
||||
SECITEM_FreeItem(&qseed, PR_FALSE);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -1388,19 +1387,26 @@ step_5:
|
|||
CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, (L + 1) / 2 + 1,
|
||||
&qseed, &p0, &pseed, &pgen_counter));
|
||||
/* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L,
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, seedBytes * 8,
|
||||
&p0, &Q, &P, &pseed, &pgen_counter));
|
||||
|
||||
/* combine all the seeds */
|
||||
seed->len = firstseed.len + qseed.len + pseed.len;
|
||||
if ((qseed.len > firstseed.len) || (pseed.len > firstseed.len)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); /* shouldn't happen */
|
||||
goto cleanup;
|
||||
}
|
||||
/* If the seed overflows, then pseed and qseed may have leading zeros which the mpl code clamps.
|
||||
* we want to make sure those are added back in so the individual seed lengths are predictable from
|
||||
* the overall seed length */
|
||||
seed->len = firstseed.len * 3;
|
||||
seed->data = PORT_ArenaZAlloc(verify->arena, seed->len);
|
||||
if (seed->data == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
PORT_Memcpy(seed->data, firstseed.data, firstseed.len);
|
||||
PORT_Memcpy(seed->data + firstseed.len, pseed.data, pseed.len);
|
||||
PORT_Memcpy(seed->data + firstseed.len + pseed.len, qseed.data, qseed.len);
|
||||
counter = 0; /* (qgen_counter << 16) | pgen_counter; */
|
||||
PORT_Memcpy(seed->data + 2 * firstseed.len - pseed.len, pseed.data, pseed.len);
|
||||
PORT_Memcpy(seed->data + 3 * firstseed.len - qseed.len, qseed.data, qseed.len);
|
||||
counter = (qgen_counter << 16) | pgen_counter;
|
||||
|
||||
/* we've generated both P and Q now, skip to generating G */
|
||||
goto generate_G;
|
||||
|
|
@ -1620,6 +1626,7 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
int j;
|
||||
unsigned int counter_max = 0; /* handle legacy L < 1024 */
|
||||
unsigned int qseed_len;
|
||||
unsigned int qgen_counter_ = 0;
|
||||
SECItem pseed_ = { 0, 0, 0 };
|
||||
HASH_HashType hashtype;
|
||||
pqgGenType type;
|
||||
|
|
@ -1699,48 +1706,55 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
/* Steps 7-12 are done only if the optional PQGVerify is supplied. */
|
||||
/* continue processing P */
|
||||
/* 7. counter < 4*L */
|
||||
CHECKPARAM((vfy->counter == -1) || (vfy->counter < counter_max));
|
||||
/* 8. g >= N and g < 2*L (g is length of seed in bits) */
|
||||
g = vfy->seed.len * 8;
|
||||
CHECKPARAM(g >= N && g < counter_max / 2);
|
||||
/* step 7 and 8 are delayed until we determine which type of generation
|
||||
* was used */
|
||||
/* 9. Q generated from SEED matches Q in PQGParams. */
|
||||
/* This function checks all possible hash and generation types to
|
||||
* find a Q_ which matches Q. */
|
||||
g = vfy->seed.len * 8;
|
||||
CHECKPARAM(findQfromSeed(L, N, g, &vfy->seed, &Q, &Q_, &qseed_len,
|
||||
&hashtype, &type) == SECSuccess);
|
||||
&hashtype, &type, &qgen_counter_) == SECSuccess);
|
||||
CHECKPARAM(mp_cmp(&Q, &Q_) == 0);
|
||||
/* now we can do steps 7 & 8*/
|
||||
if ((type == FIPS186_1_TYPE) || (type == FIPS186_3_TYPE)) {
|
||||
CHECKPARAM((vfy->counter == -1) || (vfy->counter < counter_max));
|
||||
CHECKPARAM(g >= N && g < counter_max / 2);
|
||||
}
|
||||
if (type == FIPS186_3_ST_TYPE) {
|
||||
SECItem qseed = { 0, 0, 0 };
|
||||
SECItem pseed = { 0, 0, 0 };
|
||||
unsigned int first_seed_len;
|
||||
unsigned int pgen_counter = 0;
|
||||
unsigned int pgen_counter_ = 0;
|
||||
unsigned int qgen_counter = (vfy->counter >> 16) & 0xffff;
|
||||
unsigned int pgen_counter = (vfy->counter) & 0xffff;
|
||||
|
||||
/* extract pseed and qseed from domain_parameter_seed, which is
|
||||
* first_seed || pseed || qseed. qseed is first_seed + small_integer
|
||||
* pseed is qseed + small_integer. This means most of the time
|
||||
* mod the length of first_seed. pseed is qseed + small_integer mod
|
||||
* the length of first_seed. This means most of the time
|
||||
* first_seed.len == qseed.len == pseed.len. Rarely qseed.len and/or
|
||||
* pseed.len will be one greater than first_seed.len, so we can
|
||||
* depend on the fact that
|
||||
* first_seed.len = floor(domain_parameter_seed.len/3).
|
||||
* findQfromSeed returned qseed.len, so we can calculate pseed.len as
|
||||
* pseed.len = domain_parameter_seed.len - first_seed.len - qseed.len
|
||||
* this is probably over kill, since 99.999% of the time they will all
|
||||
* be equal.
|
||||
*
|
||||
* With the lengths, we can now find the offsets;
|
||||
* pseed.len will be smaller because mpi clamps them. pqgGen
|
||||
* automatically adds the zero pad back though, so we can depend
|
||||
* domain_parameter_seed.len to be a multiple of three. We only have
|
||||
* to deal with the fact that the returned seeds from our functions
|
||||
* could be shorter.
|
||||
* first_seed.len = domain_parameter_seed.len/3
|
||||
* We can now find the offsets;
|
||||
* first_seed.data = domain_parameter_seed.data + 0
|
||||
* pseed.data = domain_parameter_seed.data + first_seed.len
|
||||
* qseed.data = domain_parameter_seed.data
|
||||
* + domain_paramter_seed.len - qseed.len
|
||||
*
|
||||
* We deal with pseed possibly having zero pad in the pseed check later.
|
||||
*/
|
||||
first_seed_len = vfy->seed.len / 3;
|
||||
CHECKPARAM(qseed_len < vfy->seed.len);
|
||||
CHECKPARAM(first_seed_len * 8 > N - 1);
|
||||
CHECKPARAM(first_seed_len + qseed_len < vfy->seed.len);
|
||||
CHECKPARAM(first_seed_len * 8 < counter_max / 2);
|
||||
CHECKPARAM(first_seed_len >= qseed_len);
|
||||
qseed.len = qseed_len;
|
||||
qseed.data = vfy->seed.data + vfy->seed.len - qseed.len;
|
||||
pseed.len = vfy->seed.len - (first_seed_len + qseed_len);
|
||||
pseed.len = first_seed_len;
|
||||
pseed.data = vfy->seed.data + first_seed_len;
|
||||
|
||||
/*
|
||||
|
|
@ -1752,14 +1766,34 @@ PQG_VerifyParams(const PQGParams *params,
|
|||
** (ST_Random_Prime((ceil(length/2)+1, input_seed)
|
||||
*/
|
||||
CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, (L + 1) / 2 + 1,
|
||||
&qseed, &p0, &pseed_, &pgen_counter));
|
||||
&qseed, &p0, &pseed_, &pgen_counter_));
|
||||
/* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L,
|
||||
&p0, &Q_, &P_, &pseed_, &pgen_counter));
|
||||
CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, first_seed_len * 8,
|
||||
&p0, &Q_, &P_, &pseed_, &pgen_counter_));
|
||||
CHECKPARAM(mp_cmp(&P, &P_) == 0);
|
||||
/* make sure pseed wasn't tampered with (since it is part of
|
||||
* calculating G) */
|
||||
if (pseed.len > pseed_.len) {
|
||||
/* handle the case of zero pad for pseed */
|
||||
int extra = pseed.len - pseed_.len;
|
||||
int i;
|
||||
for (i = 0; i < extra; i++) {
|
||||
if (pseed.data[i] != 0) {
|
||||
*result = SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
pseed.data += extra;
|
||||
pseed.len -= extra;
|
||||
/* the rest is handled in the normal compare below */
|
||||
}
|
||||
CHECKPARAM(SECITEM_CompareItem(&pseed, &pseed_) == SECEqual);
|
||||
if (vfy->counter != -1) {
|
||||
CHECKPARAM(pgen_counter < counter_max);
|
||||
CHECKPARAM(qgen_counter < counter_max);
|
||||
CHECKPARAM((pgen_counter_ == pgen_counter));
|
||||
CHECKPARAM((qgen_counter_ == qgen_counter));
|
||||
}
|
||||
} else if (vfy->counter == -1) {
|
||||
/* If counter is set to -1, we are really only verifying G, skip
|
||||
* the remainder of the checks for P */
|
||||
|
|
|
|||
|
|
@ -1032,13 +1032,19 @@ AES_CreateContext(const unsigned char *key, const unsigned char *iv,
|
|||
void
|
||||
AES_DestroyContext(AESContext *cx, PRBool freeit)
|
||||
{
|
||||
void *mem = cx->mem;
|
||||
if (cx->worker_cx && cx->destroy) {
|
||||
(*cx->destroy)(cx->worker_cx, PR_TRUE);
|
||||
cx->worker_cx = NULL;
|
||||
cx->destroy = NULL;
|
||||
}
|
||||
PORT_Memset(cx, 0, sizeof(AESContext));
|
||||
if (freeit) {
|
||||
PORT_Free(cx->mem);
|
||||
PORT_Free(mem);
|
||||
} else {
|
||||
/* if we are not freeing the context, restore mem, We may get called
|
||||
* again to actually free the context */
|
||||
cx->mem = mem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3002,17 +3002,8 @@ PKIX_PL_Cert_VerifyCertAndKeyType(
|
|||
if (CERT_CheckKeyUsage(cert->nssCert, requiredKeyUsage) != SECSuccess) {
|
||||
PKIX_ERROR(PKIX_CERTCHECKKEYUSAGEFAILED);
|
||||
}
|
||||
if (certUsage != certUsageIPsec) {
|
||||
if (!(certType & requiredCertType)) {
|
||||
PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED);
|
||||
}
|
||||
} else {
|
||||
PRBool isCritical;
|
||||
PRBool allowed = cert_EKUAllowsIPsecIKE(cert->nssCert, &isCritical);
|
||||
/* If the extension isn't critical, we allow any EKU value. */
|
||||
if (isCritical && !allowed) {
|
||||
PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED);
|
||||
}
|
||||
if (!(certType & requiredCertType)) {
|
||||
PKIX_ERROR(PKIX_CERTCHECKCERTTYPEFAILED);
|
||||
}
|
||||
cleanup:
|
||||
PKIX_DECREF(basicConstraints);
|
||||
|
|
|
|||
|
|
@ -1145,3 +1145,9 @@ HASH_GetHashOidTagByHashType;
|
|||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSS_3.44 { # NSS 3.44 release
|
||||
;+ global:
|
||||
CERT_GetCertificateDer;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.43" _NSS_CUSTOMIZED
|
||||
#define NSS_VERSION "3.44.1" _NSS_CUSTOMIZED
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 43
|
||||
#define NSS_VPATCH 0
|
||||
#define NSS_VMINOR 44
|
||||
#define NSS_VPATCH 1
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_FALSE
|
||||
|
||||
|
|
|
|||
|
|
@ -190,7 +190,6 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
|||
attrs++;
|
||||
PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
|
||||
attrs++;
|
||||
signedattr = attrs;
|
||||
PK11_SETATTRS(attrs, CKA_EC_PARAMS,
|
||||
pubKey->u.ec.DEREncodedParams.data,
|
||||
pubKey->u.ec.DEREncodedParams.len);
|
||||
|
|
@ -222,12 +221,14 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
|||
PORT_SetError(SEC_ERROR_BAD_KEY);
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
templateCount = attrs - theTemplate;
|
||||
signedcount = attrs - signedattr;
|
||||
PORT_Assert(templateCount <= (sizeof(theTemplate) / sizeof(CK_ATTRIBUTE)));
|
||||
for (attrs = signedattr; signedcount; attrs++, signedcount--) {
|
||||
pk11_SignedToUnsigned(attrs);
|
||||
if (pubKey->keyType != ecKey) {
|
||||
PORT_Assert(signedattr);
|
||||
signedcount = attrs - signedattr;
|
||||
for (attrs = signedattr; signedcount; attrs++, signedcount--) {
|
||||
pk11_SignedToUnsigned(attrs);
|
||||
}
|
||||
}
|
||||
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
|
||||
templateCount, isToken, &objectID);
|
||||
|
|
@ -1074,9 +1075,13 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
|
|||
&cktrue, &ckfalse);
|
||||
|
||||
/* Not everyone can handle zero padded key values, give
|
||||
* them the raw data as unsigned */
|
||||
for (ap = attrs; extra_count; ap++, extra_count--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
* them the raw data as unsigned. The exception is EC,
|
||||
* where the values are encoded or zero-preserving
|
||||
* per-RFC5915 */
|
||||
if (privKey->keyType != ecKey) {
|
||||
for (ap = attrs; extra_count; ap++, extra_count--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
}
|
||||
}
|
||||
|
||||
/* now Store the puppies */
|
||||
|
|
|
|||
|
|
@ -184,7 +184,9 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
|||
SECKEY_DestroyPublicKey(pubKey);
|
||||
return PR_FALSE;
|
||||
}
|
||||
pk11_SignedToUnsigned(&theTemplate);
|
||||
if (pubKey->keyType != ecKey) {
|
||||
pk11_SignedToUnsigned(&theTemplate);
|
||||
}
|
||||
if (pk11_FindObjectByTemplate(slot, &theTemplate, 1) != CK_INVALID_HANDLE) {
|
||||
SECKEY_DestroyPublicKey(pubKey);
|
||||
return PR_TRUE;
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NSS_TEST_BUILD
|
||||
#ifndef NSS_STATIC_SOFTOKEN
|
||||
static const char *my_shlib_name =
|
||||
SHLIB_PREFIX "nss" SHLIB_VERSION "." SHLIB_SUFFIX;
|
||||
static const char *softoken_shlib_name =
|
||||
|
|
@ -403,7 +403,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
|||
|
||||
/* internal modules get loaded from their internal list */
|
||||
if (mod->internal && (mod->dllName == NULL)) {
|
||||
#ifdef NSS_TEST_BUILD
|
||||
#ifdef NSS_STATIC_SOFTOKEN
|
||||
entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
|
||||
#else
|
||||
/*
|
||||
|
|
@ -430,7 +430,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
|||
|
||||
if (mod->isModuleDB) {
|
||||
mod->moduleDBFunc = (CK_C_GetFunctionList)
|
||||
#ifdef NSS_TEST_BUILD
|
||||
#ifdef NSS_STATIC_SOFTOKEN
|
||||
NSC_ModuleDBFunc;
|
||||
#else
|
||||
PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
|
||||
|
|
@ -612,7 +612,7 @@ SECMOD_UnloadModule(SECMODModule *mod)
|
|||
* if not, we should change this to SECFailure and move it above the
|
||||
* mod->loaded = PR_FALSE; */
|
||||
if (mod->internal && (mod->dllName == NULL)) {
|
||||
#ifndef NSS_TEST_BUILD
|
||||
#ifndef NSS_STATIC_SOFTOKEN
|
||||
if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) {
|
||||
if (softokenLib) {
|
||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
||||
|
|
|
|||
|
|
@ -226,6 +226,7 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
|
|||
return CKK_CAMELLIA;
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
case CKM_NSS_CHACHA20_KEY_GEN:
|
||||
case CKM_NSS_CHACHA20_CTR:
|
||||
return CKK_NSS_CHACHA20;
|
||||
case CKM_AES_ECB:
|
||||
case CKM_AES_CBC:
|
||||
|
|
@ -239,6 +240,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
|
|||
case CKM_AES_KEY_GEN:
|
||||
case CKM_NETSCAPE_AES_KEY_WRAP:
|
||||
case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
|
||||
case CKM_AES_XCBC_MAC:
|
||||
case CKM_AES_XCBC_MAC_96:
|
||||
return CKK_AES;
|
||||
case CKM_DES_ECB:
|
||||
case CKM_DES_CBC:
|
||||
|
|
@ -440,6 +443,7 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
|
|||
case CKM_CAMELLIA_KEY_GEN:
|
||||
return CKM_CAMELLIA_KEY_GEN;
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
case CKM_NSS_CHACHA20_CTR:
|
||||
return CKM_NSS_CHACHA20_KEY_GEN;
|
||||
case CKM_AES_ECB:
|
||||
case CKM_AES_CBC:
|
||||
|
|
@ -730,6 +734,9 @@ PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
|
|||
case CKM_RSA_X_509:
|
||||
/*actually it's the modulus length of the key!*/
|
||||
return -1; /* failure */
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
case CKM_NSS_CHACHA20_CTR:
|
||||
return 64;
|
||||
default:
|
||||
return pk11_lookup(type)->blockSize;
|
||||
}
|
||||
|
|
@ -784,12 +791,16 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type)
|
|||
case CKM_CAST3_CBC_PAD:
|
||||
case CKM_CAST5_CBC_PAD:
|
||||
return 8;
|
||||
case CKM_AES_GCM:
|
||||
case CKM_NSS_CHACHA20_POLY1305:
|
||||
return 12;
|
||||
case CKM_SEED_CBC:
|
||||
case CKM_SEED_CBC_PAD:
|
||||
case CKM_CAMELLIA_CBC:
|
||||
case CKM_CAMELLIA_CBC_PAD:
|
||||
case CKM_AES_CBC:
|
||||
case CKM_AES_CBC_PAD:
|
||||
case CKM_NSS_CHACHA20_CTR:
|
||||
return 16;
|
||||
case CKM_SKIPJACK_CBC64:
|
||||
case CKM_SKIPJACK_ECB64:
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ static const oidValDef curveOptList[] = {
|
|||
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
||||
{ CIPHER_NAME("SECP521R1"), SEC_OID_SECG_EC_SECP521R1,
|
||||
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
||||
{ CIPHER_NAME("CURVE25519"), SEC_OID_CURVE25519,
|
||||
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
||||
/* ANSI X9.62 named elliptic curves (characteristic two field) */
|
||||
{ CIPHER_NAME("C2PNB163V1"), SEC_OID_ANSIX962_EC_C2PNB163V1,
|
||||
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
|
|||
}
|
||||
PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
|
||||
attrs++;
|
||||
signedattr = attrs;
|
||||
/* No signed attrs for EC */
|
||||
/* curveOID always is a copy of AlgorithmID.parameters. */
|
||||
PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data,
|
||||
lpk->u.ec.curveOID.len);
|
||||
|
|
@ -523,11 +523,12 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
|
|||
}
|
||||
templateCount = attrs - theTemplate;
|
||||
PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
|
||||
PORT_Assert(signedattr != NULL);
|
||||
signedcount = attrs - signedattr;
|
||||
|
||||
for (ap = signedattr; signedcount; ap++, signedcount--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
if (lpk->keyType != ecKey) {
|
||||
PORT_Assert(signedattr);
|
||||
signedcount = attrs - signedattr;
|
||||
for (ap = signedattr; signedcount; ap++, signedcount--) {
|
||||
pk11_SignedToUnsigned(ap);
|
||||
}
|
||||
}
|
||||
|
||||
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert,
|
|||
PK11SymKey *pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
|
||||
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey);
|
||||
unsigned int pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType);
|
||||
CK_OBJECT_HANDLE PK11_DerivePubKeyFromPrivKey(SECKEYPrivateKey *privKey);
|
||||
|
||||
/**********************************************************************
|
||||
* Certs
|
||||
|
|
|
|||
|
|
@ -1598,6 +1598,7 @@ PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
|
|||
PK11_FreeSymKey(newBaseKey);
|
||||
if (crv != CKR_OK) {
|
||||
PK11_FreeSymKey(symKey);
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return NULL;
|
||||
}
|
||||
return symKey;
|
||||
|
|
@ -1839,6 +1840,35 @@ loser:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This regenerate a public key from a private key. This function is currently
|
||||
* NSS private. If we want to make it public, we need to add and optional
|
||||
* template or at least flags (a.la. PK11_DeriveWithFlags).
|
||||
*/
|
||||
CK_OBJECT_HANDLE
|
||||
PK11_DerivePubKeyFromPrivKey(SECKEYPrivateKey *privKey)
|
||||
{
|
||||
PK11SlotInfo *slot = privKey->pkcs11Slot;
|
||||
CK_MECHANISM mechanism;
|
||||
CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE;
|
||||
CK_RV crv;
|
||||
|
||||
mechanism.mechanism = CKM_NSS_PUB_FROM_PRIV;
|
||||
mechanism.pParameter = NULL;
|
||||
mechanism.ulParameterLen = 0;
|
||||
|
||||
PK11_EnterSlotMonitor(slot);
|
||||
crv = PK11_GETTAB(slot)->C_DeriveKey(slot->session, &mechanism,
|
||||
privKey->pkcs11ID, NULL, 0,
|
||||
&objectID);
|
||||
PK11_ExitSlotMonitor(slot);
|
||||
if (crv != CKR_OK) {
|
||||
PORT_SetError(PK11_MapError(crv));
|
||||
return CK_INVALID_HANDLE;
|
||||
}
|
||||
return objectID;
|
||||
}
|
||||
|
||||
/*
|
||||
* This Generates a wrapping key based on a privateKey, publicKey, and two
|
||||
* random numbers. For Mail usage RandomB should be NULL. In the Sender's
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
'target_name': 'pk11wrap_static',
|
||||
'type': 'static_library',
|
||||
'defines': [
|
||||
'NSS_TEST_BUILD',
|
||||
'NSS_STATIC_SOFTOKEN',
|
||||
],
|
||||
'dependencies': [
|
||||
'pk11wrap_base',
|
||||
|
|
|
|||
|
|
@ -492,14 +492,16 @@ typedef struct {
|
|||
static SECStatus
|
||||
collect_certs(void *arg, SECItem **certs, int numcerts)
|
||||
{
|
||||
SECStatus rv;
|
||||
collect_args *collectArgs;
|
||||
|
||||
collectArgs = (collect_args *)arg;
|
||||
|
||||
rv = SECITEM_CopyItem(collectArgs->arena, &collectArgs->cert, *certs);
|
||||
|
||||
return (rv);
|
||||
collect_args *collectArgs = (collect_args *)arg;
|
||||
if (!collectArgs || !collectArgs->arena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (numcerts < 1 || !certs || !*certs) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECITEM_CopyItem(collectArgs->arena, &collectArgs->cert, *certs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "lowkeyi.h"
|
||||
#include "secoid.h"
|
||||
#include "secerr.h"
|
||||
#include "pkcs11i.h"
|
||||
|
||||
/*
|
||||
* different platforms have different ways of calling and initial entry point
|
||||
|
|
@ -626,6 +627,10 @@ sftk_startup_tests(void)
|
|||
* the token */
|
||||
return;
|
||||
}
|
||||
rv = sftk_fips_IKE_PowerUpSelfTests();
|
||||
if (rv != SECSuccess) {
|
||||
return;
|
||||
}
|
||||
sftk_self_tests_success = PR_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -950,9 +950,9 @@ lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
|
|||
case CKA_UNWRAP:
|
||||
return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr);
|
||||
case CKA_VALUE:
|
||||
return lg_CopyPrivAttrSigned(attribute, type,
|
||||
key->u.ec.privateValue.data,
|
||||
key->u.ec.privateValue.len, sdbpw);
|
||||
return lg_CopyPrivAttribute(attribute, type,
|
||||
key->u.ec.privateValue.data,
|
||||
key->u.ec.privateValue.len, sdbpw);
|
||||
case CKA_EC_PARAMS:
|
||||
return lg_CopyAttributeSigned(attribute, type,
|
||||
key->u.ec.ecParams.DEREncoding.data,
|
||||
|
|
|
|||
|
|
@ -261,6 +261,7 @@ NSSLOWKEYPublicKey *
|
|||
nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
|
||||
{
|
||||
NSSLOWKEYPublicKey *pubk;
|
||||
SECItem publicValue;
|
||||
PLArenaPool *arena;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
|
@ -301,6 +302,19 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
|
|||
|
||||
pubk->arena = arena;
|
||||
pubk->keyType = privk->keyType;
|
||||
/* if the public key value doesn't exist, calculate it */
|
||||
if (privk->u.dsa.publicValue.len == 0) {
|
||||
rv = DH_Derive(&privk->u.dsa.params.base, &privk->u.dsa.params.prime,
|
||||
&privk->u.dsa.privateValue, &publicValue, 0);
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
rv = SECITEM_CopyItem(privk->arena, &privk->u.dsa.publicValue, &publicValue);
|
||||
SECITEM_FreeItem(&publicValue, PR_FALSE);
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue,
|
||||
&privk->u.dsa.publicValue);
|
||||
if (rv != SECSuccess)
|
||||
|
|
@ -327,6 +341,19 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk)
|
|||
|
||||
pubk->arena = arena;
|
||||
pubk->keyType = privk->keyType;
|
||||
/* if the public key value doesn't exist, calculate it */
|
||||
if (privk->u.dh.publicValue.len == 0) {
|
||||
rv = DH_Derive(&privk->u.dh.base, &privk->u.dh.prime,
|
||||
&privk->u.dh.privateValue, &publicValue, 0);
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
rv = SECITEM_CopyItem(privk->arena, &privk->u.dh.publicValue, &publicValue);
|
||||
SECITEM_FreeItem(&publicValue, PR_FALSE);
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
|
||||
&privk->u.dh.publicValue);
|
||||
if (rv != SECSuccess)
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ CSRCS = \
|
|||
sdb.c \
|
||||
sftkdb.c \
|
||||
sftkhmac.c \
|
||||
sftkike.c \
|
||||
sftkpars.c \
|
||||
sftkpwd.c \
|
||||
softkver.c \
|
||||
|
|
|
|||
|
|
@ -328,6 +328,8 @@ static const struct mechanismList mechanisms[] = {
|
|||
{ CKM_AES_CTS, { 16, 32, CKF_EN_DE }, PR_TRUE },
|
||||
{ CKM_AES_CTR, { 16, 32, CKF_EN_DE }, PR_TRUE },
|
||||
{ CKM_AES_GCM, { 16, 32, CKF_EN_DE }, PR_TRUE },
|
||||
{ CKM_AES_XCBC_MAC_96, { 16, 16, CKF_SN_VR }, PR_TRUE },
|
||||
{ CKM_AES_XCBC_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE },
|
||||
/* ------------------------- Camellia Operations --------------------- */
|
||||
{ CKM_CAMELLIA_KEY_GEN, { 16, 32, CKF_GENERATE }, PR_TRUE },
|
||||
{ CKM_CAMELLIA_ECB, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE },
|
||||
|
|
@ -346,6 +348,7 @@ static const struct mechanismList mechanisms[] = {
|
|||
/* ------------------------- ChaCha20 Operations ---------------------- */
|
||||
{ CKM_NSS_CHACHA20_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE },
|
||||
{ CKM_NSS_CHACHA20_POLY1305, { 32, 32, CKF_EN_DE }, PR_TRUE },
|
||||
{ CKM_NSS_CHACHA20_CTR, { 32, 32, CKF_EN_DE }, PR_TRUE },
|
||||
#endif /* NSS_DISABLE_CHACHAPOLY */
|
||||
/* ------------------------- Hashing Operations ----------------------- */
|
||||
{ CKM_MD2, { 0, 0, CKF_DIGEST }, PR_FALSE },
|
||||
|
|
@ -509,7 +512,11 @@ static const struct mechanismList mechanisms[] = {
|
|||
{ CKM_NSS_JPAKE_FINAL_SHA512, { 0, 0, CKF_DERIVE }, PR_TRUE },
|
||||
/* -------------------- Constant Time TLS MACs ----------------------- */
|
||||
{ CKM_NSS_HMAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE },
|
||||
{ CKM_NSS_SSL3_MAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE }
|
||||
{ CKM_NSS_SSL3_MAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE },
|
||||
/* --------------------IPSEC ----------------------- */
|
||||
{ CKM_NSS_IKE_PRF_PLUS_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE },
|
||||
{ CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE },
|
||||
{ CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE }
|
||||
};
|
||||
static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]);
|
||||
|
||||
|
|
@ -2199,6 +2206,119 @@ sftk_GetPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp)
|
|||
return priv;
|
||||
}
|
||||
|
||||
/* populate a public key object from a lowpublic keys structure */
|
||||
CK_RV
|
||||
sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType, NSSLOWKEYPublicKey *pubKey)
|
||||
{
|
||||
CK_OBJECT_CLASS classType = CKO_PUBLIC_KEY;
|
||||
CK_BBOOL cktrue = CK_TRUE;
|
||||
CK_RV crv = CKR_OK;
|
||||
sftk_DeleteAttributeType(publicKey, CKA_CLASS);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_VALUE);
|
||||
|
||||
switch (keyType) {
|
||||
case CKK_RSA:
|
||||
sftk_DeleteAttributeType(publicKey, CKA_MODULUS);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_PUBLIC_EXPONENT);
|
||||
/* format the keys */
|
||||
/* fill in the RSA dependent paramenters in the public key */
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_MODULUS,
|
||||
sftk_item_expand(&pubKey->u.rsa.modulus));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_PUBLIC_EXPONENT,
|
||||
sftk_item_expand(&pubKey->u.rsa.publicExponent));
|
||||
break;
|
||||
case CKK_DSA:
|
||||
sftk_DeleteAttributeType(publicKey, CKA_PRIME);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_SUBPRIME);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_BASE);
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_PRIME,
|
||||
sftk_item_expand(&pubKey->u.dsa.params.prime));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_SUBPRIME,
|
||||
sftk_item_expand(&pubKey->u.dsa.params.subPrime));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_BASE,
|
||||
sftk_item_expand(&pubKey->u.dsa.params.base));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
|
||||
sftk_item_expand(&pubKey->u.dsa.publicValue));
|
||||
break;
|
||||
case CKK_DH:
|
||||
sftk_DeleteAttributeType(publicKey, CKA_PRIME);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_BASE);
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_PRIME,
|
||||
sftk_item_expand(&pubKey->u.dh.prime));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_BASE,
|
||||
sftk_item_expand(&pubKey->u.dh.base));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_VALUE,
|
||||
sftk_item_expand(&pubKey->u.dh.publicValue));
|
||||
break;
|
||||
case CKK_EC:
|
||||
sftk_DeleteAttributeType(publicKey, CKA_EC_PARAMS);
|
||||
sftk_DeleteAttributeType(publicKey, CKA_EC_POINT);
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_EC_PARAMS,
|
||||
sftk_item_expand(&pubKey->u.ec.ecParams.DEREncoding));
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT,
|
||||
sftk_item_expand(&pubKey->u.ec.publicValue));
|
||||
break;
|
||||
default:
|
||||
return CKR_KEY_TYPE_INCONSISTENT;
|
||||
}
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_CLASS, &classType,
|
||||
sizeof(CK_OBJECT_CLASS));
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE, &keyType,
|
||||
sizeof(CK_KEY_TYPE));
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
/* now handle the operator attributes */
|
||||
if (sftk_isTrue(privateKey, CKA_DECRYPT)) {
|
||||
crv = sftk_forceAttribute(publicKey, CKA_ENCRYPT, &cktrue, sizeof(CK_BBOOL));
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
if (sftk_isTrue(privateKey, CKA_SIGN)) {
|
||||
crv = sftk_forceAttribute(publicKey, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
if (sftk_isTrue(privateKey, CKA_SIGN_RECOVER)) {
|
||||
crv = sftk_forceAttribute(publicKey, CKA_VERIFY_RECOVER, &cktrue, sizeof(CK_BBOOL));
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
if (sftk_isTrue(privateKey, CKA_DERIVE)) {
|
||||
crv = sftk_forceAttribute(publicKey, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
/*
|
||||
**************************** Symetric Key utils ************************
|
||||
*/
|
||||
|
|
@ -3156,7 +3276,7 @@ nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS)
|
|||
* this call doesn't force freebl to be reloaded. */
|
||||
BL_SetForkState(PR_FALSE);
|
||||
|
||||
#ifndef NSS_TEST_BUILD
|
||||
#ifndef NSS_STATIC_SOFTOKEN
|
||||
/* unload freeBL shared library from memory. This may only decrement the
|
||||
* OS refcount if it's been loaded multiple times, eg. by libssl */
|
||||
BL_Unload();
|
||||
|
|
|
|||
|
|
@ -96,42 +96,10 @@ sftk_Space(void *data, PRBool freeit)
|
|||
|
||||
/*
|
||||
* map all the SEC_ERROR_xxx error codes that may be returned by freebl
|
||||
* functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward
|
||||
* compatibility.
|
||||
* functions to CKR_xxx. Most of the mapping is done in
|
||||
* sftk_mapCryptError (now in pkcs11u.c). The next two functions adjust
|
||||
* that mapping based for different contexts (Decrypt or Verify).
|
||||
*/
|
||||
static CK_RV
|
||||
sftk_MapCryptError(int error)
|
||||
{
|
||||
switch (error) {
|
||||
case SEC_ERROR_INVALID_ARGS:
|
||||
case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
case SEC_ERROR_INPUT_LEN:
|
||||
return CKR_DATA_LEN_RANGE;
|
||||
case SEC_ERROR_OUTPUT_LEN:
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
case SEC_ERROR_LIBRARY_FAILURE:
|
||||
return CKR_GENERAL_ERROR;
|
||||
case SEC_ERROR_NO_MEMORY:
|
||||
return CKR_HOST_MEMORY;
|
||||
case SEC_ERROR_BAD_SIGNATURE:
|
||||
return CKR_SIGNATURE_INVALID;
|
||||
case SEC_ERROR_INVALID_KEY:
|
||||
return CKR_KEY_SIZE_RANGE;
|
||||
case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */
|
||||
return CKR_KEY_SIZE_RANGE; /* the closest error code */
|
||||
case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM:
|
||||
return CKR_TEMPLATE_INCONSISTENT;
|
||||
case SEC_ERROR_UNSUPPORTED_KEYALG:
|
||||
return CKR_MECHANISM_INVALID;
|
||||
case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE:
|
||||
return CKR_DOMAIN_PARAMS_INVALID;
|
||||
/* key pair generation failed after max number of attempts */
|
||||
case SEC_ERROR_NEED_RANDOM:
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
return CKR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
/* used by Decrypt and UnwrapKey (indirectly) */
|
||||
static CK_RV
|
||||
|
|
@ -760,6 +728,32 @@ sftk_ChaCha20Poly1305_Decrypt(const SFTKChaCha20Poly1305Info *ctx,
|
|||
sizeof(ctx->nonce), ad, ctx->adLen);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
sftk_ChaCha20Ctr(const SFTKChaCha20CtrInfo *ctx,
|
||||
unsigned char *output, unsigned int *outputLen,
|
||||
unsigned int maxOutputLen,
|
||||
const unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
if (maxOutputLen < inputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
ChaCha20_Xor(output, input, inputLen, ctx->key,
|
||||
ctx->nonce, ctx->counter);
|
||||
*outputLen = inputLen;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static void
|
||||
sftk_ChaCha20Ctr_DestroyContext(SFTKChaCha20CtrInfo *ctx,
|
||||
PRBool freeit)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
if (freeit) {
|
||||
PORT_Free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/** NSC_CryptInit initializes an encryption/Decryption operation.
|
||||
*
|
||||
* Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
|
||||
|
|
@ -1180,6 +1174,48 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
|||
context->destroy = (SFTKDestroy)sftk_ChaCha20Poly1305_DestroyContext;
|
||||
break;
|
||||
|
||||
case CKM_NSS_CHACHA20_CTR:
|
||||
if (key_type != CKK_NSS_CHACHA20) {
|
||||
crv = CKR_KEY_TYPE_INCONSISTENT;
|
||||
break;
|
||||
}
|
||||
if (pMechanism->pParameter == NULL || pMechanism->ulParameterLen != 16) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
att = sftk_FindAttribute(key, CKA_VALUE);
|
||||
if (att == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
break;
|
||||
}
|
||||
SFTKChaCha20CtrInfo *ctx = PORT_ZNew(SFTKChaCha20CtrInfo);
|
||||
if (!ctx) {
|
||||
sftk_FreeAttribute(att);
|
||||
crv = CKR_HOST_MEMORY;
|
||||
break;
|
||||
}
|
||||
if (att->attrib.ulValueLen != sizeof(ctx->key)) {
|
||||
sftk_FreeAttribute(att);
|
||||
PORT_Free(ctx);
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
break;
|
||||
}
|
||||
memcpy(ctx->key, att->attrib.pValue, att->attrib.ulValueLen);
|
||||
sftk_FreeAttribute(att);
|
||||
|
||||
/* The counter is little endian. */
|
||||
PRUint8 *param = pMechanism->pParameter;
|
||||
int i = 0;
|
||||
for (; i < 4; ++i) {
|
||||
ctx->counter |= param[i] << (i * 8);
|
||||
}
|
||||
memcpy(ctx->nonce, param + 4, 12);
|
||||
context->cipherInfo = ctx;
|
||||
context->update = (SFTKCipher)sftk_ChaCha20Ctr;
|
||||
context->destroy = (SFTKDestroy)sftk_ChaCha20Ctr_DestroyContext;
|
||||
break;
|
||||
|
||||
case CKM_NSS_AES_KEY_WRAP_PAD:
|
||||
context->doPad = PR_TRUE;
|
||||
/* fall thru */
|
||||
|
|
@ -2080,9 +2116,12 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
|||
CK_RC5_MAC_GENERAL_PARAMS *rc5_mac;
|
||||
#endif
|
||||
unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE];
|
||||
unsigned char k2[SFTK_MAX_BLOCK_SIZE];
|
||||
unsigned char k3[SFTK_MAX_BLOCK_SIZE];
|
||||
SFTKSessionContext *context;
|
||||
CK_RV crv;
|
||||
unsigned int blockSize;
|
||||
PRBool isXCBC = PR_FALSE;
|
||||
|
||||
switch (pMechanism->mechanism) {
|
||||
case CKM_RC2_MAC_GENERAL:
|
||||
|
|
@ -2186,6 +2225,26 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
|||
cbc_mechanism.pParameter = &ivBlock;
|
||||
cbc_mechanism.ulParameterLen = blockSize;
|
||||
break;
|
||||
case CKM_AES_XCBC_MAC_96:
|
||||
case CKM_AES_XCBC_MAC:
|
||||
/* The only difference between CKM_AES_XCBC_MAC
|
||||
* and CKM_AES_XCBC_MAC_96 is the size of the returned mac. */
|
||||
mac_bytes = pMechanism->mechanism == CKM_AES_XCBC_MAC_96 ? 12 : 16;
|
||||
blockSize = 16;
|
||||
PORT_Memset(ivBlock, 0, blockSize);
|
||||
cbc_mechanism.mechanism = CKM_AES_CBC;
|
||||
cbc_mechanism.pParameter = &ivBlock;
|
||||
cbc_mechanism.ulParameterLen = blockSize;
|
||||
/* is XCBC requires extra processing at the end of the operation */
|
||||
isXCBC = PR_TRUE;
|
||||
/* The input key is used to generate k1, k2, and k3. k2 and k3
|
||||
* are used at the end in the pad step. k1 replaces the input
|
||||
* key in the aes cbc mac */
|
||||
crv = sftk_aes_xcbc_new_keys(hSession, hKey, &hKey, k2, k3);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
|
@ -2195,24 +2254,43 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
|||
if (mac_bytes == SFTK_INVALID_MAC_SIZE)
|
||||
mac_bytes = blockSize >> 1;
|
||||
else {
|
||||
if (mac_bytes > blockSize)
|
||||
return CKR_MECHANISM_PARAM_INVALID;
|
||||
if (mac_bytes > blockSize) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey,
|
||||
CKA_ENCRYPT, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */
|
||||
keyUsage, contextType, PR_TRUE);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
goto fail;
|
||||
crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL);
|
||||
|
||||
/* this shouldn't happen! */
|
||||
PORT_Assert(crv == CKR_OK);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
goto fail;
|
||||
context->blockSize = blockSize;
|
||||
context->macSize = mac_bytes;
|
||||
context->isXCBC = isXCBC;
|
||||
if (isXCBC) {
|
||||
/* save the xcbc specific parameters */
|
||||
PORT_Memcpy(context->k2, k2, blockSize);
|
||||
PORT_Memcpy(context->k3, k3, blockSize);
|
||||
PORT_Memset(k2, 0, blockSize);
|
||||
PORT_Memset(k3, 0, blockSize);
|
||||
/* get rid of the temp key now that the context has been created */
|
||||
NSC_DestroyObject(hSession, hKey);
|
||||
}
|
||||
return CKR_OK;
|
||||
fail:
|
||||
if (isXCBC) {
|
||||
PORT_Memset(k2, 0, blockSize);
|
||||
PORT_Memset(k3, 0, blockSize);
|
||||
NSC_DestroyObject(hSession, hKey); /* get rid of our temp key */
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2828,6 +2906,13 @@ sftk_MACFinal(SFTKSessionContext *ctx)
|
|||
{
|
||||
unsigned int padLen = ctx->padDataLength;
|
||||
/* pad and proceed the residual */
|
||||
if (ctx->isXCBC) {
|
||||
CK_RV crv = sftk_xcbc_mac_pad(ctx->padBuf, padLen, ctx->blockSize,
|
||||
ctx->k2, ctx->k3);
|
||||
if (crv != CKR_OK)
|
||||
return crv;
|
||||
return sftk_MACBlock(ctx, ctx->padBuf);
|
||||
}
|
||||
if (padLen) {
|
||||
/* shd clr ctx->padLen to make sftk_MACFinal idempotent */
|
||||
PORT_Memset(ctx->padBuf + padLen, 0, ctx->blockSize - padLen);
|
||||
|
|
@ -2866,7 +2951,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
|
|||
blkSize - context->padDataLength;
|
||||
|
||||
/* not enough data even for one block */
|
||||
if (ulPartLen < minInput) {
|
||||
if (ulPartLen <= minInput) {
|
||||
PORT_Memcpy(residual, pPart, ulPartLen);
|
||||
context->padDataLength += ulPartLen;
|
||||
goto cleanup;
|
||||
|
|
@ -2880,7 +2965,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
|
|||
goto terminate;
|
||||
}
|
||||
/* MACing full blocks */
|
||||
while (ulPartLen >= blkSize) {
|
||||
while (ulPartLen > blkSize) {
|
||||
if (CKR_OK != (crv = sftk_MACBlock(context, pPart)))
|
||||
goto terminate;
|
||||
ulPartLen -= blkSize;
|
||||
|
|
@ -4645,6 +4730,13 @@ sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession,
|
|||
return crv;
|
||||
}
|
||||
|
||||
/* detect trivial signing transforms */
|
||||
if ((signature_length >= pairwise_digest_length) &&
|
||||
(PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
|
||||
PORT_Free(signature);
|
||||
return CKR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
/* Verify the known hash using the public key. */
|
||||
crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
|
||||
if (crv != CKR_OK) {
|
||||
|
|
@ -6477,6 +6569,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
extractValue = PR_FALSE;
|
||||
classType = CKO_PRIVATE_KEY;
|
||||
break;
|
||||
case CKM_NSS_PUB_FROM_PRIV:
|
||||
extractValue = PR_FALSE;
|
||||
classType = CKO_PUBLIC_KEY;
|
||||
break;
|
||||
case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */
|
||||
case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */
|
||||
case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */
|
||||
|
|
@ -6518,6 +6614,73 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
}
|
||||
|
||||
switch (mechanism) {
|
||||
/* get a public key from a private key. nsslowkey_ConvertToPublickey()
|
||||
* will generate the public portion if it doesn't already exist. */
|
||||
case CKM_NSS_PUB_FROM_PRIV: {
|
||||
NSSLOWKEYPrivateKey *privKey;
|
||||
NSSLOWKEYPublicKey *pubKey;
|
||||
int error;
|
||||
|
||||
crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE, &keyType);
|
||||
if (crv != CKR_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* privKey is stored in sourceKey and will be destroyed when
|
||||
* the sourceKey is freed. */
|
||||
privKey = sftk_GetPrivKey(sourceKey, keyType, &crv);
|
||||
if (privKey == NULL) {
|
||||
break;
|
||||
}
|
||||
pubKey = nsslowkey_ConvertToPublicKey(privKey);
|
||||
if (pubKey == NULL) {
|
||||
error = PORT_GetError();
|
||||
crv = sftk_MapCryptError(error);
|
||||
break;
|
||||
}
|
||||
crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey);
|
||||
nsslowkey_DestroyPublicKey(pubKey);
|
||||
break;
|
||||
}
|
||||
case CKM_NSS_IKE_PRF_DERIVE:
|
||||
if (pMechanism->ulParameterLen !=
|
||||
sizeof(CK_NSS_IKE_PRF_DERIVE_PARAMS)) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
crv = sftk_ike_prf(hSession, att,
|
||||
(CK_NSS_IKE_PRF_DERIVE_PARAMS *)pMechanism->pParameter, key);
|
||||
break;
|
||||
case CKM_NSS_IKE1_PRF_DERIVE:
|
||||
if (pMechanism->ulParameterLen !=
|
||||
sizeof(CK_NSS_IKE1_PRF_DERIVE_PARAMS)) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
crv = sftk_ike1_prf(hSession, att,
|
||||
(CK_NSS_IKE1_PRF_DERIVE_PARAMS *)pMechanism->pParameter,
|
||||
key, keySize);
|
||||
break;
|
||||
case CKM_NSS_IKE1_APP_B_PRF_DERIVE:
|
||||
if (pMechanism->ulParameterLen !=
|
||||
sizeof(CK_MECHANISM_TYPE)) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
crv = sftk_ike1_appendix_b_prf(hSession, att,
|
||||
(CK_MECHANISM_TYPE *)pMechanism->pParameter,
|
||||
key, keySize);
|
||||
break;
|
||||
case CKM_NSS_IKE_PRF_PLUS_DERIVE:
|
||||
if (pMechanism->ulParameterLen !=
|
||||
sizeof(CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS)) {
|
||||
crv = CKR_MECHANISM_PARAM_INVALID;
|
||||
break;
|
||||
}
|
||||
crv = sftk_ike_prf_plus(hSession, att,
|
||||
(CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *)pMechanism->pParameter,
|
||||
key, keySize);
|
||||
break;
|
||||
/*
|
||||
* generate the master secret
|
||||
*/
|
||||
|
|
@ -7480,14 +7643,14 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
|
||||
case CKM_DH_PKCS_DERIVE: {
|
||||
SECItem derived, dhPublic;
|
||||
SECItem dhPrime, dhValue;
|
||||
SECItem dhPrime, dhSubPrime, dhValue;
|
||||
/* sourceKey - values for the local existing low key */
|
||||
/* get prime and value attributes */
|
||||
crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME);
|
||||
if (crv != SECSuccess)
|
||||
if (crv != CKR_OK)
|
||||
break;
|
||||
crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE);
|
||||
if (crv != SECSuccess) {
|
||||
if (crv != CKR_OK) {
|
||||
PORT_Free(dhPrime.data);
|
||||
break;
|
||||
}
|
||||
|
|
@ -7495,6 +7658,20 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
dhPublic.data = pMechanism->pParameter;
|
||||
dhPublic.len = pMechanism->ulParameterLen;
|
||||
|
||||
/* If the caller bothered to provide Q, use Q to validate
|
||||
* the public key. */
|
||||
crv = sftk_Attribute2SecItem(NULL, &dhSubPrime, sourceKey, CKA_SUBPRIME);
|
||||
if (crv == CKR_OK) {
|
||||
rv = KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime);
|
||||
PORT_Free(dhSubPrime.data);
|
||||
if (rv != SECSuccess) {
|
||||
crv = CKR_ARGUMENTS_BAD;
|
||||
PORT_Free(dhPrime.data);
|
||||
PORT_Free(dhValue.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate private value - oct */
|
||||
rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize);
|
||||
|
||||
|
|
@ -7504,6 +7681,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
if (rv == SECSuccess) {
|
||||
sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len);
|
||||
PORT_ZFree(derived.data, derived.len);
|
||||
crv = CKR_OK;
|
||||
} else
|
||||
crv = CKR_HOST_MEMORY;
|
||||
|
||||
|
|
@ -7569,7 +7747,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
|
|||
|
||||
rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar,
|
||||
withCofactor, &tmp);
|
||||
PORT_Free(ecScalar.data);
|
||||
PORT_ZFree(ecScalar.data, ecScalar.len);
|
||||
ecScalar.data = NULL;
|
||||
if (privKey != sourceKey->objectInfo) {
|
||||
nsslowkey_DestroyPrivateKey(privKey);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
|
|||
typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
|
||||
typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
|
||||
typedef struct SFTKChaCha20Poly1305InfoStr SFTKChaCha20Poly1305Info;
|
||||
typedef struct SFTKChaCha20CtrInfoStr SFTKChaCha20CtrInfo;
|
||||
typedef struct SFTKItemTemplateStr SFTKItemTemplate;
|
||||
|
||||
/* define function pointer typdefs for pointer tables */
|
||||
|
|
@ -253,12 +254,15 @@ struct SFTKSessionContextStr {
|
|||
PRBool multi; /* is multipart */
|
||||
PRBool rsa; /* is rsa */
|
||||
PRBool doPad; /* use PKCS padding for block ciphers */
|
||||
PRBool isXCBC; /* xcbc, use special handling in final */
|
||||
unsigned int blockSize; /* blocksize for padding */
|
||||
unsigned int padDataLength; /* length of the valid data in padbuf */
|
||||
/** latest incomplete block of data for block cipher */
|
||||
unsigned char padBuf[SFTK_MAX_BLOCK_SIZE];
|
||||
/** result of MAC'ing of latest full block of data with block cipher */
|
||||
unsigned char macBuf[SFTK_MAX_BLOCK_SIZE];
|
||||
unsigned char k2[SFTK_MAX_BLOCK_SIZE];
|
||||
unsigned char k3[SFTK_MAX_BLOCK_SIZE];
|
||||
CK_ULONG macSize; /* size of a general block cipher mac*/
|
||||
void *cipherInfo;
|
||||
void *hashInfo;
|
||||
|
|
@ -409,6 +413,14 @@ struct SFTKChaCha20Poly1305InfoStr {
|
|||
unsigned int adLen;
|
||||
};
|
||||
|
||||
/* SFTKChaCha20BlockInfoStr the key, nonce and counter for a
|
||||
* ChaCha20 block operation. */
|
||||
struct SFTKChaCha20CtrInfoStr {
|
||||
PRUint8 key[32];
|
||||
PRUint8 nonce[12];
|
||||
PRUint32 counter;
|
||||
};
|
||||
|
||||
/*
|
||||
* Template based on SECItems, suitable for passing as arrays
|
||||
*/
|
||||
|
|
@ -605,6 +617,7 @@ extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot);
|
|||
extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout);
|
||||
|
||||
/* internal utility functions used by pkcs11.c */
|
||||
extern CK_RV sftk_MapCryptError(int error);
|
||||
extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object,
|
||||
CK_ATTRIBUTE_TYPE type);
|
||||
extern void sftk_FreeAttribute(SFTKAttribute *attribute);
|
||||
|
|
@ -682,10 +695,36 @@ extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,
|
|||
CK_KEY_TYPE key_type, CK_RV *crvp);
|
||||
extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object,
|
||||
CK_KEY_TYPE key_type, CK_RV *crvp);
|
||||
extern CK_RV sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privKey, CK_KEY_TYPE keyType,
|
||||
NSSLOWKEYPublicKey *pubKey);
|
||||
extern void sftk_FormatDESKey(unsigned char *key, int length);
|
||||
extern PRBool sftk_CheckDESKey(unsigned char *key);
|
||||
extern PRBool sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type);
|
||||
|
||||
/* ike and xcbc helpers */
|
||||
extern CK_RV sftk_ike_prf(CK_SESSION_HANDLE hSession,
|
||||
const SFTKAttribute *inKey,
|
||||
const CK_NSS_IKE_PRF_DERIVE_PARAMS *params, SFTKObject *outKey);
|
||||
extern CK_RV sftk_ike1_prf(CK_SESSION_HANDLE hSession,
|
||||
const SFTKAttribute *inKey,
|
||||
const CK_NSS_IKE1_PRF_DERIVE_PARAMS *params, SFTKObject *outKey,
|
||||
unsigned int keySize);
|
||||
extern CK_RV sftk_ike1_appendix_b_prf(CK_SESSION_HANDLE hSession,
|
||||
const SFTKAttribute *inKey,
|
||||
const CK_MECHANISM_TYPE *params, SFTKObject *outKey,
|
||||
unsigned int keySize);
|
||||
extern CK_RV sftk_ike_prf_plus(CK_SESSION_HANDLE hSession,
|
||||
const SFTKAttribute *inKey,
|
||||
const CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *params, SFTKObject *outKey,
|
||||
unsigned int keySize);
|
||||
extern CK_RV sftk_aes_xcbc_new_keys(CK_SESSION_HANDLE hSession,
|
||||
CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE_PTR phKey,
|
||||
unsigned char *k2, unsigned char *k3);
|
||||
extern CK_RV sftk_xcbc_mac_pad(unsigned char *padBuf, unsigned int bufLen,
|
||||
int blockSize, const unsigned char *k2,
|
||||
const unsigned char *k3);
|
||||
extern SECStatus sftk_fips_IKE_PowerUpSelfTests(void);
|
||||
|
||||
/* mechanism allows this operation */
|
||||
extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,47 @@
|
|||
#include "sftkdb.h"
|
||||
#include "softoken.h"
|
||||
|
||||
/*
|
||||
* ******************** Error mapping *******************************
|
||||
*/
|
||||
/*
|
||||
* map all the SEC_ERROR_xxx error codes that may be returned by freebl
|
||||
* functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward
|
||||
* compatibility.
|
||||
*/
|
||||
CK_RV
|
||||
sftk_MapCryptError(int error)
|
||||
{
|
||||
switch (error) {
|
||||
case SEC_ERROR_INVALID_ARGS:
|
||||
case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
case SEC_ERROR_INPUT_LEN:
|
||||
return CKR_DATA_LEN_RANGE;
|
||||
case SEC_ERROR_OUTPUT_LEN:
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
case SEC_ERROR_LIBRARY_FAILURE:
|
||||
return CKR_GENERAL_ERROR;
|
||||
case SEC_ERROR_NO_MEMORY:
|
||||
return CKR_HOST_MEMORY;
|
||||
case SEC_ERROR_BAD_SIGNATURE:
|
||||
return CKR_SIGNATURE_INVALID;
|
||||
case SEC_ERROR_INVALID_KEY:
|
||||
return CKR_KEY_SIZE_RANGE;
|
||||
case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */
|
||||
return CKR_KEY_SIZE_RANGE; /* the closest error code */
|
||||
case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM:
|
||||
return CKR_TEMPLATE_INCONSISTENT;
|
||||
case SEC_ERROR_UNSUPPORTED_KEYALG:
|
||||
return CKR_MECHANISM_INVALID;
|
||||
case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE:
|
||||
return CKR_DOMAIN_PARAMS_INVALID;
|
||||
/* key pair generation failed after max number of attempts */
|
||||
case SEC_ERROR_NEED_RANDOM:
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
return CKR_DEVICE_ERROR;
|
||||
}
|
||||
/*
|
||||
* ******************** Attribute Utilities *******************************
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -858,7 +858,6 @@ sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind)
|
|||
return sdb_mapSQLError(sdb_p->type, sqlerr);
|
||||
}
|
||||
|
||||
static const char GET_ATTRIBUTE_CMD[] = "SELECT ALL %s FROM %s WHERE id=$ID;";
|
||||
CK_RV
|
||||
sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
|
||||
CK_ATTRIBUTE *template, CK_ULONG count)
|
||||
|
|
@ -866,8 +865,6 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
|
|||
SDBPrivate *sdb_p = sdb->private;
|
||||
sqlite3 *sqlDB = NULL;
|
||||
sqlite3_stmt *stmt = NULL;
|
||||
char *getStr = NULL;
|
||||
char *newStr = NULL;
|
||||
const char *table = NULL;
|
||||
int sqlerr = SQLITE_OK;
|
||||
CK_RV error = CKR_OK;
|
||||
|
|
@ -875,59 +872,79 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
|
|||
int retry = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (count == 0) {
|
||||
error = CKR_OBJECT_HANDLE_INVALID;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* open a new db if necessary */
|
||||
error = sdb_openDBLocal(sdb_p, &sqlDB, &table);
|
||||
if (error != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
char *columns = NULL;
|
||||
for (i = 0; i < count; i++) {
|
||||
getStr = sqlite3_mprintf("a%x", template[i].type);
|
||||
|
||||
if (getStr == NULL) {
|
||||
char *newColumns;
|
||||
if (columns) {
|
||||
newColumns = sqlite3_mprintf("%s, a%x", columns, template[i].type);
|
||||
sqlite3_free(columns);
|
||||
columns = NULL;
|
||||
} else {
|
||||
newColumns = sqlite3_mprintf("a%x", template[i].type);
|
||||
}
|
||||
if (!newColumns) {
|
||||
error = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
columns = newColumns;
|
||||
}
|
||||
|
||||
newStr = sqlite3_mprintf(GET_ATTRIBUTE_CMD, getStr, table);
|
||||
sqlite3_free(getStr);
|
||||
getStr = NULL;
|
||||
if (newStr == NULL) {
|
||||
error = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
PORT_Assert(columns);
|
||||
|
||||
char *statement = sqlite3_mprintf("SELECT DISTINCT %s FROM %s where id=$ID LIMIT 1;",
|
||||
columns, table);
|
||||
sqlite3_free(columns);
|
||||
columns = NULL;
|
||||
if (!statement) {
|
||||
error = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
sqlerr = sqlite3_prepare_v2(sqlDB, statement, -1, &stmt, NULL);
|
||||
sqlite3_free(statement);
|
||||
statement = NULL;
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
// NB: indices in sqlite3_bind_int are 1-indexed
|
||||
sqlerr = sqlite3_bind_int(stmt, 1, object_id);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
PR_Sleep(SDB_BUSY_RETRY_TIME);
|
||||
}
|
||||
|
||||
sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL);
|
||||
sqlite3_free(newStr);
|
||||
newStr = NULL;
|
||||
if (sqlerr == SQLITE_ERROR) {
|
||||
template[i].ulValueLen = -1;
|
||||
error = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
continue;
|
||||
} else if (sqlerr != SQLITE_OK) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
sqlerr = sqlite3_bind_int(stmt, 1, object_id);
|
||||
if (sqlerr != SQLITE_OK) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
do {
|
||||
sqlerr = sqlite3_step(stmt);
|
||||
if (sqlerr == SQLITE_BUSY) {
|
||||
PR_Sleep(SDB_BUSY_RETRY_TIME);
|
||||
}
|
||||
if (sqlerr == SQLITE_ROW) {
|
||||
if (sqlerr == SQLITE_ROW) {
|
||||
PORT_Assert(!found);
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned int blobSize;
|
||||
const char *blobData;
|
||||
|
||||
blobSize = sqlite3_column_bytes(stmt, 0);
|
||||
blobData = sqlite3_column_blob(stmt, 0);
|
||||
// NB: indices in sqlite_column_{bytes,blob} are 0-indexed
|
||||
blobSize = sqlite3_column_bytes(stmt, i);
|
||||
blobData = sqlite3_column_blob(stmt, i);
|
||||
if (blobData == NULL) {
|
||||
/* PKCS 11 requires that get attributes process all the
|
||||
* attributes in the template, marking the attributes with
|
||||
* issues with -1. Mark the error but continue */
|
||||
template[i].ulValueLen = -1;
|
||||
error = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
/* If the blob equals our explicit NULL value, then the
|
||||
* attribute is a NULL. */
|
||||
|
|
@ -938,20 +955,21 @@ sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id,
|
|||
}
|
||||
if (template[i].pValue) {
|
||||
if (template[i].ulValueLen < blobSize) {
|
||||
/* like CKR_ATTRIBUTE_TYPE_INVALID, continue processing */
|
||||
template[i].ulValueLen = -1;
|
||||
error = CKR_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
PORT_Memcpy(template[i].pValue, blobData, blobSize);
|
||||
}
|
||||
template[i].ulValueLen = blobSize;
|
||||
found = 1;
|
||||
}
|
||||
} while (!sdb_done(sqlerr, &retry));
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
stmt = NULL;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
} while (!sdb_done(sqlerr, &retry));
|
||||
sqlite3_reset(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
stmt = NULL;
|
||||
|
||||
loser:
|
||||
/* fix up the error if necessary */
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue