зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team, a=merge
--HG-- extra : commitid : KSEbGPeZZae
This commit is contained in:
Коммит
9d24ca2703
1
.hgtags
1
.hgtags
|
@ -123,3 +123,4 @@ b297a6727acfd21e757ddd38cd61894812666265 FIREFOX_AURORA_36_BASE
|
||||||
fcef8ded82219c89298b4e376cfbdfba79a1d35a FIREFOX_AURORA_43_BASE
|
fcef8ded82219c89298b4e376cfbdfba79a1d35a FIREFOX_AURORA_43_BASE
|
||||||
67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_BASE
|
67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_BASE
|
||||||
99137d6d4061f408ae0869122649d8bdf489cc30 FIREFOX_AURORA_45_BASE
|
99137d6d4061f408ae0869122649d8bdf489cc30 FIREFOX_AURORA_45_BASE
|
||||||
|
67c66c2878aed17ae3096d7db483ddbb2293c503 FIREFOX_AURORA_46_BASE
|
||||||
|
|
2
CLOBBER
2
CLOBBER
|
@ -22,5 +22,5 @@
|
||||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# don't change CLOBBER for WebIDL changes any more.
|
||||||
|
|
||||||
Bug 1240627 - Enable AVX2 optimizations in ffvpx on Mac
|
|
||||||
|
|
||||||
|
Merge day clobber
|
|
@ -9,6 +9,9 @@ add_task(function* () {
|
||||||
const ENGINE_NAME = "Foo";
|
const ENGINE_NAME = "Foo";
|
||||||
var contextMenu;
|
var contextMenu;
|
||||||
|
|
||||||
|
// We want select events to be fired.
|
||||||
|
yield new Promise(resolve => SpecialPowers.pushPrefEnv({"set": [["dom.select_events.enabled", true]]}, resolve));
|
||||||
|
|
||||||
let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
let envService = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||||
let originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR");
|
let originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR");
|
||||||
envService.set("XPCSHELL_TEST_PROFILE_DIR", "1");
|
envService.set("XPCSHELL_TEST_PROFILE_DIR", "1");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
46.0a1
|
47.0a1
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
46.0a1
|
47.0a1
|
||||||
|
|
|
@ -10,4 +10,4 @@
|
||||||
# hardcoded milestones in the tree from these two files.
|
# hardcoded milestones in the tree from these two files.
|
||||||
#--------------------------------------------------------
|
#--------------------------------------------------------
|
||||||
|
|
||||||
46.0a1
|
47.0a1
|
||||||
|
|
|
@ -2309,7 +2309,7 @@ public:
|
||||||
|
|
||||||
// Rooter class for MozMap; this is what we mostly use in the codegen.
|
// Rooter class for MozMap; this is what we mostly use in the codegen.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class MOZ_RAII MozMapRooter : private JS::CustomAutoRooter
|
class MOZ_RAII MozMapRooter final : private JS::CustomAutoRooter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap
|
MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap
|
||||||
|
|
|
@ -412,8 +412,8 @@ private:
|
||||||
|
|
||||||
// Class for easily setting up a rooted typed array object on the stack
|
// Class for easily setting up a rooted typed array object on the stack
|
||||||
template<typename ArrayType>
|
template<typename ArrayType>
|
||||||
class MOZ_RAII RootedTypedArray : public ArrayType,
|
class MOZ_RAII RootedTypedArray final : public ArrayType,
|
||||||
private TypedArrayRooter<ArrayType>
|
private TypedArrayRooter<ArrayType>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||||
|
|
|
@ -549,6 +549,9 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||||
} else {
|
} else {
|
||||||
// StartRemoteDrawingInRegion can mutate mInvalidRegion.
|
// StartRemoteDrawingInRegion can mutate mInvalidRegion.
|
||||||
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
|
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
|
||||||
|
if (!mDrawTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mInvalidRect = mInvalidRegion.GetBounds();
|
mInvalidRect = mInvalidRegion.GetBounds();
|
||||||
if (mInvalidRect.IsEmpty()) {
|
if (mInvalidRect.IsEmpty()) {
|
||||||
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
||||||
|
|
|
@ -2087,7 +2087,7 @@ RangeAnalysis::analyzeLoopPhi(MBasicBlock* header, LoopIterationBound* loopBound
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!phi->range())
|
if (!phi->range())
|
||||||
phi->setRange(new(alloc()) Range());
|
phi->setRange(new(alloc()) Range(phi));
|
||||||
|
|
||||||
LinearSum initialSum(alloc());
|
LinearSum initialSum(alloc());
|
||||||
if (!initialSum.add(initial, 1))
|
if (!initialSum.add(initial, 1))
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: Mozilla
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: true
|
||||||
|
AlignEscapedNewlinesLeft: false
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: true
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BinPackParameters: true
|
||||||
|
BinPackArguments: true
|
||||||
|
ColumnLimit: 0
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
DerivePointerAlignment: true
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
IndentFunctionDeclarationAfterType: false
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: true
|
||||||
|
ObjCSpaceBeforeProtocolList: false
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PointerAlignment: Right
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
Standard: Cpp03
|
||||||
|
IndentWidth: 4
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
BreakBeforeBraces: Linux
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
DisableFormat: false
|
||||||
|
...
|
|
@ -1 +1 @@
|
||||||
NSS_3_21_RTM
|
NSS_3_22_BETA2
|
||||||
|
|
|
@ -3496,6 +3496,9 @@ shutdown:
|
||||||
/* Allocated by a PL_strdup call in SECU_GetModulePassword. */
|
/* Allocated by a PL_strdup call in SECU_GetModulePassword. */
|
||||||
PL_strfree(pwdata.data);
|
PL_strfree(pwdata.data);
|
||||||
}
|
}
|
||||||
|
if (email) {
|
||||||
|
PL_strfree(email);
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the batch command file.
|
/* Open the batch command file.
|
||||||
*
|
*
|
||||||
|
|
|
@ -42,7 +42,7 @@ const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = {
|
||||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
|
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
|
||||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
|
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
|
||||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
|
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
|
||||||
{ 0, }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* returns 0 for success, -1 for failure (EOF encountered) */
|
/* returns 0 for success, -1 for failure (EOF encountered) */
|
||||||
|
|
|
@ -1,575 +0,0 @@
|
||||||
/* 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 "secutil.h"
|
|
||||||
#include "plgetopt.h"
|
|
||||||
#include "cert.h"
|
|
||||||
#include "secoid.h"
|
|
||||||
#include "cryptohi.h"
|
|
||||||
|
|
||||||
/* maximum supported modulus length in bits (indicate problem if over this) */
|
|
||||||
#define MAX_MODULUS (1024)
|
|
||||||
|
|
||||||
|
|
||||||
static void Usage(char *progName)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: %s [aAvf] [certtocheck] [issuingcert]\n",
|
|
||||||
progName);
|
|
||||||
fprintf(stderr, "%-20s Cert to check is base64 encoded\n",
|
|
||||||
"-a");
|
|
||||||
fprintf(stderr, "%-20s Issuer's cert is base64 encoded\n",
|
|
||||||
"-A");
|
|
||||||
fprintf(stderr, "%-20s Verbose (indicate decoding progress etc.)\n",
|
|
||||||
"-v");
|
|
||||||
fprintf(stderr, "%-20s Force sanity checks even if pretty print fails.\n",
|
|
||||||
"-f");
|
|
||||||
fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
|
|
||||||
"-o output");
|
|
||||||
fprintf(stderr, "%-20s Specify the input type (no default)\n",
|
|
||||||
"-t type");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check integer field named fieldName, printing out results and
|
|
||||||
* returning the length of the integer in bits
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
int checkInteger(SECItem *intItem, char *fieldName, int verbose)
|
|
||||||
{
|
|
||||||
int len, bitlen;
|
|
||||||
if (verbose) {
|
|
||||||
printf("Checking %s\n", fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = intItem->len;
|
|
||||||
|
|
||||||
if (len && (intItem->data[0] & 0x80)) {
|
|
||||||
printf("PROBLEM: %s is NEGATIVE 2's-complement integer.\n",
|
|
||||||
fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* calculate bit length and check for unnecessary leading zeros */
|
|
||||||
bitlen = len << 3;
|
|
||||||
if (len > 1 && intItem->data[0] == 0) {
|
|
||||||
/* leading zero byte(s) */
|
|
||||||
if (!(intItem->data[1] & 0x80)) {
|
|
||||||
printf("PROBLEM: %s has unneeded leading zeros. Violates DER.\n",
|
|
||||||
fieldName);
|
|
||||||
}
|
|
||||||
/* strip leading zeros in length calculation */
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
while (bitlen > 8 && intItem->data[i] == 0) {
|
|
||||||
bitlen -= 8;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bitlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
void checkName(CERTName *n, char *fieldName, int verbose)
|
|
||||||
{
|
|
||||||
char *v=0;
|
|
||||||
if (verbose) {
|
|
||||||
printf("Checking %s\n", fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
v = CERT_GetCountryName(n);
|
|
||||||
if (!v) {
|
|
||||||
printf("PROBLEM: %s lacks Country Name (C)\n",
|
|
||||||
fieldName);
|
|
||||||
}
|
|
||||||
PORT_Free(v);
|
|
||||||
|
|
||||||
v = CERT_GetOrgName(n);
|
|
||||||
if (!v) {
|
|
||||||
printf("PROBLEM: %s lacks Organization Name (O)\n",
|
|
||||||
fieldName);
|
|
||||||
}
|
|
||||||
PORT_Free(v);
|
|
||||||
|
|
||||||
v = CERT_GetOrgUnitName(n);
|
|
||||||
if (!v) {
|
|
||||||
printf("WARNING: %s lacks Organization Unit Name (OU)\n",
|
|
||||||
fieldName);
|
|
||||||
}
|
|
||||||
PORT_Free(v);
|
|
||||||
|
|
||||||
v = CERT_GetCommonName(n);
|
|
||||||
if (!v) {
|
|
||||||
printf("PROBLEM: %s lacks Common Name (CN)\n",
|
|
||||||
fieldName);
|
|
||||||
}
|
|
||||||
PORT_Free(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
SECStatus
|
|
||||||
OurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,
|
|
||||||
SECItem *sig, SECAlgorithmID *sigAlgorithm)
|
|
||||||
{
|
|
||||||
SECStatus rv;
|
|
||||||
VFYContext *cx;
|
|
||||||
SECOidData *sigAlgOid, *oiddata;
|
|
||||||
SECOidTag hashAlgTag;
|
|
||||||
int showDigestOid=0;
|
|
||||||
|
|
||||||
cx = VFY_CreateContextWithAlgorithmID(key, sig, sigAlgorithm, &hashAlgTag,
|
|
||||||
NULL);
|
|
||||||
if (cx == NULL)
|
|
||||||
return SECFailure;
|
|
||||||
|
|
||||||
sigAlgOid = SECOID_FindOID(&sigAlgorithm->algorithm);
|
|
||||||
if (sigAlgOid == 0)
|
|
||||||
return SECFailure;
|
|
||||||
|
|
||||||
if (showDigestOid) {
|
|
||||||
oiddata = SECOID_FindOIDByTag(hashAlgTag);
|
|
||||||
if ( oiddata ) {
|
|
||||||
printf("PROBLEM: (cont) Digest OID is %s\n", oiddata->desc);
|
|
||||||
} else {
|
|
||||||
SECU_PrintAsHex(stdout,
|
|
||||||
&oiddata->oid, "PROBLEM: UNKNOWN OID", 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = VFY_Begin(cx);
|
|
||||||
if (rv == SECSuccess) {
|
|
||||||
rv = VFY_Update(cx, buf, len);
|
|
||||||
if (rv == SECSuccess)
|
|
||||||
rv = VFY_End(cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
VFY_DestroyContext(cx, PR_TRUE);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
SECStatus
|
|
||||||
OurVerifySignedData(CERTSignedData *sd, CERTCertificate *cert)
|
|
||||||
{
|
|
||||||
SECItem sig;
|
|
||||||
SECKEYPublicKey *pubKey = 0;
|
|
||||||
SECStatus rv;
|
|
||||||
|
|
||||||
/* check the certificate's validity */
|
|
||||||
rv = CERT_CertTimesValid(cert);
|
|
||||||
if ( rv ) {
|
|
||||||
return(SECFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get cert's public key */
|
|
||||||
pubKey = CERT_ExtractPublicKey(cert);
|
|
||||||
if ( !pubKey ) {
|
|
||||||
return(SECFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check the signature */
|
|
||||||
sig = sd->signature;
|
|
||||||
DER_ConvertBitString(&sig);
|
|
||||||
rv = OurVerifyData(sd->data.data, sd->data.len, pubKey, &sig,
|
|
||||||
&sd->signatureAlgorithm);
|
|
||||||
|
|
||||||
SECKEY_DestroyPublicKey(pubKey);
|
|
||||||
|
|
||||||
if ( rv ) {
|
|
||||||
return(SECFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(SECSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
CERTCertificate *createEmptyCertificate(void)
|
|
||||||
{
|
|
||||||
PLArenaPool *arena = 0;
|
|
||||||
CERTCertificate *c = 0;
|
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
|
||||||
if ( !arena ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
c = (CERTCertificate *) PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
|
|
||||||
|
|
||||||
if (c) {
|
|
||||||
c->referenceCount = 1;
|
|
||||||
c->arena = arena;
|
|
||||||
} else {
|
|
||||||
PORT_FreeArena(arena,PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int verbose=0, force=0;
|
|
||||||
int ascii=0, issuerAscii=0;
|
|
||||||
char *progName=0;
|
|
||||||
PRFileDesc *inFile=0, *issuerCertFile=0;
|
|
||||||
SECItem derCert, derIssuerCert;
|
|
||||||
PLArenaPool *arena=0;
|
|
||||||
CERTSignedData *signedData=0;
|
|
||||||
CERTCertificate *cert=0, *issuerCert=0;
|
|
||||||
SECKEYPublicKey *rsapubkey=0;
|
|
||||||
SECAlgorithmID md5WithRSAEncryption, md2WithRSAEncryption;
|
|
||||||
SECAlgorithmID sha1WithRSAEncryption, rsaEncryption;
|
|
||||||
SECItem spk;
|
|
||||||
int selfSigned=0;
|
|
||||||
int invalid=0;
|
|
||||||
char *inFileName = NULL, *issuerCertFileName = NULL;
|
|
||||||
PLOptState *optstate;
|
|
||||||
PLOptStatus status;
|
|
||||||
SECStatus rv;
|
|
||||||
|
|
||||||
PORT_Memset(&md5WithRSAEncryption, 0, sizeof(md5WithRSAEncryption));
|
|
||||||
PORT_Memset(&md2WithRSAEncryption, 0, sizeof(md2WithRSAEncryption));
|
|
||||||
PORT_Memset(&sha1WithRSAEncryption, 0, sizeof(sha1WithRSAEncryption));
|
|
||||||
PORT_Memset(&rsaEncryption, 0, sizeof(rsaEncryption));
|
|
||||||
|
|
||||||
progName = strrchr(argv[0], '/');
|
|
||||||
progName = progName ? progName+1 : argv[0];
|
|
||||||
|
|
||||||
optstate = PL_CreateOptState(argc, argv, "aAvf");
|
|
||||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
|
||||||
switch (optstate->option) {
|
|
||||||
case 'v':
|
|
||||||
verbose = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
force = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'a':
|
|
||||||
ascii = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'A':
|
|
||||||
issuerAscii = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\0':
|
|
||||||
if (!inFileName)
|
|
||||||
inFileName = PL_strdup(optstate->value);
|
|
||||||
else if (!issuerCertFileName)
|
|
||||||
issuerCertFileName = PL_strdup(optstate->value);
|
|
||||||
else
|
|
||||||
Usage(progName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inFileName || !issuerCertFileName || status == PL_OPT_BAD) {
|
|
||||||
/* insufficient or excess args */
|
|
||||||
Usage(progName);
|
|
||||||
}
|
|
||||||
|
|
||||||
inFile = PR_Open(inFileName, PR_RDONLY, 0);
|
|
||||||
if (!inFile) {
|
|
||||||
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
|
|
||||||
progName, inFileName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
issuerCertFile = PR_Open(issuerCertFileName, PR_RDONLY, 0);
|
|
||||||
if (!issuerCertFile) {
|
|
||||||
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
|
|
||||||
progName, issuerCertFileName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SECU_ReadDERFromFile(&derCert, inFile, ascii, PR_FALSE) != SECSuccess) {
|
|
||||||
printf("Couldn't read input certificate as DER binary or base64\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
|
||||||
if (arena == 0) {
|
|
||||||
fprintf(stderr,"%s: can't allocate scratch arena!", progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (issuerCertFile) {
|
|
||||||
CERTSignedData *issuerCertSD=0;
|
|
||||||
if (SECU_ReadDERFromFile(&derIssuerCert, issuerCertFile, issuerAscii,
|
|
||||||
PR_FALSE) != SECSuccess) {
|
|
||||||
printf("Couldn't read issuer certificate as DER binary or base64.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
issuerCertSD = PORT_ArenaZNew(arena, CERTSignedData);
|
|
||||||
if (!issuerCertSD) {
|
|
||||||
fprintf(stderr,"%s: can't allocate issuer signed data!", progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
rv = SEC_ASN1DecodeItem(arena, issuerCertSD,
|
|
||||||
SEC_ASN1_GET(CERT_SignedDataTemplate),
|
|
||||||
&derIssuerCert);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: Issuer cert isn't X509 SIGNED Data?\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
issuerCert = createEmptyCertificate();
|
|
||||||
if (!issuerCert) {
|
|
||||||
printf("%s: can't allocate space for issuer cert.", progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
rv = SEC_ASN1DecodeItem(arena, issuerCert,
|
|
||||||
SEC_ASN1_GET(CERT_CertificateTemplate),
|
|
||||||
&issuerCertSD->data);
|
|
||||||
if (rv) {
|
|
||||||
printf("%s: Does not appear to be an X509 Certificate.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
signedData = PORT_ArenaZNew(arena,CERTSignedData);
|
|
||||||
if (!signedData) {
|
|
||||||
fprintf(stderr,"%s: can't allocate signedData!", progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SEC_ASN1DecodeItem(arena, signedData,
|
|
||||||
SEC_ASN1_GET(CERT_SignedDataTemplate),
|
|
||||||
&derCert);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: Does not appear to be X509 SIGNED Data.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("Decoded ok as X509 SIGNED data.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
cert = createEmptyCertificate();
|
|
||||||
if (!cert) {
|
|
||||||
fprintf(stderr, "%s: can't allocate cert", progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SEC_ASN1DecodeItem(arena, cert,
|
|
||||||
SEC_ASN1_GET(CERT_CertificateTemplate),
|
|
||||||
&signedData->data);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: Does not appear to be an X509 Certificate.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("Decoded ok as an X509 certificate.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
SECU_RegisterDynamicOids();
|
|
||||||
rv = SECU_PrintSignedData(stdout, &derCert, "Certificate", 0,
|
|
||||||
(SECU_PPFunc)SECU_PrintCertificate);
|
|
||||||
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: Unable to pretty print cert. Error: %d\n",
|
|
||||||
progName, PORT_GetError());
|
|
||||||
if (!force) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Do various checks on the cert */
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
/* Check algorithms */
|
|
||||||
rv = SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption,
|
|
||||||
SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, NULL);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption,
|
|
||||||
SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, NULL);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption,
|
|
||||||
SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, NULL);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SECOID_SetAlgorithmID(arena, &rsaEncryption,
|
|
||||||
SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
|
|
||||||
if (rv) {
|
|
||||||
fprintf(stderr, "%s: failed to set algorithm ID for SEC_OID_PKCS1_RSA_ENCRYPTION.\n",
|
|
||||||
progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
int isMD5RSA = (SECOID_CompareAlgorithmID(&cert->signature,
|
|
||||||
&md5WithRSAEncryption) == 0);
|
|
||||||
int isMD2RSA = (SECOID_CompareAlgorithmID(&cert->signature,
|
|
||||||
&md2WithRSAEncryption) == 0);
|
|
||||||
int isSHA1RSA = (SECOID_CompareAlgorithmID(&cert->signature,
|
|
||||||
&sha1WithRSAEncryption) == 0);
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("\nDoing algorithm checks.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(isMD5RSA || isMD2RSA || isSHA1RSA)) {
|
|
||||||
printf("PROBLEM: Signature not PKCS1 MD5, MD2, or SHA1 + RSA.\n");
|
|
||||||
} else if (!isMD5RSA) {
|
|
||||||
printf("WARNING: Signature not PKCS1 MD5 with RSA Encryption\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SECOID_CompareAlgorithmID(&cert->signature,
|
|
||||||
&signedData->signatureAlgorithm)) {
|
|
||||||
printf("PROBLEM: Algorithm in sig and certInfo don't match.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SECOID_CompareAlgorithmID(&cert->subjectPublicKeyInfo.algorithm,
|
|
||||||
&rsaEncryption)) {
|
|
||||||
printf("PROBLEM: Public key algorithm is not PKCS1 RSA Encryption.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check further public key properties */
|
|
||||||
spk = cert->subjectPublicKeyInfo.subjectPublicKey;
|
|
||||||
DER_ConvertBitString(&spk);
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
printf("\nsubjectPublicKey DER\n");
|
|
||||||
rv = DER_PrettyPrint(stdout, &spk, PR_FALSE);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
rsapubkey = (SECKEYPublicKey *)
|
|
||||||
PORT_ArenaZAlloc(arena,sizeof(SECKEYPublicKey));
|
|
||||||
if (!rsapubkey) {
|
|
||||||
fprintf(stderr, "%s: rsapubkey allocation failed.\n", progName);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = SEC_ASN1DecodeItem(arena, rsapubkey,
|
|
||||||
SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), &spk);
|
|
||||||
if (rv) {
|
|
||||||
printf("PROBLEM: subjectPublicKey is not a DER PKCS1 RSAPublicKey.\n");
|
|
||||||
} else {
|
|
||||||
int mlen;
|
|
||||||
int pubexp;
|
|
||||||
if (verbose) {
|
|
||||||
printf("Decoded RSA Public Key ok. Doing key checks.\n");
|
|
||||||
}
|
|
||||||
PORT_Assert(rsapubkey->keyType == rsaKey); /* XXX RSA */
|
|
||||||
mlen = checkInteger(&rsapubkey->u.rsa.modulus, "Modulus", verbose);
|
|
||||||
printf("INFO: Public Key modulus length in bits: %d\n", mlen);
|
|
||||||
if (mlen > MAX_MODULUS) {
|
|
||||||
printf("PROBLEM: Modulus length exceeds %d bits.\n",
|
|
||||||
MAX_MODULUS);
|
|
||||||
}
|
|
||||||
if (mlen < 512) {
|
|
||||||
printf("WARNING: Short modulus.\n");
|
|
||||||
}
|
|
||||||
if (mlen != (1 << (ffs(mlen)-1))) {
|
|
||||||
printf("WARNING: Unusual modulus length (not a power of two).\n");
|
|
||||||
}
|
|
||||||
checkInteger(&rsapubkey->u.rsa.publicExponent, "Public Exponent",
|
|
||||||
verbose);
|
|
||||||
pubexp = DER_GetInteger(&rsapubkey->u.rsa.publicExponent);
|
|
||||||
if (pubexp != 17 && pubexp != 3 && pubexp != 65537) {
|
|
||||||
printf("WARNING: Public exponent not any of: 3, 17, 65537\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Name checks */
|
|
||||||
checkName(&cert->issuer, "Issuer Name", verbose);
|
|
||||||
checkName(&cert->subject, "Subject Name", verbose);
|
|
||||||
|
|
||||||
if (issuerCert) {
|
|
||||||
SECComparison c =
|
|
||||||
CERT_CompareName(&cert->issuer, &issuerCert->subject);
|
|
||||||
if (c) {
|
|
||||||
printf("PROBLEM: Issuer Name and Subject in Issuing Cert differ\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if self-signed */
|
|
||||||
selfSigned = (CERT_CompareName(&cert->issuer, &cert->subject) == 0);
|
|
||||||
if (selfSigned) {
|
|
||||||
printf("INFO: Certificate is self signed.\n");
|
|
||||||
} else {
|
|
||||||
printf("INFO: Certificate is NOT self-signed.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Validity time check */
|
|
||||||
if (CERT_CertTimesValid(cert) == SECSuccess) {
|
|
||||||
printf("INFO: Inside validity period of certificate.\n");
|
|
||||||
} else {
|
|
||||||
printf("PROBLEM: Not in validity period of certificate.\n");
|
|
||||||
invalid = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Signature check if self-signed */
|
|
||||||
if (selfSigned && !invalid) {
|
|
||||||
if (rsapubkey->u.rsa.modulus.len) {
|
|
||||||
SECStatus ver;
|
|
||||||
if (verbose) {
|
|
||||||
printf("Checking self signature.\n");
|
|
||||||
}
|
|
||||||
ver = OurVerifySignedData(signedData, cert);
|
|
||||||
if (ver != SECSuccess) {
|
|
||||||
printf("PROBLEM: Verification of self-signature failed!\n");
|
|
||||||
} else {
|
|
||||||
printf("INFO: Self-signature verifies ok.\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("INFO: Not checking signature due to key problems.\n");
|
|
||||||
}
|
|
||||||
} else if (!selfSigned && !invalid && issuerCert) {
|
|
||||||
SECStatus ver;
|
|
||||||
ver = OurVerifySignedData(signedData, issuerCert);
|
|
||||||
if (ver != SECSuccess) {
|
|
||||||
printf("PROBLEM: Verification of issuer's signature failed!\n");
|
|
||||||
} else {
|
|
||||||
printf("INFO: Issuer's signature verifies ok.\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("INFO: Not checking signature.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#
|
|
||||||
# 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/.
|
|
||||||
|
|
||||||
CORE_DEPTH = ../..
|
|
||||||
|
|
||||||
# MODULE public and private header directories are implicitly REQUIRED.
|
|
||||||
MODULE = nss
|
|
||||||
|
|
||||||
# This next line is used by .mk files
|
|
||||||
# and gets translated into $LINCS in manifest.mnw
|
|
||||||
REQUIRES = seccmd dbm
|
|
||||||
|
|
||||||
DEFINES = -DNSPR20
|
|
||||||
|
|
||||||
CSRCS = checkcert.c
|
|
||||||
|
|
||||||
PROGRAM = checkcert
|
|
|
@ -5344,9 +5344,9 @@ rsa_siggen_test(char *reqfn)
|
||||||
NSSLOWKEYPublicKey * rsa_public_key;
|
NSSLOWKEYPublicKey * rsa_public_key;
|
||||||
NSSLOWKEYPrivateKey * rsa_private_key;
|
NSSLOWKEYPrivateKey * rsa_private_key;
|
||||||
NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
|
NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
|
||||||
NSSLOWKEYRSAKey, };
|
NSSLOWKEYRSAKey };
|
||||||
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
|
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
|
||||||
NSSLOWKEYRSAKey, };
|
NSSLOWKEYRSAKey };
|
||||||
|
|
||||||
low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
|
low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
|
||||||
low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
|
low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
|
||||||
|
@ -5610,7 +5610,7 @@ rsa_sigver_test(char *reqfn)
|
||||||
SECStatus rv = SECFailure;
|
SECStatus rv = SECFailure;
|
||||||
NSSLOWKEYPublicKey * rsa_public_key;
|
NSSLOWKEYPublicKey * rsa_public_key;
|
||||||
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
|
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
|
||||||
NSSLOWKEYRSAKey, };
|
NSSLOWKEYRSAKey };
|
||||||
|
|
||||||
/* convert to a low RSA public key */
|
/* convert to a low RSA public key */
|
||||||
low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
|
low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
|
||||||
|
|
|
@ -30,6 +30,13 @@ getInteger256(const unsigned char *data, unsigned int nb)
|
||||||
val = (data[0] << 16) | (data[1] << 8) | data[2];
|
val = (data[0] << 16) | (data[1] << 8) | data[2];
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
/* If the most significant bit of data[0] is 1, val would be negative.
|
||||||
|
* Treat it as an error.
|
||||||
|
*/
|
||||||
|
if (data[0] & 0x80) {
|
||||||
|
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -232,6 +239,10 @@ prettyPrintObjectID(FILE *out, const unsigned char *data,
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
val = data[0];
|
val = data[0];
|
||||||
i = val % 40;
|
i = val % 40;
|
||||||
val = val / 40;
|
val = val / 40;
|
||||||
|
@ -282,24 +293,17 @@ prettyPrintObjectID(FILE *out, const unsigned char *data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
rv = prettyNewline(out);
|
||||||
* Finally, on a new line, print the raw bytes (if requested).
|
if (rv < 0)
|
||||||
*/
|
return rv;
|
||||||
if (raw) {
|
|
||||||
rv = prettyNewline(out);
|
|
||||||
if (rv < 0) {
|
|
||||||
PORT_SetError(SEC_ERROR_IO);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
if (raw) {
|
||||||
rv = prettyPrintByte(out, *data++, level);
|
rv = prettyPrintLeaf(out, data, len, level);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return prettyNewline(out);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *prettyTagType [32] = {
|
static char *prettyTagType [32] = {
|
||||||
|
@ -423,6 +427,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
|
||||||
*indefinitep = PR_FALSE;
|
*indefinitep = PR_FALSE;
|
||||||
|
|
||||||
lbyte = *data++;
|
lbyte = *data++;
|
||||||
|
lenLen = 1;
|
||||||
if (lbyte >= 0x80) {
|
if (lbyte >= 0x80) {
|
||||||
/* Multibyte length */
|
/* Multibyte length */
|
||||||
unsigned nb = (unsigned) (lbyte & 0x7f);
|
unsigned nb = (unsigned) (lbyte & 0x7f);
|
||||||
|
@ -444,7 +449,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
|
||||||
*lenp = 0;
|
*lenp = 0;
|
||||||
*indefinitep = PR_TRUE;
|
*indefinitep = PR_TRUE;
|
||||||
}
|
}
|
||||||
lenLen = nb + 1;
|
lenLen += nb;
|
||||||
if (raw) {
|
if (raw) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -459,7 +464,6 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*lenp = lbyte;
|
*lenp = lbyte;
|
||||||
lenLen = 1;
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
rv = prettyPrintByte(out, lbyte, lv);
|
rv = prettyPrintByte(out, lbyte, lv);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
|
|
|
@ -420,6 +420,9 @@ SECU_DefaultSSLDir(void)
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (strlen(dir) >= PR_ARRAY_SIZE(sslDir)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
sprintf(sslDir, "%s", dir);
|
sprintf(sslDir, "%s", dir);
|
||||||
|
|
||||||
if (sslDir[strlen(sslDir)-1] == '/')
|
if (sslDir[strlen(sslDir)-1] == '/')
|
||||||
|
@ -3300,6 +3303,7 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
|
||||||
errstr = "[unknown usage].";
|
errstr = "[unknown usage].";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case SEC_ERROR_INADEQUATE_CERT_TYPE:
|
case SEC_ERROR_INADEQUATE_CERT_TYPE:
|
||||||
flags = (unsigned int)((char *)node->arg - (char *)NULL);
|
flags = (unsigned int)((char *)node->arg - (char *)NULL);
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
|
@ -3326,6 +3330,7 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
|
||||||
errstr = "[unknown usage].";
|
errstr = "[unknown usage].";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case SEC_ERROR_UNKNOWN_ISSUER:
|
case SEC_ERROR_UNKNOWN_ISSUER:
|
||||||
case SEC_ERROR_UNTRUSTED_ISSUER:
|
case SEC_ERROR_UNTRUSTED_ISSUER:
|
||||||
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
|
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
|
||||||
|
|
|
@ -154,7 +154,7 @@ testFunctionRef testFnRefTable[] = {
|
||||||
{"test_mutex3", test_mutex3},
|
{"test_mutex3", test_mutex3},
|
||||||
{"test_object", test_object},
|
{"test_object", test_object},
|
||||||
{"test_oid", test_oid},
|
{"test_oid", test_oid},
|
||||||
/* {"test_rwlock", test_rwlock, }*/
|
/* {"test_rwlock", test_rwlock }*/
|
||||||
{"test_string", test_string},
|
{"test_string", test_string},
|
||||||
{"test_string2", test_string2},
|
{"test_string2", test_string2},
|
||||||
{"build_chain", build_chain},
|
{"build_chain", build_chain},
|
||||||
|
|
|
@ -28,7 +28,7 @@ const SEC_ASN1Template seckey_PQGParamsTemplate[] = {
|
||||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
|
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
|
||||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
|
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
|
||||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
|
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
|
||||||
{ 0, }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,16 +6,36 @@
|
||||||
DEPTH = ..
|
DEPTH = ..
|
||||||
# MODULE = seccmd
|
# MODULE = seccmd
|
||||||
|
|
||||||
REQUIRES = nss nspr libdbm
|
SOFTOKEN_SRCDIRS=
|
||||||
|
NSS_SRCDIRS=
|
||||||
|
LIB_SRCDIRS=
|
||||||
|
|
||||||
DIRS = lib \
|
ifdef NSS_BUILD_UTIL_ONLY
|
||||||
|
REQUIRES = nspr
|
||||||
|
else
|
||||||
|
REQUIRES = nss nspr libdbm
|
||||||
|
LIB_SRCDIRS = \
|
||||||
|
lib \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef NSS_BUILD_UTIL_ONLY
|
||||||
|
SOFTOKEN_SRCDIRS = \
|
||||||
|
$(BLTEST_SRCDIR) \
|
||||||
|
$(FIPSTEST_SRCDIR) \
|
||||||
|
$(LOWHASHTEST_SRCDIR) \
|
||||||
|
$(SHLIBSIGN_SRCDIR) \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifndef NSS_BUILD_SOFTOKEN_ONLY
|
||||||
|
ifndef NSS_BUILD_UTIL_ONLY
|
||||||
|
NSS_SRCDIRS = \
|
||||||
addbuiltin \
|
addbuiltin \
|
||||||
atob \
|
atob \
|
||||||
$(BLTEST_SRCDIR) \
|
|
||||||
btoa \
|
btoa \
|
||||||
certcgi \
|
certcgi \
|
||||||
certutil \
|
certutil \
|
||||||
checkcert \
|
|
||||||
chktest \
|
chktest \
|
||||||
crlutil \
|
crlutil \
|
||||||
crmftest \
|
crmftest \
|
||||||
|
@ -23,8 +43,6 @@ DIRS = lib \
|
||||||
derdump \
|
derdump \
|
||||||
digest \
|
digest \
|
||||||
httpserv \
|
httpserv \
|
||||||
$(FIPSTEST_SRCDIR) \
|
|
||||||
$(LOWHASHTEST_SRCDIR) \
|
|
||||||
listsuites \
|
listsuites \
|
||||||
makepqg \
|
makepqg \
|
||||||
multinit \
|
multinit \
|
||||||
|
@ -47,7 +65,6 @@ DIRS = lib \
|
||||||
selfserv \
|
selfserv \
|
||||||
signtool \
|
signtool \
|
||||||
signver \
|
signver \
|
||||||
$(SHLIBSIGN_SRCDIR) \
|
|
||||||
smimetools \
|
smimetools \
|
||||||
ssltap \
|
ssltap \
|
||||||
strsclnt \
|
strsclnt \
|
||||||
|
@ -58,6 +75,13 @@ DIRS = lib \
|
||||||
vfyserv \
|
vfyserv \
|
||||||
modutil \
|
modutil \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
DIRS = \
|
||||||
|
$(LIB_SRCDIRS) \
|
||||||
|
$(SOFTOKEN_SRCDIRS) \
|
||||||
|
$(NSS_SRCDIRS)
|
||||||
|
|
||||||
TEMPORARILY_DONT_BUILD = \
|
TEMPORARILY_DONT_BUILD = \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -193,8 +193,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
_this->relativePath = PR_Strdup(subval->string);
|
_this->relativePath = PR_Strdup(subval->string);
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
subiter = NULL;
|
|
||||||
|
|
||||||
/* Absolute directory */
|
/* Absolute directory */
|
||||||
} else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
|
} else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
|
||||||
|
@ -206,8 +205,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
_this->absolutePath = PR_Strdup(subval->string);
|
_this->absolutePath = PR_Strdup(subval->string);
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
subiter = NULL;
|
|
||||||
|
|
||||||
/* file permissions */
|
/* file permissions */
|
||||||
} else if( !PORT_Strcasecmp(subpair->key,
|
} else if( !PORT_Strcasecmp(subpair->key,
|
||||||
|
@ -227,8 +225,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
gotPerms = PR_TRUE;
|
gotPerms = PR_TRUE;
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
subiter = NULL;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
|
if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
|
||||||
|
@ -260,12 +257,10 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
if(iter) {
|
if(iter) {
|
||||||
Pk11Install_ListIter_delete(iter);
|
Pk11Install_ListIter_delete(&iter);
|
||||||
PR_Free(iter);
|
|
||||||
}
|
}
|
||||||
if(subiter) {
|
if(subiter) {
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
}
|
}
|
||||||
return errStr;
|
return errStr;
|
||||||
}
|
}
|
||||||
|
@ -636,12 +631,15 @@ Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this)
|
||||||
void
|
void
|
||||||
Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad)
|
Pk11Install_PlatformName_Print(Pk11Install_PlatformName* _this, int pad)
|
||||||
{
|
{
|
||||||
|
char *str = NULL;
|
||||||
PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>");
|
PAD(pad); printf("OS: %s\n", _this->OS ? _this->OS : "<NULL>");
|
||||||
PAD(pad); printf("Digits: ");
|
PAD(pad); printf("Digits: ");
|
||||||
if(_this->numDigits == 0) {
|
if(_this->numDigits == 0) {
|
||||||
printf("None\n");
|
printf("None\n");
|
||||||
} else {
|
} else {
|
||||||
printf("%s\n", Pk11Install_PlatformName_GetVerString(_this));
|
str = Pk11Install_PlatformName_GetVerString(_this);
|
||||||
|
printf("%s\n", str);
|
||||||
|
PR_Free(str);
|
||||||
}
|
}
|
||||||
PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>");
|
PAD(pad); printf("arch: %s\n", _this->arch ? _this->arch : "<NULL>");
|
||||||
}
|
}
|
||||||
|
@ -770,9 +768,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
_this->moduleFile = PR_Strdup(subval->string);
|
_this->moduleFile = PR_Strdup(subval->string);
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter = NULL;
|
|
||||||
gotModuleFile = PR_TRUE;
|
gotModuleFile = PR_TRUE;
|
||||||
} else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
|
} else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
|
||||||
if(gotModuleName) {
|
if(gotModuleName) {
|
||||||
|
@ -788,9 +784,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
_this->moduleName = PR_Strdup(subval->string);
|
_this->moduleName = PR_Strdup(subval->string);
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter = NULL;
|
|
||||||
gotModuleName = PR_TRUE;
|
gotModuleName = PR_TRUE;
|
||||||
} else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
|
} else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
|
||||||
endptr=NULL;
|
endptr=NULL;
|
||||||
|
@ -813,9 +807,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
||||||
Pk11Install_PlatformName_GetString(&_this->name));
|
Pk11Install_PlatformName_GetString(&_this->name));
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter=NULL;
|
|
||||||
gotMech = PR_TRUE;
|
gotMech = PR_TRUE;
|
||||||
} else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
|
} else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
|
||||||
endptr=NULL;
|
endptr=NULL;
|
||||||
|
@ -838,9 +830,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
||||||
Pk11Install_PlatformName_GetString(&_this->name));
|
Pk11Install_PlatformName_GetString(&_this->name));
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter=NULL;
|
|
||||||
gotCipher = PR_TRUE;
|
gotCipher = PR_TRUE;
|
||||||
} else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
|
} else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
|
||||||
if(gotFiles) {
|
if(gotFiles) {
|
||||||
|
@ -1089,9 +1079,7 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter = NULL;
|
|
||||||
} else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
|
} else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
|
||||||
subiter = Pk11Install_ListIter_new(pair->list);
|
subiter = Pk11Install_ListIter_new(pair->list);
|
||||||
_this->numPlatforms = pair->list->numPairs;
|
_this->numPlatforms = pair->list->numPairs;
|
||||||
|
@ -1109,9 +1097,7 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1192,14 +1178,10 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
if(iter) {
|
if(iter) {
|
||||||
Pk11Install_ListIter_delete(iter);
|
Pk11Install_ListIter_delete(&iter);
|
||||||
PR_Free(iter);
|
|
||||||
iter = NULL;
|
|
||||||
}
|
}
|
||||||
if(subiter) {
|
if(subiter) {
|
||||||
Pk11Install_ListIter_delete(subiter);
|
Pk11Install_ListIter_delete(&subiter);
|
||||||
PR_Free(subiter);
|
|
||||||
subiter = NULL;
|
|
||||||
}
|
}
|
||||||
return errStr;
|
return errStr;
|
||||||
}
|
}
|
||||||
|
@ -1348,10 +1330,12 @@ Pk11Install_ListIter_new(const Pk11Install_ValueList *_list)
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
void
|
void
|
||||||
Pk11Install_ListIter_delete(Pk11Install_ListIter* _this)
|
Pk11Install_ListIter_delete(Pk11Install_ListIter** _this)
|
||||||
{
|
{
|
||||||
_this->list=NULL;
|
(*_this)->list=NULL;
|
||||||
_this->current=NULL;
|
(*_this)->current=NULL;
|
||||||
|
PR_Free(*_this);
|
||||||
|
*_this=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
|
@ -124,7 +124,7 @@ Pk11Install_ListIter_init(Pk11Install_ListIter* _this);
|
||||||
Pk11Install_ListIter*
|
Pk11Install_ListIter*
|
||||||
Pk11Install_ListIter_new(const Pk11Install_ValueList* _list);
|
Pk11Install_ListIter_new(const Pk11Install_ValueList* _list);
|
||||||
void
|
void
|
||||||
Pk11Install_ListIter_delete(Pk11Install_ListIter* _this);
|
Pk11Install_ListIter_delete(Pk11Install_ListIter** _this);
|
||||||
void
|
void
|
||||||
Pk11Install_ListIter_reset(Pk11Install_ListIter* _this);
|
Pk11Install_ListIter_reset(Pk11Install_ListIter* _this);
|
||||||
Pk11Install_Value*
|
Pk11Install_Value*
|
||||||
|
|
|
@ -44,8 +44,8 @@ SEC_ASN1Template CERTSignatureDataTemplate[] =
|
||||||
offsetof(CERTSignedData,signatureAlgorithm),
|
offsetof(CERTSignedData,signatureAlgorithm),
|
||||||
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
|
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
|
||||||
{ SEC_ASN1_BIT_STRING,
|
{ SEC_ASN1_BIT_STRING,
|
||||||
offsetof(CERTSignedData,signature), },
|
offsetof(CERTSignedData,signature) },
|
||||||
{ 0, }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ EXTRA_SHARED_LIBS += \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef NSS_BUILD_SOFTOKEN_ONLY
|
||||||
PKIXLIB = \
|
PKIXLIB = \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \
|
||||||
|
@ -64,35 +65,100 @@ PKIXLIB = \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX)
|
$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX)
|
||||||
|
endif
|
||||||
|
|
||||||
# can't do this in manifest.mn because OS_ARCH isn't defined there.
|
NSS_LIBS_1=
|
||||||
|
SECTOOL_LIB=
|
||||||
|
NSS_LIBS_2=
|
||||||
|
NSS_LIBS_3=
|
||||||
|
NSS_LIBS_4=
|
||||||
|
|
||||||
|
ifneq ($(NSS_BUILD_UTIL_ONLY),1)
|
||||||
|
SECTOOL_LIB = \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
|
||||||
|
$(NULL)
|
||||||
|
else
|
||||||
|
SECTOOL_LIB = \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
|
||||||
ifeq ($(OS_ARCH), WINNT)
|
ifeq ($(OS_ARCH), WINNT)
|
||||||
|
# breakdown for windows
|
||||||
EXTRA_LIBS += \
|
NSS_LIBS_1 = \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
|
$(NULL)
|
||||||
|
NSS_LIBS_2 = \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
|
||||||
$(SOFTOKENLIB) \
|
$(NULL)
|
||||||
$(CRYPTOLIB) \
|
NSS_LIBS_3 = \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
|
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
|
||||||
$(PKIXLIB) \
|
$(PKIXLIB) \
|
||||||
$(DBMLIB) \
|
$(DBMLIB) \
|
||||||
|
$(NULL)
|
||||||
|
NSS_LIBS_4 = \
|
||||||
$(SQLITE_LIB_DIR)/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(LIB_SUFFIX) \
|
$(SQLITE_LIB_DIR)/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(LIB_SUFFIX) \
|
||||||
$(NSSUTIL_LIB_DIR)/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \
|
$(NSSUTIL_LIB_DIR)/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \
|
||||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
|
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
|
||||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
|
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
|
||||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
|
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
else
|
||||||
|
# breakdown for others
|
||||||
|
NSS_LIBS_1 = \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
||||||
|
$(NULL)
|
||||||
|
SECTOOL_LIB = \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
|
||||||
|
$(NULL)
|
||||||
|
NSS_LIBS_2 = \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
||||||
|
$(NULL)
|
||||||
|
NSS_LIBS_3 = \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
|
||||||
|
$(NULL)
|
||||||
|
NSS_LIBS_4 = \
|
||||||
|
$(DBMLIB) \
|
||||||
|
$(PKIXLIB) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
||||||
|
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# can't do this in manifest.mn because OS_ARCH isn't defined there.
|
||||||
|
ifeq ($(OS_ARCH), WINNT)
|
||||||
|
|
||||||
|
EXTRA_LIBS += \
|
||||||
|
$(NSS_LIBS_1) \
|
||||||
|
$(SECTOOL_LIB) \
|
||||||
|
$(NSS_LIBS_2) \
|
||||||
|
$(SOFTOKENLIB) \
|
||||||
|
$(CRYPTOLIB) \
|
||||||
|
$(NSS_LIBS_3) \
|
||||||
|
$(NSS_LIBS_4) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
|
# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
|
||||||
#OS_LIBS += \
|
#OS_LIBS += \
|
||||||
|
@ -102,30 +168,13 @@ EXTRA_LIBS += \
|
||||||
else
|
else
|
||||||
|
|
||||||
EXTRA_LIBS += \
|
EXTRA_LIBS += \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
|
$(NSS_LIBS_1) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
$(SECTOOL_LIB) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
$(NSS_LIBS_2) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)sectool.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkcs12.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pkcs7.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)cryptohi.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
|
||||||
$(SOFTOKENLIB) \
|
$(SOFTOKENLIB) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
|
$(NSS_LIBS_3) \
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
|
|
||||||
$(CRYPTOLIB) \
|
$(CRYPTOLIB) \
|
||||||
$(DBMLIB) \
|
$(NSS_LIBS_4) \
|
||||||
$(PKIXLIB) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
|
||||||
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifeq ($(OS_ARCH), AIX)
|
ifeq ($(OS_ARCH), AIX)
|
||||||
|
|
|
@ -225,6 +225,7 @@ PrintParameterUsage()
|
||||||
"-W override default DHE server weak parameters support, 0: disable, 1: enable\n"
|
"-W override default DHE server weak parameters support, 0: disable, 1: enable\n"
|
||||||
"-c Restrict ciphers\n"
|
"-c Restrict ciphers\n"
|
||||||
"-Y prints cipher values allowed for parameter -c and exits\n"
|
"-Y prints cipher values allowed for parameter -c and exits\n"
|
||||||
|
"-G enables the extended master secret extension [RFC7627]\n"
|
||||||
, stderr);
|
, stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,7 @@ void printSecurityInfo(PRFileDesc *fd)
|
||||||
{
|
{
|
||||||
CERTCertificate * cert;
|
CERTCertificate * cert;
|
||||||
const SECItemArray *csa;
|
const SECItemArray *csa;
|
||||||
|
const SECItem *scts;
|
||||||
SSL3Statistics * ssl3stats = SSL_GetStatistics();
|
SSL3Statistics * ssl3stats = SSL_GetStatistics();
|
||||||
SECStatus result;
|
SECStatus result;
|
||||||
SSLChannelInfo channel;
|
SSLChannelInfo channel;
|
||||||
|
@ -162,6 +163,11 @@ void printSecurityInfo(PRFileDesc *fd)
|
||||||
fprintf(stderr, "Received %d Cert Status items (OCSP stapled data)\n",
|
fprintf(stderr, "Received %d Cert Status items (OCSP stapled data)\n",
|
||||||
csa->len);
|
csa->len);
|
||||||
}
|
}
|
||||||
|
scts = SSL_PeerSignedCertTimestamps(fd);
|
||||||
|
if (scts && scts->len) {
|
||||||
|
fprintf(stderr, "Received a Signed Certificate Timestamp of length"
|
||||||
|
" %u\n", scts->len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -184,7 +190,7 @@ static void PrintUsageHeader(const char *progName)
|
||||||
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
|
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
|
||||||
"[-D | -d certdir] [-C] [-b | -R root-module] \n"
|
"[-D | -d certdir] [-C] [-b | -R root-module] \n"
|
||||||
"[-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n"
|
"[-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n"
|
||||||
"[-V [min-version]:[max-version]] [-K] [-T]\n"
|
"[-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
|
||||||
"[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n",
|
"[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n",
|
||||||
progName);
|
progName);
|
||||||
}
|
}
|
||||||
|
@ -232,6 +238,7 @@ static void PrintParameterUsage(void)
|
||||||
fprintf(stderr, "%-20s Enable compression.\n", "-z");
|
fprintf(stderr, "%-20s Enable compression.\n", "-z");
|
||||||
fprintf(stderr, "%-20s Enable false start.\n", "-g");
|
fprintf(stderr, "%-20s Enable false start.\n", "-g");
|
||||||
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
|
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
|
||||||
|
fprintf(stderr, "%-20s Enable the signed_certificate_timestamp extension.\n", "-U");
|
||||||
fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
|
fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
|
||||||
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
|
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
|
||||||
"%-20s -F once means: require for server cert only\n"
|
"%-20s -F once means: require for server cert only\n"
|
||||||
|
@ -250,6 +257,7 @@ static void PrintParameterUsage(void)
|
||||||
fprintf(stderr, "%-20s Enforce using an IPv4 destination address\n", "-4");
|
fprintf(stderr, "%-20s Enforce using an IPv4 destination address\n", "-4");
|
||||||
fprintf(stderr, "%-20s Enforce using an IPv6 destination address\n", "-6");
|
fprintf(stderr, "%-20s Enforce using an IPv6 destination address\n", "-6");
|
||||||
fprintf(stderr, "%-20s (Options -4 and -6 cannot be combined.)\n", "");
|
fprintf(stderr, "%-20s (Options -4 and -6 cannot be combined.)\n", "");
|
||||||
|
fprintf(stderr, "%-20s Enable the extended master secret extension [RFC7627]\n", "-G");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Usage(const char *progName)
|
static void Usage(const char *progName)
|
||||||
|
@ -920,6 +928,7 @@ int main(int argc, char **argv)
|
||||||
int enableCompression = 0;
|
int enableCompression = 0;
|
||||||
int enableFalseStart = 0;
|
int enableFalseStart = 0;
|
||||||
int enableCertStatus = 0;
|
int enableCertStatus = 0;
|
||||||
|
int enableSignedCertTimestamps = 0;
|
||||||
int forceFallbackSCSV = 0;
|
int forceFallbackSCSV = 0;
|
||||||
int enableExtendedMasterSecret = 0;
|
int enableExtendedMasterSecret = 0;
|
||||||
PRSocketOptionData opt;
|
PRSocketOptionData opt;
|
||||||
|
@ -970,7 +979,7 @@ int main(int argc, char **argv)
|
||||||
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
|
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
|
||||||
|
|
||||||
optstate = PL_CreateOptState(argc, argv,
|
optstate = PL_CreateOptState(argc, argv,
|
||||||
"46BCDFGKM:OR:STV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
|
"46BCDFGKM:OR:STUV:W:Ya:bc:d:fgh:m:n:op:qr:st:uvw:xz");
|
||||||
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||||
switch (optstate->option) {
|
switch (optstate->option) {
|
||||||
case '?':
|
case '?':
|
||||||
|
@ -1023,6 +1032,8 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
case 'T': enableCertStatus = 1; break;
|
case 'T': enableCertStatus = 1; break;
|
||||||
|
|
||||||
|
case 'U': enableSignedCertTimestamps = 1; break;
|
||||||
|
|
||||||
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
|
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
|
||||||
enabledVersions, enableSSL2,
|
enabledVersions, enableSSL2,
|
||||||
&enabledVersions, &enableSSL2) != SECSuccess) {
|
&enabledVersions, &enableSSL2) != SECSuccess) {
|
||||||
|
@ -1400,6 +1411,14 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* enable Signed Certificate Timestamps. */
|
||||||
|
rv = SSL_OptionSet(s, SSL_ENABLE_SIGNED_CERT_TIMESTAMPS,
|
||||||
|
enableSignedCertTimestamps);
|
||||||
|
if (rv != SECSuccess) {
|
||||||
|
SECU_PrintError(progName, "error enabling signed cert timestamps");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
SSL_SetPKCS11PinArg(s, &pwdata);
|
SSL_SetPKCS11PinArg(s, &pwdata);
|
||||||
|
|
||||||
serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
|
serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
|
||||||
|
|
|
@ -104,7 +104,7 @@ endif
|
||||||
DLL_SUFFIX = dll
|
DLL_SUFFIX = dll
|
||||||
|
|
||||||
ifdef NS_USE_GCC
|
ifdef NS_USE_GCC
|
||||||
OS_CFLAGS += -mwindows -mms-bitfields -Werror
|
OS_CFLAGS += -mwindows -mms-bitfields
|
||||||
_GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
|
_GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
|
||||||
DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
|
DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
|
||||||
ifdef BUILD_OPT
|
ifdef BUILD_OPT
|
||||||
|
|
|
@ -21,7 +21,7 @@ ifndef WARNING_CFLAGS
|
||||||
# and fixing this would require rearchitecture
|
# and fixing this would require rearchitecture
|
||||||
WARNING_CFLAGS += -Qunused-arguments
|
WARNING_CFLAGS += -Qunused-arguments
|
||||||
# -Wno-parentheses-equality : because clang warns about macro expansions
|
# -Wno-parentheses-equality : because clang warns about macro expansions
|
||||||
OS_CFLAGS += $(call disable_warning,parentheses-equality)
|
WARNING_CFLAGS += $(call disable_warning,parentheses-equality)
|
||||||
ifdef BUILD_OPT
|
ifdef BUILD_OPT
|
||||||
# clang is unable to handle glib's expansion of strcmp and similar for optimized
|
# clang is unable to handle glib's expansion of strcmp and similar for optimized
|
||||||
# builds, so ignore the resulting errors.
|
# builds, so ignore the resulting errors.
|
||||||
|
|
|
@ -10,3 +10,4 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#error "Do not include this header file."
|
#error "Do not include this header file."
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ GTest-based Unit Tests
|
||||||
|
|
||||||
This directory contains GTest-based unit tests for NSS libssl.
|
This directory contains GTest-based unit tests for NSS libssl.
|
||||||
|
|
||||||
These aren't built by default, because they require C++.
|
If your environment doesn't have C++ compiler suitable to build these tests,
|
||||||
To build them, set ``NSS_BUILD_GTESTS=1''
|
you may disable them using ``NSS_DISABLE_GTESTS=1''
|
||||||
|
|
||||||
Once built, they are run as part of running ``test/all.sh''
|
Once built, they are run as part of running ``test/all.sh''
|
||||||
You can run just the GTests by running ``tests/ssl_gtests/ssl_gtests.sh''
|
You can run just the GTests by running ``tests/ssl_gtests/ssl_gtests.sh''
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#! gmake
|
||||||
|
#
|
||||||
|
# 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 ../../cmd/platlibs.mk
|
||||||
|
include ../../cmd/platrules.mk
|
||||||
|
|
||||||
|
MKPROG = $(CCC)
|
||||||
|
MKSHLIB = $(CCC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
|
||||||
|
|
||||||
|
ifeq (WINNT,$(OS_ARCH))
|
||||||
|
# -EHsc because gtest has exception handlers
|
||||||
|
OS_CFLAGS += -EHsc -nologo
|
||||||
|
# http://www.suodenjoki.dk/us/archive/2010/min-max.htm
|
||||||
|
OS_CFLAGS += -DNOMINMAX
|
||||||
|
|
||||||
|
# Linking to winsock to get htonl
|
||||||
|
OS_LIBS += Ws2_32.lib
|
||||||
|
|
||||||
|
# On windows, we need to create the parent directory
|
||||||
|
# Needed because we include files from a subdirectory
|
||||||
|
MAKE_OBJDIR = $(INSTALL) -D $(dir $@)
|
||||||
|
else
|
||||||
|
CXXFLAGS += -std=c++0x
|
||||||
|
endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
/* -*- 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/. */
|
||||||
|
|
||||||
|
#ifndef scoped_ptrs_h__
|
||||||
|
#define scoped_ptrs_h__
|
||||||
|
|
||||||
|
#include "keyhi.h"
|
||||||
|
|
||||||
|
namespace nss_test {
|
||||||
|
|
||||||
|
struct ScopedDelete {
|
||||||
|
void operator()(PK11SlotInfo* slot) { PK11_FreeSlot(slot); }
|
||||||
|
void operator()(SECItem* item) { SECITEM_FreeItem(item, true); }
|
||||||
|
void operator()(PK11SymKey* key) { PK11_FreeSymKey(key); }
|
||||||
|
void operator()(SECKEYPublicKey* key) { SECKEY_DestroyPublicKey(key); }
|
||||||
|
void operator()(SECKEYPrivateKey* key) { SECKEY_DestroyPrivateKey(key); }
|
||||||
|
void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); }
|
||||||
|
void operator()(CERTSubjectPublicKeyInfo* spki) {
|
||||||
|
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct ScopedMaybeDelete {
|
||||||
|
void operator()(T* ptr) { if (ptr) { ScopedDelete del; del(ptr); } }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped ## x
|
||||||
|
|
||||||
|
SCOPED(PK11SlotInfo);
|
||||||
|
SCOPED(SECItem);
|
||||||
|
SCOPED(PK11SymKey);
|
||||||
|
SCOPED(SECKEYPublicKey);
|
||||||
|
SCOPED(SECKEYPrivateKey);
|
||||||
|
SCOPED(SECAlgorithmID);
|
||||||
|
SCOPED(CERTSubjectPublicKeyInfo);
|
||||||
|
|
||||||
|
#undef SCOPED
|
||||||
|
|
||||||
|
} // namespace nss_test
|
||||||
|
|
||||||
|
#endif
|
|
@ -26,6 +26,7 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
include ../common/gtest.mk
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (5) Execute "global" rules. (OPTIONAL) #
|
# (5) Execute "global" rules. (OPTIONAL) #
|
||||||
|
@ -41,12 +42,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (7) Execute "local" rules. (OPTIONAL). #
|
# (7) Execute "local" rules. (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
MKSHLIB = $(CCC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS)
|
|
||||||
ifeq (WINNT,$(OS_ARCH))
|
|
||||||
# -EHsc because gtest has exception handlers
|
|
||||||
OS_CFLAGS += -EHsc
|
|
||||||
# On windows, we need to create the parent directory
|
|
||||||
# Needed because we include files from a subdirectory
|
|
||||||
MAKE_OBJDIR = $(INSTALL) -D $(dir $@)
|
|
||||||
endif
|
|
||||||
|
|
|
@ -7,5 +7,6 @@ DEPTH = ..
|
||||||
|
|
||||||
DIRS = \
|
DIRS = \
|
||||||
google_test \
|
google_test \
|
||||||
|
pk11_gtest \
|
||||||
ssl_gtest \
|
ssl_gtest \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#! gmake
|
#! gmake
|
||||||
#
|
#
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# 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
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
@ -20,11 +20,12 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
include ../platlibs.mk
|
include ../common/gtest.mk
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (5) Execute "global" rules. (OPTIONAL) #
|
# (5) Execute "global" rules. (OPTIONAL) #
|
||||||
|
@ -37,12 +38,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (7) Execute "local" rules. (OPTIONAL). #
|
# (7) Execute "local" rules. (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
include ../platrules.mk
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#
|
||||||
|
# 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/.
|
||||||
|
CORE_DEPTH = ../..
|
||||||
|
DEPTH = ../..
|
||||||
|
MODULE = nss
|
||||||
|
|
||||||
|
CPPSRCS = \
|
||||||
|
pk11_pbkdf2_unittest.cc \
|
||||||
|
pk11_prf_unittest.cc \
|
||||||
|
pk11_rsapss_unittest.cc \
|
||||||
|
pk11_gtest.cc \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
INCLUDES += -I$(CORE_DEPTH)/external_tests/google_test/gtest/include \
|
||||||
|
-I$(CORE_DEPTH)/external_tests/common
|
||||||
|
|
||||||
|
REQUIRES = nspr nss libdbm gtest
|
||||||
|
|
||||||
|
PROGRAM = pk11_gtest
|
||||||
|
EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX)
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "nspr.h"
|
||||||
|
#include "nss.h"
|
||||||
|
#include "ssl.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#define GTEST_HAS_RTTI 0
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
// Start the tests
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
|
||||||
|
NSS_NoDB_Init(nullptr);
|
||||||
|
NSS_SetDomesticPolicy();
|
||||||
|
int rv = RUN_ALL_TESTS();
|
||||||
|
|
||||||
|
NSS_Shutdown();
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nss.h"
|
||||||
|
#include "pk11pub.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "scoped_ptrs.h"
|
||||||
|
|
||||||
|
namespace nss_test {
|
||||||
|
|
||||||
|
static unsigned char* ToUcharPtr(std::string& str) {
|
||||||
|
return const_cast<unsigned char*>(
|
||||||
|
reinterpret_cast<const unsigned char*>(str.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pkcs11Pbkdf2Test : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
void Derive(std::vector<uint8_t>& derived, SECOidTag hash_alg)
|
||||||
|
{
|
||||||
|
// Shared between test vectors.
|
||||||
|
const unsigned int iterations = 4096;
|
||||||
|
std::string pass("passwordPASSWORDpassword");
|
||||||
|
std::string salt("saltSALTsaltSALTsaltSALTsaltSALTsalt");
|
||||||
|
|
||||||
|
// Derivation must succeed with the right values.
|
||||||
|
EXPECT_TRUE(DeriveBytes(pass, salt, derived, hash_alg, iterations));
|
||||||
|
|
||||||
|
// Derivation must fail when the password is bogus.
|
||||||
|
std::string bogusPass("PasswordPASSWORDpassword");
|
||||||
|
EXPECT_FALSE(DeriveBytes(bogusPass, salt, derived, hash_alg, iterations));
|
||||||
|
|
||||||
|
// Derivation must fail when the salt is bogus.
|
||||||
|
std::string bogusSalt("SaltSALTsaltSALTsaltSALTsaltSALTsalt");
|
||||||
|
EXPECT_FALSE(DeriveBytes(pass, bogusSalt, derived, hash_alg, iterations));
|
||||||
|
|
||||||
|
// Derivation must fail when using the wrong hash function.
|
||||||
|
SECOidTag next_hash_alg = static_cast<SECOidTag>(hash_alg + 1);
|
||||||
|
EXPECT_FALSE(DeriveBytes(pass, salt, derived, next_hash_alg, iterations));
|
||||||
|
|
||||||
|
// Derivation must fail when using the wrong number of iterations.
|
||||||
|
EXPECT_FALSE(DeriveBytes(pass, salt, derived, hash_alg, iterations + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool DeriveBytes(std::string& pass, std::string& salt,
|
||||||
|
std::vector<uint8_t>& derived, SECOidTag hash_alg,
|
||||||
|
unsigned int iterations)
|
||||||
|
{
|
||||||
|
SECItem passItem = { siBuffer, ToUcharPtr(pass),
|
||||||
|
static_cast<unsigned int>(pass.length()) };
|
||||||
|
SECItem saltItem = { siBuffer, ToUcharPtr(salt),
|
||||||
|
static_cast<unsigned int>(salt.length()) };
|
||||||
|
|
||||||
|
// Set up PBKDF2 params.
|
||||||
|
ScopedSECAlgorithmID alg_id(
|
||||||
|
PK11_CreatePBEV2AlgorithmID(SEC_OID_PKCS5_PBKDF2, hash_alg, hash_alg,
|
||||||
|
derived.size(), iterations, &saltItem));
|
||||||
|
|
||||||
|
// Derive.
|
||||||
|
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||||
|
ScopedPK11SymKey symKey(
|
||||||
|
PK11_PBEKeyGen(slot.get(), alg_id.get(), &passItem, false, nullptr));
|
||||||
|
|
||||||
|
SECStatus rv = PK11_ExtractKeyValue(symKey.get());
|
||||||
|
EXPECT_EQ(rv, SECSuccess);
|
||||||
|
|
||||||
|
SECItem* keyData = PK11_GetKeyData(symKey.get());
|
||||||
|
return !memcmp(&derived[0], keyData->data, keyData->len);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// RFC 6070 <http://tools.ietf.org/html/rfc6070>
|
||||||
|
TEST_F(Pkcs11Pbkdf2Test, DeriveKnown1) {
|
||||||
|
std::vector<uint8_t> derived = {
|
||||||
|
0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, 0x80, 0xc8, 0xd8, 0x36,
|
||||||
|
0x62, 0xc0, 0xe4, 0x4a, 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, 0x38
|
||||||
|
};
|
||||||
|
|
||||||
|
Derive(derived, SEC_OID_HMAC_SHA1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors
|
||||||
|
TEST_F(Pkcs11Pbkdf2Test, DeriveKnown2) {
|
||||||
|
std::vector<uint8_t> derived = {
|
||||||
|
0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 0x32, 0xd8, 0x14, 0xb8,
|
||||||
|
0x11, 0x6e, 0x84, 0xcf, 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18,
|
||||||
|
0x1c, 0x4e, 0x2a, 0x1f, 0xb8, 0xdd, 0x53, 0xe1, 0xc6, 0x35, 0x51, 0x8c,
|
||||||
|
0x7d, 0xac, 0x47, 0xe9
|
||||||
|
};
|
||||||
|
|
||||||
|
Derive(derived, SEC_OID_HMAC_SHA256);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nss_test
|
||||||
|
|
|
@ -8,13 +8,10 @@
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "gtest_utils.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
namespace nss_test {
|
namespace nss_test {
|
||||||
|
|
||||||
#define CONST_UINT8_TO_UCHAR(a) const_cast<unsigned char*>( \
|
|
||||||
static_cast<const unsigned char *>(a))
|
|
||||||
|
|
||||||
const size_t kPmsSize = 48;
|
const size_t kPmsSize = 48;
|
||||||
const size_t kMasterSecretSize = 48;
|
const size_t kMasterSecretSize = 48;
|
||||||
const size_t kPrfSeedSizeSha256 = 32;
|
const size_t kPrfSeedSizeSha256 = 32;
|
||||||
|
@ -143,7 +140,7 @@ class TlsPrfTest : public ::testing::Test {
|
||||||
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS master_params = {
|
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS master_params = {
|
||||||
hash_mech,
|
hash_mech,
|
||||||
toUcharPtr(kPrfSeed),
|
toUcharPtr(kPrfSeed),
|
||||||
seed_len,
|
static_cast<CK_ULONG>(seed_len),
|
||||||
version
|
version
|
||||||
};
|
};
|
||||||
params_.data = reinterpret_cast<unsigned char*>(&master_params);
|
params_.data = reinterpret_cast<unsigned char*>(&master_params);
|
|
@ -0,0 +1,246 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nss.h"
|
||||||
|
#include "pk11pub.h"
|
||||||
|
#include "sechash.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "scoped_ptrs.h"
|
||||||
|
|
||||||
|
namespace nss_test {
|
||||||
|
|
||||||
|
// RSA-PSS test vectors, pss-vect.txt, Example 1: A 1024-bit RSA Key Pair
|
||||||
|
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
|
||||||
|
const uint8_t kTestVector1Spki[] = {
|
||||||
|
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||||
|
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02,
|
||||||
|
0x81, 0x81, 0x00, 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17, 0x58, 0x9a, 0x51,
|
||||||
|
0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec, 0x0e, 0x36, 0xad, 0x52,
|
||||||
|
0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9, 0x91, 0xd8, 0xc5, 0x10, 0x56,
|
||||||
|
0xff, 0xed, 0xb1, 0x62, 0xb4, 0xc0, 0xf2, 0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94,
|
||||||
|
0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91, 0xcb, 0xb3, 0x07, 0xce, 0xab, 0xfc, 0xe0,
|
||||||
|
0xb1, 0xdf, 0xd5, 0xcd, 0x95, 0x08, 0x09, 0x6d, 0x5b, 0x2b, 0x8b, 0x6d, 0xf5,
|
||||||
|
0xd6, 0x71, 0xef, 0x63, 0x77, 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70,
|
||||||
|
0xe2, 0x59, 0x8e, 0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3, 0xf0,
|
||||||
|
0xcb, 0x35, 0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f, 0x64, 0xc4, 0xef, 0x22,
|
||||||
|
0xe1, 0xe1, 0xf2, 0x0d, 0x0c, 0xe8, 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21,
|
||||||
|
0x37, 0x02, 0x03, 0x01, 0x00, 0x01
|
||||||
|
};
|
||||||
|
// RSA-PSS test vectors, pss-vect.txt, Example 1.1
|
||||||
|
const uint8_t kTestVector1Data[] = {
|
||||||
|
0xcd, 0xc8, 0x7d, 0xa2, 0x23, 0xd7, 0x86, 0xdf, 0x3b, 0x45, 0xe0, 0xbb, 0xbc,
|
||||||
|
0x72, 0x13, 0x26, 0xd1, 0xee, 0x2a, 0xf8, 0x06, 0xcc, 0x31, 0x54, 0x75, 0xcc,
|
||||||
|
0x6f, 0x0d, 0x9c, 0x66, 0xe1, 0xb6, 0x23, 0x71, 0xd4, 0x5c, 0xe2, 0x39, 0x2e,
|
||||||
|
0x1a, 0xc9, 0x28, 0x44, 0xc3, 0x10, 0x10, 0x2f, 0x15, 0x6a, 0x0d, 0x8d, 0x52,
|
||||||
|
0xc1, 0xf4, 0xc4, 0x0b, 0xa3, 0xaa, 0x65, 0x09, 0x57, 0x86, 0xcb, 0x76, 0x97,
|
||||||
|
0x57, 0xa6, 0x56, 0x3b, 0xa9, 0x58, 0xfe, 0xd0, 0xbc, 0xc9, 0x84, 0xe8, 0xb5,
|
||||||
|
0x17, 0xa3, 0xd5, 0xf5, 0x15, 0xb2, 0x3b, 0x8a, 0x41, 0xe7, 0x4a, 0xa8, 0x67,
|
||||||
|
0x69, 0x3f, 0x90, 0xdf, 0xb0, 0x61, 0xa6, 0xe8, 0x6d, 0xfa, 0xae, 0xe6, 0x44,
|
||||||
|
0x72, 0xc0, 0x0e, 0x5f, 0x20, 0x94, 0x57, 0x29, 0xcb, 0xeb, 0xe7, 0x7f, 0x06,
|
||||||
|
0xce, 0x78, 0xe0, 0x8f, 0x40, 0x98, 0xfb, 0xa4, 0x1f, 0x9d, 0x61, 0x93, 0xc0,
|
||||||
|
0x31, 0x7e, 0x8b, 0x60, 0xd4, 0xb6, 0x08, 0x4a, 0xcb, 0x42, 0xd2, 0x9e, 0x38,
|
||||||
|
0x08, 0xa3, 0xbc, 0x37, 0x2d, 0x85, 0xe3, 0x31, 0x17, 0x0f, 0xcb, 0xf7, 0xcc,
|
||||||
|
0x72, 0xd0, 0xb7, 0x1c, 0x29, 0x66, 0x48, 0xb3, 0xa4, 0xd1, 0x0f, 0x41, 0x62,
|
||||||
|
0x95, 0xd0, 0x80, 0x7a, 0xa6, 0x25, 0xca, 0xb2, 0x74, 0x4f, 0xd9, 0xea, 0x8f,
|
||||||
|
0xd2, 0x23, 0xc4, 0x25, 0x37, 0x02, 0x98, 0x28, 0xbd, 0x16, 0xbe, 0x02, 0x54,
|
||||||
|
0x6f, 0x13, 0x0f, 0xd2, 0xe3, 0x3b, 0x93, 0x6d, 0x26, 0x76, 0xe0, 0x8a, 0xed,
|
||||||
|
0x1b, 0x73, 0x31, 0x8b, 0x75, 0x0a, 0x01, 0x67, 0xd0
|
||||||
|
};
|
||||||
|
const uint8_t kTestVector1Sig[] = {
|
||||||
|
0x90, 0x74, 0x30, 0x8f, 0xb5, 0x98, 0xe9, 0x70, 0x1b, 0x22, 0x94, 0x38, 0x8e,
|
||||||
|
0x52, 0xf9, 0x71, 0xfa, 0xac, 0x2b, 0x60, 0xa5, 0x14, 0x5a, 0xf1, 0x85, 0xdf,
|
||||||
|
0x52, 0x87, 0xb5, 0xed, 0x28, 0x87, 0xe5, 0x7c, 0xe7, 0xfd, 0x44, 0xdc, 0x86,
|
||||||
|
0x34, 0xe4, 0x07, 0xc8, 0xe0, 0xe4, 0x36, 0x0b, 0xc2, 0x26, 0xf3, 0xec, 0x22,
|
||||||
|
0x7f, 0x9d, 0x9e, 0x54, 0x63, 0x8e, 0x8d, 0x31, 0xf5, 0x05, 0x12, 0x15, 0xdf,
|
||||||
|
0x6e, 0xbb, 0x9c, 0x2f, 0x95, 0x79, 0xaa, 0x77, 0x59, 0x8a, 0x38, 0xf9, 0x14,
|
||||||
|
0xb5, 0xb9, 0xc1, 0xbd, 0x83, 0xc4, 0xe2, 0xf9, 0xf3, 0x82, 0xa0, 0xd0, 0xaa,
|
||||||
|
0x35, 0x42, 0xff, 0xee, 0x65, 0x98, 0x4a, 0x60, 0x1b, 0xc6, 0x9e, 0xb2, 0x8d,
|
||||||
|
0xeb, 0x27, 0xdc, 0xa1, 0x2c, 0x82, 0xc2, 0xd4, 0xc3, 0xf6, 0x6c, 0xd5, 0x00,
|
||||||
|
0xf1, 0xff, 0x2b, 0x99, 0x4d, 0x8a, 0x4e, 0x30, 0xcb, 0xb3, 0x3c
|
||||||
|
};
|
||||||
|
|
||||||
|
// RSA-PSS test vectors, pss-vect.txt, Example 10: A 2048-bit RSA Key Pair
|
||||||
|
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
|
||||||
|
const uint8_t kTestVector2Spki[] = {
|
||||||
|
0x30, 0x82, 0x01, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||||
|
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0e, 0x00, 0x30, 0x82,
|
||||||
|
0x01, 0x09, 0x02, 0x82, 0x01, 0x00, 0xa5, 0xdd, 0x86, 0x7a, 0xc4, 0xcb, 0x02,
|
||||||
|
0xf9, 0x0b, 0x94, 0x57, 0xd4, 0x8c, 0x14, 0xa7, 0x70, 0xef, 0x99, 0x1c, 0x56,
|
||||||
|
0xc3, 0x9c, 0x0e, 0xc6, 0x5f, 0xd1, 0x1a, 0xfa, 0x89, 0x37, 0xce, 0xa5, 0x7b,
|
||||||
|
0x9b, 0xe7, 0xac, 0x73, 0xb4, 0x5c, 0x00, 0x17, 0x61, 0x5b, 0x82, 0xd6, 0x22,
|
||||||
|
0xe3, 0x18, 0x75, 0x3b, 0x60, 0x27, 0xc0, 0xfd, 0x15, 0x7b, 0xe1, 0x2f, 0x80,
|
||||||
|
0x90, 0xfe, 0xe2, 0xa7, 0xad, 0xcd, 0x0e, 0xef, 0x75, 0x9f, 0x88, 0xba, 0x49,
|
||||||
|
0x97, 0xc7, 0xa4, 0x2d, 0x58, 0xc9, 0xaa, 0x12, 0xcb, 0x99, 0xae, 0x00, 0x1f,
|
||||||
|
0xe5, 0x21, 0xc1, 0x3b, 0xb5, 0x43, 0x14, 0x45, 0xa8, 0xd5, 0xae, 0x4f, 0x5e,
|
||||||
|
0x4c, 0x7e, 0x94, 0x8a, 0xc2, 0x27, 0xd3, 0x60, 0x40, 0x71, 0xf2, 0x0e, 0x57,
|
||||||
|
0x7e, 0x90, 0x5f, 0xbe, 0xb1, 0x5d, 0xfa, 0xf0, 0x6d, 0x1d, 0xe5, 0xae, 0x62,
|
||||||
|
0x53, 0xd6, 0x3a, 0x6a, 0x21, 0x20, 0xb3, 0x1a, 0x5d, 0xa5, 0xda, 0xbc, 0x95,
|
||||||
|
0x50, 0x60, 0x0e, 0x20, 0xf2, 0x7d, 0x37, 0x39, 0xe2, 0x62, 0x79, 0x25, 0xfe,
|
||||||
|
0xa3, 0xcc, 0x50, 0x9f, 0x21, 0xdf, 0xf0, 0x4e, 0x6e, 0xea, 0x45, 0x49, 0xc5,
|
||||||
|
0x40, 0xd6, 0x80, 0x9f, 0xf9, 0x30, 0x7e, 0xed, 0xe9, 0x1f, 0xff, 0x58, 0x73,
|
||||||
|
0x3d, 0x83, 0x85, 0xa2, 0x37, 0xd6, 0xd3, 0x70, 0x5a, 0x33, 0xe3, 0x91, 0x90,
|
||||||
|
0x09, 0x92, 0x07, 0x0d, 0xf7, 0xad, 0xf1, 0x35, 0x7c, 0xf7, 0xe3, 0x70, 0x0c,
|
||||||
|
0xe3, 0x66, 0x7d, 0xe8, 0x3f, 0x17, 0xb8, 0xdf, 0x17, 0x78, 0xdb, 0x38, 0x1d,
|
||||||
|
0xce, 0x09, 0xcb, 0x4a, 0xd0, 0x58, 0xa5, 0x11, 0x00, 0x1a, 0x73, 0x81, 0x98,
|
||||||
|
0xee, 0x27, 0xcf, 0x55, 0xa1, 0x3b, 0x75, 0x45, 0x39, 0x90, 0x65, 0x82, 0xec,
|
||||||
|
0x8b, 0x17, 0x4b, 0xd5, 0x8d, 0x5d, 0x1f, 0x3d, 0x76, 0x7c, 0x61, 0x37, 0x21,
|
||||||
|
0xae, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01
|
||||||
|
};
|
||||||
|
// RSA-PSS test vectors, pss-vect.txt, Example 10.1
|
||||||
|
const uint8_t kTestVector2Data[] = {
|
||||||
|
0x88, 0x31, 0x77, 0xe5, 0x12, 0x6b, 0x9b, 0xe2, 0xd9, 0xa9, 0x68, 0x03, 0x27,
|
||||||
|
0xd5, 0x37, 0x0c, 0x6f, 0x26, 0x86, 0x1f, 0x58, 0x20, 0xc4, 0x3d, 0xa6, 0x7a,
|
||||||
|
0x3a, 0xd6, 0x09
|
||||||
|
};
|
||||||
|
const uint8_t kTestVector2Sig[] = {
|
||||||
|
0x82, 0xc2, 0xb1, 0x60, 0x09, 0x3b, 0x8a, 0xa3, 0xc0, 0xf7, 0x52, 0x2b, 0x19,
|
||||||
|
0xf8, 0x73, 0x54, 0x06, 0x6c, 0x77, 0x84, 0x7a, 0xbf, 0x2a, 0x9f, 0xce, 0x54,
|
||||||
|
0x2d, 0x0e, 0x84, 0xe9, 0x20, 0xc5, 0xaf, 0xb4, 0x9f, 0xfd, 0xfd, 0xac, 0xe1,
|
||||||
|
0x65, 0x60, 0xee, 0x94, 0xa1, 0x36, 0x96, 0x01, 0x14, 0x8e, 0xba, 0xd7, 0xa0,
|
||||||
|
0xe1, 0x51, 0xcf, 0x16, 0x33, 0x17, 0x91, 0xa5, 0x72, 0x7d, 0x05, 0xf2, 0x1e,
|
||||||
|
0x74, 0xe7, 0xeb, 0x81, 0x14, 0x40, 0x20, 0x69, 0x35, 0xd7, 0x44, 0x76, 0x5a,
|
||||||
|
0x15, 0xe7, 0x9f, 0x01, 0x5c, 0xb6, 0x6c, 0x53, 0x2c, 0x87, 0xa6, 0xa0, 0x59,
|
||||||
|
0x61, 0xc8, 0xbf, 0xad, 0x74, 0x1a, 0x9a, 0x66, 0x57, 0x02, 0x28, 0x94, 0x39,
|
||||||
|
0x3e, 0x72, 0x23, 0x73, 0x97, 0x96, 0xc0, 0x2a, 0x77, 0x45, 0x5d, 0x0f, 0x55,
|
||||||
|
0x5b, 0x0e, 0xc0, 0x1d, 0xdf, 0x25, 0x9b, 0x62, 0x07, 0xfd, 0x0f, 0xd5, 0x76,
|
||||||
|
0x14, 0xce, 0xf1, 0xa5, 0x57, 0x3b, 0xaa, 0xff, 0x4e, 0xc0, 0x00, 0x69, 0x95,
|
||||||
|
0x16, 0x59, 0xb8, 0x5f, 0x24, 0x30, 0x0a, 0x25, 0x16, 0x0c, 0xa8, 0x52, 0x2d,
|
||||||
|
0xc6, 0xe6, 0x72, 0x7e, 0x57, 0xd0, 0x19, 0xd7, 0xe6, 0x36, 0x29, 0xb8, 0xfe,
|
||||||
|
0x5e, 0x89, 0xe2, 0x5c, 0xc1, 0x5b, 0xeb, 0x3a, 0x64, 0x75, 0x77, 0x55, 0x92,
|
||||||
|
0x99, 0x28, 0x0b, 0x9b, 0x28, 0xf7, 0x9b, 0x04, 0x09, 0x00, 0x0b, 0xe2, 0x5b,
|
||||||
|
0xbd, 0x96, 0x40, 0x8b, 0xa3, 0xb4, 0x3c, 0xc4, 0x86, 0x18, 0x4d, 0xd1, 0xc8,
|
||||||
|
0xe6, 0x25, 0x53, 0xfa, 0x1a, 0xf4, 0x04, 0x0f, 0x60, 0x66, 0x3d, 0xe7, 0xf5,
|
||||||
|
0xe4, 0x9c, 0x04, 0x38, 0x8e, 0x25, 0x7f, 0x1c, 0xe8, 0x9c, 0x95, 0xda, 0xb4,
|
||||||
|
0x8a, 0x31, 0x5d, 0x9b, 0x66, 0xb1, 0xb7, 0x62, 0x82, 0x33, 0x87, 0x6f, 0xf2,
|
||||||
|
0x38, 0x52, 0x30, 0xd0, 0x70, 0xd0, 0x7e, 0x16, 0x66
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char* toUcharPtr(const uint8_t* v) {
|
||||||
|
return const_cast<unsigned char*>(
|
||||||
|
static_cast<const unsigned char*>(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pkcs11RsaPssTest : public ::testing::Test {
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pkcs11RsaPssVectorTest : public Pkcs11RsaPssTest {
|
||||||
|
public:
|
||||||
|
void Verify(const uint8_t* spki, size_t spki_len, const uint8_t* data,
|
||||||
|
size_t data_len, const uint8_t* sig, size_t sig_len) {
|
||||||
|
// Verify data signed with PSS/SHA-1.
|
||||||
|
SECOidTag hashOid = SEC_OID_SHA1;
|
||||||
|
CK_MECHANISM_TYPE hashMech = CKM_SHA_1;
|
||||||
|
CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA1;
|
||||||
|
|
||||||
|
// Set up PSS parameters.
|
||||||
|
unsigned int hLen = HASH_ResultLenByOidTag(hashOid);
|
||||||
|
CK_RSA_PKCS_PSS_PARAMS rsaPssParams = { hashMech, mgf, hLen };
|
||||||
|
SECItem params = { siBuffer,
|
||||||
|
reinterpret_cast<unsigned char*>(&rsaPssParams),
|
||||||
|
sizeof(rsaPssParams) };
|
||||||
|
|
||||||
|
// Import public key.
|
||||||
|
SECItem spkiItem = { siBuffer, toUcharPtr(spki),
|
||||||
|
static_cast<unsigned int>(spki_len) };
|
||||||
|
ScopedCERTSubjectPublicKeyInfo certSpki(
|
||||||
|
SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem));
|
||||||
|
ScopedSECKEYPublicKey pubKey(SECKEY_ExtractPublicKey(certSpki.get()));
|
||||||
|
|
||||||
|
// Hash the data.
|
||||||
|
std::vector<uint8_t> hashBuf(hLen);
|
||||||
|
SECItem hash = { siBuffer, &hashBuf[0],
|
||||||
|
static_cast<unsigned int>(hashBuf.size()) };
|
||||||
|
SECStatus rv = PK11_HashBuf(hashOid, hash.data, toUcharPtr(data),
|
||||||
|
data_len);
|
||||||
|
EXPECT_EQ(rv, SECSuccess);
|
||||||
|
|
||||||
|
// Verify.
|
||||||
|
CK_MECHANISM_TYPE mech = CKM_RSA_PKCS_PSS;
|
||||||
|
SECItem sigItem = { siBuffer, toUcharPtr(sig),
|
||||||
|
static_cast<unsigned int>(sig_len) };
|
||||||
|
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, ¶ms, &sigItem, &hash,
|
||||||
|
nullptr);
|
||||||
|
EXPECT_EQ(rv, SECSuccess);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PSS_TEST_VECTOR_VERIFY(spki, data, sig) \
|
||||||
|
Verify(spki, sizeof(spki), data, sizeof(data), sig, sizeof(sig));
|
||||||
|
|
||||||
|
TEST_F(Pkcs11RsaPssTest, GenerateAndSignAndVerify) {
|
||||||
|
// Sign data with a 1024-bit RSA key, using PSS/SHA-256.
|
||||||
|
SECOidTag hashOid = SEC_OID_SHA256;
|
||||||
|
CK_MECHANISM_TYPE hashMech = CKM_SHA256;
|
||||||
|
CK_RSA_PKCS_MGF_TYPE mgf = CKG_MGF1_SHA256;
|
||||||
|
PK11RSAGenParams rsaGenParams = { 1024, 0x10001 };
|
||||||
|
|
||||||
|
// Generate RSA key pair.
|
||||||
|
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||||
|
SECKEYPublicKey* pubKeyRaw = nullptr;
|
||||||
|
ScopedSECKEYPrivateKey privKey(PK11_GenerateKeyPair(slot.get(),
|
||||||
|
CKM_RSA_PKCS_KEY_PAIR_GEN,
|
||||||
|
&rsaGenParams, &pubKeyRaw,
|
||||||
|
false, false, nullptr));
|
||||||
|
ASSERT_TRUE(!!privKey && pubKeyRaw);
|
||||||
|
ScopedSECKEYPublicKey pubKey(pubKeyRaw);
|
||||||
|
|
||||||
|
// Generate random data to sign.
|
||||||
|
uint8_t dataBuf[50];
|
||||||
|
SECItem data = { siBuffer, dataBuf, sizeof(dataBuf) };
|
||||||
|
unsigned int hLen = HASH_ResultLenByOidTag(hashOid);
|
||||||
|
SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), data.data, data.len);
|
||||||
|
EXPECT_EQ(rv, SECSuccess);
|
||||||
|
|
||||||
|
// Allocate memory for the signature.
|
||||||
|
std::vector<uint8_t> sigBuf(PK11_SignatureLen(privKey.get()));
|
||||||
|
SECItem sig = { siBuffer, &sigBuf[0],
|
||||||
|
static_cast<unsigned int>(sigBuf.size()) };
|
||||||
|
|
||||||
|
// Set up PSS parameters.
|
||||||
|
CK_RSA_PKCS_PSS_PARAMS rsaPssParams = { hashMech, mgf, hLen };
|
||||||
|
SECItem params = { siBuffer, reinterpret_cast<unsigned char*>(&rsaPssParams),
|
||||||
|
sizeof(rsaPssParams) };
|
||||||
|
|
||||||
|
// Sign.
|
||||||
|
CK_MECHANISM_TYPE mech = CKM_RSA_PKCS_PSS;
|
||||||
|
rv = PK11_SignWithMechanism(privKey.get(), mech, ¶ms, &sig, &data);
|
||||||
|
EXPECT_EQ(rv, SECSuccess);
|
||||||
|
|
||||||
|
// Verify.
|
||||||
|
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, ¶ms, &sig, &data,
|
||||||
|
nullptr);
|
||||||
|
EXPECT_EQ(rv, SECSuccess);
|
||||||
|
|
||||||
|
// Verification with modified data must fail.
|
||||||
|
data.data[0] ^= 0xff;
|
||||||
|
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, ¶ms, &sig, &data,
|
||||||
|
nullptr);
|
||||||
|
EXPECT_EQ(rv, SECFailure);
|
||||||
|
|
||||||
|
// Verification with original data but the wrong signature must fail.
|
||||||
|
data.data[0] ^= 0xff; // Revert previous changes.
|
||||||
|
sig.data[0] ^= 0xff;
|
||||||
|
rv = PK11_VerifyWithMechanism(pubKey.get(), mech, ¶ms, &sig, &data,
|
||||||
|
nullptr);
|
||||||
|
EXPECT_EQ(rv, SECFailure);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RSA-PSS test vectors, pss-vect.txt, Example 1.1: A 1024-bit RSA Key Pair
|
||||||
|
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
|
||||||
|
TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature1) {
|
||||||
|
PSS_TEST_VECTOR_VERIFY(kTestVector1Spki, kTestVector1Data, kTestVector1Sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
// RSA-PSS test vectors, pss-vect.txt, Example 10.1: A 2048-bit RSA Key Pair
|
||||||
|
// <ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip>
|
||||||
|
TEST_F(Pkcs11RsaPssVectorTest, VerifyKnownSignature2) {
|
||||||
|
PSS_TEST_VECTOR_VERIFY(kTestVector2Spki, kTestVector2Data, kTestVector2Sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace nss_test
|
||||||
|
|
|
@ -25,7 +25,7 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
include ../../cmd/platlibs.mk
|
include ../common/gtest.mk
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (5) Execute "global" rules. (OPTIONAL) #
|
# (5) Execute "global" rules. (OPTIONAL) #
|
||||||
|
@ -42,19 +42,4 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
||||||
# (7) Execute "local" rules. (OPTIONAL). #
|
# (7) Execute "local" rules. (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
MKPROG = $(CCC)
|
|
||||||
CFLAGS += -I$(CORE_DEPTH)/lib/ssl
|
CFLAGS += -I$(CORE_DEPTH)/lib/ssl
|
||||||
|
|
||||||
include ../../cmd/platrules.mk
|
|
||||||
|
|
||||||
ifeq (WINNT,$(OS_ARCH))
|
|
||||||
# -EHsc because gtest has exception handlers
|
|
||||||
OS_CFLAGS += -EHsc -nologo
|
|
||||||
# http://www.suodenjoki.dk/us/archive/2010/min-max.htm
|
|
||||||
OS_CFLAGS += -DNOMINMAX
|
|
||||||
|
|
||||||
# Linking to winsock to get htonl
|
|
||||||
OS_LIBS += Ws2_32.lib
|
|
||||||
else
|
|
||||||
CXXFLAGS += -std=c++0x
|
|
||||||
endif
|
|
||||||
|
|
|
@ -51,9 +51,16 @@ class DataBuffer {
|
||||||
void Assign(const DataBuffer& other) {
|
void Assign(const DataBuffer& other) {
|
||||||
Assign(other.data(), other.len());
|
Assign(other.data(), other.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assign(const uint8_t* data, size_t len) {
|
void Assign(const uint8_t* data, size_t len) {
|
||||||
Allocate(len);
|
if (data) {
|
||||||
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len);
|
Allocate(len);
|
||||||
|
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len);
|
||||||
|
} else {
|
||||||
|
assert(len == 0);
|
||||||
|
data_ = nullptr;
|
||||||
|
len_ = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write will do a new allocation and expand the size of the buffer if needed.
|
// Write will do a new allocation and expand the size of the buffer if needed.
|
||||||
|
@ -166,6 +173,15 @@ inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) {
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const DataBuffer& a, const DataBuffer& b) {
|
||||||
|
return (a.empty() && b.empty()) ||
|
||||||
|
(a.len() == b.len() && 0 == memcmp(a.data(), b.data(), a.len()));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const DataBuffer& a, const DataBuffer& b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace nss_test
|
} // namespace nss_test
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,7 +15,6 @@ CPPSRCS = \
|
||||||
ssl_agent_unittest.cc \
|
ssl_agent_unittest.cc \
|
||||||
ssl_loopback_unittest.cc \
|
ssl_loopback_unittest.cc \
|
||||||
ssl_extension_unittest.cc \
|
ssl_extension_unittest.cc \
|
||||||
ssl_prf_unittest.cc \
|
|
||||||
ssl_skip_unittest.cc \
|
ssl_skip_unittest.cc \
|
||||||
ssl_gtest.cc \
|
ssl_gtest.cc \
|
||||||
test_io.cc \
|
test_io.cc \
|
||||||
|
|
|
@ -609,6 +609,110 @@ TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmConfiguration) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests for Certificate Transparency (RFC 6962)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Helper class - stores signed certificate timestamps as provided
|
||||||
|
// by the relevant callbacks on the client.
|
||||||
|
class SignedCertificateTimestampsExtractor {
|
||||||
|
public:
|
||||||
|
SignedCertificateTimestampsExtractor(TlsAgent& client) {
|
||||||
|
client.SetAuthCertificateCallback(
|
||||||
|
[&](TlsAgent& agent, PRBool checksig, PRBool isServer) {
|
||||||
|
const SECItem *scts = SSL_PeerSignedCertTimestamps(agent.ssl_fd());
|
||||||
|
ASSERT_TRUE(scts);
|
||||||
|
auth_timestamps_.reset(new DataBuffer(scts->data, scts->len));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
client.SetHandshakeCallback(
|
||||||
|
[&](TlsAgent& agent) {
|
||||||
|
const SECItem *scts = SSL_PeerSignedCertTimestamps(agent.ssl_fd());
|
||||||
|
ASSERT_TRUE(scts);
|
||||||
|
handshake_timestamps_.reset(new DataBuffer(scts->data, scts->len));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertTimestamps(const DataBuffer& timestamps) {
|
||||||
|
ASSERT_TRUE(auth_timestamps_);
|
||||||
|
ASSERT_EQ(timestamps, *auth_timestamps_);
|
||||||
|
|
||||||
|
ASSERT_TRUE(handshake_timestamps_);
|
||||||
|
ASSERT_EQ(timestamps, *handshake_timestamps_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<DataBuffer> auth_timestamps_;
|
||||||
|
std::unique_ptr<DataBuffer> handshake_timestamps_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test timestamps extraction during a successful handshake.
|
||||||
|
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsHandshake) {
|
||||||
|
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
|
||||||
|
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
|
||||||
|
const DataBuffer timestamps(val, sizeof(val));
|
||||||
|
|
||||||
|
server_->StartConnect();
|
||||||
|
ASSERT_EQ(SECSuccess,
|
||||||
|
SSL_SetSignedCertTimestamps(server_->ssl_fd(),
|
||||||
|
&si_timestamps, server_->kea()));
|
||||||
|
|
||||||
|
client_->StartConnect();
|
||||||
|
ASSERT_EQ(SECSuccess,
|
||||||
|
SSL_OptionSet(client_->ssl_fd(),
|
||||||
|
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE));
|
||||||
|
|
||||||
|
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
|
||||||
|
Handshake();
|
||||||
|
CheckConnected();
|
||||||
|
timestamps_extractor.assertTimestamps(timestamps);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test SSL_PeerSignedCertTimestamps returning zero-length SECItem
|
||||||
|
// when the client / the server / both have not enabled the feature.
|
||||||
|
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveClient) {
|
||||||
|
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
|
||||||
|
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
|
||||||
|
|
||||||
|
server_->StartConnect();
|
||||||
|
ASSERT_EQ(SECSuccess,
|
||||||
|
SSL_SetSignedCertTimestamps(server_->ssl_fd(),
|
||||||
|
&si_timestamps, server_->kea()));
|
||||||
|
|
||||||
|
client_->StartConnect();
|
||||||
|
|
||||||
|
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
|
||||||
|
Handshake();
|
||||||
|
CheckConnected();
|
||||||
|
timestamps_extractor.assertTimestamps(DataBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveServer) {
|
||||||
|
server_->StartConnect();
|
||||||
|
|
||||||
|
client_->StartConnect();
|
||||||
|
ASSERT_EQ(SECSuccess,
|
||||||
|
SSL_OptionSet(client_->ssl_fd(),
|
||||||
|
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, PR_TRUE));
|
||||||
|
|
||||||
|
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
|
||||||
|
Handshake();
|
||||||
|
CheckConnected();
|
||||||
|
timestamps_extractor.assertTimestamps(DataBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveBoth) {
|
||||||
|
server_->StartConnect();
|
||||||
|
client_->StartConnect();
|
||||||
|
|
||||||
|
SignedCertificateTimestampsExtractor timestamps_extractor(*client_);
|
||||||
|
Handshake();
|
||||||
|
CheckConnected();
|
||||||
|
timestamps_extractor.assertTimestamps(DataBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(ExtensionTls10, TlsExtensionTestGeneric,
|
INSTANTIATE_TEST_CASE_P(ExtensionTls10, TlsExtensionTestGeneric,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
TlsConnectTestBase::kTlsModesStream,
|
TlsConnectTestBase::kTlsModesStream,
|
||||||
|
|
|
@ -40,7 +40,9 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode, SSLKEAType kea
|
||||||
error_code_(0),
|
error_code_(0),
|
||||||
send_ctr_(0),
|
send_ctr_(0),
|
||||||
recv_ctr_(0),
|
recv_ctr_(0),
|
||||||
expected_read_error_(false) {
|
expected_read_error_(false),
|
||||||
|
handshake_callback_(),
|
||||||
|
auth_certificate_callback_() {
|
||||||
|
|
||||||
memset(&info_, 0, sizeof(info_));
|
memset(&info_, 0, sizeof(info_));
|
||||||
memset(&csinfo_, 0, sizeof(csinfo_));
|
memset(&csinfo_, 0, sizeof(csinfo_));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "test_io.h"
|
#include "test_io.h"
|
||||||
|
|
||||||
|
@ -28,6 +29,16 @@ enum SessionResumptionMode {
|
||||||
RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET
|
RESUME_BOTH = RESUME_SESSIONID | RESUME_TICKET
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TlsAgent;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
std::function<void(TlsAgent& agent, PRBool checksig, PRBool isServer)>
|
||||||
|
AuthCertificateCallbackFunction;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
std::function<void(TlsAgent& agent)>
|
||||||
|
HandshakeCallbackFunction;
|
||||||
|
|
||||||
class TlsAgent : public PollTarget {
|
class TlsAgent : public PollTarget {
|
||||||
public:
|
public:
|
||||||
enum Role { CLIENT, SERVER };
|
enum Role { CLIENT, SERVER };
|
||||||
|
@ -94,8 +105,12 @@ class TlsAgent : public PollTarget {
|
||||||
void CheckExtendedMasterSecret(bool expected);
|
void CheckExtendedMasterSecret(bool expected);
|
||||||
void DisableRollbackDetection();
|
void DisableRollbackDetection();
|
||||||
|
|
||||||
|
Role role() const { return role_; }
|
||||||
|
|
||||||
State state() const { return state_; }
|
State state() const { return state_; }
|
||||||
|
|
||||||
|
SSLKEAType kea() const { return kea_; }
|
||||||
|
|
||||||
const char* state_str() const { return state_str(state()); }
|
const char* state_str() const { return state_str(state()); }
|
||||||
|
|
||||||
const char* state_str(State state) const { return states[state]; }
|
const char* state_str(State state) const { return states[state]; }
|
||||||
|
@ -131,6 +146,15 @@ class TlsAgent : public PollTarget {
|
||||||
size_t received_bytes() const { return recv_ctr_; }
|
size_t received_bytes() const { return recv_ctr_; }
|
||||||
int32_t error_code() const { return error_code_; }
|
int32_t error_code() const { return error_code_; }
|
||||||
|
|
||||||
|
void SetHandshakeCallback(HandshakeCallbackFunction handshake_callback) {
|
||||||
|
handshake_callback_ = handshake_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetAuthCertificateCallback(
|
||||||
|
AuthCertificateCallbackFunction auth_certificate_callback) {
|
||||||
|
auth_certificate_callback_ = auth_certificate_callback;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const static char* states[];
|
const static char* states[];
|
||||||
|
|
||||||
|
@ -148,6 +172,9 @@ class TlsAgent : public PollTarget {
|
||||||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||||
agent->CheckPreliminaryInfo();
|
agent->CheckPreliminaryInfo();
|
||||||
agent->auth_certificate_hook_called_ = true;
|
agent->auth_certificate_hook_called_ = true;
|
||||||
|
if (agent->auth_certificate_callback_) {
|
||||||
|
agent->auth_certificate_callback_(*agent, checksig, isServer);
|
||||||
|
}
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +184,9 @@ class TlsAgent : public PollTarget {
|
||||||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||||
EXPECT_TRUE(agent->expect_client_auth_);
|
EXPECT_TRUE(agent->expect_client_auth_);
|
||||||
EXPECT_TRUE(isServer);
|
EXPECT_TRUE(isServer);
|
||||||
|
if (agent->auth_certificate_callback_) {
|
||||||
|
agent->auth_certificate_callback_(*agent, checksig, isServer);
|
||||||
|
}
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +238,9 @@ class TlsAgent : public PollTarget {
|
||||||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||||
agent->CheckPreliminaryInfo();
|
agent->CheckPreliminaryInfo();
|
||||||
agent->handshake_callback_called_ = true;
|
agent->handshake_callback_called_ = true;
|
||||||
|
if (agent->handshake_callback_) {
|
||||||
|
agent->handshake_callback_(*agent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckCallbacks() const;
|
void CheckCallbacks() const;
|
||||||
|
@ -237,6 +270,8 @@ class TlsAgent : public PollTarget {
|
||||||
size_t send_ctr_;
|
size_t send_ctr_;
|
||||||
size_t recv_ctr_;
|
size_t recv_ctr_;
|
||||||
bool expected_read_error_;
|
bool expected_read_error_;
|
||||||
|
HandshakeCallbackFunction handshake_callback_;
|
||||||
|
AuthCertificateCallbackFunction auth_certificate_callback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TlsAgentTestBase : public ::testing::Test {
|
class TlsAgentTestBase : public ::testing::Test {
|
||||||
|
|
|
@ -46,6 +46,10 @@ ifndef NSS_DISABLE_DBM
|
||||||
DBM_SRCDIR = dbm # Add the dbm directory to DIRS.
|
DBM_SRCDIR = dbm # Add the dbm directory to DIRS.
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(NSS_BUILD_UTIL_ONLY),1)
|
||||||
|
SYSINIT_SRCDIR=
|
||||||
|
endif
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# (5) Execute "global" rules. (OPTIONAL) #
|
# (5) Execute "global" rules. (OPTIONAL) #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
@ -62,14 +66,28 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
||||||
# (7) Execute "local" rules. (OPTIONAL). #
|
# (7) Execute "local" rules. (OPTIONAL). #
|
||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
|
ifeq ($(NSS_BUILD_UTIL_ONLY),1)
|
||||||
# Not included when building nss without softoken
|
UTIL_SRCDIR = util
|
||||||
UTIL_SRCDIR =
|
FREEBL_SRCDIR =
|
||||||
FREEBL_SRCDIR =
|
SOFTOKEN_SRCDIR =
|
||||||
SOFTOKEN_SRCDIR =
|
|
||||||
else
|
else
|
||||||
# default is to include all
|
ifeq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
|
||||||
UTIL_SRCDIR = util
|
UTIL_SRCDIR =
|
||||||
FREEBL_SRCDIR = freebl
|
FREEBL_SRCDIR = freebl
|
||||||
SOFTOKEN_SRCDIR = softoken
|
SOFTOKEN_SRCDIR = softoken
|
||||||
|
else
|
||||||
|
ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
|
||||||
|
# Not included when building nss without softoken
|
||||||
|
# This build type uses the build results of the prior
|
||||||
|
# NSS_BUILD_UTIL_ONLY and NSS_BUILD_SOFTOKEN_ONLY builds
|
||||||
|
UTIL_SRCDIR =
|
||||||
|
FREEBL_SRCDIR =
|
||||||
|
SOFTOKEN_SRCDIR =
|
||||||
|
else
|
||||||
|
# default is to include all
|
||||||
|
UTIL_SRCDIR = util
|
||||||
|
FREEBL_SRCDIR = freebl
|
||||||
|
SOFTOKEN_SRCDIR = softoken
|
||||||
|
endif
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -32,7 +32,7 @@ typedef struct nssArenaMarkStr nssArenaMark;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/*
|
/*
|
||||||
* ARENA_THREADMARK
|
* ARENA_THREADMARK
|
||||||
*
|
*
|
||||||
* Optionally, this arena implementation can be compiled with some
|
* Optionally, this arena implementation can be compiled with some
|
||||||
* runtime checking enabled, which will catch the situation where
|
* runtime checking enabled, which will catch the situation where
|
||||||
* one thread "marks" the arena, another thread allocates memory,
|
* one thread "marks" the arena, another thread allocates memory,
|
||||||
|
@ -68,14 +68,13 @@ typedef struct nssArenaMarkStr nssArenaMark;
|
||||||
|
|
||||||
typedef struct nssListStr nssList;
|
typedef struct nssListStr nssList;
|
||||||
typedef struct nssListIteratorStr nssListIterator;
|
typedef struct nssListIteratorStr nssListIterator;
|
||||||
typedef PRBool (* nssListCompareFunc)(void *a, void *b);
|
typedef PRBool (*nssListCompareFunc)(void *a, void *b);
|
||||||
typedef PRIntn (* nssListSortFunc)(void *a, void *b);
|
typedef PRIntn (*nssListSortFunc)(void *a, void *b);
|
||||||
typedef void (* nssListElementDestructorFunc)(void *el);
|
typedef void (*nssListElementDestructorFunc)(void *el);
|
||||||
|
|
||||||
typedef struct nssHashStr nssHash;
|
typedef struct nssHashStr nssHash;
|
||||||
typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
|
typedef void(PR_CALLBACK *nssHashIterator)(const void *key, void *value,
|
||||||
void *value,
|
void *arg);
|
||||||
void *arg);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nssPointerTracker
|
* nssPointerTracker
|
||||||
|
@ -89,9 +88,9 @@ typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
struct nssPointerTrackerStr {
|
struct nssPointerTrackerStr {
|
||||||
PRCallOnceType once;
|
PRCallOnceType once;
|
||||||
PZLock *lock;
|
PZLock *lock;
|
||||||
PLHashTable *table;
|
PLHashTable *table;
|
||||||
};
|
};
|
||||||
typedef struct nssPointerTrackerStr nssPointerTracker;
|
typedef struct nssPointerTrackerStr nssPointerTracker;
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
@ -107,16 +106,16 @@ typedef struct nssPointerTrackerStr nssPointerTracker;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum nssStringTypeEnum {
|
enum nssStringTypeEnum {
|
||||||
nssStringType_DirectoryString,
|
nssStringType_DirectoryString,
|
||||||
nssStringType_TeletexString, /* Not "teletext" with trailing 't' */
|
nssStringType_TeletexString, /* Not "teletext" with trailing 't' */
|
||||||
nssStringType_PrintableString,
|
nssStringType_PrintableString,
|
||||||
nssStringType_UniversalString,
|
nssStringType_UniversalString,
|
||||||
nssStringType_BMPString,
|
nssStringType_BMPString,
|
||||||
nssStringType_UTF8String,
|
nssStringType_UTF8String,
|
||||||
nssStringType_PHGString,
|
nssStringType_PHGString,
|
||||||
nssStringType_GeneralString,
|
nssStringType_GeneralString,
|
||||||
|
|
||||||
nssStringType_Unknown = -1
|
nssStringType_Unknown = -1
|
||||||
};
|
};
|
||||||
typedef enum nssStringTypeEnum nssStringType;
|
typedef enum nssStringTypeEnum nssStringType;
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
/*
|
/*
|
||||||
* error.c
|
* error.c
|
||||||
*
|
*
|
||||||
* This file contains the code implementing the per-thread error
|
* This file contains the code implementing the per-thread error
|
||||||
* stacks upon which most NSS routines report their errors.
|
* stacks upon which most NSS routines report their errors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BASE_H
|
#ifndef BASE_H
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
#endif /* BASE_H */
|
#endif /* BASE_H */
|
||||||
#include <limits.h> /* for UINT_MAX */
|
#include <limits.h> /* for UINT_MAX */
|
||||||
#include <string.h> /* for memmove */
|
#include <string.h> /* for memmove */
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct stack_header_str {
|
struct stack_header_str {
|
||||||
PRUint16 space;
|
PRUint16 space;
|
||||||
PRUint16 count;
|
PRUint16 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct error_stack_str {
|
struct error_stack_str {
|
||||||
struct stack_header_str header;
|
struct stack_header_str header;
|
||||||
PRInt32 stack[1];
|
PRInt32 stack[1];
|
||||||
};
|
};
|
||||||
typedef struct error_stack_str error_stack;
|
typedef struct error_stack_str error_stack;
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ static PRCallOnceType error_call_once;
|
||||||
* This is the once-called callback.
|
* This is the once-called callback.
|
||||||
*/
|
*/
|
||||||
static PRStatus
|
static PRStatus
|
||||||
error_once_function ( void)
|
error_once_function(void)
|
||||||
{
|
{
|
||||||
return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
|
return PR_NewThreadPrivateIndex(&error_stack_index, PR_Free);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -76,48 +76,50 @@ error_once_function ( void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static error_stack *
|
static error_stack *
|
||||||
error_get_my_stack ( void)
|
error_get_my_stack(void)
|
||||||
{
|
{
|
||||||
PRStatus st;
|
PRStatus st;
|
||||||
error_stack *rv;
|
error_stack *rv;
|
||||||
PRUintn new_size;
|
PRUintn new_size;
|
||||||
PRUint32 new_bytes;
|
PRUint32 new_bytes;
|
||||||
error_stack *new_stack;
|
error_stack *new_stack;
|
||||||
|
|
||||||
if( INVALID_TPD_INDEX == error_stack_index ) {
|
if (INVALID_TPD_INDEX == error_stack_index) {
|
||||||
st = PR_CallOnce(&error_call_once, error_once_function);
|
st = PR_CallOnce(&error_call_once, error_once_function);
|
||||||
if( PR_SUCCESS != st ) {
|
if (PR_SUCCESS != st) {
|
||||||
return (error_stack *)NULL;
|
return (error_stack *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
|
rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
|
||||||
if( (error_stack *)NULL == rv ) {
|
if ((error_stack *)NULL == rv) {
|
||||||
/* Doesn't exist; create one */
|
/* Doesn't exist; create one */
|
||||||
new_size = 16;
|
new_size = 16;
|
||||||
} else if( rv->header.count == rv->header.space &&
|
}
|
||||||
rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) {
|
else if (rv->header.count == rv->header.space &&
|
||||||
/* Too small, expand it */
|
rv->header.count < NSS_MAX_ERROR_STACK_COUNT) {
|
||||||
new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
|
/* Too small, expand it */
|
||||||
} else {
|
new_size = PR_MIN(rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
|
||||||
/* Okay, return it */
|
}
|
||||||
return rv;
|
else {
|
||||||
}
|
/* Okay, return it */
|
||||||
|
return rv;
|
||||||
new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
|
|
||||||
/* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
|
|
||||||
new_stack = PR_Calloc(1, new_bytes);
|
|
||||||
|
|
||||||
if( (error_stack *)NULL != new_stack ) {
|
|
||||||
if( (error_stack *)NULL != rv ) {
|
|
||||||
(void)nsslibc_memcpy(new_stack,rv,rv->header.space);
|
|
||||||
}
|
}
|
||||||
new_stack->header.space = new_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the value, whether or not the allocation worked */
|
new_bytes = (new_size * sizeof(PRInt32)) + sizeof(error_stack);
|
||||||
PR_SetThreadPrivate(error_stack_index, new_stack);
|
/* Use NSPR's calloc/realloc, not NSS's, to avoid loops! */
|
||||||
return new_stack;
|
new_stack = PR_Calloc(1, new_bytes);
|
||||||
|
|
||||||
|
if ((error_stack *)NULL != new_stack) {
|
||||||
|
if ((error_stack *)NULL != rv) {
|
||||||
|
(void)nsslibc_memcpy(new_stack, rv, rv->header.space);
|
||||||
|
}
|
||||||
|
new_stack->header.space = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the value, whether or not the allocation worked */
|
||||||
|
PR_SetThreadPrivate(error_stack_index, new_stack);
|
||||||
|
return new_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -151,19 +153,19 @@ error_get_my_stack ( void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRInt32
|
NSS_IMPLEMENT PRInt32
|
||||||
NSS_GetError ( void)
|
NSS_GetError(void)
|
||||||
{
|
{
|
||||||
error_stack *es = error_get_my_stack();
|
error_stack *es = error_get_my_stack();
|
||||||
|
|
||||||
if( (error_stack *)NULL == es ) {
|
if ((error_stack *)NULL == es) {
|
||||||
return NSS_ERROR_NO_MEMORY; /* Good guess! */
|
return NSS_ERROR_NO_MEMORY; /* Good guess! */
|
||||||
}
|
}
|
||||||
|
|
||||||
if( 0 == es->header.count ) {
|
if (0 == es->header.count) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return es->stack[ es->header.count-1 ];
|
return es->stack[es->header.count - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -174,7 +176,7 @@ NSS_GetError ( void)
|
||||||
* library routine called by the same thread calling this routine.
|
* library routine called by the same thread calling this routine.
|
||||||
* NOTE: the caller DOES NOT OWN the memory pointed to by the return
|
* NOTE: the caller DOES NOT OWN the memory pointed to by the return
|
||||||
* value. The pointer will remain valid until the calling thread
|
* value. The pointer will remain valid until the calling thread
|
||||||
* calls another NSS routine. The lowest-level (most specific) error
|
* calls another NSS routine. The lowest-level (most specific) error
|
||||||
* is first in the array, and the highest-level is last. The array is
|
* is first in the array, and the highest-level is last. The array is
|
||||||
* zero-terminated. This routine may return NULL upon error; this
|
* zero-terminated. This routine may return NULL upon error; this
|
||||||
* indicates a low-memory situation.
|
* indicates a low-memory situation.
|
||||||
|
@ -185,52 +187,53 @@ NSS_GetError ( void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRInt32 *
|
NSS_IMPLEMENT PRInt32 *
|
||||||
NSS_GetErrorStack ( void)
|
NSS_GetErrorStack(void)
|
||||||
{
|
{
|
||||||
error_stack *es = error_get_my_stack();
|
error_stack *es = error_get_my_stack();
|
||||||
|
|
||||||
if( (error_stack *)NULL == es ) {
|
if ((error_stack *)NULL == es) {
|
||||||
return (PRInt32 *)NULL;
|
return (PRInt32 *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure it's terminated */
|
/* Make sure it's terminated */
|
||||||
es->stack[ es->header.count ] = 0;
|
es->stack[es->header.count] = 0;
|
||||||
|
|
||||||
return es->stack;
|
return es->stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nss_SetError
|
* nss_SetError
|
||||||
*
|
*
|
||||||
* This routine places a new error code on the top of the calling
|
* This routine places a new error code on the top of the calling
|
||||||
* thread's error stack. Calling this routine wiht an error code
|
* thread's error stack. Calling this routine wiht an error code
|
||||||
* of zero will clear the error stack.
|
* of zero will clear the error stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nss_SetError ( PRUint32 error)
|
nss_SetError(PRUint32 error)
|
||||||
{
|
{
|
||||||
error_stack *es;
|
error_stack *es;
|
||||||
|
|
||||||
if( 0 == error ) {
|
if (0 == error) {
|
||||||
nss_ClearErrorStack();
|
nss_ClearErrorStack();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
es = error_get_my_stack();
|
||||||
|
if ((error_stack *)NULL == es) {
|
||||||
|
/* Oh, well. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (es->header.count < es->header.space) {
|
||||||
|
es->stack[es->header.count++] = error;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memmove(es->stack, es->stack + 1,
|
||||||
|
(es->header.space - 1) * (sizeof es->stack[0]));
|
||||||
|
es->stack[es->header.space - 1] = error;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
es = error_get_my_stack();
|
|
||||||
if( (error_stack *)NULL == es ) {
|
|
||||||
/* Oh, well. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (es->header.count < es->header.space) {
|
|
||||||
es->stack[ es->header.count++ ] = error;
|
|
||||||
} else {
|
|
||||||
memmove(es->stack, es->stack + 1,
|
|
||||||
(es->header.space - 1) * (sizeof es->stack[0]));
|
|
||||||
es->stack[ es->header.space - 1 ] = error;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -240,17 +243,17 @@ nss_SetError ( PRUint32 error)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nss_ClearErrorStack ( void)
|
nss_ClearErrorStack(void)
|
||||||
{
|
{
|
||||||
error_stack *es = error_get_my_stack();
|
error_stack *es = error_get_my_stack();
|
||||||
if( (error_stack *)NULL == es ) {
|
if ((error_stack *)NULL == es) {
|
||||||
/* Oh, well. */
|
/* Oh, well. */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
es->header.count = 0;
|
es->header.count = 0;
|
||||||
es->stack[0] = 0;
|
es->stack[0] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -260,10 +263,10 @@ nss_ClearErrorStack ( void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nss_DestroyErrorStack ( void)
|
nss_DestroyErrorStack(void)
|
||||||
{
|
{
|
||||||
if( INVALID_TPD_INDEX != error_stack_index ) {
|
if (INVALID_TPD_INDEX != error_stack_index) {
|
||||||
PR_SetThreadPrivate(error_stack_index, NULL);
|
PR_SetThreadPrivate(error_stack_index, NULL);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include "nssbaset.h"
|
#include "nssbaset.h"
|
||||||
#endif /* NSSBASET_H */
|
#endif /* NSSBASET_H */
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
const NSSError NSS_ERROR_NO_ERROR = 0;
|
const NSSError NSS_ERROR_NO_ERROR = 0;
|
||||||
const NSSError NSS_ERROR_INTERNAL_ERROR = 1;
|
const NSSError NSS_ERROR_INTERNAL_ERROR = 1;
|
||||||
const NSSError NSS_ERROR_NO_MEMORY = 2;
|
const NSSError NSS_ERROR_NO_MEMORY = 2;
|
||||||
|
@ -60,3 +62,4 @@ const NSSError NSS_ERROR_ALREADY_INITIALIZED = 37;
|
||||||
|
|
||||||
const NSSError NSS_ERROR_PKCS11 = 38;
|
const NSSError NSS_ERROR_PKCS11 = 38;
|
||||||
|
|
||||||
|
/* clang-format on */
|
|
@ -32,48 +32,42 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct nssHashStr {
|
struct nssHashStr {
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
PRBool i_alloced_arena;
|
PRBool i_alloced_arena;
|
||||||
PRLock *mutex;
|
PRLock *mutex;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The invariant that mutex protects is:
|
* The invariant that mutex protects is:
|
||||||
* The count accurately reflects the hashtable state.
|
* The count accurately reflects the hashtable state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PLHashTable *plHashTable;
|
PLHashTable *plHashTable;
|
||||||
PRUint32 count;
|
PRUint32 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static PLHashNumber
|
static PLHashNumber
|
||||||
nss_identity_hash
|
nss_identity_hash(const void *key)
|
||||||
(
|
|
||||||
const void *key
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return (PLHashNumber)((char *)key - (char *)NULL);
|
return (PLHashNumber)((char *)key - (char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLHashNumber
|
static PLHashNumber
|
||||||
nss_item_hash
|
nss_item_hash(const void *key)
|
||||||
(
|
|
||||||
const void *key
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
PLHashNumber h;
|
PLHashNumber h;
|
||||||
NSSItem *it = (NSSItem *)key;
|
NSSItem *it = (NSSItem *)key;
|
||||||
h = 0;
|
h = 0;
|
||||||
for (i=0; i<it->size; i++)
|
for (i = 0; i < it->size; i++)
|
||||||
h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i];
|
h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i];
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nss_compare_items(const void *v1, const void *v2)
|
nss_compare_items(const void *v1, const void *v2)
|
||||||
{
|
{
|
||||||
PRStatus ignore;
|
PRStatus ignore;
|
||||||
return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore);
|
return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -81,60 +75,55 @@ nss_compare_items(const void *v1, const void *v2)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT nssHash *
|
NSS_IMPLEMENT nssHash *
|
||||||
nssHash_Create
|
nssHash_Create(NSSArena *arenaOpt, PRUint32 numBuckets, PLHashFunction keyHash,
|
||||||
(
|
PLHashComparator keyCompare, PLHashComparator valueCompare)
|
||||||
NSSArena *arenaOpt,
|
|
||||||
PRUint32 numBuckets,
|
|
||||||
PLHashFunction keyHash,
|
|
||||||
PLHashComparator keyCompare,
|
|
||||||
PLHashComparator valueCompare
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
nssHash *rv;
|
nssHash *rv;
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
PRBool i_alloced;
|
PRBool i_alloced;
|
||||||
|
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
|
if (arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return (nssHash *)NULL;
|
return (nssHash *)NULL;
|
||||||
}
|
}
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
if (arenaOpt) {
|
if (arenaOpt) {
|
||||||
arena = arenaOpt;
|
arena = arenaOpt;
|
||||||
i_alloced = PR_FALSE;
|
i_alloced = PR_FALSE;
|
||||||
} else {
|
}
|
||||||
arena = nssArena_Create();
|
else {
|
||||||
i_alloced = PR_TRUE;
|
arena = nssArena_Create();
|
||||||
}
|
i_alloced = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
rv = nss_ZNEW(arena, nssHash);
|
rv = nss_ZNEW(arena, nssHash);
|
||||||
if( (nssHash *)NULL == rv ) {
|
if ((nssHash *)NULL == rv) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv->mutex = PZ_NewLock(nssILockOther);
|
rv->mutex = PZ_NewLock(nssILockOther);
|
||||||
if( (PZLock *)NULL == rv->mutex ) {
|
if ((PZLock *)NULL == rv->mutex) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv->plHashTable = PL_NewHashTable(numBuckets,
|
rv->plHashTable =
|
||||||
keyHash, keyCompare, valueCompare,
|
PL_NewHashTable(numBuckets, keyHash, keyCompare, valueCompare,
|
||||||
&nssArenaHashAllocOps, arena);
|
&nssArenaHashAllocOps, arena);
|
||||||
if( (PLHashTable *)NULL == rv->plHashTable ) {
|
if ((PLHashTable *)NULL == rv->plHashTable) {
|
||||||
(void)PZ_DestroyLock(rv->mutex);
|
(void)PZ_DestroyLock(rv->mutex);
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv->count = 0;
|
rv->count = 0;
|
||||||
rv->arena = arena;
|
rv->arena = arena;
|
||||||
rv->i_alloced_arena = i_alloced;
|
rv->i_alloced_arena = i_alloced;
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
loser:
|
loser:
|
||||||
(void)nss_ZFreeIf(rv);
|
(void)nss_ZFreeIf(rv);
|
||||||
return (nssHash *)NULL;
|
return (nssHash *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -142,14 +131,10 @@ loser:
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT nssHash *
|
NSS_IMPLEMENT nssHash *
|
||||||
nssHash_CreatePointer
|
nssHash_CreatePointer(NSSArena *arenaOpt, PRUint32 numBuckets)
|
||||||
(
|
|
||||||
NSSArena *arenaOpt,
|
|
||||||
PRUint32 numBuckets
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return nssHash_Create(arenaOpt, numBuckets,
|
return nssHash_Create(arenaOpt, numBuckets, nss_identity_hash,
|
||||||
nss_identity_hash, PL_CompareValues, PL_CompareValues);
|
PL_CompareValues, PL_CompareValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -157,14 +142,10 @@ nssHash_CreatePointer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT nssHash *
|
NSS_IMPLEMENT nssHash *
|
||||||
nssHash_CreateString
|
nssHash_CreateString(NSSArena *arenaOpt, PRUint32 numBuckets)
|
||||||
(
|
|
||||||
NSSArena *arenaOpt,
|
|
||||||
PRUint32 numBuckets
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return nssHash_Create(arenaOpt, numBuckets,
|
return nssHash_Create(arenaOpt, numBuckets, PL_HashString,
|
||||||
PL_HashString, PL_CompareStrings, PL_CompareStrings);
|
PL_CompareStrings, PL_CompareStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -172,14 +153,10 @@ nssHash_CreateString
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT nssHash *
|
NSS_IMPLEMENT nssHash *
|
||||||
nssHash_CreateItem
|
nssHash_CreateItem(NSSArena *arenaOpt, PRUint32 numBuckets)
|
||||||
(
|
|
||||||
NSSArena *arenaOpt,
|
|
||||||
PRUint32 numBuckets
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return nssHash_Create(arenaOpt, numBuckets,
|
return nssHash_Create(arenaOpt, numBuckets, nss_item_hash,
|
||||||
nss_item_hash, nss_compare_items, PL_CompareValues);
|
nss_compare_items, PL_CompareValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -187,18 +164,16 @@ nssHash_CreateItem
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nssHash_Destroy
|
nssHash_Destroy(nssHash *hash)
|
||||||
(
|
|
||||||
nssHash *hash
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
(void)PZ_DestroyLock(hash->mutex);
|
(void)PZ_DestroyLock(hash->mutex);
|
||||||
PL_HashTableDestroy(hash->plHashTable);
|
PL_HashTableDestroy(hash->plHashTable);
|
||||||
if (hash->i_alloced_arena) {
|
if (hash->i_alloced_arena) {
|
||||||
nssArena_Destroy(hash->arena);
|
nssArena_Destroy(hash->arena);
|
||||||
} else {
|
}
|
||||||
nss_ZFreeIf(hash);
|
else {
|
||||||
}
|
nss_ZFreeIf(hash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -206,31 +181,28 @@ nssHash_Destroy
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssHash_Add
|
nssHash_Add(nssHash *hash, const void *key, const void *value)
|
||||||
(
|
|
||||||
nssHash *hash,
|
|
||||||
const void *key,
|
|
||||||
const void *value
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PRStatus error = PR_FAILURE;
|
PRStatus error = PR_FAILURE;
|
||||||
PLHashEntry *he;
|
PLHashEntry *he;
|
||||||
|
|
||||||
PZ_Lock(hash->mutex);
|
PZ_Lock(hash->mutex);
|
||||||
|
|
||||||
he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
|
|
||||||
if( (PLHashEntry *)NULL == he ) {
|
|
||||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
|
||||||
} else if (he->value != value) {
|
|
||||||
nss_SetError(NSS_ERROR_HASH_COLLISION);
|
|
||||||
} else {
|
|
||||||
hash->count++;
|
|
||||||
error = PR_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)PZ_Unlock(hash->mutex);
|
he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
|
||||||
|
if ((PLHashEntry *)NULL == he) {
|
||||||
|
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||||
|
}
|
||||||
|
else if (he->value != value) {
|
||||||
|
nss_SetError(NSS_ERROR_HASH_COLLISION);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hash->count++;
|
||||||
|
error = PR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
(void)PZ_Unlock(hash->mutex);
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -238,23 +210,19 @@ nssHash_Add
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nssHash_Remove
|
nssHash_Remove(nssHash *hash, const void *it)
|
||||||
(
|
|
||||||
nssHash *hash,
|
|
||||||
const void *it
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PRBool found;
|
PRBool found;
|
||||||
|
|
||||||
PZ_Lock(hash->mutex);
|
PZ_Lock(hash->mutex);
|
||||||
|
|
||||||
found = PL_HashTableRemove(hash->plHashTable, it);
|
found = PL_HashTableRemove(hash->plHashTable, it);
|
||||||
if( found ) {
|
if (found) {
|
||||||
hash->count--;
|
hash->count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)PZ_Unlock(hash->mutex);
|
(void)PZ_Unlock(hash->mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -262,20 +230,17 @@ nssHash_Remove
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT PRUint32
|
NSS_IMPLEMENT PRUint32
|
||||||
nssHash_Count
|
nssHash_Count(nssHash *hash)
|
||||||
(
|
|
||||||
nssHash *hash
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PRUint32 count;
|
PRUint32 count;
|
||||||
|
|
||||||
PZ_Lock(hash->mutex);
|
PZ_Lock(hash->mutex);
|
||||||
|
|
||||||
count = hash->count;
|
count = hash->count;
|
||||||
|
|
||||||
(void)PZ_Unlock(hash->mutex);
|
(void)PZ_Unlock(hash->mutex);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -283,25 +248,22 @@ nssHash_Count
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT PRBool
|
NSS_IMPLEMENT PRBool
|
||||||
nssHash_Exists
|
nssHash_Exists(nssHash *hash, const void *it)
|
||||||
(
|
|
||||||
nssHash *hash,
|
|
||||||
const void *it
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
void *value;
|
void *value;
|
||||||
|
|
||||||
PZ_Lock(hash->mutex);
|
PZ_Lock(hash->mutex);
|
||||||
|
|
||||||
value = PL_HashTableLookup(hash->plHashTable, it);
|
value = PL_HashTableLookup(hash->plHashTable, it);
|
||||||
|
|
||||||
(void)PZ_Unlock(hash->mutex);
|
(void)PZ_Unlock(hash->mutex);
|
||||||
|
|
||||||
if( (void *)NULL == value ) {
|
if ((void *)NULL == value) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
} else {
|
}
|
||||||
return PR_TRUE;
|
else {
|
||||||
}
|
return PR_TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -309,39 +271,30 @@ nssHash_Exists
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT void *
|
NSS_IMPLEMENT void *
|
||||||
nssHash_Lookup
|
nssHash_Lookup(nssHash *hash, const void *it)
|
||||||
(
|
|
||||||
nssHash *hash,
|
|
||||||
const void *it
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
void *rv;
|
void *rv;
|
||||||
|
|
||||||
PZ_Lock(hash->mutex);
|
PZ_Lock(hash->mutex);
|
||||||
|
|
||||||
rv = PL_HashTableLookup(hash->plHashTable, it);
|
rv = PL_HashTableLookup(hash->plHashTable, it);
|
||||||
|
|
||||||
(void)PZ_Unlock(hash->mutex);
|
(void)PZ_Unlock(hash->mutex);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct arg_str {
|
struct arg_str {
|
||||||
nssHashIterator fcn;
|
nssHashIterator fcn;
|
||||||
void *closure;
|
void *closure;
|
||||||
};
|
};
|
||||||
|
|
||||||
static PRIntn
|
static PRIntn
|
||||||
nss_hash_enumerator
|
nss_hash_enumerator(PLHashEntry *he, PRIntn index, void *arg)
|
||||||
(
|
|
||||||
PLHashEntry *he,
|
|
||||||
PRIntn index,
|
|
||||||
void *arg
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
struct arg_str *as = (struct arg_str *)arg;
|
struct arg_str *as = (struct arg_str *)arg;
|
||||||
as->fcn(he->key, he->value, as->closure);
|
as->fcn(he->key, he->value, as->closure);
|
||||||
return HT_ENUMERATE_NEXT;
|
return HT_ENUMERATE_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -350,22 +303,17 @@ nss_hash_enumerator
|
||||||
* NOTE that the iteration function will be called with the hashtable locked.
|
* NOTE that the iteration function will be called with the hashtable locked.
|
||||||
*/
|
*/
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nssHash_Iterate
|
nssHash_Iterate(nssHash *hash, nssHashIterator fcn, void *closure)
|
||||||
(
|
|
||||||
nssHash *hash,
|
|
||||||
nssHashIterator fcn,
|
|
||||||
void *closure
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
struct arg_str as;
|
struct arg_str as;
|
||||||
as.fcn = fcn;
|
as.fcn = fcn;
|
||||||
as.closure = closure;
|
as.closure = closure;
|
||||||
|
|
||||||
PZ_Lock(hash->mutex);
|
PZ_Lock(hash->mutex);
|
||||||
|
|
||||||
PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as);
|
PL_HashTableEnumerateEntries(hash->plHashTable, nss_hash_enumerator, &as);
|
||||||
|
|
||||||
(void)PZ_Unlock(hash->mutex);
|
(void)PZ_Unlock(hash->mutex);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,73 +12,53 @@
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
#endif /* BASE_H */
|
#endif /* BASE_H */
|
||||||
|
|
||||||
static void * PR_CALLBACK
|
static void *PR_CALLBACK
|
||||||
nss_arena_hash_alloc_table
|
nss_arena_hash_alloc_table(void *pool, PRSize size)
|
||||||
(
|
|
||||||
void *pool,
|
|
||||||
PRSize size
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NSSArena *arena = (NSSArena *)NULL;
|
NSSArena *arena = (NSSArena *)NULL;
|
||||||
|
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( (void *)NULL != arena ) {
|
if ((void *)NULL != arena) {
|
||||||
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
|
if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
|
||||||
return (void *)NULL;
|
return (void *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
return nss_ZAlloc(arena, size);
|
return nss_ZAlloc(arena, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PR_CALLBACK
|
static void PR_CALLBACK
|
||||||
nss_arena_hash_free_table
|
nss_arena_hash_free_table(void *pool, void *item)
|
||||||
(
|
|
||||||
void *pool,
|
|
||||||
void *item
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
(void)nss_ZFreeIf(item);
|
(void)nss_ZFreeIf(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PLHashEntry * PR_CALLBACK
|
static PLHashEntry *PR_CALLBACK
|
||||||
nss_arena_hash_alloc_entry
|
nss_arena_hash_alloc_entry(void *pool, const void *key)
|
||||||
(
|
|
||||||
void *pool,
|
|
||||||
const void *key
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NSSArena *arena = NULL;
|
NSSArena *arena = NULL;
|
||||||
|
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( (void *)NULL != arena ) {
|
if ((void *)NULL != arena) {
|
||||||
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
|
if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
|
||||||
return (void *)NULL;
|
return (void *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
return nss_ZNEW(arena, PLHashEntry);
|
return nss_ZNEW(arena, PLHashEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PR_CALLBACK
|
static void PR_CALLBACK
|
||||||
nss_arena_hash_free_entry
|
nss_arena_hash_free_entry(void *pool, PLHashEntry *he, PRUintn flag)
|
||||||
(
|
|
||||||
void *pool,
|
|
||||||
PLHashEntry *he,
|
|
||||||
PRUintn flag
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( HT_FREE_ENTRY == flag ) {
|
if (HT_FREE_ENTRY == flag) {
|
||||||
(void)nss_ZFreeIf(he);
|
(void)nss_ZFreeIf(he);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT_DATA PLHashAllocOps
|
NSS_IMPLEMENT_DATA PLHashAllocOps nssArenaHashAllocOps = {
|
||||||
nssArenaHashAllocOps = {
|
nss_arena_hash_alloc_table, nss_arena_hash_free_table,
|
||||||
nss_arena_hash_alloc_table,
|
nss_arena_hash_alloc_entry, nss_arena_hash_free_entry
|
||||||
nss_arena_hash_free_table,
|
|
||||||
nss_arena_hash_alloc_entry,
|
|
||||||
nss_arena_hash_free_entry
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,78 +22,70 @@
|
||||||
* NSS_ERROR_NO_MEMORY
|
* NSS_ERROR_NO_MEMORY
|
||||||
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
|
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
|
||||||
* NSS_ERROR_INVALID_POINTER
|
* NSS_ERROR_INVALID_POINTER
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* A pointer to an NSSItem upon success
|
* A pointer to an NSSItem upon success
|
||||||
* NULL upon failure
|
* NULL upon failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSItem *
|
NSS_IMPLEMENT NSSItem *
|
||||||
nssItem_Create
|
nssItem_Create(NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length,
|
||||||
(
|
const void *data)
|
||||||
NSSArena *arenaOpt,
|
|
||||||
NSSItem *rvOpt,
|
|
||||||
PRUint32 length,
|
|
||||||
const void *data
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NSSItem *rv = (NSSItem *)NULL;
|
NSSItem *rv = (NSSItem *)NULL;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if( (NSSArena *)NULL != arenaOpt ) {
|
if ((NSSArena *)NULL != arenaOpt) {
|
||||||
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
|
if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
|
||||||
return (NSSItem *)NULL;
|
return (NSSItem *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( (const void *)NULL == data ) {
|
if ((const void *)NULL == data) {
|
||||||
if( length > 0 ) {
|
if (length > 0) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return (NSSItem *)NULL;
|
return (NSSItem *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
if( (NSSItem *)NULL == rvOpt ) {
|
if ((NSSItem *)NULL == rvOpt) {
|
||||||
rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
|
rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
|
||||||
if( (NSSItem *)NULL == rv ) {
|
if ((NSSItem *)NULL == rv) {
|
||||||
goto loser;
|
goto loser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = rvOpt;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
rv = rvOpt;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv->size = length;
|
rv->size = length;
|
||||||
rv->data = nss_ZAlloc(arenaOpt, length);
|
rv->data = nss_ZAlloc(arenaOpt, length);
|
||||||
if( (void *)NULL == rv->data ) {
|
if ((void *)NULL == rv->data) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( length > 0 ) {
|
if (length > 0) {
|
||||||
(void)nsslibc_memcpy(rv->data, data, length);
|
(void)nsslibc_memcpy(rv->data, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
if( rv != rvOpt ) {
|
if (rv != rvOpt) {
|
||||||
nss_ZFreeIf(rv);
|
nss_ZFreeIf(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (NSSItem *)NULL;
|
return (NSSItem *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT void
|
NSS_IMPLEMENT void
|
||||||
nssItem_Destroy
|
nssItem_Destroy(NSSItem *item)
|
||||||
(
|
|
||||||
NSSItem *item
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
nss_ClearErrorStack();
|
nss_ClearErrorStack();
|
||||||
|
|
||||||
nss_ZFreeIf(item->data);
|
|
||||||
nss_ZFreeIf(item);
|
|
||||||
|
|
||||||
|
nss_ZFreeIf(item->data);
|
||||||
|
nss_ZFreeIf(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -106,34 +98,29 @@ nssItem_Destroy
|
||||||
* NSS_ERROR_NO_MEMORY
|
* NSS_ERROR_NO_MEMORY
|
||||||
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
|
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
|
||||||
* NSS_ERROR_INVALID_ITEM
|
* NSS_ERROR_INVALID_ITEM
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* A pointer to an NSSItem upon success
|
* A pointer to an NSSItem upon success
|
||||||
* NULL upon failure
|
* NULL upon failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSItem *
|
NSS_IMPLEMENT NSSItem *
|
||||||
nssItem_Duplicate
|
nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt)
|
||||||
(
|
|
||||||
NSSItem *obj,
|
|
||||||
NSSArena *arenaOpt,
|
|
||||||
NSSItem *rvOpt
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if( (NSSArena *)NULL != arenaOpt ) {
|
if ((NSSArena *)NULL != arenaOpt) {
|
||||||
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
|
if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
|
||||||
return (NSSItem *)NULL;
|
return (NSSItem *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if( (NSSItem *)NULL == obj ) {
|
if ((NSSItem *)NULL == obj) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
||||||
return (NSSItem *)NULL;
|
return (NSSItem *)NULL;
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
|
return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -151,18 +138,15 @@ nssItem_Duplicate
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssItem_verifyPointer
|
nssItem_verifyPointer(const NSSItem *item)
|
||||||
(
|
|
||||||
const NSSItem *item
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( ((const NSSItem *)NULL == item) ||
|
if (((const NSSItem *)NULL == item) ||
|
||||||
(((void *)NULL == item->data) && (item->size > 0)) ) {
|
(((void *)NULL == item->data) && (item->size > 0))) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
@ -181,28 +165,23 @@ nssItem_verifyPointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRBool
|
NSS_IMPLEMENT PRBool
|
||||||
nssItem_Equal
|
nssItem_Equal(const NSSItem *one, const NSSItem *two, PRStatus *statusOpt)
|
||||||
(
|
|
||||||
const NSSItem *one,
|
|
||||||
const NSSItem *two,
|
|
||||||
PRStatus *statusOpt
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if( (PRStatus *)NULL != statusOpt ) {
|
if ((PRStatus *)NULL != statusOpt) {
|
||||||
*statusOpt = PR_SUCCESS;
|
*statusOpt = PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two) ) {
|
if (((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two) ) {
|
if (((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two)) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( one->size != two->size ) {
|
if (one->size != two->size) {
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
|
return nsslibc_memequal(one->data, two->data, one->size, statusOpt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
/*
|
/*
|
||||||
* libc.c
|
* libc.c
|
||||||
*
|
*
|
||||||
* This file contains our wrappers/reimplementations for "standard"
|
* This file contains our wrappers/reimplementations for "standard"
|
||||||
* libc functions. Things like "memcpy." We add to this as we need
|
* libc functions. Things like "memcpy." We add to this as we need
|
||||||
* it. Oh, and let's keep it in alphabetical order, should it ever
|
* it. Oh, and let's keep it in alphabetical order, should it ever
|
||||||
* get large. Most string/character stuff should be in utf8.c, not
|
* get large. Most string/character stuff should be in utf8.c, not
|
||||||
* here. This file (and maybe utf8.c) should be the only ones in
|
* here. This file (and maybe utf8.c) should be the only ones in
|
||||||
* NSS to include files with angle brackets.
|
* NSS to include files with angle brackets.
|
||||||
*/
|
*/
|
||||||
|
@ -38,21 +38,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT void *
|
NSS_IMPLEMENT void *
|
||||||
nsslibc_memcpy
|
nsslibc_memcpy(void *dest, const void *source, PRUint32 n)
|
||||||
(
|
|
||||||
void *dest,
|
|
||||||
const void *source,
|
|
||||||
PRUint32 n
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( ((void *)NULL == dest) || ((const void *)NULL == source) ) {
|
if (((void *)NULL == dest) || ((const void *)NULL == source)) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return (void *)NULL;
|
return (void *)NULL;
|
||||||
}
|
}
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
return memcpy(dest, source, (size_t)n);
|
return memcpy(dest, source, (size_t)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -67,21 +62,16 @@ nsslibc_memcpy
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT void *
|
NSS_IMPLEMENT void *
|
||||||
nsslibc_memset
|
nsslibc_memset(void *dest, PRUint8 byte, PRUint32 n)
|
||||||
(
|
|
||||||
void *dest,
|
|
||||||
PRUint8 byte,
|
|
||||||
PRUint32 n
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( ((void *)NULL == dest) ) {
|
if (((void *)NULL == dest)) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return (void *)NULL;
|
return (void *)NULL;
|
||||||
}
|
}
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
return memset(dest, (int)byte, (size_t)n);
|
return memset(dest, (int)byte, (size_t)n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -97,33 +87,29 @@ nsslibc_memset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRBool
|
NSS_IMPLEMENT PRBool
|
||||||
nsslibc_memequal
|
nsslibc_memequal(const void *a, const void *b, PRUint32 len,
|
||||||
(
|
PRStatus *statusOpt)
|
||||||
const void *a,
|
|
||||||
const void *b,
|
|
||||||
PRUint32 len,
|
|
||||||
PRStatus *statusOpt
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
|
if ((((void *)NULL == a) || ((void *)NULL == b))) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
if( (PRStatus *)NULL != statusOpt ) {
|
if ((PRStatus *)NULL != statusOpt) {
|
||||||
*statusOpt = PR_FAILURE;
|
*statusOpt = PR_FAILURE;
|
||||||
|
}
|
||||||
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
if( (PRStatus *)NULL != statusOpt ) {
|
if ((PRStatus *)NULL != statusOpt) {
|
||||||
*statusOpt = PR_SUCCESS;
|
*statusOpt = PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( 0 == memcmp(a, b, len) ) {
|
if (0 == memcmp(a, b, len)) {
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
} else {
|
}
|
||||||
return PR_FALSE;
|
else {
|
||||||
}
|
return PR_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -131,32 +117,26 @@ nsslibc_memequal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRInt32
|
NSS_IMPLEMENT PRInt32
|
||||||
nsslibc_memcmp
|
nsslibc_memcmp(const void *a, const void *b, PRUint32 len, PRStatus *statusOpt)
|
||||||
(
|
|
||||||
const void *a,
|
|
||||||
const void *b,
|
|
||||||
PRUint32 len,
|
|
||||||
PRStatus *statusOpt
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int v;
|
int v;
|
||||||
|
|
||||||
#ifdef NSSDEBUG
|
#ifdef NSSDEBUG
|
||||||
if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
|
if ((((void *)NULL == a) || ((void *)NULL == b))) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
if( (PRStatus *)NULL != statusOpt ) {
|
if ((PRStatus *)NULL != statusOpt) {
|
||||||
*statusOpt = PR_FAILURE;
|
*statusOpt = PR_FAILURE;
|
||||||
|
}
|
||||||
|
return -2;
|
||||||
}
|
}
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
#endif /* NSSDEBUG */
|
#endif /* NSSDEBUG */
|
||||||
|
|
||||||
if( (PRStatus *)NULL != statusOpt ) {
|
if ((PRStatus *)NULL != statusOpt) {
|
||||||
*statusOpt = PR_SUCCESS;
|
*statusOpt = PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = memcmp(a, b, len);
|
v = memcmp(a, b, len);
|
||||||
return (PRInt32)v;
|
return (PRInt32)v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -13,19 +13,19 @@
|
||||||
#endif /* BASE_H */
|
#endif /* BASE_H */
|
||||||
|
|
||||||
struct nssListElementStr {
|
struct nssListElementStr {
|
||||||
PRCList link;
|
PRCList link;
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct nssListElementStr nssListElement;
|
typedef struct nssListElementStr nssListElement;
|
||||||
|
|
||||||
struct nssListStr {
|
struct nssListStr {
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
PZLock *lock;
|
PZLock *lock;
|
||||||
nssListElement *head;
|
nssListElement *head;
|
||||||
PRUint32 count;
|
PRUint32 count;
|
||||||
nssListCompareFunc compareFunc;
|
nssListCompareFunc compareFunc;
|
||||||
nssListSortFunc sortFunc;
|
nssListSortFunc sortFunc;
|
||||||
PRBool i_alloced_arena;
|
PRBool i_alloced_arena;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,11 +35,13 @@ struct nssListIteratorStr {
|
||||||
nssListElement *current;
|
nssListElement *current;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NSSLIST_LOCK_IF(list) \
|
#define NSSLIST_LOCK_IF(list) \
|
||||||
if ((list)->lock) PZ_Lock((list)->lock)
|
if ((list)->lock) \
|
||||||
|
PZ_Lock((list)->lock)
|
||||||
|
|
||||||
#define NSSLIST_UNLOCK_IF(list) \
|
#define NSSLIST_UNLOCK_IF(list) \
|
||||||
if ((list)->lock) PZ_Unlock((list)->lock)
|
if ((list)->lock) \
|
||||||
|
PZ_Unlock((list)->lock)
|
||||||
|
|
||||||
static PRBool
|
static PRBool
|
||||||
pointer_compare(void *a, void *b)
|
pointer_compare(void *a, void *b)
|
||||||
|
@ -54,61 +56,59 @@ nsslist_get_matching_element(nssList *list, void *data)
|
||||||
nssListElement *node;
|
nssListElement *node;
|
||||||
node = list->head;
|
node = list->head;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
link = &node->link;
|
link = &node->link;
|
||||||
while (node) {
|
while (node) {
|
||||||
/* using a callback slows things down when it's just compare ... */
|
/* using a callback slows things down when it's just compare ... */
|
||||||
if (list->compareFunc(node->data, data)) {
|
if (list->compareFunc(node->data, data)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
link = &node->link;
|
link = &node->link;
|
||||||
if (link == PR_LIST_TAIL(&list->head->link)) {
|
if (link == PR_LIST_TAIL(&list->head->link)) {
|
||||||
node = NULL;
|
node = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT nssList *
|
NSS_IMPLEMENT nssList *
|
||||||
nssList_Create
|
nssList_Create(NSSArena *arenaOpt, PRBool threadSafe)
|
||||||
(
|
|
||||||
NSSArena *arenaOpt,
|
|
||||||
PRBool threadSafe
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
nssList *list;
|
nssList *list;
|
||||||
PRBool i_alloced;
|
PRBool i_alloced;
|
||||||
if (arenaOpt) {
|
if (arenaOpt) {
|
||||||
arena = arenaOpt;
|
arena = arenaOpt;
|
||||||
i_alloced = PR_FALSE;
|
i_alloced = PR_FALSE;
|
||||||
} else {
|
}
|
||||||
arena = nssArena_Create();
|
else {
|
||||||
i_alloced = PR_TRUE;
|
arena = nssArena_Create();
|
||||||
|
i_alloced = PR_TRUE;
|
||||||
}
|
}
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return (nssList *)NULL;
|
return (nssList *)NULL;
|
||||||
}
|
}
|
||||||
list = nss_ZNEW(arena, nssList);
|
list = nss_ZNEW(arena, nssList);
|
||||||
if (!list) {
|
if (!list) {
|
||||||
if (!arenaOpt) {
|
if (!arenaOpt) {
|
||||||
NSSArena_Destroy(arena);
|
NSSArena_Destroy(arena);
|
||||||
}
|
}
|
||||||
return (nssList *)NULL;
|
return (nssList *)NULL;
|
||||||
}
|
}
|
||||||
if (threadSafe) {
|
if (threadSafe) {
|
||||||
list->lock = PZ_NewLock(nssILockOther);
|
list->lock = PZ_NewLock(nssILockOther);
|
||||||
if (!list->lock) {
|
if (!list->lock) {
|
||||||
if (arenaOpt) {
|
if (arenaOpt) {
|
||||||
nss_ZFreeIf(list);
|
nss_ZFreeIf(list);
|
||||||
} else {
|
}
|
||||||
NSSArena_Destroy(arena);
|
else {
|
||||||
}
|
NSSArena_Destroy(arena);
|
||||||
return (nssList *)NULL;
|
}
|
||||||
}
|
return (nssList *)NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
list->arena = arena;
|
list->arena = arena;
|
||||||
list->i_alloced_arena = i_alloced;
|
list->i_alloced_arena = i_alloced;
|
||||||
|
@ -120,14 +120,14 @@ NSS_IMPLEMENT PRStatus
|
||||||
nssList_Destroy(nssList *list)
|
nssList_Destroy(nssList *list)
|
||||||
{
|
{
|
||||||
if (!list->i_alloced_arena) {
|
if (!list->i_alloced_arena) {
|
||||||
nssList_Clear(list, NULL);
|
nssList_Clear(list, NULL);
|
||||||
}
|
}
|
||||||
if (list->lock) {
|
if (list->lock) {
|
||||||
(void)PZ_DestroyLock(list->lock);
|
(void)PZ_DestroyLock(list->lock);
|
||||||
}
|
}
|
||||||
if (list->i_alloced_arena) {
|
if (list->i_alloced_arena) {
|
||||||
NSSArena_Destroy(list->arena);
|
NSSArena_Destroy(list->arena);
|
||||||
list = NULL;
|
list = NULL;
|
||||||
}
|
}
|
||||||
nss_ZFreeIf(list);
|
nss_ZFreeIf(list);
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
@ -161,13 +161,14 @@ nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
|
||||||
node = list->head;
|
node = list->head;
|
||||||
list->head = NULL;
|
list->head = NULL;
|
||||||
while (node && list->count > 0) {
|
while (node && list->count > 0) {
|
||||||
if (destructor) (*destructor)(node->data);
|
if (destructor)
|
||||||
link = &node->link;
|
(*destructor)(node->data);
|
||||||
tmp = (nssListElement *)PR_NEXT_LINK(link);
|
link = &node->link;
|
||||||
PR_REMOVE_LINK(link);
|
tmp = (nssListElement *)PR_NEXT_LINK(link);
|
||||||
nss_ZFreeIf(node);
|
PR_REMOVE_LINK(link);
|
||||||
node = tmp;
|
nss_ZFreeIf(node);
|
||||||
--list->count;
|
node = tmp;
|
||||||
|
--list->count;
|
||||||
}
|
}
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
}
|
}
|
||||||
|
@ -177,38 +178,41 @@ nsslist_add_element(nssList *list, void *data)
|
||||||
{
|
{
|
||||||
nssListElement *node = nss_ZNEW(list->arena, nssListElement);
|
nssListElement *node = nss_ZNEW(list->arena, nssListElement);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
PR_INIT_CLIST(&node->link);
|
PR_INIT_CLIST(&node->link);
|
||||||
node->data = data;
|
node->data = data;
|
||||||
if (list->head) {
|
if (list->head) {
|
||||||
if (list->sortFunc) {
|
if (list->sortFunc) {
|
||||||
PRCList *link;
|
PRCList *link;
|
||||||
nssListElement *currNode;
|
nssListElement *currNode;
|
||||||
currNode = list->head;
|
currNode = list->head;
|
||||||
/* insert in ordered list */
|
/* insert in ordered list */
|
||||||
while (currNode) {
|
while (currNode) {
|
||||||
link = &currNode->link;
|
link = &currNode->link;
|
||||||
if (list->sortFunc(data, currNode->data) <= 0) {
|
if (list->sortFunc(data, currNode->data) <= 0) {
|
||||||
/* new element goes before current node */
|
/* new element goes before current node */
|
||||||
PR_INSERT_BEFORE(&node->link, link);
|
PR_INSERT_BEFORE(&node->link, link);
|
||||||
/* reset head if this is first */
|
/* reset head if this is first */
|
||||||
if (currNode == list->head) list->head = node;
|
if (currNode == list->head)
|
||||||
break;
|
list->head = node;
|
||||||
}
|
break;
|
||||||
if (link == PR_LIST_TAIL(&list->head->link)) {
|
}
|
||||||
/* reached end of list, append */
|
if (link == PR_LIST_TAIL(&list->head->link)) {
|
||||||
PR_INSERT_AFTER(&node->link, link);
|
/* reached end of list, append */
|
||||||
break;
|
PR_INSERT_AFTER(&node->link, link);
|
||||||
}
|
break;
|
||||||
currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
|
}
|
||||||
}
|
currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
|
||||||
} else {
|
}
|
||||||
/* not sorting */
|
}
|
||||||
PR_APPEND_LINK(&node->link, &list->head->link);
|
else {
|
||||||
}
|
/* not sorting */
|
||||||
} else {
|
PR_APPEND_LINK(&node->link, &list->head->link);
|
||||||
list->head = node;
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
list->head = node;
|
||||||
}
|
}
|
||||||
++list->count;
|
++list->count;
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
@ -231,9 +235,9 @@ nssList_AddUnique(nssList *list, void *data)
|
||||||
NSSLIST_LOCK_IF(list);
|
NSSLIST_LOCK_IF(list);
|
||||||
node = nsslist_get_matching_element(list, data);
|
node = nsslist_get_matching_element(list, data);
|
||||||
if (node) {
|
if (node) {
|
||||||
/* already in, finish */
|
/* already in, finish */
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
nssrv = nsslist_add_element(list, data);
|
nssrv = nsslist_add_element(list, data);
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
|
@ -247,14 +251,14 @@ nssList_Remove(nssList *list, void *data)
|
||||||
NSSLIST_LOCK_IF(list);
|
NSSLIST_LOCK_IF(list);
|
||||||
node = nsslist_get_matching_element(list, data);
|
node = nsslist_get_matching_element(list, data);
|
||||||
if (node) {
|
if (node) {
|
||||||
if (node == list->head) {
|
if (node == list->head) {
|
||||||
list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
|
list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||||
}
|
}
|
||||||
PR_REMOVE_LINK(&node->link);
|
PR_REMOVE_LINK(&node->link);
|
||||||
nss_ZFreeIf(node);
|
nss_ZFreeIf(node);
|
||||||
if (--list->count == 0) {
|
if (--list->count == 0) {
|
||||||
list->head = NULL;
|
list->head = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
@ -284,16 +288,17 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
|
||||||
PR_ASSERT(maxElements > 0);
|
PR_ASSERT(maxElements > 0);
|
||||||
node = list->head;
|
node = list->head;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
NSSLIST_LOCK_IF(list);
|
NSSLIST_LOCK_IF(list);
|
||||||
while (node) {
|
while (node) {
|
||||||
rvArray[i++] = node->data;
|
rvArray[i++] = node->data;
|
||||||
if (i == maxElements) break;
|
if (i == maxElements)
|
||||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
break;
|
||||||
if (node == list->head) {
|
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||||
break;
|
if (node == list->head) {
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
|
@ -306,18 +311,18 @@ nssList_Clone(nssList *list)
|
||||||
nssListElement *node;
|
nssListElement *node;
|
||||||
rvList = nssList_Create(NULL, (list->lock != NULL));
|
rvList = nssList_Create(NULL, (list->lock != NULL));
|
||||||
if (!rvList) {
|
if (!rvList) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
NSSLIST_LOCK_IF(list);
|
NSSLIST_LOCK_IF(list);
|
||||||
if (list->count > 0) {
|
if (list->count > 0) {
|
||||||
node = list->head;
|
node = list->head;
|
||||||
while (PR_TRUE) {
|
while (PR_TRUE) {
|
||||||
nssList_Add(rvList, node->data);
|
nssList_Add(rvList, node->data);
|
||||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||||
if (node == list->head) {
|
if (node == list->head) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NSSLIST_UNLOCK_IF(list);
|
NSSLIST_UNLOCK_IF(list);
|
||||||
return rvList;
|
return rvList;
|
||||||
|
@ -329,21 +334,21 @@ nssList_CreateIterator(nssList *list)
|
||||||
nssListIterator *rvIterator;
|
nssListIterator *rvIterator;
|
||||||
rvIterator = nss_ZNEW(NULL, nssListIterator);
|
rvIterator = nss_ZNEW(NULL, nssListIterator);
|
||||||
if (!rvIterator) {
|
if (!rvIterator) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rvIterator->list = nssList_Clone(list);
|
rvIterator->list = nssList_Clone(list);
|
||||||
if (!rvIterator->list) {
|
if (!rvIterator->list) {
|
||||||
nss_ZFreeIf(rvIterator);
|
nss_ZFreeIf(rvIterator);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rvIterator->current = rvIterator->list->head;
|
rvIterator->current = rvIterator->list->head;
|
||||||
if (list->lock) {
|
if (list->lock) {
|
||||||
rvIterator->lock = PZ_NewLock(nssILockOther);
|
rvIterator->lock = PZ_NewLock(nssILockOther);
|
||||||
if (!rvIterator->lock) {
|
if (!rvIterator->lock) {
|
||||||
nssList_Destroy(rvIterator->list);
|
nssList_Destroy(rvIterator->list);
|
||||||
nss_ZFreeIf(rvIterator);
|
nss_ZFreeIf(rvIterator);
|
||||||
rvIterator = NULL;
|
rvIterator = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rvIterator;
|
return rvIterator;
|
||||||
}
|
}
|
||||||
|
@ -352,7 +357,7 @@ NSS_IMPLEMENT void
|
||||||
nssListIterator_Destroy(nssListIterator *iter)
|
nssListIterator_Destroy(nssListIterator *iter)
|
||||||
{
|
{
|
||||||
if (iter->lock) {
|
if (iter->lock) {
|
||||||
(void)PZ_DestroyLock(iter->lock);
|
(void)PZ_DestroyLock(iter->lock);
|
||||||
}
|
}
|
||||||
nssList_Destroy(iter->list);
|
nssList_Destroy(iter->list);
|
||||||
nss_ZFreeIf(iter);
|
nss_ZFreeIf(iter);
|
||||||
|
@ -363,7 +368,7 @@ nssListIterator_Start(nssListIterator *iter)
|
||||||
{
|
{
|
||||||
NSSLIST_LOCK_IF(iter);
|
NSSLIST_LOCK_IF(iter);
|
||||||
if (iter->list->count == 0) {
|
if (iter->list->count == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
iter->current = iter->list->head;
|
iter->current = iter->list->head;
|
||||||
return iter->current->data;
|
return iter->current->data;
|
||||||
|
@ -375,17 +380,17 @@ nssListIterator_Next(nssListIterator *iter)
|
||||||
nssListElement *node;
|
nssListElement *node;
|
||||||
PRCList *link;
|
PRCList *link;
|
||||||
if (iter->list->count == 1 || iter->current == NULL) {
|
if (iter->list->count == 1 || iter->current == NULL) {
|
||||||
/* Reached the end of the list. Don't change the state, force to
|
/* Reached the end of the list. Don't change the state, force to
|
||||||
* user to call nssList_Finish to clean up.
|
* user to call nssList_Finish to clean up.
|
||||||
*/
|
*/
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
|
node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
|
||||||
link = &node->link;
|
link = &node->link;
|
||||||
if (link == PR_LIST_TAIL(&iter->list->head->link)) {
|
if (link == PR_LIST_TAIL(&iter->list->head->link)) {
|
||||||
/* Signal the end of the list. */
|
/* Signal the end of the list. */
|
||||||
iter->current = NULL;
|
iter->current = NULL;
|
||||||
return node->data;
|
return node->data;
|
||||||
}
|
}
|
||||||
iter->current = node;
|
iter->current = node;
|
||||||
return node->data;
|
return node->data;
|
||||||
|
@ -397,4 +402,3 @@ nssListIterator_Finish(nssListIterator *iter)
|
||||||
iter->current = iter->list->head;
|
iter->current = iter->list->head;
|
||||||
return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
|
return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,11 +44,7 @@ PR_BEGIN_EXTERN_C
|
||||||
* A pointer to an NSSArena upon success
|
* A pointer to an NSSArena upon success
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN NSSArena *
|
NSS_EXTERN NSSArena *NSSArena_Create(void);
|
||||||
NSSArena_Create
|
|
||||||
(
|
|
||||||
void
|
|
||||||
);
|
|
||||||
|
|
||||||
extern const NSSError NSS_ERROR_NO_MEMORY;
|
extern const NSSError NSS_ERROR_NO_MEMORY;
|
||||||
|
|
||||||
|
@ -56,7 +52,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
|
||||||
* NSSArena_Destroy
|
* NSSArena_Destroy
|
||||||
*
|
*
|
||||||
* This routine will destroy the specified arena, freeing all memory
|
* This routine will destroy the specified arena, freeing all memory
|
||||||
* allocated from it. This routine returns a PRStatus value; if
|
* allocated from it. This routine returns a PRStatus value; if
|
||||||
* successful, it will return PR_SUCCESS. If unsuccessful, it will
|
* successful, it will return PR_SUCCESS. If unsuccessful, it will
|
||||||
* create an error stack and return PR_FAILURE.
|
* create an error stack and return PR_FAILURE.
|
||||||
*
|
*
|
||||||
|
@ -68,11 +64,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
|
||||||
* PR_FAILURE upon failure
|
* PR_FAILURE upon failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN PRStatus NSSArena_Destroy(NSSArena *arena);
|
||||||
NSSArena_Destroy
|
|
||||||
(
|
|
||||||
NSSArena *arena
|
|
||||||
);
|
|
||||||
|
|
||||||
extern const NSSError NSS_ERROR_INVALID_ARENA;
|
extern const NSSError NSS_ERROR_INVALID_ARENA;
|
||||||
|
|
||||||
|
@ -100,25 +92,21 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
|
||||||
* A nonzero error number
|
* A nonzero error number
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN NSSError
|
NSS_EXTERN NSSError NSS_GetError(void);
|
||||||
NSS_GetError
|
|
||||||
(
|
|
||||||
void
|
|
||||||
);
|
|
||||||
|
|
||||||
extern const NSSError NSS_ERROR_NO_ERROR;
|
extern const NSSError NSS_ERROR_NO_ERROR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NSS_GetErrorStack
|
* NSS_GetErrorStack
|
||||||
*
|
*
|
||||||
* This routine returns a pointer to an array of NSSError values,
|
* This routine returns a pointer to an array of NSSError values,
|
||||||
* containingthe entire sequence or "stack" of errors set by the most
|
* containingthe entire sequence or "stack" of errors set by the most
|
||||||
* recent NSS library routine called by the same thread calling this
|
* recent NSS library routine called by the same thread calling this
|
||||||
* routine. NOTE: the caller DOES NOT OWN the memory pointed to by
|
* routine. NOTE: the caller DOES NOT OWN the memory pointed to by
|
||||||
* the return value. The pointer will remain valid until the calling
|
* the return value. The pointer will remain valid until the calling
|
||||||
* thread calls another NSS routine. The lowest-level (most specific)
|
* thread calls another NSS routine. The lowest-level (most specific)
|
||||||
* error is first in the array, and the highest-level is last. The
|
* error is first in the array, and the highest-level is last. The
|
||||||
* array is zero-terminated. This routine may return NULL upon error;
|
* array is zero-terminated. This routine may return NULL upon error;
|
||||||
* this indicates a low-memory situation.
|
* this indicates a low-memory situation.
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
|
@ -126,21 +114,17 @@ extern const NSSError NSS_ERROR_NO_ERROR;
|
||||||
* A NON-caller-owned pointer to an array of NSSError values
|
* A NON-caller-owned pointer to an array of NSSError values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN NSSError *
|
NSS_EXTERN NSSError *NSS_GetErrorStack(void);
|
||||||
NSS_GetErrorStack
|
|
||||||
(
|
|
||||||
void
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NSS_ZNEW
|
* NSS_ZNEW
|
||||||
*
|
*
|
||||||
* This preprocessor macro will allocate memory for a new object
|
* This preprocessor macro will allocate memory for a new object
|
||||||
* of the specified type with nss_ZAlloc, and will cast the
|
* of the specified type with nss_ZAlloc, and will cast the
|
||||||
* return value appropriately. If the optional arena argument is
|
* return value appropriately. If the optional arena argument is
|
||||||
* non-null, the memory will be obtained from that arena; otherwise,
|
* non-null, the memory will be obtained from that arena; otherwise,
|
||||||
* the memory will be obtained from the heap. This routine may
|
* the memory will be obtained from the heap. This routine may
|
||||||
* return NULL upon error, in which case it will have set an error
|
* return NULL upon error, in which case it will have set an error
|
||||||
* upon the error stack.
|
* upon the error stack.
|
||||||
*
|
*
|
||||||
* The error may be one of the following values:
|
* The error may be one of the following values:
|
||||||
|
@ -152,7 +136,6 @@ NSS_GetErrorStack
|
||||||
* A pointer to the new segment of zeroed memory
|
* A pointer to the new segment of zeroed memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The following line exceeds 72 characters, but emacs barfs if we split it. */
|
|
||||||
#define NSS_ZNEW(arenaOpt, type) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type)))
|
#define NSS_ZNEW(arenaOpt, type) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -160,10 +143,10 @@ NSS_GetErrorStack
|
||||||
*
|
*
|
||||||
* This preprocessor macro will allocate memory for an array of
|
* This preprocessor macro will allocate memory for an array of
|
||||||
* new objects, and will cast the return value appropriately.
|
* new objects, and will cast the return value appropriately.
|
||||||
* If the optional arena argument is non-null, the memory will
|
* If the optional arena argument is non-null, the memory will
|
||||||
* be obtained from that arena; otherwise, the memory will be
|
* be obtained from that arena; otherwise, the memory will be
|
||||||
* obtained from the heap. This routine may return NULL upon
|
* obtained from the heap. This routine may return NULL upon
|
||||||
* error, in which case it will have set an error upon the error
|
* error, in which case it will have set an error upon the error
|
||||||
* stack. The array size may be specified as zero.
|
* stack. The array size may be specified as zero.
|
||||||
*
|
*
|
||||||
* The error may be one of the following values:
|
* The error may be one of the following values:
|
||||||
|
@ -175,20 +158,19 @@ NSS_GetErrorStack
|
||||||
* A pointer to the new segment of zeroed memory
|
* A pointer to the new segment of zeroed memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The following line exceeds 72 characters, but emacs barfs if we split it. */
|
#define NSS_ZNEWARRAY(arenaOpt, type, quantity) \
|
||||||
#define NSS_ZNEWARRAY(arenaOpt, type, quantity) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
|
((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NSS_ZAlloc
|
* NSS_ZAlloc
|
||||||
*
|
*
|
||||||
* This routine allocates and zeroes a section of memory of the
|
* This routine allocates and zeroes a section of memory of the
|
||||||
* size, and returns to the caller a pointer to that memory. If
|
* size, and returns to the caller a pointer to that memory. If
|
||||||
* the optional arena argument is non-null, the memory will be
|
* the optional arena argument is non-null, the memory will be
|
||||||
* obtained from that arena; otherwise, the memory will be obtained
|
* obtained from that arena; otherwise, the memory will be obtained
|
||||||
* from the heap. This routine may return NULL upon error, in
|
* from the heap. This routine may return NULL upon error, in
|
||||||
* which case it will have set an error upon the error stack. The
|
* which case it will have set an error upon the error stack. The
|
||||||
* value specified for size may be zero; in which case a valid
|
* value specified for size may be zero; in which case a valid
|
||||||
* zero-length block of memory will be allocated. This block may
|
* zero-length block of memory will be allocated. This block may
|
||||||
* be expanded by calling NSS_ZRealloc.
|
* be expanded by calling NSS_ZRealloc.
|
||||||
*
|
*
|
||||||
|
@ -202,21 +184,16 @@ NSS_GetErrorStack
|
||||||
* A pointer to the new segment of zeroed memory
|
* A pointer to the new segment of zeroed memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN void *
|
NSS_EXTERN void *NSS_ZAlloc(NSSArena *arenaOpt, PRUint32 size);
|
||||||
NSS_ZAlloc
|
|
||||||
(
|
|
||||||
NSSArena *arenaOpt,
|
|
||||||
PRUint32 size
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NSS_ZRealloc
|
* NSS_ZRealloc
|
||||||
*
|
*
|
||||||
* This routine reallocates a block of memory obtained by calling
|
* This routine reallocates a block of memory obtained by calling
|
||||||
* nss_ZAlloc or nss_ZRealloc. The portion of memory
|
* nss_ZAlloc or nss_ZRealloc. The portion of memory
|
||||||
* between the new and old sizes -- which is either being newly
|
* between the new and old sizes -- which is either being newly
|
||||||
* obtained or released -- is in either case zeroed. This routine
|
* obtained or released -- is in either case zeroed. This routine
|
||||||
* may return NULL upon failure, in which case it will have placed
|
* may return NULL upon failure, in which case it will have placed
|
||||||
* an error on the error stack.
|
* an error on the error stack.
|
||||||
*
|
*
|
||||||
* The error may be one of the following values:
|
* The error may be one of the following values:
|
||||||
|
@ -229,13 +206,7 @@ NSS_ZAlloc
|
||||||
* A pointer to the replacement segment of memory
|
* A pointer to the replacement segment of memory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN void *
|
NSS_EXTERN void *NSS_ZRealloc(void *pointer, PRUint32 newSize);
|
||||||
NSS_ZRealloc
|
|
||||||
(
|
|
||||||
void *pointer,
|
|
||||||
PRUint32 newSize
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NSS_ZFreeIf
|
* NSS_ZFreeIf
|
||||||
|
@ -255,11 +226,7 @@ NSS_ZRealloc
|
||||||
* PR_FAILURE
|
* PR_FAILURE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_EXTERN PRStatus
|
NSS_EXTERN PRStatus NSS_ZFreeIf(void *pointer);
|
||||||
NSS_ZFreeIf
|
|
||||||
(
|
|
||||||
void *pointer
|
|
||||||
);
|
|
||||||
|
|
||||||
PR_END_EXTERN_C
|
PR_END_EXTERN_C
|
||||||
|
|
||||||
|
|
|
@ -18,16 +18,16 @@
|
||||||
* NSS_EXTERN, NSS_IMPLEMENT, NSS_EXTERN_DATA, NSS_IMPLEMENT_DATA
|
* NSS_EXTERN, NSS_IMPLEMENT, NSS_EXTERN_DATA, NSS_IMPLEMENT_DATA
|
||||||
*
|
*
|
||||||
* NSS has its own versions of these NSPR macros, in a form which
|
* NSS has its own versions of these NSPR macros, in a form which
|
||||||
* does not confuse ctags and other related utilities. NSPR
|
* does not confuse ctags and other related utilities. NSPR
|
||||||
* defines these macros to take the type as an argument, because
|
* defines these macros to take the type as an argument, because
|
||||||
* of certain OS requirements on platforms not supported by NSS.
|
* of certain OS requirements on platforms not supported by NSS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DUMMY /* dummy */
|
#define DUMMY /* dummy */
|
||||||
#define NSS_EXTERN extern
|
#define NSS_EXTERN extern
|
||||||
#define NSS_EXTERN_DATA extern
|
#define NSS_EXTERN_DATA extern
|
||||||
#define NSS_IMPLEMENT
|
#define NSS_IMPLEMENT
|
||||||
#define NSS_IMPLEMENT_DATA
|
#define NSS_IMPLEMENT_DATA
|
||||||
|
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ PR_BEGIN_EXTERN_C
|
||||||
*
|
*
|
||||||
* Calls to NSS routines may result in one or more errors being placed
|
* Calls to NSS routines may result in one or more errors being placed
|
||||||
* on the calling thread's "error stack." Every possible error that
|
* on the calling thread's "error stack." Every possible error that
|
||||||
* may be returned from a function is declared where the function is
|
* may be returned from a function is declared where the function is
|
||||||
* prototyped. All errors are of the following type.
|
* prototyped. All errors are of the following type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ typedef PRInt32 NSSError;
|
||||||
*
|
*
|
||||||
* Arenas are logical sets of heap memory, from which memory may be
|
* Arenas are logical sets of heap memory, from which memory may be
|
||||||
* allocated. When an arena is destroyed, all memory allocated within
|
* allocated. When an arena is destroyed, all memory allocated within
|
||||||
* that arena is implicitly freed. These arenas are thread-safe:
|
* that arena is implicitly freed. These arenas are thread-safe:
|
||||||
* an arena pointer may be used by multiple threads simultaneously.
|
* an arena pointer may be used by multiple threads simultaneously.
|
||||||
* However, as they are not backed by shared memory, they may only be
|
* However, as they are not backed by shared memory, they may only be
|
||||||
* used within one process.
|
* used within one process.
|
||||||
|
@ -64,12 +64,11 @@ typedef struct NSSArenaStr NSSArena;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct NSSItemStr {
|
struct NSSItemStr {
|
||||||
void *data;
|
void *data;
|
||||||
PRUint32 size;
|
PRUint32 size;
|
||||||
};
|
};
|
||||||
typedef struct NSSItemStr NSSItem;
|
typedef struct NSSItemStr NSSItem;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NSSBER
|
* NSSBER
|
||||||
*
|
*
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tracker.c
|
* tracker.c
|
||||||
*
|
*
|
||||||
* This file contains the code used by the pointer-tracking calls used
|
* This file contains the code used by the pointer-tracking calls used
|
||||||
* in the debug builds to catch bad pointers. The entire contents are
|
* in the debug builds to catch bad pointers. The entire contents are
|
||||||
* only available in debug builds (both internal and external builds).
|
* only available in debug builds (both internal and external builds).
|
||||||
|
@ -24,12 +24,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PLHashNumber PR_CALLBACK
|
static PLHashNumber PR_CALLBACK
|
||||||
identity_hash
|
identity_hash(const void *key)
|
||||||
(
|
|
||||||
const void *key
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return (PLHashNumber)((char *)key - (char *)NULL);
|
return (PLHashNumber)((char *)key - (char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -41,44 +38,38 @@ identity_hash
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PRStatus
|
static PRStatus
|
||||||
trackerOnceFunc
|
trackerOnceFunc(void *arg)
|
||||||
(
|
|
||||||
void *arg
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
nssPointerTracker *tracker = (nssPointerTracker *)arg;
|
nssPointerTracker *tracker = (nssPointerTracker *)arg;
|
||||||
|
|
||||||
tracker->lock = PZ_NewLock(nssILockOther);
|
tracker->lock = PZ_NewLock(nssILockOther);
|
||||||
if( (PZLock *)NULL == tracker->lock ) {
|
if ((PZLock *)NULL == tracker->lock) {
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracker->table = PL_NewHashTable(0,
|
tracker->table =
|
||||||
identity_hash,
|
PL_NewHashTable(0, identity_hash, PL_CompareValues, PL_CompareValues,
|
||||||
PL_CompareValues,
|
(PLHashAllocOps *)NULL, (void *)NULL);
|
||||||
PL_CompareValues,
|
if ((PLHashTable *)NULL == tracker->table) {
|
||||||
(PLHashAllocOps *)NULL,
|
PZ_DestroyLock(tracker->lock);
|
||||||
(void *)NULL);
|
tracker->lock = (PZLock *)NULL;
|
||||||
if( (PLHashTable *)NULL == tracker->table ) {
|
return PR_FAILURE;
|
||||||
PZ_DestroyLock(tracker->lock);
|
}
|
||||||
tracker->lock = (PZLock *)NULL;
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nssPointerTracker_initialize
|
* nssPointerTracker_initialize
|
||||||
*
|
*
|
||||||
* This method is only present in debug builds.
|
* This method is only present in debug builds.
|
||||||
*
|
*
|
||||||
* This routine initializes an nssPointerTracker object. Note that
|
* This routine initializes an nssPointerTracker object. Note that
|
||||||
* the object must have been declared *static* to guarantee that it
|
* the object must have been declared *static* to guarantee that it
|
||||||
* is in a zeroed state initially. This routine is idempotent, and
|
* is in a zeroed state initially. This routine is idempotent, and
|
||||||
* may even be safely called by multiple threads simultaneously with
|
* may even be safely called by multiple threads simultaneously with
|
||||||
* the same argument. This routine returns a PRStatus value; if
|
* the same argument. This routine returns a PRStatus value; if
|
||||||
* successful, it will return PR_SUCCESS. On failure it will set an
|
* successful, it will return PR_SUCCESS. On failure it will set an
|
||||||
* error on the error stack and return PR_FAILURE.
|
* error on the error stack and return PR_FAILURE.
|
||||||
*
|
*
|
||||||
* The error may be one of the following values:
|
* The error may be one of the following values:
|
||||||
|
@ -90,17 +81,14 @@ trackerOnceFunc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssPointerTracker_initialize
|
nssPointerTracker_initialize(nssPointerTracker *tracker)
|
||||||
(
|
|
||||||
nssPointerTracker *tracker
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
|
PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
|
||||||
if( PR_SUCCESS != rv ) {
|
if (PR_SUCCESS != rv) {
|
||||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DONT_DESTROY_EMPTY_TABLES
|
#ifdef DONT_DESTROY_EMPTY_TABLES
|
||||||
|
@ -114,14 +102,9 @@ nssPointerTracker_initialize
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PRIntn PR_CALLBACK
|
static PRIntn PR_CALLBACK
|
||||||
count_entries
|
count_entries(PLHashEntry *he, PRIntn index, void *arg)
|
||||||
(
|
|
||||||
PLHashEntry *he,
|
|
||||||
PRIntn index,
|
|
||||||
void *arg
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return HT_ENUMERATE_NEXT;
|
return HT_ENUMERATE_NEXT;
|
||||||
}
|
}
|
||||||
#endif /* DONT_DESTROY_EMPTY_TABLES */
|
#endif /* DONT_DESTROY_EMPTY_TABLES */
|
||||||
|
|
||||||
|
@ -138,7 +121,7 @@ static const PRCallOnceType zero_once;
|
||||||
* nssPointerTracker_finalize
|
* nssPointerTracker_finalize
|
||||||
*
|
*
|
||||||
* This method is only present in debug builds.
|
* This method is only present in debug builds.
|
||||||
*
|
*
|
||||||
* This routine returns the nssPointerTracker object to the pre-
|
* This routine returns the nssPointerTracker object to the pre-
|
||||||
* initialized state, releasing all resources used by the object.
|
* initialized state, releasing all resources used by the object.
|
||||||
* It will *NOT* destroy the objects being tracked by the pointer
|
* It will *NOT* destroy the objects being tracked by the pointer
|
||||||
|
@ -160,58 +143,54 @@ static const PRCallOnceType zero_once;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssPointerTracker_finalize
|
nssPointerTracker_finalize(nssPointerTracker *tracker)
|
||||||
(
|
|
||||||
nssPointerTracker *tracker
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PZLock *lock;
|
PZLock *lock;
|
||||||
|
|
||||||
if( (nssPointerTracker *)NULL == tracker ) {
|
if ((nssPointerTracker *)NULL == tracker) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (PZLock *)NULL == tracker->lock ) {
|
if ((PZLock *)NULL == tracker->lock) {
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock = tracker->lock;
|
lock = tracker->lock;
|
||||||
PZ_Lock(lock);
|
PZ_Lock(lock);
|
||||||
|
|
||||||
if( (PLHashTable *)NULL == tracker->table ) {
|
if ((PLHashTable *)NULL == tracker->table) {
|
||||||
PZ_Unlock(lock);
|
PZ_Unlock(lock);
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DONT_DESTROY_EMPTY_TABLES
|
#ifdef DONT_DESTROY_EMPTY_TABLES
|
||||||
/*
|
/*
|
||||||
* I changed my mind; I think we don't want this after all.
|
* I changed my mind; I think we don't want this after all.
|
||||||
* Comments?
|
* Comments?
|
||||||
*/
|
*/
|
||||||
count = PL_HashTableEnumerateEntries(tracker->table,
|
count = PL_HashTableEnumerateEntries(tracker->table, count_entries,
|
||||||
count_entries,
|
(void *)NULL);
|
||||||
(void *)NULL);
|
|
||||||
|
|
||||||
if( 0 != count ) {
|
if (0 != count) {
|
||||||
PZ_Unlock(lock);
|
PZ_Unlock(lock);
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
|
nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
#endif /* DONT_DESTROY_EMPTY_TABLES */
|
#endif /* DONT_DESTROY_EMPTY_TABLES */
|
||||||
|
|
||||||
PL_HashTableDestroy(tracker->table);
|
PL_HashTableDestroy(tracker->table);
|
||||||
/* memset(tracker, 0, sizeof(nssPointerTracker)); */
|
/* memset(tracker, 0, sizeof(nssPointerTracker)); */
|
||||||
tracker->once = zero_once;
|
tracker->once = zero_once;
|
||||||
tracker->lock = (PZLock *)NULL;
|
tracker->lock = (PZLock *)NULL;
|
||||||
tracker->table = (PLHashTable *)NULL;
|
tracker->table = (PLHashTable *)NULL;
|
||||||
|
|
||||||
PZ_Unlock(lock);
|
PZ_Unlock(lock);
|
||||||
PZ_DestroyLock(lock);
|
PZ_DestroyLock(lock);
|
||||||
|
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -238,63 +217,59 @@ nssPointerTracker_finalize
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssPointerTracker_add
|
nssPointerTracker_add(nssPointerTracker *tracker, const void *pointer)
|
||||||
(
|
|
||||||
nssPointerTracker *tracker,
|
|
||||||
const void *pointer
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
void *check;
|
void *check;
|
||||||
PLHashEntry *entry;
|
PLHashEntry *entry;
|
||||||
|
|
||||||
if( (nssPointerTracker *)NULL == tracker ) {
|
if ((nssPointerTracker *)NULL == tracker) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (PZLock *)NULL == tracker->lock ) {
|
if ((PZLock *)NULL == tracker->lock) {
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PZ_Lock(tracker->lock);
|
PZ_Lock(tracker->lock);
|
||||||
|
|
||||||
|
if ((PLHashTable *)NULL == tracker->table) {
|
||||||
|
PZ_Unlock(tracker->lock);
|
||||||
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
|
return PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
check = PL_HashTableLookup(tracker->table, pointer);
|
||||||
|
if ((void *)NULL != check) {
|
||||||
|
PZ_Unlock(tracker->lock);
|
||||||
|
nss_SetError(NSS_ERROR_DUPLICATE_POINTER);
|
||||||
|
return PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
|
||||||
|
|
||||||
if( (PLHashTable *)NULL == tracker->table ) {
|
|
||||||
PZ_Unlock(tracker->lock);
|
PZ_Unlock(tracker->lock);
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
check = PL_HashTableLookup(tracker->table, pointer);
|
if ((PLHashEntry *)NULL == entry) {
|
||||||
if( (void *)NULL != check ) {
|
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||||
PZ_Unlock(tracker->lock);
|
return PR_FAILURE;
|
||||||
nss_SetError(NSS_ERROR_DUPLICATE_POINTER);
|
}
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
|
return PR_SUCCESS;
|
||||||
|
|
||||||
PZ_Unlock(tracker->lock);
|
|
||||||
|
|
||||||
if( (PLHashEntry *)NULL == entry ) {
|
|
||||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nssPointerTracker_remove
|
* nssPointerTracker_remove
|
||||||
*
|
*
|
||||||
* This method is only present in debug builds.
|
* This method is only present in debug builds.
|
||||||
*
|
*
|
||||||
* This routine removes the specified pointer from the
|
* This routine removes the specified pointer from the
|
||||||
* nssPointerTracker object. It does not call any destructor for the
|
* nssPointerTracker object. It does not call any destructor for the
|
||||||
* object; rather, this should be called from the object's destructor.
|
* object; rather, this should be called from the object's destructor.
|
||||||
* The nssPointerTracker is threadsafe, but this call is not
|
* The nssPointerTracker is threadsafe, but this call is not
|
||||||
* idempotent. This routine returns a PRStatus value; if successful
|
* idempotent. This routine returns a PRStatus value; if successful
|
||||||
* it will return PR_SUCCESS. On failure it will set an error on the
|
* it will return PR_SUCCESS. On failure it will set an error on the
|
||||||
* error stack and return PR_FAILURE.
|
* error stack and return PR_FAILURE.
|
||||||
*
|
*
|
||||||
* The error may be one of the following values:
|
* The error may be one of the following values:
|
||||||
|
@ -308,41 +283,37 @@ nssPointerTracker_add
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssPointerTracker_remove
|
nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer)
|
||||||
(
|
|
||||||
nssPointerTracker *tracker,
|
|
||||||
const void *pointer
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PRBool registered;
|
PRBool registered;
|
||||||
|
|
||||||
if( (nssPointerTracker *)NULL == tracker ) {
|
if ((nssPointerTracker *)NULL == tracker) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (PZLock *)NULL == tracker->lock ) {
|
if ((PZLock *)NULL == tracker->lock) {
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PZ_Lock(tracker->lock);
|
PZ_Lock(tracker->lock);
|
||||||
|
|
||||||
if( (PLHashTable *)NULL == tracker->table ) {
|
if ((PLHashTable *)NULL == tracker->table) {
|
||||||
|
PZ_Unlock(tracker->lock);
|
||||||
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
|
return PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
registered = PL_HashTableRemove(tracker->table, pointer);
|
||||||
PZ_Unlock(tracker->lock);
|
PZ_Unlock(tracker->lock);
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
registered = PL_HashTableRemove(tracker->table, pointer);
|
if (!registered) {
|
||||||
PZ_Unlock(tracker->lock);
|
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
||||||
|
return PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if( !registered ) {
|
return PR_SUCCESS;
|
||||||
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -354,10 +325,10 @@ nssPointerTracker_remove
|
||||||
* with the nssPointerTracker object. The nssPointerTracker object is
|
* with the nssPointerTracker object. The nssPointerTracker object is
|
||||||
* threadsafe, and this call may be safely called from multiple threads
|
* threadsafe, and this call may be safely called from multiple threads
|
||||||
* simultaneously with the same arguments. This routine returns a
|
* simultaneously with the same arguments. This routine returns a
|
||||||
* PRStatus value; if the pointer is registered this will return
|
* PRStatus value; if the pointer is registered this will return
|
||||||
* PR_SUCCESS. Otherwise it will set an error on the error stack and
|
* PR_SUCCESS. Otherwise it will set an error on the error stack and
|
||||||
* return PR_FAILURE. Although the error is suitable for leaving on
|
* return PR_FAILURE. Although the error is suitable for leaving on
|
||||||
* the stack, callers may wish to augment the information available by
|
* the stack, callers may wish to augment the information available by
|
||||||
* placing a more type-specific error on the stack.
|
* placing a more type-specific error on the stack.
|
||||||
*
|
*
|
||||||
* The error may be one of the following values:
|
* The error may be one of the following values:
|
||||||
|
@ -371,41 +342,37 @@ nssPointerTracker_remove
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NSS_IMPLEMENT PRStatus
|
NSS_IMPLEMENT PRStatus
|
||||||
nssPointerTracker_verify
|
nssPointerTracker_verify(nssPointerTracker *tracker, const void *pointer)
|
||||||
(
|
|
||||||
nssPointerTracker *tracker,
|
|
||||||
const void *pointer
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
void *check;
|
void *check;
|
||||||
|
|
||||||
if( (nssPointerTracker *)NULL == tracker ) {
|
if ((nssPointerTracker *)NULL == tracker) {
|
||||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (PZLock *)NULL == tracker->lock ) {
|
if ((PZLock *)NULL == tracker->lock) {
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
return PR_FAILURE;
|
return PR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PZ_Lock(tracker->lock);
|
PZ_Lock(tracker->lock);
|
||||||
|
|
||||||
if( (PLHashTable *)NULL == tracker->table ) {
|
if ((PLHashTable *)NULL == tracker->table) {
|
||||||
|
PZ_Unlock(tracker->lock);
|
||||||
|
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||||
|
return PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
check = PL_HashTableLookup(tracker->table, pointer);
|
||||||
PZ_Unlock(tracker->lock);
|
PZ_Unlock(tracker->lock);
|
||||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
check = PL_HashTableLookup(tracker->table, pointer);
|
if ((void *)NULL == check) {
|
||||||
PZ_Unlock(tracker->lock);
|
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
||||||
|
return PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if( (void *)NULL == check ) {
|
return PR_SUCCESS;
|
||||||
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
|
||||||
return PR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,18 +5,17 @@
|
||||||
#ifndef _CERTDB_H_
|
#ifndef _CERTDB_H_
|
||||||
#define _CERTDB_H_
|
#define _CERTDB_H_
|
||||||
|
|
||||||
|
|
||||||
/* common flags for all types of certificates */
|
/* common flags for all types of certificates */
|
||||||
#define CERTDB_TERMINAL_RECORD (1u<<0)
|
#define CERTDB_TERMINAL_RECORD (1u << 0)
|
||||||
#define CERTDB_TRUSTED (1u<<1)
|
#define CERTDB_TRUSTED (1u << 1)
|
||||||
#define CERTDB_SEND_WARN (1u<<2)
|
#define CERTDB_SEND_WARN (1u << 2)
|
||||||
#define CERTDB_VALID_CA (1u<<3)
|
#define CERTDB_VALID_CA (1u << 3)
|
||||||
#define CERTDB_TRUSTED_CA (1u<<4) /* trusted for issuing server certs */
|
#define CERTDB_TRUSTED_CA (1u << 4) /* trusted for issuing server certs */
|
||||||
#define CERTDB_NS_TRUSTED_CA (1u<<5)
|
#define CERTDB_NS_TRUSTED_CA (1u << 5)
|
||||||
#define CERTDB_USER (1u<<6)
|
#define CERTDB_USER (1u << 6)
|
||||||
#define CERTDB_TRUSTED_CLIENT_CA (1u<<7) /* trusted for issuing client certs */
|
#define CERTDB_TRUSTED_CLIENT_CA (1u << 7) /* trusted for issuing client certs */
|
||||||
#define CERTDB_INVISIBLE_CA (1u<<8) /* don't show in UI */
|
#define CERTDB_INVISIBLE_CA (1u << 8) /* don't show in UI */
|
||||||
#define CERTDB_GOVT_APPROVED_CA (1u<<9) /* can do strong crypto in export ver */
|
#define CERTDB_GOVT_APPROVED_CA (1u << 9) /* can do strong crypto in export ver */
|
||||||
|
|
||||||
/* old usage, to keep old programs compiling */
|
/* old usage, to keep old programs compiling */
|
||||||
/* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
|
/* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
|
||||||
|
@ -26,54 +25,48 @@
|
||||||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
|
#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
|
||||||
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
|
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
|
||||||
#else
|
#else
|
||||||
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated
|
typedef unsigned int __CERTDB_VALID_PEER __attribute__((
|
||||||
("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD")));
|
deprecated("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD")));
|
||||||
#endif
|
#endif
|
||||||
#define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER) CERTDB_TERMINAL_RECORD)
|
#define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER)CERTDB_TERMINAL_RECORD)
|
||||||
#else
|
#else
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#pragma deprecated(CERTDB_VALID_PEER)
|
#pragma deprecated(CERTDB_VALID_PEER)
|
||||||
#endif
|
#endif
|
||||||
#define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
|
#define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SEC_BEGIN_PROTOS
|
SEC_BEGIN_PROTOS
|
||||||
|
|
||||||
CERTSignedCrl *
|
CERTSignedCrl *SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey,
|
||||||
SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type);
|
int type);
|
||||||
|
|
||||||
CERTSignedCrl *
|
CERTSignedCrl *SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey,
|
||||||
SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type);
|
int type);
|
||||||
|
|
||||||
CERTSignedCrl *
|
CERTSignedCrl *SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl,
|
||||||
SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type);
|
int type);
|
||||||
|
|
||||||
PRBool
|
PRBool SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
|
||||||
SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
|
CERTCertDBHandle *handle);
|
||||||
CERTCertDBHandle *handle);
|
CERTSignedCrl *SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl,
|
||||||
CERTSignedCrl *
|
int type);
|
||||||
SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus SEC_DeletePermCRL(CERTSignedCrl *crl);
|
||||||
SEC_DeletePermCRL(CERTSignedCrl *crl);
|
|
||||||
|
|
||||||
|
SECStatus SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes,
|
||||||
|
int type);
|
||||||
|
|
||||||
SECStatus
|
SECStatus SEC_DestroyCrl(CERTSignedCrl *crl);
|
||||||
SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type);
|
|
||||||
|
|
||||||
SECStatus
|
CERTSignedCrl *SEC_DupCrl(CERTSignedCrl *acrl);
|
||||||
SEC_DestroyCrl(CERTSignedCrl *crl);
|
|
||||||
|
|
||||||
CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl);
|
SECStatus CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
||||||
|
CERTCertTrust *trust);
|
||||||
SECStatus
|
|
||||||
CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
|
|
||||||
CERTCertTrust *trust);
|
|
||||||
|
|
||||||
SECStatus SEC_DeletePermCertificate(CERTCertificate *cert);
|
SECStatus SEC_DeletePermCertificate(CERTCertificate *cert);
|
||||||
|
|
||||||
PRBool
|
PRBool SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
|
||||||
SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Extract the validity times from a CRL
|
** Extract the validity times from a CRL
|
||||||
|
@ -81,8 +74,7 @@ SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
|
||||||
** "notBefore" is the start of the validity period (last update)
|
** "notBefore" is the start of the validity period (last update)
|
||||||
** "notAfter" is the end of the validity period (next update)
|
** "notAfter" is the end of the validity period (next update)
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
|
||||||
SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Check the validity times of a crl vs. time 't', allowing
|
** Check the validity times of a crl vs. time 't', allowing
|
||||||
|
@ -90,8 +82,7 @@ SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
|
||||||
** "crl" is the certificate to be checked
|
** "crl" is the certificate to be checked
|
||||||
** "t" is the time to check against
|
** "t" is the time to check against
|
||||||
*/
|
*/
|
||||||
SECCertTimeValidity
|
SECCertTimeValidity SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
|
||||||
SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
|
|
||||||
|
|
||||||
SEC_END_PROTOS
|
SEC_END_PROTOS
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,7 @@ struct OpaqueCRLFieldsStr {
|
||||||
|
|
||||||
typedef struct PreAllocatorStr PreAllocator;
|
typedef struct PreAllocatorStr PreAllocator;
|
||||||
|
|
||||||
struct PreAllocatorStr
|
struct PreAllocatorStr {
|
||||||
{
|
|
||||||
PRSize len;
|
PRSize len;
|
||||||
void* data;
|
void* data;
|
||||||
PRSize used;
|
PRSize used;
|
||||||
|
@ -56,32 +55,31 @@ struct CRLEntryCacheStr {
|
||||||
CRLEntryCache *prev, *next;
|
CRLEntryCache *prev, *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
|
#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
|
||||||
if we have CRL objects with an invalid DER or signature. Can be
|
if we have CRL objects with an invalid DER or signature. Can be
|
||||||
cleared if the invalid objects are deleted from the token */
|
cleared if the invalid objects are deleted from the token */
|
||||||
#define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set
|
#define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set
|
||||||
if the last CRL fetch encountered an error. Can be cleared if a
|
if the last CRL fetch encountered an error. Can be cleared if a
|
||||||
new fetch succeeds */
|
new fetch succeeds */
|
||||||
|
|
||||||
#define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set
|
#define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set
|
||||||
if we don't have enough memory to build the hash table of entries */
|
if we don't have enough memory to build the hash table of entries */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CRL_OriginToken = 0, /* CRL came from PKCS#11 token */
|
CRL_OriginToken = 0, /* CRL came from PKCS#11 token */
|
||||||
CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */
|
CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */
|
||||||
} CRLOrigin;
|
} CRLOrigin;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
dpcacheNoEntry = 0, /* no entry found for this SN */
|
dpcacheNoEntry = 0, /* no entry found for this SN */
|
||||||
dpcacheFoundEntry = 1, /* entry found for this SN */
|
dpcacheFoundEntry = 1, /* entry found for this SN */
|
||||||
dpcacheCallerError = 2, /* invalid args */
|
dpcacheCallerError = 2, /* invalid args */
|
||||||
dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */
|
dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */
|
||||||
/* or unverified */
|
/* or unverified */
|
||||||
dpcacheEmpty = 4, /* no CRL in cache */
|
dpcacheEmpty = 4, /* no CRL in cache */
|
||||||
dpcacheLookupError = 5 /* internal error */
|
dpcacheLookupError = 5 /* internal error */
|
||||||
} dpcacheStatus;
|
} dpcacheStatus;
|
||||||
|
|
||||||
|
|
||||||
struct CachedCrlStr {
|
struct CachedCrlStr {
|
||||||
CERTSignedCrl* crl;
|
CERTSignedCrl* crl;
|
||||||
CRLOrigin origin;
|
CRLOrigin origin;
|
||||||
|
@ -98,11 +96,11 @@ struct CachedCrlStr {
|
||||||
*/
|
*/
|
||||||
PLHashTable* entries;
|
PLHashTable* entries;
|
||||||
PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */
|
PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */
|
||||||
PRBool sigChecked; /* this CRL signature has already been checked */
|
PRBool sigChecked; /* this CRL signature has already been checked */
|
||||||
PRBool sigValid; /* signature verification status .
|
PRBool sigValid; /* signature verification status .
|
||||||
Only meaningful if checked is PR_TRUE . */
|
Only meaningful if checked is PR_TRUE . */
|
||||||
PRBool unbuildable; /* Avoid using assosiated CRL is it fails
|
PRBool unbuildable; /* Avoid using assosiated CRL is it fails
|
||||||
* a decoding step */
|
* a decoding step */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CRL distribution point cache object
|
/* CRL distribution point cache object
|
||||||
|
@ -116,15 +114,15 @@ struct CRLDPCacheStr {
|
||||||
#else
|
#else
|
||||||
PRLock* lock;
|
PRLock* lock;
|
||||||
#endif
|
#endif
|
||||||
SECItem *issuerDERCert; /* issuer DER cert. Don't hold a reference
|
SECItem* issuerDERCert; /* issuer DER cert. Don't hold a reference
|
||||||
to the actual cert so the trust can be
|
to the actual cert so the trust can be
|
||||||
updated on the cert automatically.
|
updated on the cert automatically.
|
||||||
XXX there may be multiple issuer certs,
|
XXX there may be multiple issuer certs,
|
||||||
with different validity dates. Also
|
with different validity dates. Also
|
||||||
need to deal with SKID/AKID . See
|
need to deal with SKID/AKID . See
|
||||||
bugzilla 217387, 233118 */
|
bugzilla 217387, 233118 */
|
||||||
|
|
||||||
CERTCertDBHandle *dbHandle;
|
CERTCertDBHandle* dbHandle;
|
||||||
|
|
||||||
SECItem* subject; /* DER of issuer subject */
|
SECItem* subject; /* DER of issuer subject */
|
||||||
SECItem* distributionPoint; /* DER of distribution point. This may be
|
SECItem* distributionPoint; /* DER of distribution point. This may be
|
||||||
|
@ -133,31 +131,31 @@ struct CRLDPCacheStr {
|
||||||
Currently not used. */
|
Currently not used. */
|
||||||
|
|
||||||
/* array of full CRLs matching this distribution point */
|
/* array of full CRLs matching this distribution point */
|
||||||
PRUint32 ncrls; /* total number of CRLs in crls */
|
PRUint32 ncrls; /* total number of CRLs in crls */
|
||||||
CachedCrl** crls; /* array of all matching CRLs */
|
CachedCrl** crls; /* array of all matching CRLs */
|
||||||
/* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several
|
/* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several
|
||||||
issuers. In the future, we'll need to globally recycle the CRL in a
|
issuers. In the future, we'll need to globally recycle the CRL in a
|
||||||
separate list in order to avoid extra lookups, decodes, and copies */
|
separate list in order to avoid extra lookups, decodes, and copies */
|
||||||
|
|
||||||
/* pointers to good decoded CRLs used to build the cache */
|
/* pointers to good decoded CRLs used to build the cache */
|
||||||
CachedCrl* selected; /* full CRL selected for use in the cache */
|
CachedCrl* selected; /* full CRL selected for use in the cache */
|
||||||
#if 0
|
#if 0
|
||||||
/* for future use */
|
/* for future use */
|
||||||
PRInt32 numdeltas; /* number of delta CRLs used for the cache */
|
PRInt32 numdeltas; /* number of delta CRLs used for the cache */
|
||||||
CachedCrl** deltas; /* delta CRLs used for the cache */
|
CachedCrl** deltas; /* delta CRLs used for the cache */
|
||||||
#endif
|
#endif
|
||||||
/* cache invalidity bitflag */
|
/* cache invalidity bitflag */
|
||||||
PRUint16 invalid; /* this state will be set if either
|
PRUint16 invalid; /* this state will be set if either
|
||||||
CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
|
CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
|
||||||
In those cases, all certs are considered to have unknown status.
|
In those cases, all certs are considered to have unknown status.
|
||||||
The invalid state can only be cleared during an update if all
|
The invalid state can only be cleared during an update if all
|
||||||
error states are cleared */
|
error states are cleared */
|
||||||
PRBool refresh; /* manual refresh from tokens has been forced */
|
PRBool refresh; /* manual refresh from tokens has been forced */
|
||||||
PRBool mustchoose; /* trigger reselection algorithm, for case when
|
PRBool mustchoose; /* trigger reselection algorithm, for case when
|
||||||
RAM CRL objects are dropped from the cache */
|
RAM CRL objects are dropped from the cache */
|
||||||
PRTime lastfetch; /* time a CRL token fetch was last performed */
|
PRTime lastfetch; /* time a CRL token fetch was last performed */
|
||||||
PRTime lastcheck; /* time CRL token objects were last checked for
|
PRTime lastcheck; /* time CRL token objects were last checked for
|
||||||
existence */
|
existence */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CRL issuer cache object
|
/* CRL issuer cache object
|
||||||
|
@ -168,7 +166,7 @@ struct CRLDPCacheStr {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct CRLIssuerCacheStr {
|
struct CRLIssuerCacheStr {
|
||||||
SECItem* subject; /* DER of issuer subject */
|
SECItem* subject; /* DER of issuer subject */
|
||||||
CRLDPCache* dpp;
|
CRLDPCache* dpp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,46 +192,40 @@ SECStatus ShutdownCRLCache(void);
|
||||||
** null-terminated strings, terminated by a zero-length string.
|
** null-terminated strings, terminated by a zero-length string.
|
||||||
** This function is intended to be internal to NSS.
|
** This function is intended to be internal to NSS.
|
||||||
*/
|
*/
|
||||||
extern char * cert_GetCertificateEmailAddresses(CERTCertificate *cert);
|
extern char* cert_GetCertificateEmailAddresses(CERTCertificate* cert);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These functions are used to map subjectKeyID extension values to certs
|
* These functions are used to map subjectKeyID extension values to certs
|
||||||
* and to keep track of the checks for user certificates in each slot
|
* and to keep track of the checks for user certificates in each slot
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus cert_CreateSubjectKeyIDHashTable(void);
|
||||||
cert_CreateSubjectKeyIDHashTable(void);
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus cert_AddSubjectKeyIDMapping(SECItem* subjKeyID,
|
||||||
cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert);
|
CERTCertificate* cert);
|
||||||
|
|
||||||
SECStatus
|
SECStatus cert_UpdateSubjectKeyIDSlotCheck(SECItem* slotid, int series);
|
||||||
cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series);
|
|
||||||
|
|
||||||
int
|
int cert_SubjectKeyIDSlotCheckSeries(SECItem* slotid);
|
||||||
cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call this function to remove an entry from the mapping table.
|
* Call this function to remove an entry from the mapping table.
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus cert_RemoveSubjectKeyIDMapping(SECItem* subjKeyID);
|
||||||
cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID);
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus cert_DestroySubjectKeyIDHashTable(void);
|
||||||
cert_DestroySubjectKeyIDHashTable(void);
|
|
||||||
|
|
||||||
SECItem*
|
SECItem* cert_FindDERCertBySubjectKeyID(SECItem* subjKeyID);
|
||||||
cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID);
|
|
||||||
|
|
||||||
/* return maximum length of AVA value based on its type OID tag. */
|
/* return maximum length of AVA value based on its type OID tag. */
|
||||||
extern int cert_AVAOidTagToMaxLen(SECOidTag tag);
|
extern int cert_AVAOidTagToMaxLen(SECOidTag tag);
|
||||||
|
|
||||||
/* Make an AVA, allocated from pool, from OID and DER encoded value */
|
/* Make an AVA, allocated from pool, from OID and DER encoded value */
|
||||||
extern CERTAVA * CERT_CreateAVAFromRaw(PLArenaPool *pool,
|
extern CERTAVA* CERT_CreateAVAFromRaw(PLArenaPool* pool, const SECItem* OID,
|
||||||
const SECItem * OID, const SECItem * value);
|
const SECItem* value);
|
||||||
|
|
||||||
/* Make an AVA from binary input specified by SECItem */
|
/* Make an AVA from binary input specified by SECItem */
|
||||||
extern CERTAVA * CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind,
|
extern CERTAVA* CERT_CreateAVAFromSECItem(PLArenaPool* arena, SECOidTag kind,
|
||||||
int valueType, SECItem *value);
|
int valueType, SECItem* value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get a DPCache object for the given issuer subject and dp
|
* get a DPCache object for the given issuer subject and dp
|
||||||
|
@ -260,10 +252,11 @@ void CERT_MapStanError();
|
||||||
/* Like CERT_VerifyCert, except with an additional argument, flags. The
|
/* Like CERT_VerifyCert, except with an additional argument, flags. The
|
||||||
* flags are defined immediately below.
|
* flags are defined immediately below.
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus cert_VerifyCertWithFlags(CERTCertDBHandle* handle,
|
||||||
cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
|
CERTCertificate* cert, PRBool checkSig,
|
||||||
PRBool checkSig, SECCertUsage certUsage, PRTime t,
|
SECCertUsage certUsage, PRTime t,
|
||||||
PRUint32 flags, void *wincx, CERTVerifyLog *log);
|
PRUint32 flags, void* wincx,
|
||||||
|
CERTVerifyLog* log);
|
||||||
|
|
||||||
/* Use the default settings.
|
/* Use the default settings.
|
||||||
* cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is
|
* cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is
|
||||||
|
@ -281,15 +274,10 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||||
|
|
||||||
/* Interface function for libpkix cert validation engine:
|
/* Interface function for libpkix cert validation engine:
|
||||||
* cert_verify wrapper. */
|
* cert_verify wrapper. */
|
||||||
SECStatus
|
SECStatus cert_VerifyCertChainPkix(CERTCertificate* cert, PRBool checkSig,
|
||||||
cert_VerifyCertChainPkix(CERTCertificate *cert,
|
SECCertUsage requiredUsage, PRTime time,
|
||||||
PRBool checkSig,
|
void* wincx, CERTVerifyLog* log,
|
||||||
SECCertUsage requiredUsage,
|
PRBool* sigError, PRBool* revoked);
|
||||||
PRTime time,
|
|
||||||
void *wincx,
|
|
||||||
CERTVerifyLog *log,
|
|
||||||
PRBool *sigError,
|
|
||||||
PRBool *revoked);
|
|
||||||
|
|
||||||
SECStatus cert_InitLocks(void);
|
SECStatus cert_InitLocks(void);
|
||||||
|
|
||||||
|
@ -298,17 +286,16 @@ SECStatus cert_DestroyLocks(void);
|
||||||
/*
|
/*
|
||||||
* fill in nsCertType field of the cert based on the cert extension
|
* fill in nsCertType field of the cert based on the cert extension
|
||||||
*/
|
*/
|
||||||
extern SECStatus cert_GetCertType(CERTCertificate *cert);
|
extern SECStatus cert_GetCertType(CERTCertificate* cert);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* compute and return the value of nsCertType for cert, but do not
|
* compute and return the value of nsCertType for cert, but do not
|
||||||
* update the CERTCertificate.
|
* update the CERTCertificate.
|
||||||
*/
|
*/
|
||||||
extern PRUint32 cert_ComputeCertType(CERTCertificate *cert);
|
extern PRUint32 cert_ComputeCertType(CERTCertificate* cert);
|
||||||
|
|
||||||
void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
|
void cert_AddToVerifyLog(CERTVerifyLog* log, CERTCertificate* cert,
|
||||||
long errorCode, unsigned int depth,
|
long errorCode, unsigned int depth, void* arg);
|
||||||
void *arg);
|
|
||||||
|
|
||||||
/* Insert a DER CRL into the CRL cache, and take ownership of it.
|
/* Insert a DER CRL into the CRL cache, and take ownership of it.
|
||||||
*
|
*
|
||||||
|
@ -323,7 +310,7 @@ void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
|
||||||
* the same encoding. To facilitate X.500 name matching, a canonicalized
|
* the same encoding. To facilitate X.500 name matching, a canonicalized
|
||||||
* encoding of the GeneralName should be used, if available.
|
* encoding of the GeneralName should be used, if available.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
|
SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
|
||||||
const SECItem* canonicalizedName);
|
const SECItem* canonicalizedName);
|
||||||
|
|
||||||
|
@ -336,15 +323,15 @@ struct NamedCRLCacheStr {
|
||||||
* and read by cert_FindCRLByGeneralName */
|
* and read by cert_FindCRLByGeneralName */
|
||||||
struct NamedCRLCacheEntryStr {
|
struct NamedCRLCacheEntryStr {
|
||||||
SECItem* canonicalizedName;
|
SECItem* canonicalizedName;
|
||||||
SECItem* crl; /* DER, kept only if CRL
|
SECItem* crl; /* DER, kept only if CRL
|
||||||
* is successfully cached */
|
* is successfully cached */
|
||||||
PRBool inCRLCache;
|
PRBool inCRLCache;
|
||||||
PRTime successfulInsertionTime; /* insertion time */
|
PRTime successfulInsertionTime; /* insertion time */
|
||||||
PRTime lastAttemptTime; /* time of last call to
|
PRTime lastAttemptTime; /* time of last call to
|
||||||
cert_CacheCRLByGeneralName with this name */
|
cert_CacheCRLByGeneralName with this name */
|
||||||
PRBool badDER; /* ASN.1 error */
|
PRBool badDER; /* ASN.1 error */
|
||||||
PRBool dupe; /* matching DER CRL already in CRL cache */
|
PRBool dupe; /* matching DER CRL already in CRL cache */
|
||||||
PRBool unsupported; /* IDP, delta, any other reason */
|
PRBool unsupported; /* IDP, delta, any other reason */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -355,12 +342,12 @@ typedef enum {
|
||||||
|
|
||||||
/* Returns detailed status of the cert(revStatus variable). Tells if
|
/* Returns detailed status of the cert(revStatus variable). Tells if
|
||||||
* issuer cache has OriginFetchedWithTimeout crl in it. */
|
* issuer cache has OriginFetchedWithTimeout crl in it. */
|
||||||
SECStatus
|
SECStatus cert_CheckCertRevocationStatus(CERTCertificate* cert,
|
||||||
cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
|
CERTCertificate* issuer,
|
||||||
const SECItem* dp, PRTime t, void *wincx,
|
const SECItem* dp, PRTime t,
|
||||||
CERTRevocationStatus *revStatus,
|
void* wincx,
|
||||||
CERTCRLEntryReasonCode *revReason);
|
CERTRevocationStatus* revStatus,
|
||||||
|
CERTCRLEntryReasonCode* revReason);
|
||||||
|
|
||||||
SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned);
|
SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned);
|
||||||
|
|
||||||
|
@ -374,26 +361,21 @@ SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc,
|
||||||
SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc);
|
SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc);
|
||||||
|
|
||||||
/* This is private for now. Maybe shoule be public. */
|
/* This is private for now. Maybe shoule be public. */
|
||||||
CERTGeneralName *
|
CERTGeneralName* cert_GetSubjectAltNameList(const CERTCertificate* cert,
|
||||||
cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena);
|
PLArenaPool* arena);
|
||||||
|
|
||||||
/* Count DNS names and IP addresses in a list of GeneralNames */
|
/* Count DNS names and IP addresses in a list of GeneralNames */
|
||||||
PRUint32
|
PRUint32 cert_CountDNSPatterns(CERTGeneralName* firstName);
|
||||||
cert_CountDNSPatterns(CERTGeneralName *firstName);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns the trust status of the leaf certificate based on usage.
|
* returns the trust status of the leaf certificate based on usage.
|
||||||
* If the leaf is explicitly untrusted, this function will fail and
|
* If the leaf is explicitly untrusted, this function will fail and
|
||||||
* failedFlags will be set to the trust bit value that lead to the failure.
|
* failedFlags will be set to the trust bit value that lead to the failure.
|
||||||
* If the leaf is trusted, isTrusted is set to true and the function returns
|
* If the leaf is trusted, isTrusted is set to true and the function returns
|
||||||
* SECSuccess. This function does not check if the cert is fit for a
|
* SECSuccess. This function does not check if the cert is fit for a
|
||||||
* particular usage.
|
* particular usage.
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus cert_CheckLeafTrust(CERTCertificate* cert, SECCertUsage usage,
|
||||||
cert_CheckLeafTrust(CERTCertificate *cert,
|
unsigned int* failedFlags, PRBool* isTrusted);
|
||||||
SECCertUsage usage,
|
|
||||||
unsigned int *failedFlags,
|
|
||||||
PRBool *isTrusted);
|
|
||||||
|
|
||||||
#endif /* _CERTI_H_ */
|
#endif /* _CERTI_H_ */
|
||||||
|
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,17 +15,15 @@
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid,
|
CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, SECItem *value)
|
||||||
SECItem *value)
|
|
||||||
{
|
{
|
||||||
return (cert_FindExtensionByOID (cert->extensions, oid, value));
|
return (cert_FindExtensionByOID(cert->extensions, oid, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value)
|
CERT_FindCertExtension(const CERTCertificate *cert, int tag, SECItem *value)
|
||||||
{
|
{
|
||||||
return (cert_FindExtension (cert->extensions, tag, value));
|
return (cert_FindExtension(cert->extensions, tag, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -34,13 +32,13 @@ SetExts(void *object, CERTCertExtension **exts)
|
||||||
CERTCertificate *cert = (CERTCertificate *)object;
|
CERTCertificate *cert = (CERTCertificate *)object;
|
||||||
|
|
||||||
cert->extensions = exts;
|
cert->extensions = exts;
|
||||||
DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
|
DER_SetUInteger(cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
CERT_StartCertExtensions(CERTCertificate *cert)
|
CERT_StartCertExtensions(CERTCertificate *cert)
|
||||||
{
|
{
|
||||||
return (cert_StartExtensions ((void *)cert, cert->arena, SetExts));
|
return (cert_StartExtensions((void *)cert, cert->arena, SetExts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -50,62 +48,60 @@ SECStatus
|
||||||
CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem)
|
CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (CERT_FindBitStringExtension
|
return (CERT_FindBitStringExtension(
|
||||||
(cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
|
cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the value of a string type extension
|
* get the value of a string type extension
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag)
|
CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag)
|
||||||
{
|
{
|
||||||
SECItem wrapperItem, tmpItem = {siBuffer,0};
|
SECItem wrapperItem, tmpItem = { siBuffer, 0 };
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
PLArenaPool *arena = NULL;
|
PLArenaPool *arena = NULL;
|
||||||
char *retstring = NULL;
|
char *retstring = NULL;
|
||||||
|
|
||||||
wrapperItem.data = NULL;
|
wrapperItem.data = NULL;
|
||||||
tmpItem.data = NULL;
|
tmpItem.data = NULL;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
|
|
||||||
if ( ! arena ) {
|
if (!arena) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
|
||||||
|
|
||||||
rv = cert_FindExtension(cert->extensions, oidtag,
|
|
||||||
&wrapperItem);
|
|
||||||
if ( rv != SECSuccess ) {
|
|
||||||
goto loser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
rv = cert_FindExtension(cert->extensions, oidtag, &wrapperItem);
|
||||||
SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
|
if (rv != SECSuccess) {
|
||||||
|
goto loser;
|
||||||
if ( rv != SECSuccess ) {
|
|
||||||
goto loser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retstring = (char *)PORT_Alloc(tmpItem.len + 1 );
|
rv = SEC_QuickDERDecodeItem(
|
||||||
if ( retstring == NULL ) {
|
arena, &tmpItem, SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
|
||||||
goto loser;
|
|
||||||
|
if (rv != SECSuccess) {
|
||||||
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retstring = (char *)PORT_Alloc(tmpItem.len + 1);
|
||||||
|
if (retstring == NULL) {
|
||||||
|
goto loser;
|
||||||
|
}
|
||||||
|
|
||||||
PORT_Memcpy(retstring, tmpItem.data, tmpItem.len);
|
PORT_Memcpy(retstring, tmpItem.data, tmpItem.len);
|
||||||
retstring[tmpItem.len] = '\0';
|
retstring[tmpItem.len] = '\0';
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
if ( arena ) {
|
if (arena) {
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
if ( wrapperItem.data ) {
|
|
||||||
PORT_Free(wrapperItem.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(retstring);
|
if (wrapperItem.data) {
|
||||||
|
PORT_Free(wrapperItem.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (retstring);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -116,7 +112,7 @@ CERT_FindKeyUsageExtension(CERTCertificate *cert, SECItem *retItem)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (CERT_FindBitStringExtension(cert->extensions,
|
return (CERT_FindBitStringExtension(cert->extensions,
|
||||||
SEC_OID_X509_KEY_USAGE, retItem));
|
SEC_OID_X509_KEY_USAGE, retItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -127,24 +123,25 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
|
||||||
{
|
{
|
||||||
|
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
SECItem encodedValue = {siBuffer, NULL, 0 };
|
SECItem encodedValue = { siBuffer, NULL, 0 };
|
||||||
SECItem decodedValue = {siBuffer, NULL, 0 };
|
SECItem decodedValue = { siBuffer, NULL, 0 };
|
||||||
|
|
||||||
rv = cert_FindExtension
|
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID,
|
||||||
(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue);
|
&encodedValue);
|
||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
PLArenaPool *tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
if (tmpArena) {
|
if (tmpArena) {
|
||||||
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
|
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
|
||||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||||
&encodedValue);
|
&encodedValue);
|
||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
|
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
|
||||||
}
|
}
|
||||||
PORT_FreeArena(tmpArena, PR_FALSE);
|
PORT_FreeArena(tmpArena, PR_FALSE);
|
||||||
} else {
|
}
|
||||||
rv = SECFailure;
|
else {
|
||||||
}
|
rv = SECFailure;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SECITEM_FreeItem(&encodedValue, PR_FALSE);
|
SECITEM_FreeItem(&encodedValue, PR_FALSE);
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -152,7 +149,7 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FindBasicConstraintExten(CERTCertificate *cert,
|
CERT_FindBasicConstraintExten(CERTCertificate *cert,
|
||||||
CERTBasicConstraints *value)
|
CERTBasicConstraints *value)
|
||||||
{
|
{
|
||||||
SECItem encodedExtenValue;
|
SECItem encodedExtenValue;
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
|
@ -161,42 +158,42 @@ CERT_FindBasicConstraintExten(CERTCertificate *cert,
|
||||||
encodedExtenValue.len = 0;
|
encodedExtenValue.len = 0;
|
||||||
|
|
||||||
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
|
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
|
||||||
&encodedExtenValue);
|
&encodedExtenValue);
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue);
|
rv = CERT_DecodeBasicConstraintValue(value, &encodedExtenValue);
|
||||||
|
|
||||||
/* free the raw extension data */
|
/* free the raw extension data */
|
||||||
PORT_Free(encodedExtenValue.data);
|
PORT_Free(encodedExtenValue.data);
|
||||||
encodedExtenValue.data = NULL;
|
encodedExtenValue.data = NULL;
|
||||||
|
|
||||||
return(rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTAuthKeyID *
|
CERTAuthKeyID *
|
||||||
CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert)
|
CERT_FindAuthKeyIDExten(PLArenaPool *arena, CERTCertificate *cert)
|
||||||
{
|
{
|
||||||
SECItem encodedExtenValue;
|
SECItem encodedExtenValue;
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
CERTAuthKeyID *ret;
|
CERTAuthKeyID *ret;
|
||||||
|
|
||||||
encodedExtenValue.data = NULL;
|
encodedExtenValue.data = NULL;
|
||||||
encodedExtenValue.len = 0;
|
encodedExtenValue.len = 0;
|
||||||
|
|
||||||
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID,
|
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID,
|
||||||
&encodedExtenValue);
|
&encodedExtenValue);
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
|
ret = CERT_DecodeAuthKeyID(arena, &encodedExtenValue);
|
||||||
|
|
||||||
PORT_Free(encodedExtenValue.data);
|
PORT_Free(encodedExtenValue.data);
|
||||||
encodedExtenValue.data = NULL;
|
encodedExtenValue.data = NULL;
|
||||||
|
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
|
@ -207,9 +204,9 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
|
||||||
|
|
||||||
/* There is no extension, v1 or v2 certificate */
|
/* There is no extension, v1 or v2 certificate */
|
||||||
if (cert->extensions == NULL) {
|
if (cert->extensions == NULL) {
|
||||||
return (SECSuccess);
|
return (SECSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
keyUsage.data = NULL;
|
keyUsage.data = NULL;
|
||||||
|
|
||||||
/* This code formerly ignored the Key Usage extension if it was
|
/* This code formerly ignored the Key Usage extension if it was
|
||||||
|
@ -218,12 +215,13 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
|
||||||
*/
|
*/
|
||||||
rv = CERT_FindKeyUsageExtension(cert, &keyUsage);
|
rv = CERT_FindKeyUsageExtension(cert, &keyUsage);
|
||||||
if (rv == SECFailure) {
|
if (rv == SECFailure) {
|
||||||
rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ?
|
rv = (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) ? SECSuccess
|
||||||
SECSuccess : SECFailure;
|
: SECFailure;
|
||||||
} else if (!(keyUsage.data[0] & usage)) {
|
|
||||||
PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID);
|
|
||||||
rv = SECFailure;
|
|
||||||
}
|
}
|
||||||
PORT_Free (keyUsage.data);
|
else if (!(keyUsage.data[0] & usage)) {
|
||||||
|
PORT_SetError(SEC_ERROR_CERT_USAGES_INVALID);
|
||||||
|
rv = SECFailure;
|
||||||
|
}
|
||||||
|
PORT_Free(keyUsage.data);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,93 +16,93 @@
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
|
||||||
#ifdef OLD
|
#ifdef OLD
|
||||||
#include "ocspti.h" /* XXX a better extensions interface would not
|
#include "ocspti.h" /* XXX a better extensions interface would not
|
||||||
* require knowledge of data structures of callers */
|
* require knowledge of data structures of callers */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CERTCertExtension *
|
static CERTCertExtension *
|
||||||
GetExtension (CERTCertExtension **extensions, SECItem *oid)
|
GetExtension(CERTCertExtension **extensions, SECItem *oid)
|
||||||
{
|
{
|
||||||
CERTCertExtension **exts;
|
CERTCertExtension **exts;
|
||||||
CERTCertExtension *ext = NULL;
|
CERTCertExtension *ext = NULL;
|
||||||
SECComparison comp;
|
SECComparison comp;
|
||||||
|
|
||||||
exts = extensions;
|
exts = extensions;
|
||||||
|
|
||||||
if (exts) {
|
|
||||||
while ( *exts ) {
|
|
||||||
ext = *exts;
|
|
||||||
comp = SECITEM_CompareItem(oid, &ext->id);
|
|
||||||
if ( comp == SECEqual )
|
|
||||||
break;
|
|
||||||
|
|
||||||
exts++;
|
if (exts) {
|
||||||
}
|
while (*exts) {
|
||||||
return (*exts ? ext : NULL);
|
ext = *exts;
|
||||||
|
comp = SECITEM_CompareItem(oid, &ext->id);
|
||||||
|
if (comp == SECEqual)
|
||||||
|
break;
|
||||||
|
|
||||||
|
exts++;
|
||||||
|
}
|
||||||
|
return (*exts ? ext : NULL);
|
||||||
}
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value)
|
cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid,
|
||||||
|
SECItem *value)
|
||||||
{
|
{
|
||||||
CERTCertExtension *ext;
|
CERTCertExtension *ext;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
ext = GetExtension (extensions, oid);
|
ext = GetExtension(extensions, oid);
|
||||||
if (ext == NULL) {
|
if (ext == NULL) {
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
|
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||||
return (SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
if (value)
|
if (value)
|
||||||
rv = SECITEM_CopyItem(NULL, value, &ext->value);
|
rv = SECITEM_CopyItem(NULL, value, &ext->value);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical)
|
CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag,
|
||||||
|
PRBool *isCritical)
|
||||||
{
|
{
|
||||||
CERTCertExtension *ext;
|
CERTCertExtension *ext;
|
||||||
SECOidData *oid;
|
SECOidData *oid;
|
||||||
|
|
||||||
if (!isCritical)
|
if (!isCritical)
|
||||||
return (SECSuccess);
|
return (SECSuccess);
|
||||||
|
|
||||||
/* find the extension in the extensions list */
|
/* find the extension in the extensions list */
|
||||||
oid = SECOID_FindOIDByTag((SECOidTag)tag);
|
oid = SECOID_FindOIDByTag((SECOidTag)tag);
|
||||||
if ( !oid ) {
|
if (!oid) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
ext = GetExtension (extensions, &oid->oid);
|
ext = GetExtension(extensions, &oid->oid);
|
||||||
if (ext == NULL) {
|
if (ext == NULL) {
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
|
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||||
return (SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the criticality is omitted, then it is false by default.
|
/* If the criticality is omitted, then it is false by default.
|
||||||
ex->critical.data is NULL */
|
ex->critical.data is NULL */
|
||||||
if (ext->critical.data == NULL)
|
if (ext->critical.data == NULL)
|
||||||
*isCritical = PR_FALSE;
|
*isCritical = PR_FALSE;
|
||||||
else
|
else
|
||||||
*isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
|
*isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
|
||||||
return (SECSuccess);
|
return (SECSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
|
cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
|
||||||
{
|
{
|
||||||
SECOidData *oid;
|
SECOidData *oid;
|
||||||
|
|
||||||
oid = SECOID_FindOIDByTag((SECOidTag)tag);
|
oid = SECOID_FindOIDByTag((SECOidTag)tag);
|
||||||
if ( !oid ) {
|
if (!oid) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(cert_FindExtensionByOID(extensions, &oid->oid, value));
|
return (cert_FindExtensionByOID(extensions, &oid->oid, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct _extNode {
|
typedef struct _extNode {
|
||||||
struct _extNode *next;
|
struct _extNode *next;
|
||||||
CERTCertExtension *ext;
|
CERTCertExtension *ext;
|
||||||
|
@ -115,7 +115,7 @@ typedef struct {
|
||||||
PLArenaPool *arena;
|
PLArenaPool *arena;
|
||||||
extNode *head;
|
extNode *head;
|
||||||
int count;
|
int count;
|
||||||
}extRec;
|
} extRec;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cert_StartExtensions
|
* cert_StartExtensions
|
||||||
|
@ -125,20 +125,20 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
||||||
void (*setExts)(void *object, CERTCertExtension **exts))
|
void (*setExts)(void *object, CERTCertExtension **exts))
|
||||||
{
|
{
|
||||||
PLArenaPool *arena;
|
PLArenaPool *arena;
|
||||||
extRec *handle;
|
extRec *handle;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
if ( !arena ) {
|
if (!arena) {
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
|
handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
|
||||||
if ( !handle ) {
|
if (!handle) {
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->object = owner;
|
handle->object = owner;
|
||||||
|
@ -148,8 +148,8 @@ cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
||||||
handle->arena = arena;
|
handle->arena = arena;
|
||||||
handle->head = 0;
|
handle->head = 0;
|
||||||
handle->count = 0;
|
handle->count = 0;
|
||||||
|
|
||||||
return(handle);
|
return (handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char hextrue = 0xff;
|
static unsigned char hextrue = 0xff;
|
||||||
|
@ -158,77 +158,78 @@ static unsigned char hextrue = 0xff;
|
||||||
* Note - assumes that data pointed to by oid->data will not move
|
* Note - assumes that data pointed to by oid->data will not move
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value,
|
CERT_AddExtensionByOID(void *exthandle, SECItem *oid, SECItem *value,
|
||||||
PRBool critical, PRBool copyData)
|
PRBool critical, PRBool copyData)
|
||||||
{
|
{
|
||||||
CERTCertExtension *ext;
|
CERTCertExtension *ext;
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
extNode *node;
|
extNode *node;
|
||||||
extRec *handle;
|
extRec *handle;
|
||||||
|
|
||||||
handle = (extRec *)exthandle;
|
handle = (extRec *)exthandle;
|
||||||
|
|
||||||
/* allocate space for extension and list node */
|
/* allocate space for extension and list node */
|
||||||
ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena,
|
ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena,
|
||||||
sizeof(CERTCertExtension));
|
sizeof(CERTCertExtension));
|
||||||
if ( !ext ) {
|
if (!ext) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
|
node = (extNode *)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
|
||||||
if ( !node ) {
|
if (!node) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add to list */
|
/* add to list */
|
||||||
node->next = handle->head;
|
node->next = handle->head;
|
||||||
handle->head = node;
|
handle->head = node;
|
||||||
|
|
||||||
/* point to ext struct */
|
/* point to ext struct */
|
||||||
node->ext = ext;
|
node->ext = ext;
|
||||||
|
|
||||||
/* the object ID of the extension */
|
/* the object ID of the extension */
|
||||||
ext->id = *oid;
|
ext->id = *oid;
|
||||||
|
|
||||||
/* set critical field */
|
/* set critical field */
|
||||||
if ( critical ) {
|
if (critical) {
|
||||||
ext->critical.data = (unsigned char*)&hextrue;
|
ext->critical.data = (unsigned char *)&hextrue;
|
||||||
ext->critical.len = 1;
|
ext->critical.len = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the value */
|
/* set the value */
|
||||||
if ( copyData ) {
|
if (copyData) {
|
||||||
rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
|
rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
|
||||||
if ( rv ) {
|
if (rv) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
ext->value = *value;
|
else {
|
||||||
|
ext->value = *value;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->count++;
|
|
||||||
|
|
||||||
return(SECSuccess);
|
|
||||||
|
|
||||||
|
handle->count++;
|
||||||
|
|
||||||
|
return (SECSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_AddExtension(void *exthandle, int idtag, SECItem *value,
|
CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical,
|
||||||
PRBool critical, PRBool copyData)
|
PRBool copyData)
|
||||||
{
|
{
|
||||||
SECOidData *oid;
|
SECOidData *oid;
|
||||||
|
|
||||||
oid = SECOID_FindOIDByTag((SECOidTag)idtag);
|
oid = SECOID_FindOIDByTag((SECOidTag)idtag);
|
||||||
if ( !oid ) {
|
if (!oid) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData));
|
return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical,
|
||||||
|
copyData));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
|
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
|
||||||
PRBool critical, const SEC_ASN1Template *atemplate)
|
PRBool critical, const SEC_ASN1Template *atemplate)
|
||||||
{
|
{
|
||||||
extRec *handle;
|
extRec *handle;
|
||||||
SECItem *encitem;
|
SECItem *encitem;
|
||||||
|
@ -236,45 +237,43 @@ CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
|
||||||
handle = (extRec *)exthandle;
|
handle = (extRec *)exthandle;
|
||||||
|
|
||||||
encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
|
encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
|
||||||
if ( encitem == NULL ) {
|
if (encitem == NULL) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
|
return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value)
|
PrepareBitStringForEncoding(SECItem *bitsmap, SECItem *value)
|
||||||
{
|
{
|
||||||
unsigned char onebyte;
|
unsigned char onebyte;
|
||||||
unsigned int i, len = 0;
|
unsigned int i, len = 0;
|
||||||
|
|
||||||
/* to prevent warning on some platform at compile time */
|
/* to prevent warning on some platform at compile time */
|
||||||
onebyte = '\0';
|
onebyte = '\0';
|
||||||
/* Get the position of the right-most turn-on bit */
|
/* Get the position of the right-most turn-on bit */
|
||||||
for (i = 0; i < (value->len ) * 8; ++i) {
|
for (i = 0; i < (value->len) * 8; ++i) {
|
||||||
if (i % 8 == 0)
|
if (i % 8 == 0)
|
||||||
onebyte = value->data[i/8];
|
onebyte = value->data[i / 8];
|
||||||
if (onebyte & 0x80)
|
if (onebyte & 0x80)
|
||||||
len = i;
|
len = i;
|
||||||
onebyte <<= 1;
|
onebyte <<= 1;
|
||||||
|
}
|
||||||
}
|
bitsmap->data = value->data;
|
||||||
bitsmap->data = value->data;
|
/* Add one here since we work with base 1 */
|
||||||
/* Add one here since we work with base 1 */
|
bitsmap->len = len + 1;
|
||||||
bitsmap->len = len + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag,
|
CERT_EncodeAndAddBitStrExtension(void *exthandle, int idtag, SECItem *value,
|
||||||
SECItem *value, PRBool critical)
|
PRBool critical)
|
||||||
{
|
{
|
||||||
SECItem bitsmap;
|
SECItem bitsmap;
|
||||||
|
|
||||||
PrepareBitStringForEncoding (&bitsmap, value);
|
PrepareBitStringForEncoding(&bitsmap, value);
|
||||||
return (CERT_EncodeAndAddExtension
|
return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical,
|
||||||
(exthandle, idtag, &bitsmap, critical,
|
SEC_ASN1_GET(SEC_BitStringTemplate)));
|
||||||
SEC_ASN1_GET(SEC_BitStringTemplate)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
|
@ -284,53 +283,53 @@ CERT_FinishExtensions(void *exthandle)
|
||||||
extNode *node;
|
extNode *node;
|
||||||
CERTCertExtension **exts;
|
CERTCertExtension **exts;
|
||||||
SECStatus rv = SECFailure;
|
SECStatus rv = SECFailure;
|
||||||
|
|
||||||
handle = (extRec *)exthandle;
|
handle = (extRec *)exthandle;
|
||||||
|
|
||||||
/* allocate space for extensions array */
|
/* allocate space for extensions array */
|
||||||
exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
|
exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
|
||||||
handle->count + 1);
|
handle->count + 1);
|
||||||
if (exts == NULL) {
|
if (exts == NULL) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* put extensions in owner object and update its version number */
|
/* put extensions in owner object and update its version number */
|
||||||
|
|
||||||
#ifdef OLD
|
#ifdef OLD
|
||||||
switch (handle->type) {
|
switch (handle->type) {
|
||||||
case CertificateExtensions:
|
case CertificateExtensions:
|
||||||
handle->owner.cert->extensions = exts;
|
handle->owner.cert->extensions = exts;
|
||||||
DER_SetUInteger (ownerArena, &(handle->owner.cert->version),
|
DER_SetUInteger(ownerArena, &(handle->owner.cert->version),
|
||||||
SEC_CERTIFICATE_VERSION_3);
|
SEC_CERTIFICATE_VERSION_3);
|
||||||
break;
|
break;
|
||||||
case CrlExtensions:
|
case CrlExtensions:
|
||||||
handle->owner.crl->extensions = exts;
|
handle->owner.crl->extensions = exts;
|
||||||
DER_SetUInteger (ownerArena, &(handle->owner.crl->version),
|
DER_SetUInteger(ownerArena, &(handle->owner.crl->version),
|
||||||
SEC_CRL_VERSION_2);
|
SEC_CRL_VERSION_2);
|
||||||
break;
|
break;
|
||||||
case OCSPRequestExtensions:
|
case OCSPRequestExtensions:
|
||||||
handle->owner.request->tbsRequest->requestExtensions = exts;
|
handle->owner.request->tbsRequest->requestExtensions = exts;
|
||||||
break;
|
break;
|
||||||
case OCSPSingleRequestExtensions:
|
case OCSPSingleRequestExtensions:
|
||||||
handle->owner.singleRequest->singleRequestExtensions = exts;
|
handle->owner.singleRequest->singleRequestExtensions = exts;
|
||||||
break;
|
break;
|
||||||
case OCSPResponseSingleExtensions:
|
case OCSPResponseSingleExtensions:
|
||||||
handle->owner.singleResponse->singleExtensions = exts;
|
handle->owner.singleResponse->singleExtensions = exts;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
handle->setExts(handle->object, exts);
|
handle->setExts(handle->object, exts);
|
||||||
|
|
||||||
/* update the version number */
|
/* update the version number */
|
||||||
|
|
||||||
/* copy each extension pointer */
|
/* copy each extension pointer */
|
||||||
node = handle->head;
|
node = handle->head;
|
||||||
while ( node ) {
|
while (node) {
|
||||||
*exts = node->ext;
|
*exts = node->ext;
|
||||||
|
|
||||||
node = node->next;
|
node = node->next;
|
||||||
exts++;
|
exts++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* terminate the array of extensions */
|
/* terminate the array of extensions */
|
||||||
|
@ -352,14 +351,14 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
||||||
SECOidTag tag;
|
SECOidTag tag;
|
||||||
extNode *node;
|
extNode *node;
|
||||||
extRec *handle = exthandle;
|
extRec *handle = exthandle;
|
||||||
|
|
||||||
if (!exthandle || !extensions) {
|
if (!exthandle || !extensions) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
while ((ext = *extensions++) != NULL) {
|
while ((ext = *extensions++) != NULL) {
|
||||||
tag = SECOID_FindOIDTag(&ext->id);
|
tag = SECOID_FindOIDTag(&ext->id);
|
||||||
for (node=handle->head; node != NULL; node=node->next) {
|
for (node = handle->head; node != NULL; node = node->next) {
|
||||||
if (tag == 0) {
|
if (tag == 0) {
|
||||||
if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
|
if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
|
||||||
break;
|
break;
|
||||||
|
@ -372,15 +371,15 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
||||||
}
|
}
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
PRBool critical = (ext->critical.len != 0 &&
|
PRBool critical = (ext->critical.len != 0 &&
|
||||||
ext->critical.data[ext->critical.len - 1] != 0);
|
ext->critical.data[ext->critical.len - 1] != 0);
|
||||||
if (critical && tag == SEC_OID_UNKNOWN) {
|
if (critical && tag == SEC_OID_UNKNOWN) {
|
||||||
PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
|
PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* add to list */
|
/* add to list */
|
||||||
rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value,
|
rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value,
|
||||||
critical, PR_TRUE);
|
critical, PR_TRUE);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -392,108 +391,107 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
||||||
* get the value of the Netscape Certificate Type Extension
|
* get the value of the Netscape Certificate Type Extension
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag,
|
CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
|
||||||
SECItem *retItem)
|
SECItem *retItem)
|
||||||
{
|
{
|
||||||
SECItem wrapperItem, tmpItem = {siBuffer,0};
|
SECItem wrapperItem, tmpItem = { siBuffer, 0 };
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
PLArenaPool *arena = NULL;
|
PLArenaPool *arena = NULL;
|
||||||
|
|
||||||
wrapperItem.data = NULL;
|
wrapperItem.data = NULL;
|
||||||
tmpItem.data = NULL;
|
tmpItem.data = NULL;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
|
|
||||||
if ( ! arena ) {
|
if (!arena) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = cert_FindExtension(extensions, tag, &wrapperItem);
|
rv = cert_FindExtension(extensions, tag, &wrapperItem);
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
rv = SEC_QuickDERDecodeItem(
|
||||||
SEC_ASN1_GET(SEC_BitStringTemplate),
|
arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);
|
||||||
&wrapperItem);
|
|
||||||
|
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 );
|
retItem->data = (unsigned char *)PORT_Alloc((tmpItem.len + 7) >> 3);
|
||||||
if ( retItem->data == NULL ) {
|
if (retItem->data == NULL) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT_Memcpy(retItem->data, tmpItem.data, ( tmpItem.len + 7 ) >> 3);
|
PORT_Memcpy(retItem->data, tmpItem.data, (tmpItem.len + 7) >> 3);
|
||||||
retItem->len = tmpItem.len;
|
retItem->len = tmpItem.len;
|
||||||
|
|
||||||
rv = SECSuccess;
|
rv = SECSuccess;
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if ( arena ) {
|
if (arena) {
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
if ( wrapperItem.data ) {
|
|
||||||
PORT_Free(wrapperItem.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(rv);
|
if (wrapperItem.data) {
|
||||||
|
PORT_Free(wrapperItem.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
cert_HasCriticalExtension (CERTCertExtension **extensions)
|
cert_HasCriticalExtension(CERTCertExtension **extensions)
|
||||||
{
|
{
|
||||||
CERTCertExtension **exts;
|
CERTCertExtension **exts;
|
||||||
CERTCertExtension *ext = NULL;
|
CERTCertExtension *ext = NULL;
|
||||||
PRBool hasCriticalExten = PR_FALSE;
|
PRBool hasCriticalExten = PR_FALSE;
|
||||||
|
|
||||||
exts = extensions;
|
exts = extensions;
|
||||||
|
|
||||||
if (exts) {
|
if (exts) {
|
||||||
while ( *exts ) {
|
while (*exts) {
|
||||||
ext = *exts;
|
ext = *exts;
|
||||||
/* If the criticality is omitted, it's non-critical */
|
/* If the criticality is omitted, it's non-critical */
|
||||||
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
||||||
hasCriticalExten = PR_TRUE;
|
hasCriticalExten = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exts++;
|
exts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (hasCriticalExten);
|
return (hasCriticalExten);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
cert_HasUnknownCriticalExten (CERTCertExtension **extensions)
|
cert_HasUnknownCriticalExten(CERTCertExtension **extensions)
|
||||||
{
|
{
|
||||||
CERTCertExtension **exts;
|
CERTCertExtension **exts;
|
||||||
CERTCertExtension *ext = NULL;
|
CERTCertExtension *ext = NULL;
|
||||||
PRBool hasUnknownCriticalExten = PR_FALSE;
|
PRBool hasUnknownCriticalExten = PR_FALSE;
|
||||||
|
|
||||||
exts = extensions;
|
exts = extensions;
|
||||||
|
|
||||||
if (exts) {
|
if (exts) {
|
||||||
while ( *exts ) {
|
while (*exts) {
|
||||||
ext = *exts;
|
ext = *exts;
|
||||||
/* If the criticality is omitted, it's non-critical.
|
/* If the criticality is omitted, it's non-critical.
|
||||||
If an extension is critical, make sure that we know
|
If an extension is critical, make sure that we know
|
||||||
how to process the extension.
|
how to process the extension.
|
||||||
*/
|
*/
|
||||||
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
||||||
if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) {
|
if (SECOID_KnownCertExtenOID(&ext->id) == PR_FALSE) {
|
||||||
hasUnknownCriticalExten = PR_TRUE;
|
hasUnknownCriticalExten = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exts++;
|
exts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (hasUnknownCriticalExten);
|
return (hasUnknownCriticalExten);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef _CERTXUTL_H_
|
#ifndef _CERTXUTL_H_
|
||||||
#define _CERTXUTL_H_
|
#define _CERTXUTL_H_
|
||||||
|
|
||||||
|
@ -23,28 +22,23 @@ typedef enum {
|
||||||
} ExtensionsType;
|
} ExtensionsType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern PRBool
|
extern PRBool cert_HasCriticalExtension(CERTCertExtension **extensions);
|
||||||
cert_HasCriticalExtension (CERTCertExtension **extensions);
|
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus CERT_FindBitStringExtension(CERTCertExtension **extensions,
|
||||||
CERT_FindBitStringExtension (CERTCertExtension **extensions,
|
int tag, SECItem *retItem);
|
||||||
int tag, SECItem *retItem);
|
extern void *cert_StartExtensions(void *owner, PLArenaPool *arena,
|
||||||
extern void *
|
void (*setExts)(void *object,
|
||||||
cert_StartExtensions (void *owner, PLArenaPool *arena,
|
CERTCertExtension **exts));
|
||||||
void (*setExts)(void *object, CERTCertExtension **exts));
|
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus cert_FindExtension(CERTCertExtension **extensions, int tag,
|
||||||
cert_FindExtension (CERTCertExtension **extensions, int tag, SECItem *value);
|
SECItem *value);
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus cert_FindExtensionByOID(CERTCertExtension **extensions,
|
||||||
cert_FindExtensionByOID (CERTCertExtension **extensions,
|
SECItem *oid, SECItem *value);
|
||||||
SECItem *oid, SECItem *value);
|
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus cert_GetExtenCriticality(CERTCertExtension **extensions,
|
||||||
cert_GetExtenCriticality (CERTCertExtension **extensions,
|
int tag, PRBool *isCritical);
|
||||||
int tag, PRBool *isCritical);
|
|
||||||
|
|
||||||
extern PRBool
|
extern PRBool cert_HasUnknownCriticalExten(CERTCertExtension **extensions);
|
||||||
cert_HasUnknownCriticalExten (CERTCertExtension **extensions);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -17,89 +17,76 @@ SEC_BEGIN_PROTOS
|
||||||
|
|
||||||
extern const SEC_ASN1Template CERT_GeneralNamesTemplate[];
|
extern const SEC_ASN1Template CERT_GeneralNamesTemplate[];
|
||||||
|
|
||||||
extern SECItem **
|
extern SECItem **cert_EncodeGeneralNames(PLArenaPool *arena,
|
||||||
cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names);
|
CERTGeneralName *names);
|
||||||
|
|
||||||
extern CERTGeneralName *
|
extern CERTGeneralName *cert_DecodeGeneralNames(PLArenaPool *arena,
|
||||||
cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName);
|
SECItem **encodedGenName);
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus cert_DestroyGeneralNames(CERTGeneralName *name);
|
||||||
cert_DestroyGeneralNames(CERTGeneralName *name);
|
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus cert_EncodeNameConstraints(CERTNameConstraints *constraints,
|
||||||
cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena,
|
PLArenaPool *arena, SECItem *dest);
|
||||||
SECItem *dest);
|
|
||||||
|
|
||||||
extern CERTNameConstraints *
|
extern CERTNameConstraints *cert_DecodeNameConstraints(
|
||||||
cert_DecodeNameConstraints(PLArenaPool *arena, const SECItem *encodedConstraints);
|
PLArenaPool *arena, const SECItem *encodedConstraints);
|
||||||
|
|
||||||
extern CERTGeneralName *
|
extern CERTGeneralName *cert_CombineNamesLists(CERTGeneralName *list1,
|
||||||
cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2);
|
CERTGeneralName *list2);
|
||||||
|
|
||||||
extern CERTNameConstraint *
|
extern CERTNameConstraint *cert_CombineConstraintsLists(
|
||||||
cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2);
|
CERTNameConstraint *list1, CERTNameConstraint *list2);
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
/* A thread safe implementation of General Names */
|
/* A thread safe implementation of General Names */
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
/* Destroy a Single CERTGeneralName */
|
/* Destroy a Single CERTGeneralName */
|
||||||
void
|
void CERT_DestroyGeneralName(CERTGeneralName *name);
|
||||||
CERT_DestroyGeneralName(CERTGeneralName *name);
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
|
||||||
CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus CERT_CopyGeneralName(PLArenaPool *arena, CERTGeneralName *dest,
|
||||||
CERT_CopyGeneralName(PLArenaPool *arena,
|
CERTGeneralName *src);
|
||||||
CERTGeneralName *dest,
|
|
||||||
CERTGeneralName *src);
|
|
||||||
|
|
||||||
/* General Name Lists are a thread safe, reference counting layer to
|
/* General Name Lists are a thread safe, reference counting layer to
|
||||||
* general names */
|
* general names */
|
||||||
|
|
||||||
/* Destroys a CERTGeneralNameList */
|
/* Destroys a CERTGeneralNameList */
|
||||||
void
|
void CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
|
||||||
CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
|
|
||||||
|
|
||||||
/* Creates a CERTGeneralNameList */
|
/* Creates a CERTGeneralNameList */
|
||||||
CERTGeneralNameList *
|
CERTGeneralNameList *CERT_CreateGeneralNameList(CERTGeneralName *name);
|
||||||
CERT_CreateGeneralNameList(CERTGeneralName *name);
|
|
||||||
|
|
||||||
/* Compares two CERTGeneralNameList */
|
/* Compares two CERTGeneralNameList */
|
||||||
SECStatus
|
SECStatus CERT_CompareGeneralNameLists(CERTGeneralNameList *a,
|
||||||
CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b);
|
CERTGeneralNameList *b);
|
||||||
|
|
||||||
/* returns a copy of the first name of the type requested */
|
/* returns a copy of the first name of the type requested */
|
||||||
void *
|
void *CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
|
||||||
CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
|
CERTGeneralNameType type,
|
||||||
CERTGeneralNameType type,
|
PLArenaPool *arena);
|
||||||
PLArenaPool *arena);
|
|
||||||
|
|
||||||
/* Adds a name to the tail of the list */
|
/* Adds a name to the tail of the list */
|
||||||
void
|
void CERT_AddGeneralNameToList(CERTGeneralNameList *list,
|
||||||
CERT_AddGeneralNameToList(CERTGeneralNameList *list,
|
CERTGeneralNameType type, void *data,
|
||||||
CERTGeneralNameType type,
|
SECItem *oid);
|
||||||
void *data, SECItem *oid);
|
|
||||||
|
|
||||||
/* returns a duplicate of the CERTGeneralNameList */
|
/* returns a duplicate of the CERTGeneralNameList */
|
||||||
CERTGeneralNameList *
|
CERTGeneralNameList *CERT_DupGeneralNameList(CERTGeneralNameList *list);
|
||||||
CERT_DupGeneralNameList(CERTGeneralNameList *list);
|
|
||||||
|
|
||||||
/* returns the number of CERTGeneralName objects in the doubly linked
|
/* returns the number of CERTGeneralName objects in the doubly linked
|
||||||
** list of which *names is a member.
|
** list of which *names is a member.
|
||||||
*/
|
*/
|
||||||
extern int
|
extern int CERT_GetNamesLength(CERTGeneralName *names);
|
||||||
CERT_GetNamesLength(CERTGeneralName *names);
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
SECStatus
|
SECStatus CERT_CompareNameSpace(CERTCertificate *cert,
|
||||||
CERT_CompareNameSpace(CERTCertificate *cert,
|
CERTGeneralName *namesList,
|
||||||
CERTGeneralName *namesList,
|
CERTCertificate **certsList,
|
||||||
CERTCertificate **certsList,
|
PLArenaPool *reqArena,
|
||||||
PLArenaPool *reqArena,
|
CERTCertificate **pBadCert);
|
||||||
CERTCertificate **pBadCert);
|
|
||||||
|
|
||||||
SEC_END_PROTOS
|
SEC_END_PROTOS
|
||||||
|
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "cert.h"
|
#include "cert.h"
|
||||||
#include "secoid.h"
|
#include "secoid.h"
|
||||||
#include "secder.h" /* XXX remove this when remove the DERTemplates */
|
#include "secder.h" /* XXX remove this when remove the DERTemplates */
|
||||||
#include "secasn1.h"
|
#include "secasn1.h"
|
||||||
#include "secitem.h"
|
#include "secitem.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -12,29 +12,25 @@
|
||||||
#include "certi.h"
|
#include "certi.h"
|
||||||
|
|
||||||
static const SEC_ASN1Template cert_AVATemplate[] = {
|
static const SEC_ASN1Template cert_AVATemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAVA) },
|
||||||
0, NULL, sizeof(CERTAVA) },
|
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAVA, type) },
|
||||||
{ SEC_ASN1_OBJECT_ID,
|
{ SEC_ASN1_ANY, offsetof(CERTAVA, value) },
|
||||||
offsetof(CERTAVA,type), },
|
{ 0 }
|
||||||
{ SEC_ASN1_ANY,
|
|
||||||
offsetof(CERTAVA,value), },
|
|
||||||
{ 0, }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEC_ASN1Template CERT_RDNTemplate[] = {
|
const SEC_ASN1Template CERT_RDNTemplate[] = {
|
||||||
{ SEC_ASN1_SET_OF,
|
{ SEC_ASN1_SET_OF, offsetof(CERTRDN, avas), cert_AVATemplate,
|
||||||
offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
|
sizeof(CERTRDN) }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
CountArray(void **array)
|
CountArray(void **array)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
if (array) {
|
if (array) {
|
||||||
while (*array++) {
|
while (*array++) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -49,36 +45,37 @@ AddToArray(PLArenaPool *arena, void **array, void *element)
|
||||||
count = 0;
|
count = 0;
|
||||||
ap = array;
|
ap = array;
|
||||||
if (ap) {
|
if (ap) {
|
||||||
while (*ap++) {
|
while (*ap++) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array) {
|
if (array) {
|
||||||
array = (void**) PORT_ArenaGrow(arena, array,
|
array =
|
||||||
(count + 1) * sizeof(void *),
|
(void **)PORT_ArenaGrow(arena, array, (count + 1) * sizeof(void *),
|
||||||
(count + 2) * sizeof(void *));
|
(count + 2) * sizeof(void *));
|
||||||
} else {
|
}
|
||||||
array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
|
else {
|
||||||
|
array = (void **)PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
|
||||||
}
|
}
|
||||||
if (array) {
|
if (array) {
|
||||||
array[count] = element;
|
array[count] = element;
|
||||||
array[count+1] = 0;
|
array[count + 1] = 0;
|
||||||
}
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECOidTag
|
SECOidTag
|
||||||
CERT_GetAVATag(CERTAVA *ava)
|
CERT_GetAVATag(CERTAVA *ava)
|
||||||
{
|
{
|
||||||
SECOidData *oid;
|
SECOidData *oid;
|
||||||
if (!ava->type.data) return (SECOidTag)-1;
|
if (!ava->type.data)
|
||||||
|
return (SECOidTag)-1;
|
||||||
|
|
||||||
oid = SECOID_FindOID(&ava->type);
|
oid = SECOID_FindOID(&ava->type);
|
||||||
|
|
||||||
if ( oid ) {
|
if (oid) {
|
||||||
return(oid->offset);
|
return (oid->offset);
|
||||||
}
|
}
|
||||||
return (SECOidTag)-1;
|
return (SECOidTag)-1;
|
||||||
}
|
}
|
||||||
|
@ -89,25 +86,25 @@ SetupAVAType(PLArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
|
||||||
unsigned char *oid;
|
unsigned char *oid;
|
||||||
unsigned oidLen;
|
unsigned oidLen;
|
||||||
unsigned char *cp;
|
unsigned char *cp;
|
||||||
int maxLen;
|
int maxLen;
|
||||||
SECOidData *oidrec;
|
SECOidData *oidrec;
|
||||||
|
|
||||||
oidrec = SECOID_FindOIDByTag(type);
|
oidrec = SECOID_FindOIDByTag(type);
|
||||||
if (oidrec == NULL)
|
if (oidrec == NULL)
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
|
|
||||||
oid = oidrec->oid.data;
|
oid = oidrec->oid.data;
|
||||||
oidLen = oidrec->oid.len;
|
oidLen = oidrec->oid.len;
|
||||||
|
|
||||||
maxLen = cert_AVAOidTagToMaxLen(type);
|
maxLen = cert_AVAOidTagToMaxLen(type);
|
||||||
if (maxLen < 0) {
|
if (maxLen < 0) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen);
|
it->data = cp = (unsigned char *)PORT_ArenaAlloc(arena, oidLen);
|
||||||
if (cp == NULL) {
|
if (cp == NULL) {
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
it->len = oidLen;
|
it->len = oidLen;
|
||||||
PORT_Memcpy(cp, oid, oidLen);
|
PORT_Memcpy(cp, oid, oidLen);
|
||||||
|
@ -123,65 +120,66 @@ SetupAVAValue(PLArenaPool *arena, int valueType, const SECItem *in,
|
||||||
unsigned valueLen, valueLenLen, total;
|
unsigned valueLen, valueLenLen, total;
|
||||||
unsigned ucs4Len = 0, ucs4MaxLen;
|
unsigned ucs4Len = 0, ucs4MaxLen;
|
||||||
|
|
||||||
value = in->data;
|
value = in->data;
|
||||||
valueLen = in->len;
|
valueLen = in->len;
|
||||||
switch (valueType) {
|
switch (valueType) {
|
||||||
case SEC_ASN1_PRINTABLE_STRING:
|
case SEC_ASN1_PRINTABLE_STRING:
|
||||||
case SEC_ASN1_IA5_STRING:
|
case SEC_ASN1_IA5_STRING:
|
||||||
case SEC_ASN1_T61_STRING:
|
case SEC_ASN1_T61_STRING:
|
||||||
case SEC_ASN1_UTF8_STRING: /* no conversion required */
|
case SEC_ASN1_UTF8_STRING: /* no conversion required */
|
||||||
break;
|
break;
|
||||||
case SEC_ASN1_UNIVERSAL_STRING:
|
case SEC_ASN1_UNIVERSAL_STRING:
|
||||||
ucs4MaxLen = valueLen * 6;
|
ucs4MaxLen = valueLen * 6;
|
||||||
ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
|
ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
|
||||||
if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen,
|
if (!ucs4Val ||
|
||||||
ucs4Val, ucs4MaxLen, &ucs4Len)) {
|
!PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen, ucs4Val,
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
ucs4MaxLen, &ucs4Len)) {
|
||||||
return SECFailure;
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
}
|
return SECFailure;
|
||||||
value = ucs4Val;
|
}
|
||||||
valueLen = ucs4Len;
|
value = ucs4Val;
|
||||||
maxLen *= 4;
|
valueLen = ucs4Len;
|
||||||
break;
|
maxLen *= 4;
|
||||||
default:
|
break;
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
default:
|
||||||
return SECFailure;
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueLen > maxLen) {
|
if (valueLen > maxLen) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
valueLenLen = DER_LengthLength(valueLen);
|
valueLenLen = DER_LengthLength(valueLen);
|
||||||
total = 1 + valueLenLen + valueLen;
|
total = 1 + valueLenLen + valueLen;
|
||||||
cp = (PRUint8*)PORT_ArenaAlloc(arena, total);
|
cp = (PRUint8 *)PORT_ArenaAlloc(arena, total);
|
||||||
if (!cp) {
|
if (!cp) {
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
out->data = cp;
|
out->data = cp;
|
||||||
out->len = total;
|
out->len = total;
|
||||||
cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen);
|
cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen);
|
||||||
PORT_Memcpy(cp, value, valueLen);
|
PORT_Memcpy(cp, value, valueLen);
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTAVA *
|
CERTAVA *
|
||||||
CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem * OID,
|
CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem *OID,
|
||||||
const SECItem * value)
|
const SECItem *value)
|
||||||
{
|
{
|
||||||
CERTAVA *ava;
|
CERTAVA *ava;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
ava = PORT_ArenaZNew(pool, CERTAVA);
|
ava = PORT_ArenaZNew(pool, CERTAVA);
|
||||||
if (ava) {
|
if (ava) {
|
||||||
rv = SECITEM_CopyItem(pool, &ava->type, OID);
|
rv = SECITEM_CopyItem(pool, &ava->type, OID);
|
||||||
if (rv)
|
if (rv)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rv = SECITEM_CopyItem(pool, &ava->value, value);
|
rv = SECITEM_CopyItem(pool, &ava->value, value);
|
||||||
if (rv)
|
if (rv)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return ava;
|
return ava;
|
||||||
}
|
}
|
||||||
|
@ -194,18 +192,18 @@ CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, int valueType,
|
||||||
int rv;
|
int rv;
|
||||||
unsigned maxLen;
|
unsigned maxLen;
|
||||||
|
|
||||||
ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
||||||
if (ava) {
|
if (ava) {
|
||||||
rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
|
rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
/* Illegal AVA type */
|
/* Illegal AVA type */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
|
rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
/* Illegal value type */
|
/* Illegal value type */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ava;
|
return ava;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +214,7 @@ CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind, int valueType, char *value)
|
||||||
SECItem item = { siBuffer, NULL, 0 };
|
SECItem item = { siBuffer, NULL, 0 };
|
||||||
|
|
||||||
item.data = (PRUint8 *)value;
|
item.data = (PRUint8 *)value;
|
||||||
item.len = PORT_Strlen(value);
|
item.len = PORT_Strlen(value);
|
||||||
|
|
||||||
return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item);
|
return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item);
|
||||||
}
|
}
|
||||||
|
@ -227,16 +225,18 @@ CERT_CopyAVA(PLArenaPool *arena, CERTAVA *from)
|
||||||
CERTAVA *ava;
|
CERTAVA *ava;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
||||||
if (ava) {
|
if (ava) {
|
||||||
rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
|
rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
|
goto loser;
|
||||||
if (rv) goto loser;
|
rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
|
||||||
|
if (rv)
|
||||||
|
goto loser;
|
||||||
}
|
}
|
||||||
return ava;
|
return ava;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,34 +249,34 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
|
||||||
unsigned count;
|
unsigned count;
|
||||||
CERTAVA **avap;
|
CERTAVA **avap;
|
||||||
|
|
||||||
rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN));
|
rdn = (CERTRDN *)PORT_ArenaAlloc(arena, sizeof(CERTRDN));
|
||||||
if (rdn) {
|
if (rdn) {
|
||||||
/* Count number of avas going into the rdn */
|
/* Count number of avas going into the rdn */
|
||||||
count = 0;
|
count = 0;
|
||||||
if (ava0) {
|
if (ava0) {
|
||||||
count++;
|
count++;
|
||||||
va_start(ap, ava0);
|
va_start(ap, ava0);
|
||||||
while ((ava = va_arg(ap, CERTAVA*)) != 0) {
|
while ((ava = va_arg(ap, CERTAVA *)) != 0) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now fill in the pointers */
|
/* Now fill in the pointers */
|
||||||
rdn->avas = avap =
|
rdn->avas = avap =
|
||||||
(CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*));
|
(CERTAVA **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTAVA *));
|
||||||
if (!avap) {
|
if (!avap) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ava0) {
|
if (ava0) {
|
||||||
*avap++ = ava0;
|
*avap++ = ava0;
|
||||||
va_start(ap, ava0);
|
va_start(ap, ava0);
|
||||||
while ((ava = va_arg(ap, CERTAVA*)) != 0) {
|
while ((ava = va_arg(ap, CERTAVA *)) != 0) {
|
||||||
*avap++ = ava;
|
*avap++ = ava;
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
*avap++ = 0;
|
*avap++ = 0;
|
||||||
}
|
}
|
||||||
return rdn;
|
return rdn;
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
|
CERT_AddAVA(PLArenaPool *arena, CERTRDN *rdn, CERTAVA *ava)
|
||||||
{
|
{
|
||||||
rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava);
|
rdn->avas = (CERTAVA **)AddToArray(arena, (void **)rdn->avas, ava);
|
||||||
return rdn->avas ? SECSuccess : SECFailure;
|
return rdn->avas ? SECSuccess : SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,20 +297,20 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
|
||||||
/* Copy each ava from from */
|
/* Copy each ava from from */
|
||||||
avas = from->avas;
|
avas = from->avas;
|
||||||
if (avas) {
|
if (avas) {
|
||||||
if (avas[0] == NULL) {
|
if (avas[0] == NULL) {
|
||||||
rv = CERT_AddAVA(arena, to, NULL);
|
rv = CERT_AddAVA(arena, to, NULL);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
while ((fava = *avas++) != 0) {
|
while ((fava = *avas++) != 0) {
|
||||||
tava = CERT_CopyAVA(arena, fava);
|
tava = CERT_CopyAVA(arena, fava);
|
||||||
if (!tava) {
|
if (!tava) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rv = CERT_AddAVA(arena, to, tava);
|
rv = CERT_AddAVA(arena, to, tava);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -318,8 +318,8 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
const SEC_ASN1Template CERT_NameTemplate[] = {
|
const SEC_ASN1Template CERT_NameTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE_OF,
|
{ SEC_ASN1_SEQUENCE_OF, offsetof(CERTName, rdns), CERT_RDNTemplate,
|
||||||
offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) }
|
sizeof(CERTName) }
|
||||||
};
|
};
|
||||||
|
|
||||||
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
|
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
|
||||||
|
@ -333,71 +333,72 @@ CERT_CreateName(CERTRDN *rdn0, ...)
|
||||||
unsigned count;
|
unsigned count;
|
||||||
CERTRDN **rdnp;
|
CERTRDN **rdnp;
|
||||||
PLArenaPool *arena;
|
PLArenaPool *arena;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
if ( !arena ) {
|
if (!arena) {
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName));
|
name = (CERTName *)PORT_ArenaAlloc(arena, sizeof(CERTName));
|
||||||
if (name) {
|
if (name) {
|
||||||
name->arena = arena;
|
name->arena = arena;
|
||||||
|
|
||||||
/* Count number of RDNs going into the Name */
|
|
||||||
if (!rdn0) {
|
|
||||||
count = 0;
|
|
||||||
} else {
|
|
||||||
count = 1;
|
|
||||||
va_start(ap, rdn0);
|
|
||||||
while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate space (including space for terminal null ptr) */
|
/* Count number of RDNs going into the Name */
|
||||||
name->rdns = rdnp =
|
if (!rdn0) {
|
||||||
(CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*));
|
count = 0;
|
||||||
if (!name->rdns) {
|
}
|
||||||
goto loser;
|
else {
|
||||||
}
|
count = 1;
|
||||||
|
va_start(ap, rdn0);
|
||||||
|
while ((rdn = va_arg(ap, CERTRDN *)) != 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
/* Now fill in the pointers */
|
/* Allocate space (including space for terminal null ptr) */
|
||||||
if (count > 0) {
|
name->rdns = rdnp =
|
||||||
*rdnp++ = rdn0;
|
(CERTRDN **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN *));
|
||||||
va_start(ap, rdn0);
|
if (!name->rdns) {
|
||||||
while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
|
goto loser;
|
||||||
*rdnp++ = rdn;
|
}
|
||||||
}
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* null terminate the list */
|
/* Now fill in the pointers */
|
||||||
*rdnp++ = 0;
|
if (count > 0) {
|
||||||
|
*rdnp++ = rdn0;
|
||||||
|
va_start(ap, rdn0);
|
||||||
|
while ((rdn = va_arg(ap, CERTRDN *)) != 0) {
|
||||||
|
*rdnp++ = rdn;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* null terminate the list */
|
||||||
|
*rdnp++ = 0;
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CERT_DestroyName(CERTName *name)
|
CERT_DestroyName(CERTName *name)
|
||||||
{
|
{
|
||||||
if (name)
|
if (name) {
|
||||||
{
|
|
||||||
PLArenaPool *arena = name->arena;
|
PLArenaPool *arena = name->arena;
|
||||||
name->rdns = NULL;
|
name->rdns = NULL;
|
||||||
name->arena = NULL;
|
name->arena = NULL;
|
||||||
if (arena) PORT_FreeArena(arena, PR_FALSE);
|
if (arena)
|
||||||
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_AddRDN(CERTName *name, CERTRDN *rdn)
|
CERT_AddRDN(CERTName *name, CERTRDN *rdn)
|
||||||
{
|
{
|
||||||
name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn);
|
name->rdns = (CERTRDN **)AddToArray(name->arena, (void **)name->rdns, rdn);
|
||||||
return name->rdns ? SECSuccess : SECFailure;
|
return name->rdns ? SECSuccess : SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,8 +409,8 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
if (!to || !from) {
|
if (!to || !from) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
CERT_DestroyName(to);
|
CERT_DestroyName(to);
|
||||||
|
@ -418,23 +419,23 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
|
||||||
/* Copy each rdn from from */
|
/* Copy each rdn from from */
|
||||||
rdns = from->rdns;
|
rdns = from->rdns;
|
||||||
if (rdns) {
|
if (rdns) {
|
||||||
if (rdns[0] == NULL) {
|
if (rdns[0] == NULL) {
|
||||||
rv = CERT_AddRDN(to, NULL);
|
rv = CERT_AddRDN(to, NULL);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
while ((frdn = *rdns++) != NULL) {
|
while ((frdn = *rdns++) != NULL) {
|
||||||
trdn = CERT_CreateRDN(arena, NULL);
|
trdn = CERT_CreateRDN(arena, NULL);
|
||||||
if (!trdn) {
|
if (!trdn) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rv = CERT_CopyRDN(arena, trdn, frdn);
|
rv = CERT_CopyRDN(arena, trdn, frdn);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
rv = CERT_AddRDN(to, trdn);
|
rv = CERT_AddRDN(to, trdn);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -442,34 +443,36 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
canonicalize(SECItem * foo)
|
canonicalize(SECItem *foo)
|
||||||
{
|
{
|
||||||
int ch, lastch, len, src, dest;
|
int ch, lastch, len, src, dest;
|
||||||
|
|
||||||
/* strip trailing whitespace. */
|
/* strip trailing whitespace. */
|
||||||
len = foo->len;
|
len = foo->len;
|
||||||
while (len > 0 && ((ch = foo->data[len - 1]) == ' ' ||
|
while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || ch == '\t' ||
|
||||||
ch == '\t' || ch == '\r' || ch == '\n')) {
|
ch == '\r' || ch == '\n')) {
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = 0;
|
src = 0;
|
||||||
/* strip leading whitespace. */
|
/* strip leading whitespace. */
|
||||||
while (src < len && ((ch = foo->data[src]) == ' ' ||
|
while (src < len && ((ch = foo->data[src]) == ' ' || ch == '\t' ||
|
||||||
ch == '\t' || ch == '\r' || ch == '\n')) {
|
ch == '\r' || ch == '\n')) {
|
||||||
src++;
|
src++;
|
||||||
}
|
}
|
||||||
dest = 0; lastch = ' ';
|
dest = 0;
|
||||||
|
lastch = ' ';
|
||||||
while (src < len) {
|
while (src < len) {
|
||||||
ch = foo->data[src++];
|
ch = foo->data[src++];
|
||||||
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
|
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
|
||||||
ch = ' ';
|
ch = ' ';
|
||||||
if (ch == lastch)
|
if (ch == lastch)
|
||||||
continue;
|
continue;
|
||||||
} else if (ch >= 'A' && ch <= 'Z') {
|
}
|
||||||
ch |= 0x20; /* downshift */
|
else if (ch >= 'A' && ch <= 'Z') {
|
||||||
}
|
ch |= 0x20; /* downshift */
|
||||||
foo->data[dest++] = lastch = ch;
|
}
|
||||||
|
foo->data[dest++] = lastch = ch;
|
||||||
}
|
}
|
||||||
foo->len = dest;
|
foo->len = dest;
|
||||||
}
|
}
|
||||||
|
@ -479,14 +482,13 @@ SECComparison
|
||||||
CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b)
|
CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b)
|
||||||
{
|
{
|
||||||
SECComparison rv = SECLessThan;
|
SECComparison rv = SECLessThan;
|
||||||
SECItem * aVal = CERT_DecodeAVAValue(a);
|
SECItem *aVal = CERT_DecodeAVAValue(a);
|
||||||
SECItem * bVal = CERT_DecodeAVAValue(b);
|
SECItem *bVal = CERT_DecodeAVAValue(b);
|
||||||
|
|
||||||
if (aVal && aVal->len && aVal->data &&
|
if (aVal && aVal->len && aVal->data && bVal && bVal->len && bVal->data) {
|
||||||
bVal && bVal->len && bVal->data) {
|
canonicalize(aVal);
|
||||||
canonicalize(aVal);
|
canonicalize(bVal);
|
||||||
canonicalize(bVal);
|
rv = SECITEM_CompareItem(aVal, bVal);
|
||||||
rv = SECITEM_CompareItem(aVal, bVal);
|
|
||||||
}
|
}
|
||||||
SECITEM_FreeItem(aVal, PR_TRUE);
|
SECITEM_FreeItem(aVal, PR_TRUE);
|
||||||
SECITEM_FreeItem(bVal, PR_TRUE);
|
SECITEM_FreeItem(bVal, PR_TRUE);
|
||||||
|
@ -500,30 +502,31 @@ CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b)
|
||||||
|
|
||||||
rv = SECITEM_CompareItem(&a->type, &b->type);
|
rv = SECITEM_CompareItem(&a->type, &b->type);
|
||||||
if (SECEqual != rv)
|
if (SECEqual != rv)
|
||||||
return rv; /* Attribute types don't match. */
|
return rv; /* Attribute types don't match. */
|
||||||
/* Let's be optimistic. Maybe the values will just compare equal. */
|
/* Let's be optimistic. Maybe the values will just compare equal. */
|
||||||
rv = SECITEM_CompareItem(&a->value, &b->value);
|
rv = SECITEM_CompareItem(&a->value, &b->value);
|
||||||
if (SECEqual == rv)
|
if (SECEqual == rv)
|
||||||
return rv; /* values compared exactly. */
|
return rv; /* values compared exactly. */
|
||||||
if (a->value.len && a->value.data && b->value.len && b->value.data) {
|
if (a->value.len && a->value.data && b->value.len && b->value.data) {
|
||||||
/* Here, the values did not match.
|
/* Here, the values did not match.
|
||||||
** If the values had different encodings, convert them to the same
|
** If the values had different encodings, convert them to the same
|
||||||
** encoding and compare that way.
|
** encoding and compare that way.
|
||||||
*/
|
*/
|
||||||
if (a->value.data[0] != b->value.data[0]) {
|
if (a->value.data[0] != b->value.data[0]) {
|
||||||
/* encodings differ. Convert both to UTF-8 and compare. */
|
/* encodings differ. Convert both to UTF-8 and compare. */
|
||||||
SECItem * aVal = CERT_DecodeAVAValue(&a->value);
|
SECItem *aVal = CERT_DecodeAVAValue(&a->value);
|
||||||
SECItem * bVal = CERT_DecodeAVAValue(&b->value);
|
SECItem *bVal = CERT_DecodeAVAValue(&b->value);
|
||||||
if (aVal && aVal->len && aVal->data &&
|
if (aVal && aVal->len && aVal->data && bVal && bVal->len &&
|
||||||
bVal && bVal->len && bVal->data) {
|
bVal->data) {
|
||||||
rv = SECITEM_CompareItem(aVal, bVal);
|
rv = SECITEM_CompareItem(aVal, bVal);
|
||||||
}
|
}
|
||||||
SECITEM_FreeItem(aVal, PR_TRUE);
|
SECITEM_FreeItem(aVal, PR_TRUE);
|
||||||
SECITEM_FreeItem(bVal, PR_TRUE);
|
SECITEM_FreeItem(bVal, PR_TRUE);
|
||||||
} else if (a->value.data[0] == 0x13) { /* both are printable strings. */
|
}
|
||||||
/* printable strings */
|
else if (a->value.data[0] == 0x13) { /* both are printable strings. */
|
||||||
rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
|
/* printable strings */
|
||||||
}
|
rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -543,23 +546,25 @@ CERT_CompareRDN(const CERTRDN *a, const CERTRDN *b)
|
||||||
** Make sure array of ava's are the same length. If not, then we are
|
** Make sure array of ava's are the same length. If not, then we are
|
||||||
** not equal
|
** not equal
|
||||||
*/
|
*/
|
||||||
ac = CountArray((void**) aavas);
|
ac = CountArray((void **)aavas);
|
||||||
bc = CountArray((void**) bavas);
|
bc = CountArray((void **)bavas);
|
||||||
if (ac < bc) return SECLessThan;
|
if (ac < bc)
|
||||||
if (ac > bc) return SECGreaterThan;
|
return SECLessThan;
|
||||||
|
if (ac > bc)
|
||||||
|
return SECGreaterThan;
|
||||||
|
|
||||||
while (NULL != (aava = *aavas++)) {
|
while (NULL != (aava = *aavas++)) {
|
||||||
for (bavas = b->avas; NULL != (bava = *bavas++); ) {
|
for (bavas = b->avas; NULL != (bava = *bavas++);) {
|
||||||
rv = SECITEM_CompareItem(&aava->type, &bava->type);
|
rv = SECITEM_CompareItem(&aava->type, &bava->type);
|
||||||
if (SECEqual == rv) {
|
if (SECEqual == rv) {
|
||||||
rv = CERT_CompareAVA(aava, bava);
|
rv = CERT_CompareAVA(aava, bava);
|
||||||
if (SECEqual != rv)
|
if (SECEqual != rv)
|
||||||
return rv;
|
return rv;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!bava) /* didn't find a match */
|
if (!bava) /* didn't find a match */
|
||||||
return SECGreaterThan;
|
return SECGreaterThan;
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -579,19 +584,22 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
|
||||||
** Make sure array of rdn's are the same length. If not, then we are
|
** Make sure array of rdn's are the same length. If not, then we are
|
||||||
** not equal
|
** not equal
|
||||||
*/
|
*/
|
||||||
ac = CountArray((void**) ardns);
|
ac = CountArray((void **)ardns);
|
||||||
bc = CountArray((void**) brdns);
|
bc = CountArray((void **)brdns);
|
||||||
if (ac < bc) return SECLessThan;
|
if (ac < bc)
|
||||||
if (ac > bc) return SECGreaterThan;
|
return SECLessThan;
|
||||||
|
if (ac > bc)
|
||||||
|
return SECGreaterThan;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ardn = *ardns++;
|
ardn = *ardns++;
|
||||||
brdn = *brdns++;
|
brdn = *brdns++;
|
||||||
if (!ardn) {
|
if (!ardn) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rv = CERT_CompareRDN(ardn, brdn);
|
rv = CERT_CompareRDN(ardn, brdn);
|
||||||
if (rv) return rv;
|
if (rv)
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -600,47 +608,47 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
|
||||||
SECItem *
|
SECItem *
|
||||||
CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||||
{
|
{
|
||||||
SECItem *retItem;
|
SECItem *retItem;
|
||||||
const SEC_ASN1Template *theTemplate = NULL;
|
const SEC_ASN1Template *theTemplate = NULL;
|
||||||
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
|
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
|
||||||
SECItem avaValue = {siBuffer, 0};
|
SECItem avaValue = { siBuffer, 0 };
|
||||||
PLArenaPool *newarena = NULL;
|
PLArenaPool *newarena = NULL;
|
||||||
|
|
||||||
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
|
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(derAVAValue->data[0]) {
|
switch (derAVAValue->data[0]) {
|
||||||
case SEC_ASN1_UNIVERSAL_STRING:
|
case SEC_ASN1_UNIVERSAL_STRING:
|
||||||
convert = conv_ucs4;
|
convert = conv_ucs4;
|
||||||
theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate);
|
theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate);
|
||||||
break;
|
break;
|
||||||
case SEC_ASN1_IA5_STRING:
|
case SEC_ASN1_IA5_STRING:
|
||||||
theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
|
theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
|
||||||
break;
|
break;
|
||||||
case SEC_ASN1_PRINTABLE_STRING:
|
case SEC_ASN1_PRINTABLE_STRING:
|
||||||
theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate);
|
theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate);
|
||||||
break;
|
break;
|
||||||
case SEC_ASN1_T61_STRING:
|
case SEC_ASN1_T61_STRING:
|
||||||
/*
|
/*
|
||||||
* Per common practice, we're not decoding actual T.61, but instead
|
* Per common practice, we're not decoding actual T.61, but instead
|
||||||
* treating T61-labeled strings as containing ISO-8859-1.
|
* treating T61-labeled strings as containing ISO-8859-1.
|
||||||
*/
|
*/
|
||||||
convert = conv_iso88591;
|
convert = conv_iso88591;
|
||||||
theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate);
|
theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate);
|
||||||
break;
|
break;
|
||||||
case SEC_ASN1_BMP_STRING:
|
case SEC_ASN1_BMP_STRING:
|
||||||
convert = conv_ucs2;
|
convert = conv_ucs2;
|
||||||
theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
|
theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
|
||||||
break;
|
break;
|
||||||
case SEC_ASN1_UTF8_STRING:
|
case SEC_ASN1_UTF8_STRING:
|
||||||
/* No conversion needed ! */
|
/* No conversion needed ! */
|
||||||
theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
|
theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT_Memset(&avaValue, 0, sizeof(SECItem));
|
PORT_Memset(&avaValue, 0, sizeof(SECItem));
|
||||||
|
@ -648,51 +656,54 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||||
if (!newarena) {
|
if (!newarena) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue)
|
if (SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) !=
|
||||||
!= SECSuccess) {
|
SECSuccess) {
|
||||||
PORT_FreeArena(newarena, PR_FALSE);
|
PORT_FreeArena(newarena, PR_FALSE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convert != conv_none) {
|
if (convert != conv_none) {
|
||||||
unsigned int utf8ValLen = avaValue.len * 3;
|
unsigned int utf8ValLen = avaValue.len * 3;
|
||||||
unsigned char *utf8Val = (unsigned char*)
|
unsigned char *utf8Val =
|
||||||
PORT_ArenaZAlloc(newarena, utf8ValLen);
|
(unsigned char *)PORT_ArenaZAlloc(newarena, utf8ValLen);
|
||||||
|
|
||||||
switch (convert) {
|
switch (convert) {
|
||||||
case conv_ucs4:
|
case conv_ucs4:
|
||||||
if(avaValue.len % 4 != 0 ||
|
if (avaValue.len % 4 != 0 ||
|
||||||
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
|
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data,
|
||||||
utf8Val, utf8ValLen, &utf8ValLen)) {
|
avaValue.len, utf8Val, utf8ValLen,
|
||||||
PORT_FreeArena(newarena, PR_FALSE);
|
&utf8ValLen)) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
PORT_FreeArena(newarena, PR_FALSE);
|
||||||
return NULL;
|
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||||
}
|
return NULL;
|
||||||
break;
|
}
|
||||||
case conv_ucs2:
|
break;
|
||||||
if(avaValue.len % 2 != 0 ||
|
case conv_ucs2:
|
||||||
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
|
if (avaValue.len % 2 != 0 ||
|
||||||
utf8Val, utf8ValLen, &utf8ValLen)) {
|
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data,
|
||||||
PORT_FreeArena(newarena, PR_FALSE);
|
avaValue.len, utf8Val, utf8ValLen,
|
||||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
&utf8ValLen)) {
|
||||||
return NULL;
|
PORT_FreeArena(newarena, PR_FALSE);
|
||||||
}
|
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||||
break;
|
return NULL;
|
||||||
case conv_iso88591:
|
}
|
||||||
if(!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
|
break;
|
||||||
utf8Val, utf8ValLen, &utf8ValLen)) {
|
case conv_iso88591:
|
||||||
PORT_FreeArena(newarena, PR_FALSE);
|
if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
|
||||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
utf8Val, utf8ValLen,
|
||||||
return NULL;
|
&utf8ValLen)) {
|
||||||
}
|
PORT_FreeArena(newarena, PR_FALSE);
|
||||||
break;
|
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||||
case conv_none:
|
return NULL;
|
||||||
PORT_Assert(0); /* not reached */
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case conv_none:
|
||||||
|
PORT_Assert(0); /* not reached */
|
||||||
avaValue.data = utf8Val;
|
break;
|
||||||
avaValue.len = utf8ValLen;
|
}
|
||||||
|
|
||||||
|
avaValue.data = utf8Val;
|
||||||
|
avaValue.len = utf8ValLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
retItem = SECITEM_DupItem(&avaValue);
|
retItem = SECITEM_DupItem(&avaValue);
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* X.509 v3 Subject Key Usage Extension
|
* X.509 v3 Subject Key Usage Extension
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
#include "secasn1t.h"
|
#include "secasn1t.h"
|
||||||
#include "secasn1.h"
|
#include "secasn1.h"
|
||||||
#include "secport.h"
|
#include "secport.h"
|
||||||
#include "certt.h"
|
#include "certt.h"
|
||||||
#include "genname.h"
|
#include "genname.h"
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
|
||||||
|
@ -24,105 +24,106 @@ SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
|
||||||
const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
|
const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
|
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
||||||
offsetof(CERTAuthKeyID,keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate)},
|
offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||||
offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate},
|
offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
|
||||||
offsetof(CERTAuthKeyID,authCertSerialNumber),
|
offsetof(CERTAuthKeyID, authCertSerialNumber),
|
||||||
SEC_ASN1_SUB(SEC_IntegerTemplate) },
|
SEC_ASN1_SUB(SEC_IntegerTemplate) },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SECStatus
|
||||||
|
CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
|
||||||
SECStatus CERT_EncodeAuthKeyID (PLArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue)
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
SECStatus rv = SECFailure;
|
SECStatus rv = SECFailure;
|
||||||
|
|
||||||
PORT_Assert (value);
|
PORT_Assert(value);
|
||||||
PORT_Assert (arena);
|
PORT_Assert(arena);
|
||||||
PORT_Assert (value->DERAuthCertIssuer == NULL);
|
PORT_Assert(value->DERAuthCertIssuer == NULL);
|
||||||
PORT_Assert (encodedValue);
|
PORT_Assert(encodedValue);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
/* If both of the authCertIssuer and the serial number exist, encode
|
|
||||||
the name first. Otherwise, it is an error if one exist and the other
|
|
||||||
is not.
|
|
||||||
*/
|
|
||||||
if (value->authCertIssuer) {
|
|
||||||
if (!value->authCertSerialNumber.data) {
|
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
value->DERAuthCertIssuer = cert_EncodeGeneralNames
|
/* If both of the authCertIssuer and the serial number exist, encode
|
||||||
(arena, value->authCertIssuer);
|
the name first. Otherwise, it is an error if one exist and the other
|
||||||
if (!value->DERAuthCertIssuer) {
|
is not.
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
*/
|
||||||
break;
|
if (value->authCertIssuer) {
|
||||||
}
|
if (!value->authCertSerialNumber.data) {
|
||||||
}
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
else if (value->authCertSerialNumber.data) {
|
break;
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SEC_ASN1EncodeItem (arena, encodedValue, value,
|
value->DERAuthCertIssuer =
|
||||||
CERTAuthKeyIDTemplate) == NULL)
|
cert_EncodeGeneralNames(arena, value->authCertIssuer);
|
||||||
break;
|
if (!value->DERAuthCertIssuer) {
|
||||||
rv = SECSuccess;
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (value->authCertSerialNumber.data) {
|
||||||
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SEC_ASN1EncodeItem(arena, encodedValue, value,
|
||||||
|
CERTAuthKeyIDTemplate) == NULL)
|
||||||
|
break;
|
||||||
|
rv = SECSuccess;
|
||||||
|
|
||||||
} while (0);
|
} while (0);
|
||||||
return(rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTAuthKeyID *
|
CERTAuthKeyID *
|
||||||
CERT_DecodeAuthKeyID (PLArenaPool *arena, const SECItem *encodedValue)
|
CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
CERTAuthKeyID * value = NULL;
|
CERTAuthKeyID *value = NULL;
|
||||||
SECStatus rv = SECFailure;
|
SECStatus rv = SECFailure;
|
||||||
void * mark;
|
void *mark;
|
||||||
SECItem newEncodedValue;
|
SECItem newEncodedValue;
|
||||||
|
|
||||||
|
PORT_Assert(arena);
|
||||||
|
|
||||||
PORT_Assert (arena);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
mark = PORT_ArenaMark (arena);
|
mark = PORT_ArenaMark(arena);
|
||||||
value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value));
|
value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value));
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
break;
|
break;
|
||||||
value->DERAuthCertIssuer = NULL;
|
value->DERAuthCertIssuer = NULL;
|
||||||
/* copy the DER into the arena, since Quick DER returns data that points
|
/* copy the DER into the arena, since Quick DER returns data that points
|
||||||
into the DER input, which may get freed by the caller */
|
into the DER input, which may get freed by the caller */
|
||||||
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
|
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem
|
rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate,
|
||||||
(arena, value, CERTAuthKeyIDTemplate, &newEncodedValue);
|
&newEncodedValue);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer);
|
value->authCertIssuer =
|
||||||
if (value->authCertIssuer == NULL)
|
cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer);
|
||||||
break;
|
if (value->authCertIssuer == NULL)
|
||||||
|
break;
|
||||||
/* what if the general name contains other format but not URI ?
|
|
||||||
hl
|
/* what if the general name contains other format but not URI ?
|
||||||
*/
|
hl
|
||||||
if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
|
*/
|
||||||
(!value->authCertSerialNumber.data && value->authCertIssuer)){
|
if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
(!value->authCertSerialNumber.data && value->authCertIssuer)) {
|
||||||
break;
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
if (rv != SECSuccess) {
|
if (rv != SECSuccess) {
|
||||||
PORT_ArenaRelease (arena, mark);
|
PORT_ArenaRelease(arena, mark);
|
||||||
return ((CERTAuthKeyID *)NULL);
|
return ((CERTAuthKeyID *)NULL);
|
||||||
}
|
}
|
||||||
PORT_ArenaUnmark(arena, mark);
|
PORT_ArenaUnmark(arena, mark);
|
||||||
return (value);
|
return (value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* X.509 v3 Basic Constraints Extension
|
* X.509 v3 Basic Constraints Extension
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "prtypes.h"
|
#include "prtypes.h"
|
||||||
#include <limits.h> /* for LONG_MAX */
|
#include <limits.h> /* for LONG_MAX */
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
#include "secdert.h"
|
#include "secdert.h"
|
||||||
#include "secoidt.h"
|
#include "secoidt.h"
|
||||||
|
@ -18,128 +18,132 @@
|
||||||
#include "prprf.h"
|
#include "prprf.h"
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
|
||||||
typedef struct EncodedContext{
|
typedef struct EncodedContext {
|
||||||
SECItem isCA;
|
SECItem isCA;
|
||||||
SECItem pathLenConstraint;
|
SECItem pathLenConstraint;
|
||||||
SECItem encodedValue;
|
SECItem encodedValue;
|
||||||
PLArenaPool *arena;
|
PLArenaPool *arena;
|
||||||
}EncodedContext;
|
} EncodedContext;
|
||||||
|
|
||||||
static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = {
|
static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(EncodedContext) },
|
||||||
0, NULL, sizeof(EncodedContext) },
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
offsetof(EncodedContext, isCA) },
|
||||||
offsetof(EncodedContext,isCA)},
|
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
|
||||||
offsetof(EncodedContext,pathLenConstraint) },
|
offsetof(EncodedContext, pathLenConstraint) },
|
||||||
{ 0, }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char hexTrue = 0xff;
|
static unsigned char hexTrue = 0xff;
|
||||||
static unsigned char hexFalse = 0x00;
|
static unsigned char hexFalse = 0x00;
|
||||||
|
|
||||||
#define GEN_BREAK(status) rv = status; break;
|
#define GEN_BREAK(status) \
|
||||||
|
rv = status; \
|
||||||
|
break;
|
||||||
|
|
||||||
SECStatus CERT_EncodeBasicConstraintValue
|
SECStatus
|
||||||
(PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue)
|
CERT_EncodeBasicConstraintValue(PLArenaPool *arena, CERTBasicConstraints *value,
|
||||||
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
EncodedContext encodeContext;
|
EncodedContext encodeContext;
|
||||||
PLArenaPool *our_pool = NULL;
|
PLArenaPool *our_pool = NULL;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
|
PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
|
||||||
if (!value->isCA && value->pathLenConstraint >= 0) {
|
if (!value->isCA && value->pathLenConstraint >= 0) {
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
GEN_BREAK (SECFailure);
|
GEN_BREAK(SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeContext.arena = arena;
|
encodeContext.arena = arena;
|
||||||
if (value->isCA == PR_TRUE) {
|
if (value->isCA == PR_TRUE) {
|
||||||
encodeContext.isCA.data = &hexTrue ;
|
encodeContext.isCA.data = &hexTrue;
|
||||||
encodeContext.isCA.len = 1;
|
encodeContext.isCA.len = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the pathLenConstraint is less than 0, then it should be
|
/* If the pathLenConstraint is less than 0, then it should be
|
||||||
* omitted from the encoding.
|
* omitted from the encoding.
|
||||||
*/
|
*/
|
||||||
if (value->isCA && value->pathLenConstraint >= 0) {
|
if (value->isCA && value->pathLenConstraint >= 0) {
|
||||||
our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
|
our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||||
if (our_pool == NULL) {
|
if (our_pool == NULL) {
|
||||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||||
GEN_BREAK (SECFailure);
|
GEN_BREAK(SECFailure);
|
||||||
}
|
}
|
||||||
if (SEC_ASN1EncodeUnsignedInteger
|
if (SEC_ASN1EncodeUnsignedInteger(
|
||||||
(our_pool, &encodeContext.pathLenConstraint,
|
our_pool, &encodeContext.pathLenConstraint,
|
||||||
(unsigned long)value->pathLenConstraint) == NULL) {
|
(unsigned long)value->pathLenConstraint) == NULL) {
|
||||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||||
GEN_BREAK (SECFailure);
|
GEN_BREAK(SECFailure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
|
if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
|
||||||
CERTBasicConstraintsTemplate) == NULL) {
|
CERTBasicConstraintsTemplate) == NULL) {
|
||||||
GEN_BREAK (SECFailure);
|
GEN_BREAK(SECFailure);
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
if (our_pool)
|
if (our_pool)
|
||||||
PORT_FreeArena (our_pool, PR_FALSE);
|
PORT_FreeArena(our_pool, PR_FALSE);
|
||||||
return(rv);
|
return (rv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus CERT_DecodeBasicConstraintValue
|
SECStatus
|
||||||
(CERTBasicConstraints *value, const SECItem *encodedValue)
|
CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
|
||||||
|
const SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
EncodedContext decodeContext;
|
EncodedContext decodeContext;
|
||||||
PLArenaPool *our_pool;
|
PLArenaPool *our_pool;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
PORT_Memset (&decodeContext, 0, sizeof (decodeContext));
|
PORT_Memset(&decodeContext, 0, sizeof(decodeContext));
|
||||||
/* initialize the value just in case we got "0x30 00", or when the
|
/* initialize the value just in case we got "0x30 00", or when the
|
||||||
pathLenConstraint is omitted.
|
pathLenConstraint is omitted.
|
||||||
*/
|
*/
|
||||||
decodeContext.isCA.data =&hexFalse;
|
decodeContext.isCA.data = &hexFalse;
|
||||||
decodeContext.isCA.len = 1;
|
decodeContext.isCA.len = 1;
|
||||||
|
|
||||||
our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
|
our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||||
if (our_pool == NULL) {
|
if (our_pool == NULL) {
|
||||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||||
GEN_BREAK (SECFailure);
|
GEN_BREAK(SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = SEC_QuickDERDecodeItem(our_pool, &decodeContext,
|
||||||
|
CERTBasicConstraintsTemplate, encodedValue);
|
||||||
|
if (rv == SECFailure)
|
||||||
|
break;
|
||||||
|
|
||||||
|
value->isCA = decodeContext.isCA.data
|
||||||
|
? (PRBool)(decodeContext.isCA.data[0] != 0)
|
||||||
|
: PR_FALSE;
|
||||||
|
if (decodeContext.pathLenConstraint.data == NULL) {
|
||||||
|
/* if the pathLenConstraint is not encoded, and the current setting
|
||||||
|
is CA, then the pathLenConstraint should be set to a negative
|
||||||
|
number
|
||||||
|
for unlimited certificate path.
|
||||||
|
*/
|
||||||
|
if (value->isCA)
|
||||||
|
value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
|
||||||
|
}
|
||||||
|
else if (value->isCA) {
|
||||||
|
long len = DER_GetInteger(&decodeContext.pathLenConstraint);
|
||||||
|
if (len < 0 || len == LONG_MAX) {
|
||||||
|
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||||
|
GEN_BREAK(SECFailure);
|
||||||
|
}
|
||||||
|
value->pathLenConstraint = len;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* here we get an error where the subject is not a CA, but
|
||||||
|
the pathLenConstraint is set */
|
||||||
|
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||||
|
GEN_BREAK(SECFailure);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem
|
|
||||||
(our_pool, &decodeContext, CERTBasicConstraintsTemplate, encodedValue);
|
|
||||||
if (rv == SECFailure)
|
|
||||||
break;
|
|
||||||
|
|
||||||
value->isCA = decodeContext.isCA.data
|
|
||||||
? (PRBool)(decodeContext.isCA.data[0] != 0)
|
|
||||||
: PR_FALSE;
|
|
||||||
if (decodeContext.pathLenConstraint.data == NULL) {
|
|
||||||
/* if the pathLenConstraint is not encoded, and the current setting
|
|
||||||
is CA, then the pathLenConstraint should be set to a negative number
|
|
||||||
for unlimited certificate path.
|
|
||||||
*/
|
|
||||||
if (value->isCA)
|
|
||||||
value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;
|
|
||||||
} else if (value->isCA) {
|
|
||||||
long len = DER_GetInteger (&decodeContext.pathLenConstraint);
|
|
||||||
if (len < 0 || len == LONG_MAX) {
|
|
||||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
|
||||||
GEN_BREAK (SECFailure);
|
|
||||||
}
|
|
||||||
value->pathLenConstraint = len;
|
|
||||||
} else {
|
|
||||||
/* here we get an error where the subject is not a CA, but
|
|
||||||
the pathLenConstraint is set */
|
|
||||||
PORT_SetError (SEC_ERROR_BAD_DER);
|
|
||||||
GEN_BREAK (SECFailure);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (0);
|
} while (0);
|
||||||
PORT_FreeArena (our_pool, PR_FALSE);
|
PORT_FreeArena(our_pool, PR_FALSE);
|
||||||
return (rv);
|
return (rv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* X.509 Extension Encoding
|
* X.509 Extension Encoding
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "prtypes.h"
|
#include "prtypes.h"
|
||||||
|
@ -20,12 +20,10 @@
|
||||||
#include "secasn1.h"
|
#include "secasn1.h"
|
||||||
#include "secerr.h"
|
#include "secerr.h"
|
||||||
|
|
||||||
|
|
||||||
static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
|
static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
|
||||||
{ SEC_ASN1_OCTET_STRING }
|
{ SEC_ASN1_OCTET_STRING }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
|
static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
|
||||||
{ SEC_ASN1_IA5_STRING }
|
{ SEC_ASN1_IA5_STRING }
|
||||||
};
|
};
|
||||||
|
@ -33,40 +31,34 @@ static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
|
||||||
SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
|
SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
|
||||||
|
|
||||||
static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
|
static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
|
||||||
0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
offsetof(CERTPrivKeyUsagePeriod, notBefore),
|
||||||
offsetof(CERTPrivKeyUsagePeriod, notBefore),
|
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
|
||||||
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
offsetof(CERTPrivKeyUsagePeriod, notAfter),
|
||||||
offsetof(CERTPrivKeyUsagePeriod, notAfter),
|
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
|
||||||
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate)},
|
{ 0 }
|
||||||
{ 0, }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const SEC_ASN1Template CERTAltNameTemplate[] = {
|
const SEC_ASN1Template CERTAltNameTemplate[] = {
|
||||||
{ SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
|
{ SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
|
||||||
CERT_GeneralNamesTemplate}
|
CERT_GeneralNamesTemplate }
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
|
const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthInfoAccess) },
|
||||||
0, NULL, sizeof(CERTAuthInfoAccess) },
|
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAuthInfoAccess, method) },
|
||||||
{ SEC_ASN1_OBJECT_ID,
|
{ SEC_ASN1_ANY, offsetof(CERTAuthInfoAccess, derLocation) },
|
||||||
offsetof(CERTAuthInfoAccess, method) },
|
{ 0 }
|
||||||
{ SEC_ASN1_ANY,
|
|
||||||
offsetof(CERTAuthInfoAccess, derLocation) },
|
|
||||||
{ 0, }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
|
const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
|
{ SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SECStatus
|
||||||
SECStatus
|
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
|
||||||
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
|
|
||||||
SECItem *encodedValue)
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
@ -75,27 +67,26 @@ CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
if (SEC_ASN1EncodeItem (arena, encodedValue, srcString,
|
if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
|
||||||
CERTSubjectKeyIDTemplate) == NULL) {
|
CERTSubjectKeyIDTemplate) == NULL) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
||||||
CERTPrivKeyUsagePeriod *pkup,
|
CERTPrivKeyUsagePeriod *pkup,
|
||||||
SECItem *encodedValue)
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
|
if (SEC_ASN1EncodeItem(arena, encodedValue, pkup,
|
||||||
CERTPrivateKeyUsagePeriodTemplate) == NULL) {
|
CERTPrivateKeyUsagePeriodTemplate) == NULL) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
}
|
}
|
||||||
return(rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTPrivKeyUsagePeriod *
|
CERTPrivKeyUsagePeriod *
|
||||||
|
@ -107,63 +98,62 @@ CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
|
||||||
|
|
||||||
/* allocate the certificate policies structure */
|
/* allocate the certificate policies structure */
|
||||||
pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
|
pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
|
||||||
if ( pPeriod == NULL ) {
|
if (pPeriod == NULL) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
pPeriod->arena = arena;
|
pPeriod->arena = arena;
|
||||||
|
|
||||||
/* copy the DER into the arena, since Quick DER returns data that points
|
/* copy the DER into the arena, since Quick DER returns data that points
|
||||||
into the DER input, which may get freed by the caller */
|
into the DER input, which may get freed by the caller */
|
||||||
rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
|
rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem(arena, pPeriod,
|
rv = SEC_QuickDERDecodeItem(
|
||||||
CERTPrivateKeyUsagePeriodTemplate,
|
arena, pPeriod, CERTPrivateKeyUsagePeriodTemplate, &newExtnValue);
|
||||||
&newExtnValue);
|
if (rv != SECSuccess) {
|
||||||
if ( rv != SECSuccess ) {
|
goto loser;
|
||||||
goto loser;
|
|
||||||
}
|
}
|
||||||
return pPeriod;
|
return pPeriod;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECStatus
|
||||||
SECStatus
|
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
|
||||||
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue)
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
SECItem encodeContext;
|
SECItem encodeContext;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
|
PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
|
||||||
|
|
||||||
PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
|
|
||||||
|
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
encodeContext.data = (unsigned char *)value;
|
encodeContext.data = (unsigned char *)value;
|
||||||
encodeContext.len = strlen(value);
|
encodeContext.len = strlen(value);
|
||||||
}
|
}
|
||||||
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
|
if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
|
||||||
CERTIA5TypeTemplate) == NULL) {
|
CERTIA5TypeTemplate) == NULL) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue)
|
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
|
||||||
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
SECItem **encodedGenName;
|
SECItem **encodedGenName;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
encodedGenName = cert_EncodeGeneralNames(arena, value);
|
encodedGenName = cert_EncodeGeneralNames(arena, value);
|
||||||
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
|
if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
|
||||||
CERT_GeneralNamesTemplate) == NULL) {
|
CERT_GeneralNamesTemplate) == NULL) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -172,9 +162,9 @@ CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECIte
|
||||||
CERTGeneralName *
|
CERTGeneralName *
|
||||||
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
|
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
|
||||||
{
|
{
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
CERTAltNameEncodedContext encodedContext;
|
CERTAltNameEncodedContext encodedContext;
|
||||||
SECItem* newEncodedAltName;
|
SECItem *newEncodedAltName;
|
||||||
|
|
||||||
if (!reqArena) {
|
if (!reqArena) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
@ -188,14 +178,13 @@ CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
|
||||||
|
|
||||||
encodedContext.encodedGenName = NULL;
|
encodedContext.encodedGenName = NULL;
|
||||||
PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
|
PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
|
||||||
rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext,
|
rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
|
||||||
CERT_GeneralNamesTemplate, newEncodedAltName);
|
CERT_GeneralNamesTemplate, newEncodedAltName);
|
||||||
if (rv == SECFailure) {
|
if (rv == SECFailure) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
|
if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
|
||||||
return cert_DecodeGeneralNames(reqArena,
|
return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
|
||||||
encodedContext.encodedGenName);
|
|
||||||
/* Extension contained an empty GeneralNames sequence */
|
/* Extension contained an empty GeneralNames sequence */
|
||||||
/* Treat as extension not found */
|
/* Treat as extension not found */
|
||||||
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||||
|
@ -203,35 +192,32 @@ loser:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
||||||
CERTNameConstraints *value,
|
CERTNameConstraints *value,
|
||||||
SECItem *encodedValue)
|
SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
rv = cert_EncodeNameConstraints(value, arena, encodedValue);
|
rv = cert_EncodeNameConstraints(value, arena, encodedValue);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CERTNameConstraints *
|
CERTNameConstraints *
|
||||||
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
|
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
|
||||||
const SECItem *encodedConstraints)
|
const SECItem *encodedConstraints)
|
||||||
{
|
{
|
||||||
return cert_DecodeNameConstraints(arena, encodedConstraints);
|
return cert_DecodeNameConstraints(arena, encodedConstraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CERTAuthInfoAccess **
|
CERTAuthInfoAccess **
|
||||||
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
|
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
|
||||||
const SECItem *encodedExtension)
|
const SECItem *encodedExtension)
|
||||||
{
|
{
|
||||||
CERTAuthInfoAccess **info = NULL;
|
CERTAuthInfoAccess **info = NULL;
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
int i;
|
int i;
|
||||||
SECItem* newEncodedExtension;
|
SECItem *newEncodedExtension;
|
||||||
|
|
||||||
if (!reqArena) {
|
if (!reqArena) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
@ -243,24 +229,22 @@ CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
|
rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
|
||||||
newEncodedExtension);
|
newEncodedExtension);
|
||||||
if (rv != SECSuccess || info == NULL) {
|
if (rv != SECSuccess || info == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; info[i] != NULL; i++) {
|
for (i = 0; info[i] != NULL; i++) {
|
||||||
info[i]->location = CERT_DecodeGeneralName(reqArena,
|
info[i]->location =
|
||||||
&(info[i]->derLocation),
|
CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
|
CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
|
||||||
CERTAuthInfoAccess **info,
|
SECItem *dest)
|
||||||
SECItem *dest)
|
|
||||||
{
|
{
|
||||||
SECItem *dummy;
|
SECItem *dummy;
|
||||||
int i;
|
int i;
|
||||||
|
@ -268,19 +252,18 @@ CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
|
||||||
PORT_Assert(info != NULL);
|
PORT_Assert(info != NULL);
|
||||||
PORT_Assert(dest != NULL);
|
PORT_Assert(dest != NULL);
|
||||||
if (info == NULL || dest == NULL) {
|
if (info == NULL || dest == NULL) {
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; info[i] != NULL; i++) {
|
for (i = 0; info[i] != NULL; i++) {
|
||||||
if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
|
if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
|
||||||
arena) == NULL)
|
arena) == NULL)
|
||||||
/* Note that this may leave some of the locations filled in. */
|
/* Note that this may leave some of the locations filled in. */
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
dummy = SEC_ASN1EncodeItem(arena, dest, &info,
|
dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
|
||||||
CERTAuthInfoAccessTemplate);
|
|
||||||
if (dummy == NULL) {
|
if (dummy == NULL) {
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,27 +10,21 @@ typedef struct CERTAltNameEncodedContextStr {
|
||||||
SECItem **encodedGenName;
|
SECItem **encodedGenName;
|
||||||
} CERTAltNameEncodedContext;
|
} CERTAltNameEncodedContext;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SEC_BEGIN_PROTOS
|
SEC_BEGIN_PROTOS
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
||||||
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
CERTPrivKeyUsagePeriod *pkup,
|
||||||
CERTPrivKeyUsagePeriod *pkup,
|
SECItem *encodedValue);
|
||||||
SECItem *encodedValue);
|
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
||||||
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
CERTNameConstraints *value,
|
||||||
CERTNameConstraints *value,
|
SECItem *encodedValue);
|
||||||
SECItem *encodedValue);
|
|
||||||
|
|
||||||
extern SECStatus
|
extern SECStatus CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
|
||||||
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
|
SECItem *encodedValue);
|
||||||
SECItem *encodedValue);
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
|
||||||
cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
|
CERTAuthInfoAccess **info,
|
||||||
CERTAuthInfoAccess **info,
|
SECItem *dest);
|
||||||
SECItem *dest);
|
|
||||||
SEC_END_PROTOS
|
SEC_END_PROTOS
|
||||||
#endif
|
#endif
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -22,31 +22,33 @@ static char *hex = "0123456789ABCDEF";
|
||||||
/*
|
/*
|
||||||
** Convert a der-encoded integer to a hex printable string form
|
** Convert a der-encoded integer to a hex printable string form
|
||||||
*/
|
*/
|
||||||
char *CERT_Hexify (SECItem *i, int do_colon)
|
char *
|
||||||
|
CERT_Hexify(SECItem *i, int do_colon)
|
||||||
{
|
{
|
||||||
unsigned char *cp, *end;
|
unsigned char *cp, *end;
|
||||||
char *rv, *o;
|
char *rv, *o;
|
||||||
|
|
||||||
if (!i->len) {
|
if (!i->len) {
|
||||||
return PORT_Strdup("00");
|
return PORT_Strdup("00");
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = o = (char*) PORT_Alloc(i->len * 3);
|
rv = o = (char *)PORT_Alloc(i->len * 3);
|
||||||
if (!rv) return rv;
|
if (!rv)
|
||||||
|
return rv;
|
||||||
|
|
||||||
cp = i->data;
|
cp = i->data;
|
||||||
end = cp + i->len;
|
end = cp + i->len;
|
||||||
while (cp < end) {
|
while (cp < end) {
|
||||||
unsigned char ch = *cp++;
|
unsigned char ch = *cp++;
|
||||||
*o++ = hex[(ch >> 4) & 0xf];
|
*o++ = hex[(ch >> 4) & 0xf];
|
||||||
*o++ = hex[ch & 0xf];
|
*o++ = hex[ch & 0xf];
|
||||||
if (cp != end) {
|
if (cp != end) {
|
||||||
if (do_colon) {
|
if (do_colon) {
|
||||||
*o++ = ':';
|
*o++ = ':';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*o = 0; /* Null terminate the string */
|
*o = 0; /* Null terminate the string */
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,132 +60,132 @@ char *CERT_Hexify (SECItem *i, int do_colon)
|
||||||
#define MAX_OUS 20
|
#define MAX_OUS 20
|
||||||
#define MAX_DC MAX_OUS
|
#define MAX_DC MAX_OUS
|
||||||
|
|
||||||
|
char *
|
||||||
char *CERT_FormatName (CERTName *name)
|
CERT_FormatName(CERTName *name)
|
||||||
{
|
{
|
||||||
CERTRDN** rdns;
|
CERTRDN **rdns;
|
||||||
CERTRDN * rdn;
|
CERTRDN *rdn;
|
||||||
CERTAVA** avas;
|
CERTAVA **avas;
|
||||||
CERTAVA* ava;
|
CERTAVA *ava;
|
||||||
char * buf = 0;
|
char *buf = 0;
|
||||||
char * tmpbuf = 0;
|
char *tmpbuf = 0;
|
||||||
SECItem * cn = 0;
|
SECItem *cn = 0;
|
||||||
SECItem * email = 0;
|
SECItem *email = 0;
|
||||||
SECItem * org = 0;
|
SECItem *org = 0;
|
||||||
SECItem * loc = 0;
|
SECItem *loc = 0;
|
||||||
SECItem * state = 0;
|
SECItem *state = 0;
|
||||||
SECItem * country = 0;
|
SECItem *country = 0;
|
||||||
SECItem * dq = 0;
|
SECItem *dq = 0;
|
||||||
|
|
||||||
unsigned len = 0;
|
unsigned len = 0;
|
||||||
int tag;
|
int tag;
|
||||||
int i;
|
int i;
|
||||||
int ou_count = 0;
|
int ou_count = 0;
|
||||||
int dc_count = 0;
|
int dc_count = 0;
|
||||||
PRBool first;
|
PRBool first;
|
||||||
SECItem * orgunit[MAX_OUS];
|
SECItem *orgunit[MAX_OUS];
|
||||||
SECItem * dc[MAX_DC];
|
SECItem *dc[MAX_DC];
|
||||||
|
|
||||||
/* Loop over name components and gather the interesting ones */
|
/* Loop over name components and gather the interesting ones */
|
||||||
rdns = name->rdns;
|
rdns = name->rdns;
|
||||||
while ((rdn = *rdns++) != 0) {
|
while ((rdn = *rdns++) != 0) {
|
||||||
avas = rdn->avas;
|
avas = rdn->avas;
|
||||||
while ((ava = *avas++) != 0) {
|
while ((ava = *avas++) != 0) {
|
||||||
tag = CERT_GetAVATag(ava);
|
tag = CERT_GetAVATag(ava);
|
||||||
switch(tag) {
|
switch (tag) {
|
||||||
case SEC_OID_AVA_COMMON_NAME:
|
case SEC_OID_AVA_COMMON_NAME:
|
||||||
if (cn) {
|
if (cn) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cn = CERT_DecodeAVAValue(&ava->value);
|
cn = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!cn) {
|
if (!cn) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += cn->len;
|
len += cn->len;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_COUNTRY_NAME:
|
case SEC_OID_AVA_COUNTRY_NAME:
|
||||||
if (country) {
|
if (country) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
country = CERT_DecodeAVAValue(&ava->value);
|
country = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!country) {
|
if (!country) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += country->len;
|
len += country->len;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_LOCALITY:
|
case SEC_OID_AVA_LOCALITY:
|
||||||
if (loc) {
|
if (loc) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
loc = CERT_DecodeAVAValue(&ava->value);
|
loc = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!loc) {
|
if (!loc) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += loc->len;
|
len += loc->len;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_STATE_OR_PROVINCE:
|
case SEC_OID_AVA_STATE_OR_PROVINCE:
|
||||||
if (state) {
|
if (state) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state = CERT_DecodeAVAValue(&ava->value);
|
state = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!state) {
|
if (!state) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += state->len;
|
len += state->len;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_ORGANIZATION_NAME:
|
case SEC_OID_AVA_ORGANIZATION_NAME:
|
||||||
if (org) {
|
if (org) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
org = CERT_DecodeAVAValue(&ava->value);
|
org = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!org) {
|
if (!org) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += org->len;
|
len += org->len;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_DN_QUALIFIER:
|
case SEC_OID_AVA_DN_QUALIFIER:
|
||||||
if (dq) {
|
if (dq) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dq = CERT_DecodeAVAValue(&ava->value);
|
dq = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!dq) {
|
if (!dq) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += dq->len;
|
len += dq->len;
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
|
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
|
||||||
if (ou_count < MAX_OUS) {
|
if (ou_count < MAX_OUS) {
|
||||||
orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
|
orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!orgunit[ou_count]) {
|
if (!orgunit[ou_count]) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += orgunit[ou_count++]->len;
|
len += orgunit[ou_count++]->len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SEC_OID_AVA_DC:
|
case SEC_OID_AVA_DC:
|
||||||
if (dc_count < MAX_DC) {
|
if (dc_count < MAX_DC) {
|
||||||
dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
|
dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!dc[dc_count]) {
|
if (!dc[dc_count]) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += dc[dc_count++]->len;
|
len += dc[dc_count++]->len;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SEC_OID_PKCS9_EMAIL_ADDRESS:
|
case SEC_OID_PKCS9_EMAIL_ADDRESS:
|
||||||
case SEC_OID_RFC1274_MAIL:
|
case SEC_OID_RFC1274_MAIL:
|
||||||
if (email) {
|
if (email) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
email = CERT_DecodeAVAValue(&ava->value);
|
email = CERT_DecodeAVAValue(&ava->value);
|
||||||
if (!email) {
|
if (!email) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
len += email->len;
|
len += email->len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX - add some for formatting */
|
/* XXX - add some for formatting */
|
||||||
|
@ -191,109 +193,108 @@ char *CERT_FormatName (CERTName *name)
|
||||||
|
|
||||||
/* allocate buffer */
|
/* allocate buffer */
|
||||||
buf = (char *)PORT_Alloc(len);
|
buf = (char *)PORT_Alloc(len);
|
||||||
if ( !buf ) {
|
if (!buf) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpbuf = buf;
|
tmpbuf = buf;
|
||||||
|
|
||||||
if ( cn ) {
|
if (cn) {
|
||||||
PORT_Memcpy(tmpbuf, cn->data, cn->len);
|
PORT_Memcpy(tmpbuf, cn->data, cn->len);
|
||||||
tmpbuf += cn->len;
|
tmpbuf += cn->len;
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
if ( email ) {
|
if (email) {
|
||||||
PORT_Memcpy(tmpbuf, email->data, email->len);
|
PORT_Memcpy(tmpbuf, email->data, email->len);
|
||||||
tmpbuf += ( email->len );
|
tmpbuf += (email->len);
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
for (i=ou_count-1; i >= 0; i--) {
|
for (i = ou_count - 1; i >= 0; i--) {
|
||||||
PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
|
PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
|
||||||
tmpbuf += ( orgunit[i]->len );
|
tmpbuf += (orgunit[i]->len);
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
if ( dq ) {
|
if (dq) {
|
||||||
PORT_Memcpy(tmpbuf, dq->data, dq->len);
|
PORT_Memcpy(tmpbuf, dq->data, dq->len);
|
||||||
tmpbuf += ( dq->len );
|
tmpbuf += (dq->len);
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
if ( org ) {
|
if (org) {
|
||||||
PORT_Memcpy(tmpbuf, org->data, org->len);
|
PORT_Memcpy(tmpbuf, org->data, org->len);
|
||||||
tmpbuf += ( org->len );
|
tmpbuf += (org->len);
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
for (i=dc_count-1; i >= 0; i--) {
|
for (i = dc_count - 1; i >= 0; i--) {
|
||||||
PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
|
PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
|
||||||
tmpbuf += ( dc[i]->len );
|
tmpbuf += (dc[i]->len);
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
first = PR_TRUE;
|
first = PR_TRUE;
|
||||||
if ( loc ) {
|
if (loc) {
|
||||||
PORT_Memcpy(tmpbuf, loc->data, loc->len);
|
PORT_Memcpy(tmpbuf, loc->data, loc->len);
|
||||||
tmpbuf += ( loc->len );
|
tmpbuf += (loc->len);
|
||||||
first = PR_FALSE;
|
first = PR_FALSE;
|
||||||
}
|
}
|
||||||
if ( state ) {
|
if (state) {
|
||||||
if ( !first ) {
|
if (!first) {
|
||||||
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
||||||
tmpbuf += COMMALEN;
|
tmpbuf += COMMALEN;
|
||||||
}
|
}
|
||||||
PORT_Memcpy(tmpbuf, state->data, state->len);
|
PORT_Memcpy(tmpbuf, state->data, state->len);
|
||||||
tmpbuf += ( state->len );
|
tmpbuf += (state->len);
|
||||||
first = PR_FALSE;
|
first = PR_FALSE;
|
||||||
}
|
}
|
||||||
if ( country ) {
|
if (country) {
|
||||||
if ( !first ) {
|
if (!first) {
|
||||||
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
||||||
tmpbuf += COMMALEN;
|
tmpbuf += COMMALEN;
|
||||||
}
|
}
|
||||||
PORT_Memcpy(tmpbuf, country->data, country->len);
|
PORT_Memcpy(tmpbuf, country->data, country->len);
|
||||||
tmpbuf += ( country->len );
|
tmpbuf += (country->len);
|
||||||
first = PR_FALSE;
|
first = PR_FALSE;
|
||||||
}
|
}
|
||||||
if ( !first ) {
|
if (!first) {
|
||||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||||
tmpbuf += BREAKLEN;
|
tmpbuf += BREAKLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
*tmpbuf = 0;
|
*tmpbuf = 0;
|
||||||
|
|
||||||
/* fall through and clean */
|
/* fall through and clean */
|
||||||
loser:
|
loser:
|
||||||
if ( cn ) {
|
if (cn) {
|
||||||
SECITEM_FreeItem(cn, PR_TRUE);
|
SECITEM_FreeItem(cn, PR_TRUE);
|
||||||
}
|
}
|
||||||
if ( email ) {
|
if (email) {
|
||||||
SECITEM_FreeItem(email, PR_TRUE);
|
SECITEM_FreeItem(email, PR_TRUE);
|
||||||
}
|
}
|
||||||
for (i=ou_count-1; i >= 0; i--) {
|
for (i = ou_count - 1; i >= 0; i--) {
|
||||||
SECITEM_FreeItem(orgunit[i], PR_TRUE);
|
SECITEM_FreeItem(orgunit[i], PR_TRUE);
|
||||||
}
|
}
|
||||||
if ( dq ) {
|
if (dq) {
|
||||||
SECITEM_FreeItem(dq, PR_TRUE);
|
SECITEM_FreeItem(dq, PR_TRUE);
|
||||||
}
|
}
|
||||||
if ( org ) {
|
if (org) {
|
||||||
SECITEM_FreeItem(org, PR_TRUE);
|
SECITEM_FreeItem(org, PR_TRUE);
|
||||||
}
|
}
|
||||||
for (i=dc_count-1; i >= 0; i--) {
|
for (i = dc_count - 1; i >= 0; i--) {
|
||||||
SECITEM_FreeItem(dc[i], PR_TRUE);
|
SECITEM_FreeItem(dc[i], PR_TRUE);
|
||||||
}
|
}
|
||||||
if ( loc ) {
|
if (loc) {
|
||||||
SECITEM_FreeItem(loc, PR_TRUE);
|
SECITEM_FreeItem(loc, PR_TRUE);
|
||||||
}
|
}
|
||||||
if ( state ) {
|
if (state) {
|
||||||
SECITEM_FreeItem(state, PR_TRUE);
|
SECITEM_FreeItem(state, PR_TRUE);
|
||||||
}
|
}
|
||||||
if ( country ) {
|
if (country) {
|
||||||
SECITEM_FreeItem(country, PR_TRUE);
|
SECITEM_FreeItem(country, PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@ SEC_ASN1_MKSUB(SEC_AnyTemplate)
|
||||||
|
|
||||||
const SEC_ASN1Template CERT_AttributeTemplate[] = {
|
const SEC_ASN1Template CERT_AttributeTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(CERTAttribute) },
|
0, NULL, sizeof(CERTAttribute) },
|
||||||
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
|
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
|
||||||
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
|
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
|
||||||
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,18 +27,18 @@ const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
|
||||||
|
|
||||||
const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
|
const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(CERTCertificateRequest) },
|
0, NULL, sizeof(CERTCertificateRequest) },
|
||||||
{ SEC_ASN1_INTEGER,
|
{ SEC_ASN1_INTEGER,
|
||||||
offsetof(CERTCertificateRequest,version) },
|
offsetof(CERTCertificateRequest, version) },
|
||||||
{ SEC_ASN1_INLINE,
|
{ SEC_ASN1_INLINE,
|
||||||
offsetof(CERTCertificateRequest,subject),
|
offsetof(CERTCertificateRequest, subject),
|
||||||
CERT_NameTemplate },
|
CERT_NameTemplate },
|
||||||
{ SEC_ASN1_INLINE,
|
{ SEC_ASN1_INLINE,
|
||||||
offsetof(CERTCertificateRequest,subjectPublicKeyInfo),
|
offsetof(CERTCertificateRequest, subjectPublicKeyInfo),
|
||||||
CERT_SubjectPublicKeyInfoTemplate },
|
CERT_SubjectPublicKeyInfoTemplate },
|
||||||
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||||
offsetof(CERTCertificateRequest,attributes),
|
offsetof(CERTCertificateRequest, attributes),
|
||||||
CERT_SetOfAttributeTemplate },
|
CERT_SetOfAttributeTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,25 +46,25 @@ SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)
|
||||||
|
|
||||||
CERTCertificate *
|
CERTCertificate *
|
||||||
CERT_CreateCertificate(unsigned long serialNumber,
|
CERT_CreateCertificate(unsigned long serialNumber,
|
||||||
CERTName *issuer,
|
CERTName *issuer,
|
||||||
CERTValidity *validity,
|
CERTValidity *validity,
|
||||||
CERTCertificateRequest *req)
|
CERTCertificateRequest *req)
|
||||||
{
|
{
|
||||||
CERTCertificate *c;
|
CERTCertificate *c;
|
||||||
int rv;
|
int rv;
|
||||||
PLArenaPool *arena;
|
PLArenaPool *arena;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
|
|
||||||
if ( !arena ) {
|
if (!arena) {
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
|
c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
|
||||||
|
|
||||||
if (!c) {
|
if (!c) {
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->referenceCount = 1;
|
c->referenceCount = 1;
|
||||||
|
@ -75,44 +75,50 @@ CERT_CreateCertificate(unsigned long serialNumber,
|
||||||
* If extensions are added, it will get changed as appropriate.
|
* If extensions are added, it will get changed as appropriate.
|
||||||
*/
|
*/
|
||||||
rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
|
rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
|
goto loser;
|
||||||
|
|
||||||
rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
|
rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
|
goto loser;
|
||||||
|
|
||||||
rv = CERT_CopyName(arena, &c->issuer, issuer);
|
rv = CERT_CopyName(arena, &c->issuer, issuer);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
|
goto loser;
|
||||||
|
|
||||||
rv = CERT_CopyValidity(arena, &c->validity, validity);
|
rv = CERT_CopyValidity(arena, &c->validity, validity);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
|
goto loser;
|
||||||
|
|
||||||
rv = CERT_CopyName(arena, &c->subject, &req->subject);
|
rv = CERT_CopyName(arena, &c->subject, &req->subject);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
|
goto loser;
|
||||||
rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
|
rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
|
||||||
&req->subjectPublicKeyInfo);
|
&req->subjectPublicKeyInfo);
|
||||||
if (rv) goto loser;
|
if (rv)
|
||||||
|
goto loser;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
CERT_DestroyCertificate(c);
|
CERT_DestroyCertificate(c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* It's clear from the comments that the original author of this
|
/* It's clear from the comments that the original author of this
|
||||||
* function expected the template for certificate requests to treat
|
* function expected the template for certificate requests to treat
|
||||||
* the attributes as a SET OF ANY. This function expected to be
|
* the attributes as a SET OF ANY. This function expected to be
|
||||||
* passed an array of SECItems each of which contained an already encoded
|
* passed an array of SECItems each of which contained an already encoded
|
||||||
* Attribute. But the cert request template does not treat the
|
* Attribute. But the cert request template does not treat the
|
||||||
* Attributes as a SET OF ANY, and AFAIK never has. Instead the template
|
* Attributes as a SET OF ANY, and AFAIK never has. Instead the template
|
||||||
* encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
|
* encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
|
||||||
* each of the Attributes, not have them pre-encoded. Consequently an
|
* each of the Attributes, not have them pre-encoded. Consequently an
|
||||||
* array of SECItems containing encoded Attributes is of no value to this
|
* array of SECItems containing encoded Attributes is of no value to this
|
||||||
* function. But we cannot change the signature of this public function.
|
* function. But we cannot change the signature of this public function.
|
||||||
* It must continue to take SECItems.
|
* It must continue to take SECItems.
|
||||||
*
|
*
|
||||||
* I have recoded this function so that each SECItem contains an
|
* I have recoded this function so that each SECItem contains an
|
||||||
* encoded cert extension. The encoded cert extensions form the list for the
|
* encoded cert extension. The encoded cert extensions form the list for the
|
||||||
* single attribute of the cert request. In this implementation there is at most
|
* single attribute of the cert request. In this implementation there is at most
|
||||||
* one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
|
* one attribute and it is always of type SEC_OID_PKCS9_EXTENSION_REQUEST.
|
||||||
|
@ -120,95 +126,95 @@ CERT_CreateCertificate(unsigned long serialNumber,
|
||||||
|
|
||||||
CERTCertificateRequest *
|
CERTCertificateRequest *
|
||||||
CERT_CreateCertificateRequest(CERTName *subject,
|
CERT_CreateCertificateRequest(CERTName *subject,
|
||||||
CERTSubjectPublicKeyInfo *spki,
|
CERTSubjectPublicKeyInfo *spki,
|
||||||
SECItem **attributes)
|
SECItem **attributes)
|
||||||
{
|
{
|
||||||
CERTCertificateRequest *certreq;
|
CERTCertificateRequest *certreq;
|
||||||
PLArenaPool *arena;
|
PLArenaPool *arena;
|
||||||
CERTAttribute * attribute;
|
CERTAttribute *attribute;
|
||||||
SECOidData * oidData;
|
SECOidData *oidData;
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
if ( arena == NULL ) {
|
if (arena == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
|
certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
|
||||||
if (!certreq) {
|
if (!certreq) {
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* below here it is safe to goto loser */
|
/* below here it is safe to goto loser */
|
||||||
|
|
||||||
certreq->arena = arena;
|
certreq->arena = arena;
|
||||||
|
|
||||||
rv = DER_SetUInteger(arena, &certreq->version,
|
rv = DER_SetUInteger(arena, &certreq->version,
|
||||||
SEC_CERTIFICATE_REQUEST_VERSION);
|
SEC_CERTIFICATE_REQUEST_VERSION);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
rv = CERT_CopyName(arena, &certreq->subject, subject);
|
rv = CERT_CopyName(arena, &certreq->subject, subject);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
rv = SECKEY_CopySubjectPublicKeyInfo(arena,
|
rv = SECKEY_CopySubjectPublicKeyInfo(arena,
|
||||||
&certreq->subjectPublicKeyInfo,
|
&certreq->subjectPublicKeyInfo,
|
||||||
spki);
|
spki);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2);
|
certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute *, 2);
|
||||||
if(!certreq->attributes)
|
if (!certreq->attributes)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
/* Copy over attribute information */
|
/* Copy over attribute information */
|
||||||
if (!attributes || !attributes[0]) {
|
if (!attributes || !attributes[0]) {
|
||||||
/*
|
/*
|
||||||
** Invent empty attribute information. According to the
|
** Invent empty attribute information. According to the
|
||||||
** pkcs#10 spec, attributes has this ASN.1 type:
|
** pkcs#10 spec, attributes has this ASN.1 type:
|
||||||
**
|
**
|
||||||
** attributes [0] IMPLICIT Attributes
|
** attributes [0] IMPLICIT Attributes
|
||||||
**
|
**
|
||||||
** Which means, we should create a NULL terminated list
|
** Which means, we should create a NULL terminated list
|
||||||
** with the first entry being NULL;
|
** with the first entry being NULL;
|
||||||
*/
|
*/
|
||||||
certreq->attributes[0] = NULL;
|
certreq->attributes[0] = NULL;
|
||||||
return certreq;
|
return certreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate space for attributes */
|
/* allocate space for attributes */
|
||||||
attribute = PORT_ArenaZNew(arena, CERTAttribute);
|
attribute = PORT_ArenaZNew(arena, CERTAttribute);
|
||||||
if (!attribute)
|
if (!attribute)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST );
|
oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
|
||||||
PORT_Assert(oidData);
|
PORT_Assert(oidData);
|
||||||
if (!oidData)
|
if (!oidData)
|
||||||
goto loser;
|
goto loser;
|
||||||
rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
|
rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
for (i = 0; attributes[i] != NULL ; i++)
|
for (i = 0; attributes[i] != NULL; i++)
|
||||||
;
|
;
|
||||||
attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1);
|
attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i + 1);
|
||||||
if (!attribute->attrValue)
|
if (!attribute->attrValue)
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
/* copy attributes */
|
/* copy attributes */
|
||||||
for (i = 0; attributes[i]; i++) {
|
for (i = 0; attributes[i]; i++) {
|
||||||
/*
|
/*
|
||||||
** Attributes are a SetOf Attribute which implies
|
** Attributes are a SetOf Attribute which implies
|
||||||
** lexigraphical ordering. It is assumes that the
|
** lexigraphical ordering. It is assumes that the
|
||||||
** attributes are passed in sorted. If we need to
|
** attributes are passed in sorted. If we need to
|
||||||
** add functionality to sort them, there is an
|
** add functionality to sort them, there is an
|
||||||
** example in the PKCS 7 code.
|
** example in the PKCS 7 code.
|
||||||
*/
|
*/
|
||||||
attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
|
attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
|
||||||
if(!attribute->attrValue[i])
|
if (!attribute->attrValue[i])
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
certreq->attributes[0] = attribute;
|
certreq->attributes[0] = attribute;
|
||||||
|
@ -224,7 +230,7 @@ void
|
||||||
CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
|
CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
|
||||||
{
|
{
|
||||||
if (req && req->arena) {
|
if (req && req->arena) {
|
||||||
PORT_FreeArena(req->arena, PR_FALSE);
|
PORT_FreeArena(req->arena, PR_FALSE);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -241,11 +247,11 @@ setCRExt(void *o, CERTCertExtension **exts)
|
||||||
** attribute list by CERT_FinishCRAttributes().
|
** attribute list by CERT_FinishCRAttributes().
|
||||||
*/
|
*/
|
||||||
extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
||||||
void (*setExts)(void *object, CERTCertExtension **exts));
|
void (*setExts)(void *object, CERTCertExtension **exts));
|
||||||
void *
|
void *
|
||||||
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
|
CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||||
{
|
{
|
||||||
return (cert_StartExtensions ((void *)req, req->arena, setCRExt));
|
return (cert_StartExtensions((void *)req, req->arena, setCRExt));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -257,38 +263,39 @@ CERT_StartCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||||
*/
|
*/
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
|
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||||
{ SECItem *extlist;
|
{
|
||||||
|
SECItem *extlist;
|
||||||
SECOidData *oidrec;
|
SECOidData *oidrec;
|
||||||
CERTAttribute *attribute;
|
CERTAttribute *attribute;
|
||||||
|
|
||||||
if (!req || !req->arena) {
|
if (!req || !req->arena) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
if (req->attributes == NULL || req->attributes[0] == NULL)
|
if (req->attributes == NULL || req->attributes[0] == NULL)
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
|
|
||||||
extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
|
extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
|
||||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
|
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
|
||||||
if (extlist == NULL)
|
if (extlist == NULL)
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
|
|
||||||
oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
|
oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
|
||||||
if (oidrec == NULL)
|
if (oidrec == NULL)
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
|
|
||||||
/* now change the list of cert extensions into a list of attributes
|
/* now change the list of cert extensions into a list of attributes
|
||||||
*/
|
*/
|
||||||
req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute*, 2);
|
req->attributes = PORT_ArenaZNewArray(req->arena, CERTAttribute *, 2);
|
||||||
|
|
||||||
attribute = PORT_ArenaZNew(req->arena, CERTAttribute);
|
attribute = PORT_ArenaZNew(req->arena, CERTAttribute);
|
||||||
|
|
||||||
if (req->attributes == NULL || attribute == NULL ||
|
if (req->attributes == NULL || attribute == NULL ||
|
||||||
SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
|
SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
|
||||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem*, 2);
|
attribute->attrValue = PORT_ArenaZNewArray(req->arena, SECItem *, 2);
|
||||||
|
|
||||||
if (attribute->attrValue == NULL)
|
if (attribute->attrValue == NULL)
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
|
@ -303,22 +310,22 @@ CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
|
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
|
||||||
CERTCertExtension ***exts)
|
CERTCertExtension ***exts)
|
||||||
{
|
{
|
||||||
if (req == NULL || exts == NULL) {
|
if (req == NULL || exts == NULL) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->attributes == NULL || *req->attributes == NULL)
|
|
||||||
return SECSuccess;
|
|
||||||
|
|
||||||
if ((*req->attributes)->attrValue == NULL) {
|
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(SEC_ASN1DecodeItem(req->arena, exts,
|
if (req->attributes == NULL || *req->attributes == NULL)
|
||||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
|
return SECSuccess;
|
||||||
(*req->attributes)->attrValue[0]));
|
|
||||||
|
if ((*req->attributes)->attrValue == NULL) {
|
||||||
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
return SECFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (SEC_ASN1DecodeItem(req->arena, exts,
|
||||||
|
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
|
||||||
|
(*req->attributes)->attrValue[0]));
|
||||||
}
|
}
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -17,17 +17,15 @@
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value)
|
CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value)
|
||||||
{
|
{
|
||||||
return (cert_FindExtensionByOID (crl->extensions, oid, value));
|
return (cert_FindExtensionByOID(crl->extensions, oid, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value)
|
CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value)
|
||||||
{
|
{
|
||||||
return (cert_FindExtension (crl->extensions, tag, value));
|
return (cert_FindExtension(crl->extensions, tag, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Callback to set extensions and adjust verison */
|
/* Callback to set extensions and adjust verison */
|
||||||
static void
|
static void
|
||||||
SetCrlExts(void *object, CERTCertExtension **exts)
|
SetCrlExts(void *object, CERTCertExtension **exts)
|
||||||
|
@ -35,13 +33,13 @@ SetCrlExts(void *object, CERTCertExtension **exts)
|
||||||
CERTCrl *crl = (CERTCrl *)object;
|
CERTCrl *crl = (CERTCrl *)object;
|
||||||
|
|
||||||
crl->extensions = exts;
|
crl->extensions = exts;
|
||||||
DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2);
|
DER_SetUInteger(crl->arena, &crl->version, SEC_CRL_VERSION_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
CERT_StartCRLExtensions(CERTCrl *crl)
|
CERT_StartCRLExtensions(CERTCrl *crl)
|
||||||
{
|
{
|
||||||
return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts));
|
return (cert_StartExtensions((void *)crl, crl->arena, SetCrlExts));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -55,11 +53,12 @@ SetCrlEntryExts(void *object, CERTCertExtension **exts)
|
||||||
void *
|
void *
|
||||||
CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry)
|
CERT_StartCRLEntryExtensions(CERTCrl *crl, CERTCrlEntry *entry)
|
||||||
{
|
{
|
||||||
return (cert_StartExtensions (entry, crl->arena, SetCrlEntryExts));
|
return (cert_StartExtensions(entry, crl->arena, SetCrlEntryExts));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
|
SECStatus
|
||||||
SECItem *value)
|
CERT_FindCRLNumberExten(PLArenaPool *arena, CERTCrl *crl,
|
||||||
|
SECItem *value)
|
||||||
{
|
{
|
||||||
SECItem encodedExtenValue;
|
SECItem encodedExtenValue;
|
||||||
SECItem *tmpItem = NULL;
|
SECItem *tmpItem = NULL;
|
||||||
|
@ -70,91 +69,94 @@ SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
|
||||||
encodedExtenValue.len = 0;
|
encodedExtenValue.len = 0;
|
||||||
|
|
||||||
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER,
|
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER,
|
||||||
&encodedExtenValue);
|
&encodedExtenValue);
|
||||||
if ( rv != SECSuccess )
|
if (rv != SECSuccess)
|
||||||
return (rv);
|
return (rv);
|
||||||
|
|
||||||
mark = PORT_ArenaMark(arena);
|
mark = PORT_ArenaMark(arena);
|
||||||
|
|
||||||
tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue);
|
tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue);
|
||||||
if (tmpItem) {
|
if (tmpItem) {
|
||||||
rv = SEC_QuickDERDecodeItem (arena, value,
|
rv = SEC_QuickDERDecodeItem(arena, value,
|
||||||
SEC_ASN1_GET(SEC_IntegerTemplate),
|
SEC_ASN1_GET(SEC_IntegerTemplate),
|
||||||
tmpItem);
|
tmpItem);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT_Free (encodedExtenValue.data);
|
PORT_Free(encodedExtenValue.data);
|
||||||
if (rv == SECFailure) {
|
if (rv == SECFailure) {
|
||||||
PORT_ArenaRelease(arena, mark);
|
PORT_ArenaRelease(arena, mark);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
PORT_ArenaUnmark(arena, mark);
|
PORT_ArenaUnmark(arena, mark);
|
||||||
}
|
}
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry,
|
SECStatus
|
||||||
CERTCRLEntryReasonCode *value)
|
CERT_FindCRLEntryReasonExten(CERTCrlEntry *crlEntry,
|
||||||
|
CERTCRLEntryReasonCode *value)
|
||||||
{
|
{
|
||||||
SECItem wrapperItem = {siBuffer,0};
|
SECItem wrapperItem = { siBuffer, 0 };
|
||||||
SECItem tmpItem = {siBuffer,0};
|
SECItem tmpItem = { siBuffer, 0 };
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
PLArenaPool *arena = NULL;
|
PLArenaPool *arena = NULL;
|
||||||
|
|
||||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
if ( ! arena ) {
|
if (!arena) {
|
||||||
return(SECFailure);
|
return (SECFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
|
rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
|
||||||
&wrapperItem);
|
&wrapperItem);
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
||||||
SEC_ASN1_GET(SEC_EnumeratedTemplate),
|
SEC_ASN1_GET(SEC_EnumeratedTemplate),
|
||||||
&wrapperItem);
|
&wrapperItem);
|
||||||
|
|
||||||
if ( rv != SECSuccess ) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
*value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem);
|
*value = (CERTCRLEntryReasonCode)DER_GetInteger(&tmpItem);
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
if ( arena ) {
|
if (arena) {
|
||||||
PORT_FreeArena(arena, PR_FALSE);
|
PORT_FreeArena(arena, PR_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( wrapperItem.data ) {
|
if (wrapperItem.data) {
|
||||||
PORT_Free(wrapperItem.data);
|
PORT_Free(wrapperItem.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value)
|
SECStatus
|
||||||
|
CERT_FindInvalidDateExten(CERTCrl *crl, PRTime *value)
|
||||||
{
|
{
|
||||||
SECItem encodedExtenValue;
|
SECItem encodedExtenValue;
|
||||||
SECItem decodedExtenValue = {siBuffer,0};
|
SECItem decodedExtenValue = { siBuffer, 0 };
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
|
|
||||||
encodedExtenValue.data = decodedExtenValue.data = NULL;
|
encodedExtenValue.data = decodedExtenValue.data = NULL;
|
||||||
encodedExtenValue.len = decodedExtenValue.len = 0;
|
encodedExtenValue.len = decodedExtenValue.len = 0;
|
||||||
|
|
||||||
rv = cert_FindExtension
|
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue);
|
||||||
(crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue);
|
if (rv != SECSuccess)
|
||||||
if ( rv != SECSuccess )
|
return (rv);
|
||||||
return (rv);
|
|
||||||
|
|
||||||
rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue,
|
rv = SEC_ASN1DecodeItem(NULL, &decodedExtenValue,
|
||||||
SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
|
SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
|
||||||
&encodedExtenValue);
|
&encodedExtenValue);
|
||||||
if (rv == SECSuccess)
|
if (rv == SECSuccess)
|
||||||
rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
|
rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
|
||||||
PORT_Free (decodedExtenValue.data);
|
PORT_Free(decodedExtenValue.data);
|
||||||
PORT_Free (encodedExtenValue.data);
|
PORT_Free(encodedExtenValue.data);
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -9,7 +9,6 @@
|
||||||
#ifndef _OCSP_H_
|
#ifndef _OCSP_H_
|
||||||
#define _OCSP_H_
|
#define _OCSP_H_
|
||||||
|
|
||||||
|
|
||||||
#include "plarena.h"
|
#include "plarena.h"
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
#include "secoidt.h"
|
#include "secoidt.h"
|
||||||
|
@ -17,7 +16,6 @@
|
||||||
#include "certt.h"
|
#include "certt.h"
|
||||||
#include "ocspt.h"
|
#include "ocspt.h"
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
SEC_BEGIN_PROTOS
|
SEC_BEGIN_PROTOS
|
||||||
|
|
||||||
|
@ -134,7 +132,7 @@ CERT_DisableOCSPChecking(CERTCertDBHandle *handle);
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
|
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
|
||||||
const char *url, const char *name);
|
const char *url, const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_EnableOCSPDefaultResponder
|
* FUNCTION: CERT_EnableOCSPDefaultResponder
|
||||||
|
@ -174,7 +172,7 @@ CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle);
|
||||||
/* If forcePost is set, OCSP requests will only be sent using the HTTP POST
|
/* If forcePost is set, OCSP requests will only be sent using the HTTP POST
|
||||||
* method. When forcePost is not set, OCSP requests will be sent using the
|
* method. When forcePost is not set, OCSP requests will be sent using the
|
||||||
* HTTP GET method, with a fallback to POST when we fail to receive a response
|
* HTTP GET method, with a fallback to POST when we fail to receive a response
|
||||||
* and/or when we receive an uncacheable response like "Unknown."
|
* and/or when we receive an uncacheable response like "Unknown."
|
||||||
*
|
*
|
||||||
* The default is to use GET and fallback to POST.
|
* The default is to use GET and fallback to POST.
|
||||||
*/
|
*/
|
||||||
|
@ -191,7 +189,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_CreateOCSPRequest
|
* FUNCTION: CERT_CreateOCSPRequest
|
||||||
* Creates a CERTOCSPRequest, requesting the status of the certs in
|
* Creates a CERTOCSPRequest, requesting the status of the certs in
|
||||||
* the given list.
|
* the given list.
|
||||||
* INPUTS:
|
* INPUTS:
|
||||||
* CERTCertList *certList
|
* CERTCertList *certList
|
||||||
|
@ -203,7 +201,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
|
||||||
* to this routine), who knows about where the request(s) are being
|
* to this routine), who knows about where the request(s) are being
|
||||||
* sent and whether there are any trusted responders in place.
|
* sent and whether there are any trusted responders in place.
|
||||||
* PRTime time
|
* PRTime time
|
||||||
* Indicates the time for which the certificate status is to be
|
* Indicates the time for which the certificate status is to be
|
||||||
* determined -- this may be used in the search for the cert's issuer
|
* determined -- this may be used in the search for the cert's issuer
|
||||||
* but has no effect on the request itself.
|
* but has no effect on the request itself.
|
||||||
* PRBool addServiceLocator
|
* PRBool addServiceLocator
|
||||||
|
@ -221,9 +219,9 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
|
||||||
* Other errors are low-level problems (no memory, bad database, etc.).
|
* Other errors are low-level problems (no memory, bad database, etc.).
|
||||||
*/
|
*/
|
||||||
extern CERTOCSPRequest *
|
extern CERTOCSPRequest *
|
||||||
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
|
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
|
||||||
PRBool addServiceLocator,
|
PRBool addServiceLocator,
|
||||||
CERTCertificate *signerCert);
|
CERTCertificate *signerCert);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_AddOCSPAcceptableResponses
|
* FUNCTION: CERT_AddOCSPAcceptableResponses
|
||||||
|
@ -243,13 +241,13 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
|
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
|
||||||
SECOidTag responseType0, ...);
|
SECOidTag responseType0, ...);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_EncodeOCSPRequest
|
* FUNCTION: CERT_EncodeOCSPRequest
|
||||||
* DER encodes an OCSP Request, possibly adding a signature as well.
|
* DER encodes an OCSP Request, possibly adding a signature as well.
|
||||||
* XXX Signing is not yet supported, however; see comments in code.
|
* XXX Signing is not yet supported, however; see comments in code.
|
||||||
* INPUTS:
|
* INPUTS:
|
||||||
* PLArenaPool *arena
|
* PLArenaPool *arena
|
||||||
* The return value is allocated from here.
|
* The return value is allocated from here.
|
||||||
* If a NULL is passed in, allocation is done from the heap instead.
|
* If a NULL is passed in, allocation is done from the heap instead.
|
||||||
|
@ -264,8 +262,8 @@ CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
|
||||||
* (e.g. no memory).
|
* (e.g. no memory).
|
||||||
*/
|
*/
|
||||||
extern SECItem *
|
extern SECItem *
|
||||||
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
|
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
|
||||||
void *pwArg);
|
void *pwArg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_DecodeOCSPRequest
|
* FUNCTION: CERT_DecodeOCSPRequest
|
||||||
|
@ -341,7 +339,7 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
|
||||||
* const char *location
|
* const char *location
|
||||||
* The location of the OCSP responder (a URL).
|
* The location of the OCSP responder (a URL).
|
||||||
* PRTime time
|
* PRTime time
|
||||||
* Indicates the time for which the certificate status is to be
|
* Indicates the time for which the certificate status is to be
|
||||||
* determined -- this may be used in the search for the cert's issuer
|
* determined -- this may be used in the search for the cert's issuer
|
||||||
* but has no other bearing on the operation.
|
* but has no other bearing on the operation.
|
||||||
* PRBool addServiceLocator
|
* PRBool addServiceLocator
|
||||||
|
@ -369,10 +367,10 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
|
||||||
*/
|
*/
|
||||||
extern SECItem *
|
extern SECItem *
|
||||||
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
|
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
|
||||||
const char *location, PRTime time,
|
const char *location, PRTime time,
|
||||||
PRBool addServiceLocator,
|
PRBool addServiceLocator,
|
||||||
CERTCertificate *signerCert, void *pwArg,
|
CERTCertificate *signerCert, void *pwArg,
|
||||||
CERTOCSPRequest **pRequest);
|
CERTOCSPRequest **pRequest);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_VerifyOCSPResponseSignature
|
* FUNCTION: CERT_VerifyOCSPResponseSignature
|
||||||
|
@ -406,10 +404,10 @@ CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
|
||||||
* verifying the signer's cert, or low-level problems (no memory, etc.)
|
* verifying the signer's cert, or low-level problems (no memory, etc.)
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
|
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
|
||||||
CERTCertDBHandle *handle, void *pwArg,
|
CERTCertDBHandle *handle, void *pwArg,
|
||||||
CERTCertificate **pSignerCert,
|
CERTCertificate **pSignerCert,
|
||||||
CERTCertificate *issuerCert);
|
CERTCertificate *issuerCert);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
|
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
|
||||||
|
@ -425,7 +423,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
|
||||||
* extension is not present or it does not contain an entry for OCSP,
|
* extension is not present or it does not contain an entry for OCSP,
|
||||||
* SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned.
|
* SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned.
|
||||||
* Any other error will also result in a NULL being returned.
|
* Any other error will also result in a NULL being returned.
|
||||||
*
|
*
|
||||||
* This result should be freed (via PORT_Free) when no longer in use.
|
* This result should be freed (via PORT_Free) when no longer in use.
|
||||||
*/
|
*/
|
||||||
extern char *
|
extern char *
|
||||||
|
@ -433,21 +431,21 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack
|
* FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack
|
||||||
* This function serves two purposes.
|
* This function serves two purposes.
|
||||||
* 1) It registers the address of a callback function that will be
|
* 1) It registers the address of a callback function that will be
|
||||||
* called for certs that have no OCSP AIA extension, to see if the
|
* called for certs that have no OCSP AIA extension, to see if the
|
||||||
* callback wishes to supply an alternative URL for such an OCSP inquiry.
|
* callback wishes to supply an alternative URL for such an OCSP inquiry.
|
||||||
* 2) It outputs the previously registered function's address to the
|
* 2) It outputs the previously registered function's address to the
|
||||||
* address supplied by the caller, unless that is NULL.
|
* address supplied by the caller, unless that is NULL.
|
||||||
* The registered callback function returns NULL, or an allocated string
|
* The registered callback function returns NULL, or an allocated string
|
||||||
* that may be subsequently freed by calling PORT_Free().
|
* that may be subsequently freed by calling PORT_Free().
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* SECSuccess or SECFailure (if the library is not yet intialized)
|
* SECSuccess or SECFailure (if the library is not yet intialized)
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_RegisterAlternateOCSPAIAInfoCallBack(
|
CERT_RegisterAlternateOCSPAIAInfoCallBack(
|
||||||
CERT_StringFromCertFcn newCallback,
|
CERT_StringFromCertFcn newCallback,
|
||||||
CERT_StringFromCertFcn * oldCallback);
|
CERT_StringFromCertFcn *oldCallback);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_ParseURL
|
* FUNCTION: CERT_ParseURL
|
||||||
|
@ -521,10 +519,10 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath);
|
||||||
* (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
|
* (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when
|
||||||
* verifying the signer's cert, or low-level problems (error allocating
|
* verifying the signer's cert, or low-level problems (error allocating
|
||||||
* memory, error performing ASN.1 decoding, etc.).
|
* memory, error performing ASN.1 decoding, etc.).
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||||
PRTime time, void *pwArg);
|
PRTime time, void *pwArg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_CacheOCSPResponseFromSideChannel
|
* FUNCTION: CERT_CacheOCSPResponseFromSideChannel
|
||||||
|
@ -556,10 +554,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
||||||
CERTCertificate *cert,
|
CERTCertificate *cert,
|
||||||
PRTime time,
|
PRTime time,
|
||||||
const SECItem *encodedResponse,
|
const SECItem *encodedResponse,
|
||||||
void *pwArg);
|
void *pwArg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: CERT_GetOCSPStatusForCertID
|
* FUNCTION: CERT_GetOCSPStatusForCertID
|
||||||
|
@ -581,11 +579,11 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
||||||
* Return values are the same as those for CERT_CheckOCSPStatus
|
* Return values are the same as those for CERT_CheckOCSPStatus
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
|
CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
|
||||||
CERTOCSPResponse *response,
|
CERTOCSPResponse *response,
|
||||||
CERTOCSPCertID *certID,
|
CERTOCSPCertID *certID,
|
||||||
CERTCertificate *signerCert,
|
CERTCertificate *signerCert,
|
||||||
PRTime time);
|
PRTime time);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION CERT_GetOCSPResponseStatus
|
* FUNCTION CERT_GetOCSPResponseStatus
|
||||||
|
@ -619,10 +617,10 @@ CERT_GetOCSPResponseStatus(CERTOCSPResponse *response);
|
||||||
* the issuing CA may be an older expired certificate.
|
* the issuing CA may be an older expired certificate.
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* A new copy of a CERTOCSPCertID*. The memory for this certID
|
* A new copy of a CERTOCSPCertID*. The memory for this certID
|
||||||
* should be freed by calling CERT_DestroyOCSPCertID when the
|
* should be freed by calling CERT_DestroyOCSPCertID when the
|
||||||
* certID is no longer necessary.
|
* certID is no longer necessary.
|
||||||
*/
|
*/
|
||||||
extern CERTOCSPCertID*
|
extern CERTOCSPCertID *
|
||||||
CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
|
CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -630,7 +628,7 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
|
||||||
* Frees the memory associated with the certID passed in.
|
* Frees the memory associated with the certID passed in.
|
||||||
* INPUTS:
|
* INPUTS:
|
||||||
* CERTOCSPCertID* certID
|
* CERTOCSPCertID* certID
|
||||||
* The certID that the caller no longer needs and wants to
|
* The certID that the caller no longer needs and wants to
|
||||||
* free the associated memory.
|
* free the associated memory.
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* SECSuccess if freeing the memory was successful. Returns
|
* SECSuccess if freeing the memory was successful. Returns
|
||||||
|
@ -638,31 +636,30 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
|
||||||
* a call to CERT_CreateOCSPCertID.
|
* a call to CERT_CreateOCSPCertID.
|
||||||
*/
|
*/
|
||||||
extern SECStatus
|
extern SECStatus
|
||||||
CERT_DestroyOCSPCertID(CERTOCSPCertID* certID);
|
CERT_DestroyOCSPCertID(CERTOCSPCertID *certID);
|
||||||
|
|
||||||
|
extern CERTOCSPSingleResponse *
|
||||||
extern CERTOCSPSingleResponse*
|
|
||||||
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id,
|
CERTOCSPCertID *id,
|
||||||
PRTime thisUpdate,
|
PRTime thisUpdate,
|
||||||
const PRTime *nextUpdate);
|
const PRTime *nextUpdate);
|
||||||
|
|
||||||
extern CERTOCSPSingleResponse*
|
extern CERTOCSPSingleResponse *
|
||||||
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id,
|
CERTOCSPCertID *id,
|
||||||
PRTime thisUpdate,
|
PRTime thisUpdate,
|
||||||
const PRTime *nextUpdate);
|
const PRTime *nextUpdate);
|
||||||
|
|
||||||
extern CERTOCSPSingleResponse*
|
extern CERTOCSPSingleResponse *
|
||||||
CERT_CreateOCSPSingleResponseRevoked(
|
CERT_CreateOCSPSingleResponseRevoked(
|
||||||
PLArenaPool *arena,
|
PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id,
|
CERTOCSPCertID *id,
|
||||||
PRTime thisUpdate,
|
PRTime thisUpdate,
|
||||||
const PRTime *nextUpdate,
|
const PRTime *nextUpdate,
|
||||||
PRTime revocationTime,
|
PRTime revocationTime,
|
||||||
const CERTCRLEntryReasonCode* revocationReason);
|
const CERTCRLEntryReasonCode *revocationReason);
|
||||||
|
|
||||||
extern SECItem*
|
extern SECItem *
|
||||||
CERT_CreateEncodedOCSPSuccessResponse(
|
CERT_CreateEncodedOCSPSuccessResponse(
|
||||||
PLArenaPool *arena,
|
PLArenaPool *arena,
|
||||||
CERTCertificate *responderCert,
|
CERTCertificate *responderCert,
|
||||||
|
@ -703,7 +700,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
||||||
* SEC_ERROR_INVALID_ARGS
|
* SEC_ERROR_INVALID_ARGS
|
||||||
* Other errors are low-level problems (no memory, bad database, etc.).
|
* Other errors are low-level problems (no memory, bad database, etc.).
|
||||||
*/
|
*/
|
||||||
extern SECItem*
|
extern SECItem *
|
||||||
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
|
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
|
||||||
|
|
||||||
/* Sends an OCSP request using the HTTP POST method to the location addressed
|
/* Sends an OCSP request using the HTTP POST method to the location addressed
|
||||||
|
@ -717,7 +714,7 @@ CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
|
||||||
* SEC_RegisterDefaultHttpClient then that client is used. Otherwise, an
|
* SEC_RegisterDefaultHttpClient then that client is used. Otherwise, an
|
||||||
* internal HTTP client is used.
|
* internal HTTP client is used.
|
||||||
*/
|
*/
|
||||||
SECItem* CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
|
SECItem *CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
|
||||||
const SECItem *encodedRequest);
|
const SECItem *encodedRequest);
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -35,13 +35,15 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
|
||||||
void *pwArg);
|
void *pwArg);
|
||||||
|
|
||||||
CERTOCSPRequest *
|
CERTOCSPRequest *
|
||||||
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
|
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
|
||||||
CERTCertificate *singleCert,
|
CERTCertificate *singleCert,
|
||||||
PRTime time,
|
PRTime time,
|
||||||
PRBool addServiceLocator,
|
PRBool addServiceLocator,
|
||||||
CERTCertificate *signerCert);
|
CERTCertificate *signerCert);
|
||||||
|
|
||||||
typedef enum { ocspMissing, ocspFresh, ocspStale } OCSPFreshness;
|
typedef enum { ocspMissing,
|
||||||
|
ocspFresh,
|
||||||
|
ocspStale } OCSPFreshness;
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
||||||
|
@ -84,13 +86,13 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
|
cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
|
||||||
CERTOCSPResponse *response,
|
CERTOCSPResponse *response,
|
||||||
CERTOCSPCertID *certID,
|
CERTOCSPCertID *certID,
|
||||||
CERTCertificate *signerCert,
|
CERTCertificate *signerCert,
|
||||||
PRTime time,
|
PRTime time,
|
||||||
PRBool *certIDWasConsumed,
|
PRBool *certIDWasConsumed,
|
||||||
SECStatus *cacheUpdateStatus);
|
SECStatus *cacheUpdateStatus);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: cert_RememberOCSPProcessingFailure
|
* FUNCTION: cert_RememberOCSPProcessingFailure
|
||||||
|
@ -109,7 +111,7 @@ cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
|
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
|
||||||
PRBool *certIDWasConsumed);
|
PRBool *certIDWasConsumed);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: ocsp_GetResponderLocation
|
* FUNCTION: ocsp_GetResponderLocation
|
||||||
|
@ -146,11 +148,11 @@ size_t
|
||||||
ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf);
|
ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf);
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
|
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
|
||||||
CERTOCSPResponse *response,
|
CERTOCSPResponse *response,
|
||||||
CERTOCSPCertID *certID,
|
CERTOCSPCertID *certID,
|
||||||
CERTCertificate *signerCert,
|
CERTCertificate *signerCert,
|
||||||
PRTime time,
|
PRTime time,
|
||||||
CERTOCSPSingleResponse **pSingleResponse);
|
CERTOCSPSingleResponse **pSingleResponse);
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
|
@ -158,7 +160,7 @@ ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time);
|
||||||
|
|
||||||
void
|
void
|
||||||
ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
|
ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
|
||||||
CERTOCSPSingleResponse *single,
|
CERTOCSPSingleResponse *single,
|
||||||
PRBool *certIDWasConsumed);
|
PRBool *certIDWasConsumed);
|
||||||
|
|
||||||
#endif /* _OCSPI_H_ */
|
#endif /* _OCSPI_H_ */
|
||||||
|
|
|
@ -19,12 +19,11 @@
|
||||||
#include "ocspi.h"
|
#include "ocspi.h"
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
|
|
||||||
|
|
||||||
extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
|
extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
|
||||||
extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
|
extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
|
||||||
extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];
|
extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];
|
||||||
|
|
||||||
ocspCertStatus*
|
ocspCertStatus *
|
||||||
ocsp_CreateCertStatus(PLArenaPool *arena,
|
ocsp_CreateCertStatus(PLArenaPool *arena,
|
||||||
ocspCertStatusType status,
|
ocspCertStatusType status,
|
||||||
PRTime revocationTime)
|
PRTime revocationTime)
|
||||||
|
@ -45,7 +44,7 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cs = PORT_ArenaZNew(arena, ocspCertStatus);
|
cs = PORT_ArenaZNew(arena, ocspCertStatus);
|
||||||
if (!cs)
|
if (!cs)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -71,8 +70,9 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
|
||||||
if (!cs->certStatusInfo.revokedInfo->revocationReason)
|
if (!cs->certStatusInfo.revokedInfo->revocationReason)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (DER_TimeToGeneralizedTimeArena(arena,
|
if (DER_TimeToGeneralizedTimeArena(arena,
|
||||||
&cs->certStatusInfo.revokedInfo->revocationTime,
|
&cs->certStatusInfo.revokedInfo->revocationTime,
|
||||||
revocationTime) != SECSuccess)
|
revocationTime) !=
|
||||||
|
SECSuccess)
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -91,11 +91,11 @@ static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
|
static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
|
||||||
{ SEC_ASN1_GENERALIZED_TIME,
|
{ SEC_ASN1_GENERALIZED_TIME,
|
||||||
offsetof(ocspRevokedInfo, revocationTime) },
|
offsetof(ocspRevokedInfo, revocationTime) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||||
offsetof(ocspRevokedInfo, revocationReason),
|
offsetof(ocspRevokedInfo, revocationReason),
|
||||||
mySEC_PointerToEnumeratedTemplate },
|
mySEC_PointerToEnumeratedTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -110,26 +110,26 @@ static const SEC_ASN1Template mySEC_NullTemplate[] = {
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
|
static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
|
||||||
{ SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
|
{ SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
|
||||||
0, sizeof(ocspCertStatus) },
|
0, sizeof(ocspCertStatus) },
|
||||||
{ SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
{ SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||||
0, mySEC_NullTemplate, ocspCertStatus_good },
|
0, mySEC_NullTemplate, ocspCertStatus_good },
|
||||||
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
|
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
|
||||||
SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||||
offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
|
offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
|
||||||
ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
|
ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
|
||||||
{ SEC_ASN1_CONTEXT_SPECIFIC | 2,
|
{ SEC_ASN1_CONTEXT_SPECIFIC | 2,
|
||||||
0, mySEC_NullTemplate, ocspCertStatus_unknown },
|
0, mySEC_NullTemplate, ocspCertStatus_unknown },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
|
static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(SECAlgorithmID) },
|
0, NULL, sizeof(SECAlgorithmID) },
|
||||||
{ SEC_ASN1_OBJECT_ID,
|
{ SEC_ASN1_OBJECT_ID,
|
||||||
offsetof(SECAlgorithmID,algorithm), },
|
offsetof(SECAlgorithmID, algorithm) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
|
||||||
offsetof(SECAlgorithmID,parameters), },
|
offsetof(SECAlgorithmID, parameters) },
|
||||||
{ 0, }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template mySEC_AnyTemplate[] = {
|
static const SEC_ASN1Template mySEC_AnyTemplate[] = {
|
||||||
|
@ -153,7 +153,7 @@ static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
|
static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
|
||||||
{ SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
|
{ SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
|
static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
|
||||||
|
@ -162,29 +162,29 @@ static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
|
static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(CERTOCSPCertID) },
|
0, NULL, sizeof(CERTOCSPCertID) },
|
||||||
{ SEC_ASN1_INLINE,
|
{ SEC_ASN1_INLINE,
|
||||||
offsetof(CERTOCSPCertID, hashAlgorithm),
|
offsetof(CERTOCSPCertID, hashAlgorithm),
|
||||||
mySECOID_AlgorithmIDTemplate },
|
mySECOID_AlgorithmIDTemplate },
|
||||||
{ SEC_ASN1_OCTET_STRING,
|
{ SEC_ASN1_OCTET_STRING,
|
||||||
offsetof(CERTOCSPCertID, issuerNameHash) },
|
offsetof(CERTOCSPCertID, issuerNameHash) },
|
||||||
{ SEC_ASN1_OCTET_STRING,
|
{ SEC_ASN1_OCTET_STRING,
|
||||||
offsetof(CERTOCSPCertID, issuerKeyHash) },
|
offsetof(CERTOCSPCertID, issuerKeyHash) },
|
||||||
{ SEC_ASN1_INTEGER,
|
{ SEC_ASN1_INTEGER,
|
||||||
offsetof(CERTOCSPCertID, serialNumber) },
|
offsetof(CERTOCSPCertID, serialNumber) },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
|
static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(CERTCertExtension) },
|
0, NULL, sizeof(CERTCertExtension) },
|
||||||
{ SEC_ASN1_OBJECT_ID,
|
{ SEC_ASN1_OBJECT_ID,
|
||||||
offsetof(CERTCertExtension,id) },
|
offsetof(CERTCertExtension, id) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
||||||
offsetof(CERTCertExtension,critical) },
|
offsetof(CERTCertExtension, critical) },
|
||||||
{ SEC_ASN1_OCTET_STRING,
|
{ SEC_ASN1_OCTET_STRING,
|
||||||
offsetof(CERTCertExtension,value) },
|
offsetof(CERTCertExtension, value) },
|
||||||
{ 0, }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
|
static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
|
||||||
|
@ -197,66 +197,65 @@ static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[]
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
|
static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(CERTOCSPSingleResponse) },
|
0, NULL, sizeof(CERTOCSPSingleResponse) },
|
||||||
{ SEC_ASN1_POINTER,
|
{ SEC_ASN1_POINTER,
|
||||||
offsetof(CERTOCSPSingleResponse, certID),
|
offsetof(CERTOCSPSingleResponse, certID),
|
||||||
ocsp_myCertIDTemplate },
|
ocsp_myCertIDTemplate },
|
||||||
{ SEC_ASN1_ANY,
|
{ SEC_ASN1_ANY,
|
||||||
offsetof(CERTOCSPSingleResponse, derCertStatus) },
|
offsetof(CERTOCSPSingleResponse, derCertStatus) },
|
||||||
{ SEC_ASN1_GENERALIZED_TIME,
|
{ SEC_ASN1_GENERALIZED_TIME,
|
||||||
offsetof(CERTOCSPSingleResponse, thisUpdate) },
|
offsetof(CERTOCSPSingleResponse, thisUpdate) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||||
offsetof(CERTOCSPSingleResponse, nextUpdate),
|
offsetof(CERTOCSPSingleResponse, nextUpdate),
|
||||||
mySEC_PointerToGeneralizedTimeTemplate },
|
mySEC_PointerToGeneralizedTimeTemplate },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||||
offsetof(CERTOCSPSingleResponse, singleExtensions),
|
offsetof(CERTOCSPSingleResponse, singleExtensions),
|
||||||
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
|
static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(ocspResponseData) },
|
0, NULL, sizeof(ocspResponseData) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||||
offsetof(ocspResponseData, version),
|
offsetof(ocspResponseData, version),
|
||||||
mySEC_PointerToIntegerTemplate },
|
mySEC_PointerToIntegerTemplate },
|
||||||
{ SEC_ASN1_ANY,
|
{ SEC_ASN1_ANY,
|
||||||
offsetof(ocspResponseData, derResponderID) },
|
offsetof(ocspResponseData, derResponderID) },
|
||||||
{ SEC_ASN1_GENERALIZED_TIME,
|
{ SEC_ASN1_GENERALIZED_TIME,
|
||||||
offsetof(ocspResponseData, producedAt) },
|
offsetof(ocspResponseData, producedAt) },
|
||||||
{ SEC_ASN1_SEQUENCE_OF,
|
{ SEC_ASN1_SEQUENCE_OF,
|
||||||
offsetof(ocspResponseData, responses),
|
offsetof(ocspResponseData, responses),
|
||||||
ocsp_mySingleResponseTemplate },
|
ocsp_mySingleResponseTemplate },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||||
offsetof(ocspResponseData, responseExtensions),
|
offsetof(ocspResponseData, responseExtensions),
|
||||||
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
|
static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(ocspBasicOCSPResponse) },
|
0, NULL, sizeof(ocspBasicOCSPResponse) },
|
||||||
{ SEC_ASN1_POINTER,
|
{ SEC_ASN1_POINTER,
|
||||||
offsetof(ocspBasicOCSPResponse, tbsResponseData),
|
offsetof(ocspBasicOCSPResponse, tbsResponseData),
|
||||||
ocsp_myResponseDataTemplate },
|
ocsp_myResponseDataTemplate },
|
||||||
{ SEC_ASN1_INLINE,
|
{ SEC_ASN1_INLINE,
|
||||||
offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
|
offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
|
||||||
mySECOID_AlgorithmIDTemplate },
|
mySECOID_AlgorithmIDTemplate },
|
||||||
{ SEC_ASN1_BIT_STRING,
|
{ SEC_ASN1_BIT_STRING,
|
||||||
offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
|
offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||||
offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
|
offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
|
||||||
mySEC_PointerToSequenceOfAnyTemplate },
|
mySEC_PointerToSequenceOfAnyTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static CERTOCSPSingleResponse*
|
static CERTOCSPSingleResponse *
|
||||||
ocsp_CreateSingleResponse(PLArenaPool *arena,
|
ocsp_CreateSingleResponse(PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id, ocspCertStatus *status,
|
CERTOCSPCertID *id, ocspCertStatus *status,
|
||||||
PRTime thisUpdate, const PRTime *nextUpdate)
|
PRTime thisUpdate, const PRTime *nextUpdate)
|
||||||
|
@ -274,25 +273,25 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
|
||||||
sr->arena = arena;
|
sr->arena = arena;
|
||||||
sr->certID = id;
|
sr->certID = id;
|
||||||
sr->certStatus = status;
|
sr->certStatus = status;
|
||||||
if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate)
|
if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) !=
|
||||||
!= SECSuccess)
|
SECSuccess)
|
||||||
return NULL;
|
return NULL;
|
||||||
sr->nextUpdate = NULL;
|
sr->nextUpdate = NULL;
|
||||||
if (nextUpdate) {
|
if (nextUpdate) {
|
||||||
sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
|
sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
|
||||||
if (!sr->nextUpdate)
|
if (!sr->nextUpdate)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate)
|
if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) !=
|
||||||
!= SECSuccess)
|
SECSuccess)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1);
|
sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension *, 1);
|
||||||
if (!sr->singleExtensions)
|
if (!sr->singleExtensions)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sr->singleExtensions[0] = NULL;
|
sr->singleExtensions[0] = NULL;
|
||||||
|
|
||||||
if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
|
if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
|
||||||
status, ocsp_CertStatusTemplate))
|
status, ocsp_CertStatusTemplate))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -300,13 +299,13 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
|
||||||
return sr;
|
return sr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTOCSPSingleResponse*
|
CERTOCSPSingleResponse *
|
||||||
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id,
|
CERTOCSPCertID *id,
|
||||||
PRTime thisUpdate,
|
PRTime thisUpdate,
|
||||||
const PRTime *nextUpdate)
|
const PRTime *nextUpdate)
|
||||||
{
|
{
|
||||||
ocspCertStatus * cs;
|
ocspCertStatus *cs;
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -317,13 +316,13 @@ CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
||||||
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTOCSPSingleResponse*
|
CERTOCSPSingleResponse *
|
||||||
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id,
|
CERTOCSPCertID *id,
|
||||||
PRTime thisUpdate,
|
PRTime thisUpdate,
|
||||||
const PRTime *nextUpdate)
|
const PRTime *nextUpdate)
|
||||||
{
|
{
|
||||||
ocspCertStatus * cs;
|
ocspCertStatus *cs;
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -334,16 +333,16 @@ CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
||||||
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTOCSPSingleResponse*
|
CERTOCSPSingleResponse *
|
||||||
CERT_CreateOCSPSingleResponseRevoked(
|
CERT_CreateOCSPSingleResponseRevoked(
|
||||||
PLArenaPool *arena,
|
PLArenaPool *arena,
|
||||||
CERTOCSPCertID *id,
|
CERTOCSPCertID *id,
|
||||||
PRTime thisUpdate,
|
PRTime thisUpdate,
|
||||||
const PRTime *nextUpdate,
|
const PRTime *nextUpdate,
|
||||||
PRTime revocationTime,
|
PRTime revocationTime,
|
||||||
const CERTCRLEntryReasonCode* revocationReason)
|
const CERTCRLEntryReasonCode *revocationReason)
|
||||||
{
|
{
|
||||||
ocspCertStatus * cs;
|
ocspCertStatus *cs;
|
||||||
/* revocationReason is not yet supported, so it must be NULL. */
|
/* revocationReason is not yet supported, so it must be NULL. */
|
||||||
if (!arena || revocationReason) {
|
if (!arena || revocationReason) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
|
@ -357,7 +356,7 @@ CERT_CreateOCSPSingleResponseRevoked(
|
||||||
|
|
||||||
/* responderCert == 0 means:
|
/* responderCert == 0 means:
|
||||||
* create a response with an invalid signature (for testing purposes) */
|
* create a response with an invalid signature (for testing purposes) */
|
||||||
SECItem*
|
SECItem *
|
||||||
CERT_CreateEncodedOCSPSuccessResponse(
|
CERT_CreateEncodedOCSPSuccessResponse(
|
||||||
PLArenaPool *arena,
|
PLArenaPool *arena,
|
||||||
CERTCertificate *responderCert,
|
CERTCertificate *responderCert,
|
||||||
|
@ -373,12 +372,12 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
||||||
ocspBasicOCSPResponse *br = NULL;
|
ocspBasicOCSPResponse *br = NULL;
|
||||||
ocspResponseBytes *rb = NULL;
|
ocspResponseBytes *rb = NULL;
|
||||||
CERTOCSPResponse *response = NULL;
|
CERTOCSPResponse *response = NULL;
|
||||||
|
|
||||||
SECOidTag algID;
|
SECOidTag algID;
|
||||||
SECOidData *od = NULL;
|
SECOidData *od = NULL;
|
||||||
SECKEYPrivateKey *privKey = NULL;
|
SECKEYPrivateKey *privKey = NULL;
|
||||||
SECItem *result = NULL;
|
SECItem *result = NULL;
|
||||||
|
|
||||||
if (!arena || !responses) {
|
if (!arena || !responses) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -408,114 +407,114 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
||||||
response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
|
response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
|
||||||
if (!response)
|
if (!response)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
rd->version.data=NULL;
|
rd->version.data = NULL;
|
||||||
rd->version.len=0;
|
rd->version.len = 0;
|
||||||
rd->responseExtensions = NULL;
|
rd->responseExtensions = NULL;
|
||||||
rd->responses = responses;
|
rd->responses = responses;
|
||||||
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
|
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) !=
|
||||||
!= SECSuccess)
|
SECSuccess)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (!responderCert) {
|
if (!responderCert) {
|
||||||
/* use invalid signature for testing purposes */
|
/* use invalid signature for testing purposes */
|
||||||
unsigned char dummyChar = 'd';
|
unsigned char dummyChar = 'd';
|
||||||
SECItem dummy;
|
SECItem dummy;
|
||||||
|
|
||||||
dummy.len = 1;
|
dummy.len = 1;
|
||||||
dummy.data = &dummyChar;
|
dummy.data = &dummyChar;
|
||||||
|
|
||||||
/* it's easier to produdce a keyHash out of nowhere,
|
/* it's easier to produdce a keyHash out of nowhere,
|
||||||
* than to produce an encoded subject,
|
* than to produce an encoded subject,
|
||||||
* so for our dummy response we always use byKey
|
* so for our dummy response we always use byKey
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rid->responderIDType = ocspResponderID_byKey;
|
|
||||||
if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
|
|
||||||
&dummy))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
rid->responderIDType = ocspResponderID_byKey;
|
||||||
ocsp_ResponderIDByKeyTemplate))
|
if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
|
||||||
goto done;
|
&dummy))
|
||||||
|
goto done;
|
||||||
|
|
||||||
br->tbsResponseData = rd;
|
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||||
|
ocsp_ResponderIDByKeyTemplate))
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
br->tbsResponseData = rd;
|
||||||
ocsp_myResponseDataTemplate))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
|
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
||||||
if (!br->responseSignature.derCerts)
|
ocsp_myResponseDataTemplate))
|
||||||
goto done;
|
goto done;
|
||||||
br->responseSignature.derCerts[0] = NULL;
|
|
||||||
|
|
||||||
algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
|
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
|
||||||
if (algID == SEC_OID_UNKNOWN)
|
if (!br->responseSignature.derCerts)
|
||||||
goto done;
|
goto done;
|
||||||
|
br->responseSignature.derCerts[0] = NULL;
|
||||||
|
|
||||||
/* match the regular signature code, which doesn't use the arena */
|
algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
|
||||||
if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
|
if (algID == SEC_OID_UNKNOWN)
|
||||||
goto done;
|
goto done;
|
||||||
PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
|
|
||||||
|
|
||||||
/* convert len-in-bytes to len-in-bits */
|
/* match the regular signature code, which doesn't use the arena */
|
||||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
|
||||||
|
goto done;
|
||||||
|
PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
|
||||||
|
|
||||||
|
/* convert len-in-bytes to len-in-bits */
|
||||||
|
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rid->responderIDType = responderIDType;
|
rid->responderIDType = responderIDType;
|
||||||
if (responderIDType == ocspResponderID_byName) {
|
if (responderIDType == ocspResponderID_byName) {
|
||||||
responderIDTemplate = ocsp_ResponderIDByNameTemplate;
|
responderIDTemplate = ocsp_ResponderIDByNameTemplate;
|
||||||
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
|
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
|
||||||
&responderCert->subject) != SECSuccess)
|
&responderCert->subject) != SECSuccess)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
|
responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
|
||||||
if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
|
if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
|
||||||
SEC_OID_SHA1, &rid->responderIDValue.keyHash))
|
SEC_OID_SHA1, &rid->responderIDValue.keyHash))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||||
responderIDTemplate))
|
responderIDTemplate))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
br->tbsResponseData = rd;
|
br->tbsResponseData = rd;
|
||||||
|
|
||||||
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
||||||
ocsp_myResponseDataTemplate))
|
ocsp_myResponseDataTemplate))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
|
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
|
||||||
if (!br->responseSignature.derCerts)
|
if (!br->responseSignature.derCerts)
|
||||||
goto done;
|
goto done;
|
||||||
br->responseSignature.derCerts[0] = NULL;
|
br->responseSignature.derCerts[0] = NULL;
|
||||||
|
|
||||||
privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
|
privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
|
||||||
if (!privKey)
|
if (!privKey)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
||||||
if (algID == SEC_OID_UNKNOWN)
|
if (algID == SEC_OID_UNKNOWN)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (SEC_SignData(&br->responseSignature.signature,
|
if (SEC_SignData(&br->responseSignature.signature,
|
||||||
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
|
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
|
||||||
privKey, algID)
|
privKey, algID) !=
|
||||||
!= SECSuccess)
|
SECSuccess)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* convert len-in-bytes to len-in-bits */
|
/* convert len-in-bytes to len-in-bits */
|
||||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||||
|
|
||||||
/* br->responseSignature.signature wasn't allocated from arena,
|
/* br->responseSignature.signature wasn't allocated from arena,
|
||||||
* we must free it when done. */
|
* we must free it when done. */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0)
|
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) !=
|
||||||
!= SECSuccess)
|
SECSuccess)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
|
if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
|
||||||
ocsp_EncodeBasicOCSPResponseTemplate))
|
ocsp_EncodeBasicOCSPResponseTemplate))
|
||||||
|
@ -552,15 +551,15 @@ done:
|
||||||
|
|
||||||
static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
|
static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE,
|
{ SEC_ASN1_SEQUENCE,
|
||||||
0, NULL, sizeof(CERTOCSPResponse) },
|
0, NULL, sizeof(CERTOCSPResponse) },
|
||||||
{ SEC_ASN1_ENUMERATED,
|
{ SEC_ASN1_ENUMERATED,
|
||||||
offsetof(CERTOCSPResponse, responseStatus) },
|
offsetof(CERTOCSPResponse, responseStatus) },
|
||||||
{ 0, 0,
|
{ 0, 0,
|
||||||
mySEC_NullTemplate },
|
mySEC_NullTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
SECItem*
|
SECItem *
|
||||||
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
|
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
|
||||||
{
|
{
|
||||||
CERTOCSPResponse response;
|
CERTOCSPResponse response;
|
||||||
|
|
|
@ -46,8 +46,8 @@ typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse;
|
||||||
* dependent, and should be opaque to the user.
|
* dependent, and should be opaque to the user.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void * SEC_HTTP_SERVER_SESSION;
|
typedef void *SEC_HTTP_SERVER_SESSION;
|
||||||
typedef void * SEC_HTTP_REQUEST_SESSION;
|
typedef void *SEC_HTTP_REQUEST_SESSION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a
|
* This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a
|
||||||
|
@ -61,9 +61,9 @@ typedef void * SEC_HTTP_REQUEST_SESSION;
|
||||||
* after processing is finished.
|
* after processing is finished.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
|
typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
|
||||||
const char *host,
|
const char *host,
|
||||||
PRUint16 portnum,
|
PRUint16 portnum,
|
||||||
SEC_HTTP_SERVER_SESSION *pSession);
|
SEC_HTTP_SERVER_SESSION *pSession);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is called to allow the implementation to attempt to keep
|
* This function is called to allow the implementation to attempt to keep
|
||||||
|
@ -77,10 +77,10 @@ typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
|
||||||
* SECWouldBlock and store a nonzero value at "pPollDesc". In that case
|
* SECWouldBlock and store a nonzero value at "pPollDesc". In that case
|
||||||
* the caller may wait on the poll descriptor, and should call this function
|
* the caller may wait on the poll descriptor, and should call this function
|
||||||
* again until SECSuccess (and a zero value at "pPollDesc") is obtained.
|
* again until SECSuccess (and a zero value at "pPollDesc") is obtained.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
|
typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
|
||||||
SEC_HTTP_SERVER_SESSION session,
|
SEC_HTTP_SERVER_SESSION session,
|
||||||
PRPollDesc **pPollDesc);
|
PRPollDesc **pPollDesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function frees the client SEC_HTTP_SERVER_SESSION object, closes all
|
* This function frees the client SEC_HTTP_SERVER_SESSION object, closes all
|
||||||
|
@ -88,9 +88,9 @@ typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
|
||||||
* frees any memory that was allocated by the client, and invalidates any
|
* frees any memory that was allocated by the client, and invalidates any
|
||||||
* response pointers that might have been returned by prior server or request
|
* response pointers that might have been returned by prior server or request
|
||||||
* functions.
|
* functions.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
|
typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
|
||||||
SEC_HTTP_SERVER_SESSION session);
|
SEC_HTTP_SERVER_SESSION session);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a
|
* This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a
|
||||||
|
@ -111,30 +111,30 @@ typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
|
||||||
* after processing is finished.
|
* after processing is finished.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpRequest_CreateFcn)(
|
typedef SECStatus (*SEC_HttpRequest_CreateFcn)(
|
||||||
SEC_HTTP_SERVER_SESSION session,
|
SEC_HTTP_SERVER_SESSION session,
|
||||||
const char *http_protocol_variant, /* usually "http" */
|
const char *http_protocol_variant, /* usually "http" */
|
||||||
const char *path_and_query_string,
|
const char *path_and_query_string,
|
||||||
const char *http_request_method,
|
const char *http_request_method,
|
||||||
const PRIntervalTime timeout,
|
const PRIntervalTime timeout,
|
||||||
SEC_HTTP_REQUEST_SESSION *pRequest);
|
SEC_HTTP_REQUEST_SESSION *pRequest);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sets data to be sent to the server for an HTTP request
|
* This function sets data to be sent to the server for an HTTP request
|
||||||
* of http_request_method == POST. If a particular implementation
|
* of http_request_method == POST. If a particular implementation
|
||||||
* supports it, the details for the POST request can be set by calling
|
* supports it, the details for the POST request can be set by calling
|
||||||
* this function, prior to activating the request with TrySendAndReceiveFcn.
|
* this function, prior to activating the request with TrySendAndReceiveFcn.
|
||||||
*
|
*
|
||||||
* An implementation that does not support the POST method should
|
* An implementation that does not support the POST method should
|
||||||
* implement a SetPostDataFcn function that returns immediately.
|
* implement a SetPostDataFcn function that returns immediately.
|
||||||
*
|
*
|
||||||
* Setting http_content_type is optional, the parameter may
|
* Setting http_content_type is optional, the parameter may
|
||||||
* by NULL or the empty string.
|
* by NULL or the empty string.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
|
typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
|
||||||
SEC_HTTP_REQUEST_SESSION request,
|
SEC_HTTP_REQUEST_SESSION request,
|
||||||
const char *http_data,
|
const char *http_data,
|
||||||
const PRUint32 http_data_len,
|
const PRUint32 http_data_len,
|
||||||
const char *http_content_type);
|
const char *http_content_type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sets an additional HTTP protocol request header.
|
* This function sets an additional HTTP protocol request header.
|
||||||
|
@ -144,11 +144,11 @@ typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
|
||||||
*
|
*
|
||||||
* An implementation that does not support setting additional headers
|
* An implementation that does not support setting additional headers
|
||||||
* should implement an AddRequestHeaderFcn function that returns immediately.
|
* should implement an AddRequestHeaderFcn function that returns immediately.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
||||||
SEC_HTTP_REQUEST_SESSION request,
|
SEC_HTTP_REQUEST_SESSION request,
|
||||||
const char *http_header_name,
|
const char *http_header_name,
|
||||||
const char *http_header_value);
|
const char *http_header_value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function initiates or continues an HTTP request. After
|
* This function initiates or continues an HTTP request. After
|
||||||
|
@ -180,10 +180,10 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
||||||
* size, the function will return SECFailure.
|
* size, the function will return SECFailure.
|
||||||
* http_response_data_len will be set to a value different from zero to
|
* http_response_data_len will be set to a value different from zero to
|
||||||
* indicate the reason of the failure.
|
* indicate the reason of the failure.
|
||||||
* An out value of "0" means, the failure was unrelated to the
|
* An out value of "0" means, the failure was unrelated to the
|
||||||
* acceptable size.
|
* acceptable size.
|
||||||
* An out value of "1" means, the result data is larger than the
|
* An out value of "1" means, the result data is larger than the
|
||||||
* accpeptable size, but the real size is not yet known to the http client
|
* accpeptable size, but the real size is not yet known to the http client
|
||||||
* implementation and it stopped retrieving it,
|
* implementation and it stopped retrieving it,
|
||||||
* Any other out value combined with a return value of SECFailure
|
* Any other out value combined with a return value of SECFailure
|
||||||
* will indicate the actual size of the server data.
|
* will indicate the actual size of the server data.
|
||||||
|
@ -195,64 +195,64 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
||||||
* the completion of the operation.
|
* the completion of the operation.
|
||||||
*
|
*
|
||||||
* All returned pointers will be owned by the the HttpClient
|
* All returned pointers will be owned by the the HttpClient
|
||||||
* implementation and will remain valid until the call to
|
* implementation and will remain valid until the call to
|
||||||
* SEC_HttpRequest_FreeFcn.
|
* SEC_HttpRequest_FreeFcn.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)(
|
typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)(
|
||||||
SEC_HTTP_REQUEST_SESSION request,
|
SEC_HTTP_REQUEST_SESSION request,
|
||||||
PRPollDesc **pPollDesc,
|
PRPollDesc **pPollDesc,
|
||||||
PRUint16 *http_response_code,
|
PRUint16 *http_response_code,
|
||||||
const char **http_response_content_type,
|
const char **http_response_content_type,
|
||||||
const char **http_response_headers,
|
const char **http_response_headers,
|
||||||
const char **http_response_data,
|
const char **http_response_data,
|
||||||
PRUint32 *http_response_data_len);
|
PRUint32 *http_response_data_len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calling CancelFcn asks for premature termination of the request.
|
* Calling CancelFcn asks for premature termination of the request.
|
||||||
*
|
*
|
||||||
* Future calls to SEC_HttpRequest_TrySendAndReceive should
|
* Future calls to SEC_HttpRequest_TrySendAndReceive should
|
||||||
* by avoided, but in this case the HttpClient implementation
|
* by avoided, but in this case the HttpClient implementation
|
||||||
* is expected to return immediately with SECFailure.
|
* is expected to return immediately with SECFailure.
|
||||||
*
|
*
|
||||||
* After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn
|
* After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn
|
||||||
* is still necessary to free resources.
|
* is still necessary to free resources.
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpRequest_CancelFcn)(
|
typedef SECStatus (*SEC_HttpRequest_CancelFcn)(
|
||||||
SEC_HTTP_REQUEST_SESSION request);
|
SEC_HTTP_REQUEST_SESSION request);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before calling this function, it must be assured the request
|
* Before calling this function, it must be assured the request
|
||||||
* has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has
|
* has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has
|
||||||
* returned SECSuccess, or the request has been canceled with
|
* returned SECSuccess, or the request has been canceled with
|
||||||
* a call to SEC_HttpRequest_CancelFcn.
|
* a call to SEC_HttpRequest_CancelFcn.
|
||||||
*
|
*
|
||||||
* This function frees the client state object, closes all sockets,
|
* This function frees the client state object, closes all sockets,
|
||||||
* discards all partial results, frees any memory that was allocated
|
* discards all partial results, frees any memory that was allocated
|
||||||
* by the client, and invalidates all response pointers that might
|
* by the client, and invalidates all response pointers that might
|
||||||
* have been returned by SEC_HttpRequest_TrySendAndReceiveFcn
|
* have been returned by SEC_HttpRequest_TrySendAndReceiveFcn
|
||||||
*/
|
*/
|
||||||
typedef SECStatus (*SEC_HttpRequest_FreeFcn)(
|
typedef SECStatus (*SEC_HttpRequest_FreeFcn)(
|
||||||
SEC_HTTP_REQUEST_SESSION request);
|
SEC_HTTP_REQUEST_SESSION request);
|
||||||
|
|
||||||
typedef struct SEC_HttpClientFcnV1Struct {
|
typedef struct SEC_HttpClientFcnV1Struct {
|
||||||
SEC_HttpServer_CreateSessionFcn createSessionFcn;
|
SEC_HttpServer_CreateSessionFcn createSessionFcn;
|
||||||
SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn;
|
SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn;
|
||||||
SEC_HttpServer_FreeSessionFcn freeSessionFcn;
|
SEC_HttpServer_FreeSessionFcn freeSessionFcn;
|
||||||
SEC_HttpRequest_CreateFcn createFcn;
|
SEC_HttpRequest_CreateFcn createFcn;
|
||||||
SEC_HttpRequest_SetPostDataFcn setPostDataFcn;
|
SEC_HttpRequest_SetPostDataFcn setPostDataFcn;
|
||||||
SEC_HttpRequest_AddHeaderFcn addHeaderFcn;
|
SEC_HttpRequest_AddHeaderFcn addHeaderFcn;
|
||||||
SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn;
|
SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn;
|
||||||
SEC_HttpRequest_CancelFcn cancelFcn;
|
SEC_HttpRequest_CancelFcn cancelFcn;
|
||||||
SEC_HttpRequest_FreeFcn freeFcn;
|
SEC_HttpRequest_FreeFcn freeFcn;
|
||||||
} SEC_HttpClientFcnV1;
|
} SEC_HttpClientFcnV1;
|
||||||
|
|
||||||
typedef struct SEC_HttpClientFcnStruct {
|
typedef struct SEC_HttpClientFcnStruct {
|
||||||
PRInt16 version;
|
PRInt16 version;
|
||||||
union {
|
union {
|
||||||
SEC_HttpClientFcnV1 ftable1;
|
SEC_HttpClientFcnV1 ftable1;
|
||||||
/* SEC_HttpClientFcnV2 ftable2; */
|
/* SEC_HttpClientFcnV2 ftable2; */
|
||||||
/* ... */
|
/* ... */
|
||||||
} fcnTable;
|
} fcnTable;
|
||||||
} SEC_HttpClientFcn;
|
} SEC_HttpClientFcn;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -293,7 +293,7 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ocspResponderID_other = -1, /* unknown kind of responderID */
|
ocspResponderID_other = -1, /* unknown kind of responderID */
|
||||||
ocspResponderID_byName = 1,
|
ocspResponderID_byName = 1,
|
||||||
ocspResponderID_byKey = 2
|
ocspResponderID_byKey = 2
|
||||||
} CERTOCSPResponderIDType;
|
} CERTOCSPResponderIDType;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
#include "secoidt.h"
|
#include "secoidt.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some notes about naming conventions...
|
* Some notes about naming conventions...
|
||||||
*
|
*
|
||||||
|
@ -49,7 +48,6 @@
|
||||||
* way around (reference before definition).
|
* way around (reference before definition).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forward-declarations of internal-only data structures.
|
* Forward-declarations of internal-only data structures.
|
||||||
*
|
*
|
||||||
|
@ -67,12 +65,11 @@ typedef struct ocspSingleRequestStr ocspSingleRequest;
|
||||||
typedef struct ocspSingleResponseStr ocspSingleResponse;
|
typedef struct ocspSingleResponseStr ocspSingleResponse;
|
||||||
typedef struct ocspTBSRequestStr ocspTBSRequest;
|
typedef struct ocspTBSRequestStr ocspTBSRequest;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
|
* An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
|
||||||
*/
|
*/
|
||||||
struct CERTOCSPRequestStr {
|
struct CERTOCSPRequestStr {
|
||||||
PLArenaPool *arena; /* local; not part of encoding */
|
PLArenaPool *arena; /* local; not part of encoding */
|
||||||
ocspTBSRequest *tbsRequest;
|
ocspTBSRequest *tbsRequest;
|
||||||
ocspSignature *optionalSignature;
|
ocspSignature *optionalSignature;
|
||||||
};
|
};
|
||||||
|
@ -92,12 +89,12 @@ struct CERTOCSPRequestStr {
|
||||||
* in-progress extensions as they are optionally added to the request.
|
* in-progress extensions as they are optionally added to the request.
|
||||||
*/
|
*/
|
||||||
struct ocspTBSRequestStr {
|
struct ocspTBSRequestStr {
|
||||||
SECItem version; /* an INTEGER */
|
SECItem version; /* an INTEGER */
|
||||||
SECItem *derRequestorName; /* encoded GeneralName; see above */
|
SECItem *derRequestorName; /* encoded GeneralName; see above */
|
||||||
CERTGeneralNameList *requestorName; /* local; not part of encoding */
|
CERTGeneralNameList *requestorName; /* local; not part of encoding */
|
||||||
ocspSingleRequest **requestList;
|
ocspSingleRequest **requestList;
|
||||||
CERTCertExtension **requestExtensions;
|
CERTCertExtension **requestExtensions;
|
||||||
void *extensionHandle; /* local; not part of encoding */
|
void *extensionHandle; /* local; not part of encoding */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -124,12 +121,12 @@ struct ocspTBSRequestStr {
|
||||||
*/
|
*/
|
||||||
struct ocspSignatureStr {
|
struct ocspSignatureStr {
|
||||||
SECAlgorithmID signatureAlgorithm;
|
SECAlgorithmID signatureAlgorithm;
|
||||||
SECItem signature; /* a BIT STRING */
|
SECItem signature; /* a BIT STRING */
|
||||||
SECItem **derCerts; /* a SEQUENCE OF Certificate */
|
SECItem **derCerts; /* a SEQUENCE OF Certificate */
|
||||||
CERTCertificate *cert; /* local; not part of encoding */
|
CERTCertificate *cert; /* local; not part of encoding */
|
||||||
PRBool wasChecked; /* local; not part of encoding */
|
PRBool wasChecked; /* local; not part of encoding */
|
||||||
SECStatus status; /* local; not part of encoding */
|
SECStatus status; /* local; not part of encoding */
|
||||||
int failureReason; /* local; not part of encoding */
|
int failureReason; /* local; not part of encoding */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -140,11 +137,11 @@ struct ocspSignatureStr {
|
||||||
* but since that seemed confusing (vs. an OCSPRequest) and to be more
|
* but since that seemed confusing (vs. an OCSPRequest) and to be more
|
||||||
* consistent with the parallel type "SingleResponse", I called it a
|
* consistent with the parallel type "SingleResponse", I called it a
|
||||||
* "SingleRequest".
|
* "SingleRequest".
|
||||||
*
|
*
|
||||||
* XXX figure out how to get rid of that arena -- there must be a way
|
* XXX figure out how to get rid of that arena -- there must be a way
|
||||||
*/
|
*/
|
||||||
struct ocspSingleRequestStr {
|
struct ocspSingleRequestStr {
|
||||||
PLArenaPool *arena; /* just a copy of the response arena,
|
PLArenaPool *arena; /* just a copy of the response arena,
|
||||||
* needed here for extension handling
|
* needed here for extension handling
|
||||||
* routines, on creation only */
|
* routines, on creation only */
|
||||||
CERTOCSPCertID *reqCert;
|
CERTOCSPCertID *reqCert;
|
||||||
|
@ -160,14 +157,14 @@ struct ocspSingleRequestStr {
|
||||||
*/
|
*/
|
||||||
struct CERTOCSPCertIDStr {
|
struct CERTOCSPCertIDStr {
|
||||||
SECAlgorithmID hashAlgorithm;
|
SECAlgorithmID hashAlgorithm;
|
||||||
SECItem issuerNameHash; /* an OCTET STRING */
|
SECItem issuerNameHash; /* an OCTET STRING */
|
||||||
SECItem issuerKeyHash; /* an OCTET STRING */
|
SECItem issuerKeyHash; /* an OCTET STRING */
|
||||||
SECItem serialNumber; /* an INTEGER */
|
SECItem serialNumber; /* an INTEGER */
|
||||||
SECItem issuerSHA1NameHash; /* keep other hashes around when */
|
SECItem issuerSHA1NameHash; /* keep other hashes around when */
|
||||||
SECItem issuerMD5NameHash; /* we have them */
|
SECItem issuerMD5NameHash; /* we have them */
|
||||||
SECItem issuerMD2NameHash;
|
SECItem issuerMD2NameHash;
|
||||||
SECItem issuerSHA1KeyHash; /* keep other hashes around when */
|
SECItem issuerSHA1KeyHash; /* keep other hashes around when */
|
||||||
SECItem issuerMD5KeyHash; /* we have them */
|
SECItem issuerMD5KeyHash; /* we have them */
|
||||||
SECItem issuerMD2KeyHash;
|
SECItem issuerMD2KeyHash;
|
||||||
PLArenaPool *poolp;
|
PLArenaPool *poolp;
|
||||||
};
|
};
|
||||||
|
@ -209,10 +206,10 @@ typedef enum {
|
||||||
* type ocspResponseStatus.
|
* type ocspResponseStatus.
|
||||||
*/
|
*/
|
||||||
struct CERTOCSPResponseStr {
|
struct CERTOCSPResponseStr {
|
||||||
PLArenaPool *arena; /* local; not part of encoding */
|
PLArenaPool *arena; /* local; not part of encoding */
|
||||||
SECItem responseStatus; /* an ENUMERATED, see above */
|
SECItem responseStatus; /* an ENUMERATED, see above */
|
||||||
ocspResponseStatus statusValue; /* local; not part of encoding */
|
ocspResponseStatus statusValue; /* local; not part of encoding */
|
||||||
ocspResponseBytes *responseBytes; /* only when status is successful */
|
ocspResponseBytes *responseBytes; /* only when status is successful */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -230,12 +227,12 @@ struct CERTOCSPResponseStr {
|
||||||
* response types, just add them to the union.
|
* response types, just add them to the union.
|
||||||
*/
|
*/
|
||||||
struct ocspResponseBytesStr {
|
struct ocspResponseBytesStr {
|
||||||
SECItem responseType; /* an OBJECT IDENTIFIER */
|
SECItem responseType; /* an OBJECT IDENTIFIER */
|
||||||
SECOidTag responseTypeTag; /* local; not part of encoding */
|
SECOidTag responseTypeTag; /* local; not part of encoding */
|
||||||
SECItem response; /* an OCTET STRING */
|
SECItem response; /* an OCTET STRING */
|
||||||
union {
|
union {
|
||||||
ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
|
ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
|
||||||
} decodedResponse; /* local; not part of encoding */
|
} decodedResponse; /* local; not part of encoding */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -250,7 +247,7 @@ struct ocspResponseBytesStr {
|
||||||
*/
|
*/
|
||||||
struct ocspBasicOCSPResponseStr {
|
struct ocspBasicOCSPResponseStr {
|
||||||
SECItem tbsResponseDataDER;
|
SECItem tbsResponseDataDER;
|
||||||
ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
|
ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
|
||||||
ocspSignature responseSignature;
|
ocspSignature responseSignature;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -260,38 +257,38 @@ struct ocspBasicOCSPResponseStr {
|
||||||
* (a per-certificate status).
|
* (a per-certificate status).
|
||||||
*/
|
*/
|
||||||
struct ocspResponseDataStr {
|
struct ocspResponseDataStr {
|
||||||
SECItem version; /* an INTEGER */
|
SECItem version; /* an INTEGER */
|
||||||
SECItem derResponderID;
|
SECItem derResponderID;
|
||||||
ocspResponderID *responderID; /* local; not part of encoding */
|
ocspResponderID *responderID; /* local; not part of encoding */
|
||||||
SECItem producedAt; /* a GeneralizedTime */
|
SECItem producedAt; /* a GeneralizedTime */
|
||||||
CERTOCSPSingleResponse **responses;
|
CERTOCSPSingleResponse **responses;
|
||||||
CERTCertExtension **responseExtensions;
|
CERTCertExtension **responseExtensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ocspResponderIDStr {
|
struct ocspResponderIDStr {
|
||||||
CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */
|
CERTOCSPResponderIDType responderIDType; /* local; not part of encoding */
|
||||||
union {
|
union {
|
||||||
CERTName name; /* when ocspResponderID_byName */
|
CERTName name; /* when ocspResponderID_byName */
|
||||||
SECItem keyHash; /* when ocspResponderID_byKey */
|
SECItem keyHash; /* when ocspResponderID_byKey */
|
||||||
SECItem other; /* when ocspResponderID_other */
|
SECItem other; /* when ocspResponderID_other */
|
||||||
} responderIDValue;
|
} responderIDValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
|
* The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
|
||||||
* SingleResponse -- one for each certificate whose status is being supplied.
|
* SingleResponse -- one for each certificate whose status is being supplied.
|
||||||
*
|
*
|
||||||
* XXX figure out how to get rid of that arena -- there must be a way
|
* XXX figure out how to get rid of that arena -- there must be a way
|
||||||
*/
|
*/
|
||||||
struct CERTOCSPSingleResponseStr {
|
struct CERTOCSPSingleResponseStr {
|
||||||
PLArenaPool *arena; /* just a copy of the response arena,
|
PLArenaPool *arena; /* just a copy of the response arena,
|
||||||
* needed here for extension handling
|
* needed here for extension handling
|
||||||
* routines, on creation only */
|
* routines, on creation only */
|
||||||
CERTOCSPCertID *certID;
|
CERTOCSPCertID *certID;
|
||||||
SECItem derCertStatus;
|
SECItem derCertStatus;
|
||||||
ocspCertStatus *certStatus; /* local; not part of encoding */
|
ocspCertStatus *certStatus; /* local; not part of encoding */
|
||||||
SECItem thisUpdate; /* a GeneralizedTime */
|
SECItem thisUpdate; /* a GeneralizedTime */
|
||||||
SECItem *nextUpdate; /* a GeneralizedTime */
|
SECItem *nextUpdate; /* a GeneralizedTime */
|
||||||
CERTCertExtension **singleExtensions;
|
CERTCertExtension **singleExtensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -313,10 +310,10 @@ struct CERTOCSPSingleResponseStr {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ocspCertStatus_good, /* cert is not revoked */
|
ocspCertStatus_good, /* cert is not revoked */
|
||||||
ocspCertStatus_revoked, /* cert is revoked */
|
ocspCertStatus_revoked, /* cert is revoked */
|
||||||
ocspCertStatus_unknown, /* cert was unknown to the responder */
|
ocspCertStatus_unknown, /* cert was unknown to the responder */
|
||||||
ocspCertStatus_other /* status was not an expected value */
|
ocspCertStatus_other /* status was not an expected value */
|
||||||
} ocspCertStatusType;
|
} ocspCertStatusType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -327,13 +324,13 @@ typedef enum {
|
||||||
* gives more detailed information.)
|
* gives more detailed information.)
|
||||||
*/
|
*/
|
||||||
struct ocspCertStatusStr {
|
struct ocspCertStatusStr {
|
||||||
ocspCertStatusType certStatusType; /* local; not part of encoding */
|
ocspCertStatusType certStatusType; /* local; not part of encoding */
|
||||||
union {
|
union {
|
||||||
SECItem *goodInfo; /* when ocspCertStatus_good */
|
SECItem *goodInfo; /* when ocspCertStatus_good */
|
||||||
ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
|
ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
|
||||||
SECItem *unknownInfo; /* when ocspCertStatus_unknown */
|
SECItem *unknownInfo; /* when ocspCertStatus_unknown */
|
||||||
SECItem *otherInfo; /* when ocspCertStatus_other */
|
SECItem *otherInfo; /* when ocspCertStatus_other */
|
||||||
} certStatusInfo;
|
} certStatusInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -341,8 +338,8 @@ struct ocspCertStatusStr {
|
||||||
* was revoked and why.
|
* was revoked and why.
|
||||||
*/
|
*/
|
||||||
struct ocspRevokedInfoStr {
|
struct ocspRevokedInfoStr {
|
||||||
SECItem revocationTime; /* a GeneralizedTime */
|
SECItem revocationTime; /* a GeneralizedTime */
|
||||||
SECItem *revocationReason; /* a CRLReason; ignored for now */
|
SECItem *revocationReason; /* a CRLReason; ignored for now */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -353,7 +350,7 @@ struct ocspRevokedInfoStr {
|
||||||
*/
|
*/
|
||||||
struct ocspServiceLocatorStr {
|
struct ocspServiceLocatorStr {
|
||||||
CERTName *issuer;
|
CERTName *issuer;
|
||||||
SECItem locator; /* DER encoded authInfoAccess extension from cert */
|
SECItem locator; /* DER encoded authInfoAccess extension from cert */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _OCSPTI_H_ */
|
#endif /* _OCSPTI_H_ */
|
||||||
|
|
|
@ -12,203 +12,201 @@
|
||||||
SEC_ASN1_MKSUB(SEC_AnyTemplate)
|
SEC_ASN1_MKSUB(SEC_AnyTemplate)
|
||||||
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
|
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
|
||||||
|
|
||||||
extern void PrepareBitStringForEncoding (SECItem *bitMap, SECItem *value);
|
extern void PrepareBitStringForEncoding(SECItem *bitMap, SECItem *value);
|
||||||
|
|
||||||
static const SEC_ASN1Template FullNameTemplate[] = {
|
static const SEC_ASN1Template FullNameTemplate[] = {
|
||||||
{SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
||||||
offsetof (CRLDistributionPoint,derFullName),
|
offsetof(CRLDistributionPoint, derFullName),
|
||||||
CERT_GeneralNamesTemplate}
|
CERT_GeneralNamesTemplate }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template RelativeNameTemplate[] = {
|
static const SEC_ASN1Template RelativeNameTemplate[] = {
|
||||||
{SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
||||||
offsetof (CRLDistributionPoint,distPoint.relativeName),
|
offsetof(CRLDistributionPoint, distPoint.relativeName),
|
||||||
CERT_RDNTemplate}
|
CERT_RDNTemplate }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template DistributionPointNameTemplate[] = {
|
static const SEC_ASN1Template DistributionPointNameTemplate[] = {
|
||||||
{ SEC_ASN1_CHOICE,
|
{ SEC_ASN1_CHOICE,
|
||||||
offsetof(CRLDistributionPoint, distPointType), NULL,
|
offsetof(CRLDistributionPoint, distPointType), NULL,
|
||||||
sizeof(CRLDistributionPoint) },
|
sizeof(CRLDistributionPoint) },
|
||||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
||||||
offsetof (CRLDistributionPoint, derFullName),
|
offsetof(CRLDistributionPoint, derFullName),
|
||||||
CERT_GeneralNamesTemplate, generalName },
|
CERT_GeneralNamesTemplate, generalName },
|
||||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
||||||
offsetof (CRLDistributionPoint, distPoint.relativeName),
|
offsetof(CRLDistributionPoint, distPoint.relativeName),
|
||||||
CERT_RDNTemplate, relativeDistinguishedName },
|
CERT_RDNTemplate, relativeDistinguishedName },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const SEC_ASN1Template CRLDistributionPointTemplate[] = {
|
static const SEC_ASN1Template CRLDistributionPointTemplate[] = {
|
||||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) },
|
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
|
SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
|
||||||
offsetof(CRLDistributionPoint,derDistPoint),
|
offsetof(CRLDistributionPoint, derDistPoint),
|
||||||
SEC_ASN1_SUB(SEC_AnyTemplate)},
|
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
||||||
offsetof(CRLDistributionPoint,bitsmap),
|
offsetof(CRLDistributionPoint, bitsmap),
|
||||||
SEC_ASN1_SUB(SEC_BitStringTemplate) },
|
SEC_ASN1_SUB(SEC_BitStringTemplate) },
|
||||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||||
SEC_ASN1_CONSTRUCTED | 2,
|
SEC_ASN1_CONSTRUCTED | 2,
|
||||||
offsetof(CRLDistributionPoint, derCrlIssuer),
|
offsetof(CRLDistributionPoint, derCrlIssuer),
|
||||||
CERT_GeneralNamesTemplate},
|
CERT_GeneralNamesTemplate },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = {
|
const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = {
|
||||||
{SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate}
|
{ SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate }
|
||||||
};
|
};
|
||||||
|
|
||||||
SECStatus
|
SECStatus
|
||||||
CERT_EncodeCRLDistributionPoints (PLArenaPool *arena,
|
CERT_EncodeCRLDistributionPoints(PLArenaPool *arena,
|
||||||
CERTCrlDistributionPoints *value,
|
CERTCrlDistributionPoints *value,
|
||||||
SECItem *derValue)
|
SECItem *derValue)
|
||||||
{
|
{
|
||||||
CRLDistributionPoint **pointList, *point;
|
CRLDistributionPoint **pointList, *point;
|
||||||
PLArenaPool *ourPool = NULL;
|
PLArenaPool *ourPool = NULL;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
|
|
||||||
PORT_Assert (derValue);
|
PORT_Assert(derValue);
|
||||||
PORT_Assert (value && value->distPoints);
|
PORT_Assert(value && value->distPoints);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ourPool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
|
ourPool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||||
if (ourPool == NULL) {
|
if (ourPool == NULL) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointList = value->distPoints;
|
|
||||||
while (*pointList) {
|
|
||||||
point = *pointList;
|
|
||||||
point->derFullName = NULL;
|
|
||||||
point->derDistPoint.data = NULL;
|
|
||||||
|
|
||||||
switch (point->distPointType) {
|
pointList = value->distPoints;
|
||||||
case generalName:
|
while (*pointList) {
|
||||||
point->derFullName = cert_EncodeGeneralNames
|
point = *pointList;
|
||||||
(ourPool, point->distPoint.fullName);
|
point->derFullName = NULL;
|
||||||
|
point->derDistPoint.data = NULL;
|
||||||
if (!point->derFullName ||
|
|
||||||
!SEC_ASN1EncodeItem (ourPool, &point->derDistPoint,
|
|
||||||
point, FullNameTemplate))
|
|
||||||
rv = SECFailure;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case relativeDistinguishedName:
|
switch (point->distPointType) {
|
||||||
if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
|
case generalName:
|
||||||
point, RelativeNameTemplate))
|
point->derFullName = cert_EncodeGeneralNames(ourPool, point->distPoint.fullName);
|
||||||
rv = SECFailure;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
if (!point->derFullName ||
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
|
||||||
rv = SECFailure;
|
point, FullNameTemplate))
|
||||||
break;
|
rv = SECFailure;
|
||||||
}
|
break;
|
||||||
|
|
||||||
if (rv != SECSuccess)
|
case relativeDistinguishedName:
|
||||||
break;
|
if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
|
||||||
|
point, RelativeNameTemplate))
|
||||||
|
rv = SECFailure;
|
||||||
|
break;
|
||||||
|
|
||||||
if (point->reasons.data)
|
default:
|
||||||
PrepareBitStringForEncoding (&point->bitsmap, &point->reasons);
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
|
rv = SECFailure;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (point->crlIssuer) {
|
if (rv != SECSuccess)
|
||||||
point->derCrlIssuer = cert_EncodeGeneralNames
|
break;
|
||||||
(ourPool, point->crlIssuer);
|
|
||||||
if (!point->derCrlIssuer) {
|
if (point->reasons.data)
|
||||||
rv = SECFailure;
|
PrepareBitStringForEncoding(&point->bitsmap, &point->reasons);
|
||||||
break;
|
|
||||||
}
|
if (point->crlIssuer) {
|
||||||
}
|
point->derCrlIssuer = cert_EncodeGeneralNames(ourPool, point->crlIssuer);
|
||||||
++pointList;
|
if (!point->derCrlIssuer) {
|
||||||
}
|
rv = SECFailure;
|
||||||
if (rv != SECSuccess)
|
break;
|
||||||
break;
|
}
|
||||||
if (!SEC_ASN1EncodeItem(arena, derValue, value,
|
}
|
||||||
CERTCRLDistributionPointsTemplate)) {
|
++pointList;
|
||||||
rv = SECFailure;
|
}
|
||||||
break;
|
if (rv != SECSuccess)
|
||||||
}
|
break;
|
||||||
|
if (!SEC_ASN1EncodeItem(arena, derValue, value,
|
||||||
|
CERTCRLDistributionPointsTemplate)) {
|
||||||
|
rv = SECFailure;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
PORT_FreeArena (ourPool, PR_FALSE);
|
PORT_FreeArena(ourPool, PR_FALSE);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
CERTCrlDistributionPoints *
|
CERTCrlDistributionPoints *
|
||||||
CERT_DecodeCRLDistributionPoints (PLArenaPool *arena, SECItem *encodedValue)
|
CERT_DecodeCRLDistributionPoints(PLArenaPool *arena, SECItem *encodedValue)
|
||||||
{
|
{
|
||||||
CERTCrlDistributionPoints *value = NULL;
|
CERTCrlDistributionPoints *value = NULL;
|
||||||
CRLDistributionPoint **pointList, *point;
|
CRLDistributionPoint **pointList, *point;
|
||||||
SECStatus rv = SECSuccess;
|
SECStatus rv = SECSuccess;
|
||||||
SECItem newEncodedValue;
|
SECItem newEncodedValue;
|
||||||
|
|
||||||
PORT_Assert (arena);
|
PORT_Assert(arena);
|
||||||
do {
|
do {
|
||||||
value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
|
value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the DER into the arena, since Quick DER returns data that points
|
/* copy the DER into the arena, since Quick DER returns data that points
|
||||||
into the DER input, which may get freed by the caller */
|
into the DER input, which may get freed by the caller */
|
||||||
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
|
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
rv = SEC_QuickDERDecodeItem(arena, &value->distPoints,
|
rv = SEC_QuickDERDecodeItem(arena, &value->distPoints,
|
||||||
CERTCRLDistributionPointsTemplate, &newEncodedValue);
|
CERTCRLDistributionPointsTemplate, &newEncodedValue);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pointList = value->distPoints;
|
pointList = value->distPoints;
|
||||||
while (NULL != (point = *pointList)) {
|
while (NULL != (point = *pointList)) {
|
||||||
|
|
||||||
/* get the data if the distributionPointName is not omitted */
|
/* get the data if the distributionPointName is not omitted */
|
||||||
if (point->derDistPoint.data != NULL) {
|
if (point->derDistPoint.data != NULL) {
|
||||||
rv = SEC_QuickDERDecodeItem(arena, point,
|
rv = SEC_QuickDERDecodeItem(arena, point,
|
||||||
DistributionPointNameTemplate, &(point->derDistPoint));
|
DistributionPointNameTemplate, &(point->derDistPoint));
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (point->distPointType) {
|
switch (point->distPointType) {
|
||||||
case generalName:
|
case generalName:
|
||||||
point->distPoint.fullName =
|
point->distPoint.fullName =
|
||||||
cert_DecodeGeneralNames(arena, point->derFullName);
|
cert_DecodeGeneralNames(arena, point->derFullName);
|
||||||
rv = point->distPoint.fullName ? SECSuccess : SECFailure;
|
rv = point->distPoint.fullName ? SECSuccess : SECFailure;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case relativeDistinguishedName:
|
case relativeDistinguishedName:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
break;
|
break;
|
||||||
} /* end switch */
|
} /* end switch */
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
} /* end if */
|
} /* end if */
|
||||||
|
|
||||||
/* Get the reason code if it's not omitted in the encoding */
|
/* Get the reason code if it's not omitted in the encoding */
|
||||||
if (point->bitsmap.data != NULL) {
|
if (point->bitsmap.data != NULL) {
|
||||||
SECItem bitsmap = point->bitsmap;
|
SECItem bitsmap = point->bitsmap;
|
||||||
DER_ConvertBitString(&bitsmap);
|
DER_ConvertBitString(&bitsmap);
|
||||||
rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap);
|
rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap);
|
||||||
if (rv != SECSuccess)
|
if (rv != SECSuccess)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the crl issuer name if it's not omitted in the encoding */
|
/* Get the crl issuer name if it's not omitted in the encoding */
|
||||||
if (point->derCrlIssuer != NULL) {
|
if (point->derCrlIssuer != NULL) {
|
||||||
point->crlIssuer = cert_DecodeGeneralNames(arena,
|
point->crlIssuer = cert_DecodeGeneralNames(arena,
|
||||||
point->derCrlIssuer);
|
point->derCrlIssuer);
|
||||||
if (!point->crlIssuer)
|
if (!point->crlIssuer)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++pointList;
|
++pointList;
|
||||||
} /* end while points remain */
|
} /* end while points remain */
|
||||||
} while (0);
|
} while (0);
|
||||||
return (rv == SECSuccess ? value : NULL);
|
return (rv == SECSuccess ? value : NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
* builtins/anchor.c
|
* builtins/anchor.c
|
||||||
*
|
*
|
||||||
* This file "anchors" the actual cryptoki entry points in this module's
|
* This file "anchors" the actual cryptoki entry points in this module's
|
||||||
* shared library, which is required for dynamic loading. See the
|
* shared library, which is required for dynamic loading. See the
|
||||||
* comments in nssck.api for more information.
|
* comments in nssck.api for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "builtins.h"
|
#include "builtins.h"
|
||||||
|
|
||||||
#define MODULE_NAME builtins
|
#define MODULE_NAME builtins
|
||||||
#define INSTANCE_NAME (NSSCKMDInstance *)&nss_builtins_mdInstance
|
#define INSTANCE_NAME (NSSCKMDInstance *) & nss_builtins_mdInstance
|
||||||
#include "nssck.api"
|
#include "nssck.api"
|
||||||
|
|
|
@ -14,258 +14,250 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct builtinsFOStr {
|
struct builtinsFOStr {
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
CK_ULONG n;
|
CK_ULONG n;
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
builtinsInternalObject **objs;
|
builtinsInternalObject **objs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
builtins_mdFindObjects_Final
|
builtins_mdFindObjects_Final(
|
||||||
(
|
NSSCKMDFindObjects *mdFindObjects,
|
||||||
NSSCKMDFindObjects *mdFindObjects,
|
NSSCKFWFindObjects *fwFindObjects,
|
||||||
NSSCKFWFindObjects *fwFindObjects,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance)
|
||||||
NSSCKFWInstance *fwInstance
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
||||||
NSSArena *arena = fo->arena;
|
NSSArena *arena = fo->arena;
|
||||||
|
|
||||||
nss_ZFreeIf(fo->objs);
|
nss_ZFreeIf(fo->objs);
|
||||||
nss_ZFreeIf(fo);
|
nss_ZFreeIf(fo);
|
||||||
nss_ZFreeIf(mdFindObjects);
|
nss_ZFreeIf(mdFindObjects);
|
||||||
if ((NSSArena *)NULL != arena) {
|
if ((NSSArena *)NULL != arena) {
|
||||||
NSSArena_Destroy(arena);
|
NSSArena_Destroy(arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSSCKMDObject *
|
static NSSCKMDObject *
|
||||||
builtins_mdFindObjects_Next
|
builtins_mdFindObjects_Next(
|
||||||
(
|
NSSCKMDFindObjects *mdFindObjects,
|
||||||
NSSCKMDFindObjects *mdFindObjects,
|
NSSCKFWFindObjects *fwFindObjects,
|
||||||
NSSCKFWFindObjects *fwFindObjects,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
NSSArena *arena,
|
||||||
NSSArena *arena,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
||||||
builtinsInternalObject *io;
|
builtinsInternalObject *io;
|
||||||
|
|
||||||
if( fo->i == fo->n ) {
|
if (fo->i == fo->n) {
|
||||||
*pError = CKR_OK;
|
*pError = CKR_OK;
|
||||||
return (NSSCKMDObject *)NULL;
|
return (NSSCKMDObject *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
io = fo->objs[ fo->i ];
|
io = fo->objs[fo->i];
|
||||||
fo->i++;
|
fo->i++;
|
||||||
|
|
||||||
return nss_builtins_CreateMDObject(arena, io, pError);
|
return nss_builtins_CreateMDObject(arena, io, pError);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest) {
|
builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest)
|
||||||
|
{
|
||||||
unsigned char *start = src;
|
unsigned char *start = src;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (*src ++ != 2) {
|
if (*src++ != 2) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
len = *src++;
|
len = *src++;
|
||||||
if (len & 0x80) {
|
if (len & 0x80) {
|
||||||
int count = len & 0x7f;
|
int count = len & 0x7f;
|
||||||
len =0;
|
len = 0;
|
||||||
|
|
||||||
if (count+2 > size) {
|
if (count + 2 > size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while (count-- > 0) {
|
while (count-- > 0) {
|
||||||
len = (len << 8) | *src++;
|
len = (len << 8) | *src++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len + (src-start) != size) {
|
if (len + (src - start) != size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*dest = src;
|
*dest = src;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_BBOOL
|
static CK_BBOOL
|
||||||
builtins_attrmatch
|
builtins_attrmatch(
|
||||||
(
|
CK_ATTRIBUTE_PTR a,
|
||||||
CK_ATTRIBUTE_PTR a,
|
const NSSItem *b)
|
||||||
const NSSItem *b
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PRBool prb;
|
PRBool prb;
|
||||||
|
|
||||||
if( a->ulValueLen != b->size ) {
|
if (a->ulValueLen != b->size) {
|
||||||
/* match a decoded serial number */
|
/* match a decoded serial number */
|
||||||
if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
|
if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
|
||||||
int len;
|
int len;
|
||||||
unsigned char *data = NULL;
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
len = builtins_derUnwrapInt(b->data,b->size,&data);
|
len = builtins_derUnwrapInt(b->data, b->size, &data);
|
||||||
if (data &&
|
if (data &&
|
||||||
(len == a->ulValueLen) &&
|
(len == a->ulValueLen) &&
|
||||||
nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
|
nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
|
||||||
return CK_TRUE;
|
return CK_TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return CK_FALSE;
|
||||||
}
|
}
|
||||||
return CK_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
|
prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
|
||||||
|
|
||||||
if( PR_TRUE == prb ) {
|
if (PR_TRUE == prb) {
|
||||||
return CK_TRUE;
|
return CK_TRUE;
|
||||||
} else {
|
}
|
||||||
return CK_FALSE;
|
else {
|
||||||
}
|
return CK_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static CK_BBOOL
|
static CK_BBOOL
|
||||||
builtins_match
|
builtins_match(
|
||||||
(
|
CK_ATTRIBUTE_PTR pTemplate,
|
||||||
CK_ATTRIBUTE_PTR pTemplate,
|
CK_ULONG ulAttributeCount,
|
||||||
CK_ULONG ulAttributeCount,
|
builtinsInternalObject *o)
|
||||||
builtinsInternalObject *o
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
|
|
||||||
for( i = 0; i < ulAttributeCount; i++ ) {
|
for (i = 0; i < ulAttributeCount; i++) {
|
||||||
CK_ULONG j;
|
CK_ULONG j;
|
||||||
|
|
||||||
for( j = 0; j < o->n; j++ ) {
|
for (j = 0; j < o->n; j++) {
|
||||||
if( o->types[j] == pTemplate[i].type ) {
|
if (o->types[j] == pTemplate[i].type) {
|
||||||
if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) {
|
if (CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j])) {
|
||||||
return CK_FALSE;
|
return CK_FALSE;
|
||||||
} else {
|
}
|
||||||
break;
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == o->n) {
|
||||||
|
/* Loop ran to the end: no matching attribute */
|
||||||
|
return CK_FALSE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( j == o->n ) {
|
/* Every attribute passed */
|
||||||
/* Loop ran to the end: no matching attribute */
|
return CK_TRUE;
|
||||||
return CK_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Every attribute passed */
|
|
||||||
return CK_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCKMDFindObjects *
|
NSS_IMPLEMENT NSSCKMDFindObjects *
|
||||||
nss_builtins_FindObjectsInit
|
nss_builtins_FindObjectsInit(
|
||||||
(
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
CK_ATTRIBUTE_PTR pTemplate,
|
||||||
CK_ATTRIBUTE_PTR pTemplate,
|
CK_ULONG ulAttributeCount,
|
||||||
CK_ULONG ulAttributeCount,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
/* This could be made more efficient. I'm rather rushed. */
|
/* This could be made more efficient. I'm rather rushed. */
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
|
NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
|
||||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
|
struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 99% of the time we get 0 or 1 matches. So we start with a small
|
* 99% of the time we get 0 or 1 matches. So we start with a small
|
||||||
* stack-allocated array to hold the matches and switch to a heap-allocated
|
* stack-allocated array to hold the matches and switch to a heap-allocated
|
||||||
* array later if the number of matches exceeds STACK_BUF_LENGTH.
|
* array later if the number of matches exceeds STACK_BUF_LENGTH.
|
||||||
*/
|
*/
|
||||||
#define STACK_BUF_LENGTH 1
|
#define STACK_BUF_LENGTH 1
|
||||||
builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
|
builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
|
||||||
builtinsInternalObject **temp = stackTemp;
|
builtinsInternalObject **temp = stackTemp;
|
||||||
PRBool tempIsHeapAllocated = PR_FALSE;
|
PRBool tempIsHeapAllocated = PR_FALSE;
|
||||||
PRUint32 i;
|
PRUint32 i;
|
||||||
|
|
||||||
arena = NSSArena_Create();
|
arena = NSSArena_Create();
|
||||||
if( (NSSArena *)NULL == arena ) {
|
if ((NSSArena *)NULL == arena) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
|
||||||
|
|
||||||
rv = nss_ZNEW(arena, NSSCKMDFindObjects);
|
|
||||||
if( (NSSCKMDFindObjects *)NULL == rv ) {
|
|
||||||
*pError = CKR_HOST_MEMORY;
|
|
||||||
goto loser;
|
|
||||||
}
|
|
||||||
|
|
||||||
fo = nss_ZNEW(arena, struct builtinsFOStr);
|
|
||||||
if( (struct builtinsFOStr *)NULL == fo ) {
|
|
||||||
*pError = CKR_HOST_MEMORY;
|
|
||||||
goto loser;
|
|
||||||
}
|
|
||||||
|
|
||||||
fo->arena = arena;
|
|
||||||
/* fo->n and fo->i are already zero */
|
|
||||||
|
|
||||||
rv->etc = (void *)fo;
|
|
||||||
rv->Final = builtins_mdFindObjects_Final;
|
|
||||||
rv->Next = builtins_mdFindObjects_Next;
|
|
||||||
rv->null = (void *)NULL;
|
|
||||||
|
|
||||||
for( i = 0; i < nss_builtins_nObjects; i++ ) {
|
|
||||||
builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
|
|
||||||
|
|
||||||
if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
|
|
||||||
if( fo->n == STACK_BUF_LENGTH ) {
|
|
||||||
/* Switch from the small stack array to a heap-allocated array large
|
|
||||||
* enough to handle matches in all remaining cases. */
|
|
||||||
temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
|
|
||||||
fo->n + nss_builtins_nObjects - i);
|
|
||||||
if( (builtinsInternalObject **)NULL == temp ) {
|
|
||||||
*pError = CKR_HOST_MEMORY;
|
|
||||||
goto loser;
|
|
||||||
}
|
|
||||||
tempIsHeapAllocated = PR_TRUE;
|
|
||||||
(void)nsslibc_memcpy(temp, stackTemp,
|
|
||||||
sizeof(builtinsInternalObject *) * fo->n);
|
|
||||||
}
|
|
||||||
|
|
||||||
temp[ fo->n ] = o;
|
|
||||||
fo->n++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
|
rv = nss_ZNEW(arena, NSSCKMDFindObjects);
|
||||||
if( (builtinsInternalObject **)NULL == fo->objs ) {
|
if ((NSSCKMDFindObjects *)NULL == rv) {
|
||||||
*pError = CKR_HOST_MEMORY;
|
*pError = CKR_HOST_MEMORY;
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
|
fo = nss_ZNEW(arena, struct builtinsFOStr);
|
||||||
if (tempIsHeapAllocated) {
|
if ((struct builtinsFOStr *)NULL == fo) {
|
||||||
nss_ZFreeIf(temp);
|
*pError = CKR_HOST_MEMORY;
|
||||||
temp = (builtinsInternalObject **)NULL;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
fo->arena = arena;
|
||||||
|
/* fo->n and fo->i are already zero */
|
||||||
|
|
||||||
loser:
|
rv->etc = (void *)fo;
|
||||||
if (tempIsHeapAllocated) {
|
rv->Final = builtins_mdFindObjects_Final;
|
||||||
nss_ZFreeIf(temp);
|
rv->Next = builtins_mdFindObjects_Next;
|
||||||
}
|
rv->null = (void *)NULL;
|
||||||
nss_ZFreeIf(fo);
|
|
||||||
nss_ZFreeIf(rv);
|
for (i = 0; i < nss_builtins_nObjects; i++) {
|
||||||
if ((NSSArena *)NULL != arena) {
|
builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
|
||||||
NSSArena_Destroy(arena);
|
|
||||||
}
|
if (CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o)) {
|
||||||
return (NSSCKMDFindObjects *)NULL;
|
if (fo->n == STACK_BUF_LENGTH) {
|
||||||
|
/* Switch from the small stack array to a heap-allocated array large
|
||||||
|
* enough to handle matches in all remaining cases. */
|
||||||
|
temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
|
||||||
|
fo->n + nss_builtins_nObjects - i);
|
||||||
|
if ((builtinsInternalObject **)NULL == temp) {
|
||||||
|
*pError =
|
||||||
|
CKR_HOST_MEMORY;
|
||||||
|
goto loser;
|
||||||
|
}
|
||||||
|
tempIsHeapAllocated = PR_TRUE;
|
||||||
|
(void)nsslibc_memcpy(temp, stackTemp,
|
||||||
|
sizeof(builtinsInternalObject *) * fo->n);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp[fo->n] = o;
|
||||||
|
fo->n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
|
||||||
|
if ((builtinsInternalObject **)NULL == fo->objs) {
|
||||||
|
*pError = CKR_HOST_MEMORY;
|
||||||
|
goto loser;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
|
||||||
|
if (tempIsHeapAllocated) {
|
||||||
|
nss_ZFreeIf(temp);
|
||||||
|
temp = (builtinsInternalObject **)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
loser:
|
||||||
|
if (tempIsHeapAllocated) {
|
||||||
|
nss_ZFreeIf(temp);
|
||||||
|
}
|
||||||
|
nss_ZFreeIf(fo);
|
||||||
|
nss_ZFreeIf(rv);
|
||||||
|
if ((NSSArena *)NULL != arena) {
|
||||||
|
NSSArena_Destroy(arena);
|
||||||
|
}
|
||||||
|
return (NSSCKMDFindObjects *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
/*
|
/*
|
||||||
* builtins/instance.c
|
* builtins/instance.c
|
||||||
*
|
*
|
||||||
* This file implements the NSSCKMDInstance object for the
|
* This file implements the NSSCKMDInstance object for the
|
||||||
* "builtin objects" cryptoki module.
|
* "builtin objects" cryptoki module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -16,84 +16,72 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static CK_ULONG
|
static CK_ULONG
|
||||||
builtins_mdInstance_GetNSlots
|
builtins_mdInstance_GetNSlots(
|
||||||
(
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return (CK_ULONG)1;
|
return (CK_ULONG)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_VERSION
|
static CK_VERSION
|
||||||
builtins_mdInstance_GetCryptokiVersion
|
builtins_mdInstance_GetCryptokiVersion(
|
||||||
(
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance)
|
||||||
NSSCKFWInstance *fwInstance
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return nss_builtins_CryptokiVersion;
|
return nss_builtins_CryptokiVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSSUTF8 *
|
static NSSUTF8 *
|
||||||
builtins_mdInstance_GetManufacturerID
|
builtins_mdInstance_GetManufacturerID(
|
||||||
(
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return (NSSUTF8 *)nss_builtins_ManufacturerID;
|
return (NSSUTF8 *)nss_builtins_ManufacturerID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSSUTF8 *
|
static NSSUTF8 *
|
||||||
builtins_mdInstance_GetLibraryDescription
|
builtins_mdInstance_GetLibraryDescription(
|
||||||
(
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return (NSSUTF8 *)nss_builtins_LibraryDescription;
|
return (NSSUTF8 *)nss_builtins_LibraryDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_VERSION
|
static CK_VERSION
|
||||||
builtins_mdInstance_GetLibraryVersion
|
builtins_mdInstance_GetLibraryVersion(
|
||||||
(
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance)
|
||||||
NSSCKFWInstance *fwInstance
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
#define NSS_VERSION_VARIABLE __nss_builtins_version
|
#define NSS_VERSION_VARIABLE __nss_builtins_version
|
||||||
#include "verref.h"
|
#include "verref.h"
|
||||||
return nss_builtins_LibraryVersion;
|
return nss_builtins_LibraryVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_RV
|
static CK_RV
|
||||||
builtins_mdInstance_GetSlots
|
builtins_mdInstance_GetSlots(
|
||||||
(
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
NSSCKMDSlot *slots[])
|
||||||
NSSCKMDSlot *slots[]
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
|
slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NSSCKMDInstance
|
const NSSCKMDInstance
|
||||||
nss_builtins_mdInstance = {
|
nss_builtins_mdInstance = {
|
||||||
(void *)NULL, /* etc */
|
(void *)NULL, /* etc */
|
||||||
NULL, /* Initialize */
|
NULL, /* Initialize */
|
||||||
NULL, /* Finalize */
|
NULL, /* Finalize */
|
||||||
builtins_mdInstance_GetNSlots,
|
builtins_mdInstance_GetNSlots,
|
||||||
builtins_mdInstance_GetCryptokiVersion,
|
builtins_mdInstance_GetCryptokiVersion,
|
||||||
builtins_mdInstance_GetManufacturerID,
|
builtins_mdInstance_GetManufacturerID,
|
||||||
builtins_mdInstance_GetLibraryDescription,
|
builtins_mdInstance_GetLibraryDescription,
|
||||||
builtins_mdInstance_GetLibraryVersion,
|
builtins_mdInstance_GetLibraryVersion,
|
||||||
NULL, /* ModuleHandlesSessionObjects -- defaults to false */
|
NULL, /* ModuleHandlesSessionObjects -- defaults to false */
|
||||||
builtins_mdInstance_GetSlots,
|
builtins_mdInstance_GetSlots,
|
||||||
NULL, /* WaitForSlotEvent */
|
NULL, /* WaitForSlotEvent */
|
||||||
(void *)NULL /* null terminator */
|
(void *)NULL /* null terminator */
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,199 +24,183 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static CK_RV
|
static CK_RV
|
||||||
builtins_mdObject_Destroy
|
builtins_mdObject_Destroy(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance)
|
||||||
NSSCKFWInstance *fwInstance
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return CKR_SESSION_READ_ONLY;
|
return CKR_SESSION_READ_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_BBOOL
|
static CK_BBOOL
|
||||||
builtins_mdObject_IsTokenObject
|
builtins_mdObject_IsTokenObject(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance)
|
||||||
NSSCKFWInstance *fwInstance
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return CK_TRUE;
|
return CK_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_ULONG
|
static CK_ULONG
|
||||||
builtins_mdObject_GetAttributeCount
|
builtins_mdObject_GetAttributeCount(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||||
return io->n;
|
return io->n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_RV
|
static CK_RV
|
||||||
builtins_mdObject_GetAttributeTypes
|
builtins_mdObject_GetAttributeTypes(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_ATTRIBUTE_TYPE_PTR typeArray,
|
||||||
CK_ATTRIBUTE_TYPE_PTR typeArray,
|
CK_ULONG ulCount)
|
||||||
CK_ULONG ulCount
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
|
|
||||||
if( io->n != ulCount ) {
|
if (io->n != ulCount) {
|
||||||
return CKR_BUFFER_TOO_SMALL;
|
return CKR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i = 0; i < io->n; i++ ) {
|
for (i = 0; i < io->n; i++) {
|
||||||
typeArray[i] = io->types[i];
|
typeArray[i] = io->types[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_ULONG
|
static CK_ULONG
|
||||||
builtins_mdObject_GetAttributeSize
|
builtins_mdObject_GetAttributeSize(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_ATTRIBUTE_TYPE attribute,
|
||||||
CK_ATTRIBUTE_TYPE attribute,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
|
|
||||||
for( i = 0; i < io->n; i++ ) {
|
for (i = 0; i < io->n; i++) {
|
||||||
if( attribute == io->types[i] ) {
|
if (attribute == io->types[i]) {
|
||||||
return (CK_ULONG)(io->items[i].size);
|
return (CK_ULONG)(io->items[i].size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSSCKFWItem
|
static NSSCKFWItem
|
||||||
builtins_mdObject_GetAttribute
|
builtins_mdObject_GetAttribute(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_ATTRIBUTE_TYPE attribute,
|
||||||
CK_ATTRIBUTE_TYPE attribute,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NSSCKFWItem mdItem;
|
NSSCKFWItem mdItem;
|
||||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
|
|
||||||
mdItem.needsFreeing = PR_FALSE;
|
mdItem.needsFreeing = PR_FALSE;
|
||||||
mdItem.item = (NSSItem*) NULL;
|
mdItem.item = (NSSItem *)NULL;
|
||||||
|
|
||||||
for( i = 0; i < io->n; i++ ) {
|
for (i = 0; i < io->n; i++) {
|
||||||
if( attribute == io->types[i] ) {
|
if (attribute == io->types[i]) {
|
||||||
mdItem.item = (NSSItem*) &io->items[i];
|
mdItem.item = (NSSItem *)&io->items[i];
|
||||||
return mdItem;
|
return mdItem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||||
return mdItem;
|
return mdItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CK_ULONG
|
static CK_ULONG
|
||||||
builtins_mdObject_GetObjectSize
|
builtins_mdObject_GetObjectSize(
|
||||||
(
|
NSSCKMDObject *mdObject,
|
||||||
NSSCKMDObject *mdObject,
|
NSSCKFWObject *fwObject,
|
||||||
NSSCKFWObject *fwObject,
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||||
CK_ULONG i;
|
CK_ULONG i;
|
||||||
CK_ULONG rv = sizeof(CK_ULONG);
|
CK_ULONG rv = sizeof(CK_ULONG);
|
||||||
|
|
||||||
for( i = 0; i < io->n; i++ ) {
|
for (i = 0; i < io->n; i++) {
|
||||||
rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
|
rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const NSSCKMDObject
|
static const NSSCKMDObject
|
||||||
builtins_prototype_mdObject = {
|
builtins_prototype_mdObject = {
|
||||||
(void *)NULL, /* etc */
|
(void *)NULL, /* etc */
|
||||||
NULL, /* Finalize */
|
NULL, /* Finalize */
|
||||||
builtins_mdObject_Destroy,
|
builtins_mdObject_Destroy,
|
||||||
builtins_mdObject_IsTokenObject,
|
builtins_mdObject_IsTokenObject,
|
||||||
builtins_mdObject_GetAttributeCount,
|
builtins_mdObject_GetAttributeCount,
|
||||||
builtins_mdObject_GetAttributeTypes,
|
builtins_mdObject_GetAttributeTypes,
|
||||||
builtins_mdObject_GetAttributeSize,
|
builtins_mdObject_GetAttributeSize,
|
||||||
builtins_mdObject_GetAttribute,
|
builtins_mdObject_GetAttribute,
|
||||||
NULL, /* FreeAttribute */
|
NULL, /* FreeAttribute */
|
||||||
NULL, /* SetAttribute */
|
NULL, /* SetAttribute */
|
||||||
builtins_mdObject_GetObjectSize,
|
builtins_mdObject_GetObjectSize,
|
||||||
(void *)NULL /* null terminator */
|
(void *)NULL /* null terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCKMDObject *
|
NSS_IMPLEMENT NSSCKMDObject *
|
||||||
nss_builtins_CreateMDObject
|
nss_builtins_CreateMDObject(
|
||||||
(
|
NSSArena *arena,
|
||||||
NSSArena *arena,
|
builtinsInternalObject *io,
|
||||||
builtinsInternalObject *io,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if ( (void*)NULL == io->mdObject.etc) {
|
if ((void *)NULL == io->mdObject.etc) {
|
||||||
(void) nsslibc_memcpy(&io->mdObject,&builtins_prototype_mdObject,
|
(void)nsslibc_memcpy(&io->mdObject, &builtins_prototype_mdObject,
|
||||||
sizeof(builtins_prototype_mdObject));
|
sizeof(builtins_prototype_mdObject));
|
||||||
io->mdObject.etc = (void *)io;
|
io->mdObject.etc = (void *)io;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &io->mdObject;
|
return &io->mdObject;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,69 +7,65 @@
|
||||||
/*
|
/*
|
||||||
* builtins/session.c
|
* builtins/session.c
|
||||||
*
|
*
|
||||||
* This file implements the NSSCKMDSession object for the
|
* This file implements the NSSCKMDSession object for the
|
||||||
* "builtin objects" cryptoki module.
|
* "builtin objects" cryptoki module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static NSSCKMDFindObjects *
|
static NSSCKMDFindObjects *
|
||||||
builtins_mdSession_FindObjectsInit
|
builtins_mdSession_FindObjectsInit(
|
||||||
(
|
NSSCKMDSession *mdSession,
|
||||||
NSSCKMDSession *mdSession,
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
NSSCKMDToken *mdToken,
|
||||||
NSSCKMDToken *mdToken,
|
NSSCKFWToken *fwToken,
|
||||||
NSSCKFWToken *fwToken,
|
NSSCKMDInstance *mdInstance,
|
||||||
NSSCKMDInstance *mdInstance,
|
NSSCKFWInstance *fwInstance,
|
||||||
NSSCKFWInstance *fwInstance,
|
CK_ATTRIBUTE_PTR pTemplate,
|
||||||
CK_ATTRIBUTE_PTR pTemplate,
|
CK_ULONG ulAttributeCount,
|
||||||
CK_ULONG ulAttributeCount,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
|
return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSS_IMPLEMENT NSSCKMDSession *
|
NSS_IMPLEMENT NSSCKMDSession *
|
||||||
nss_builtins_CreateSession
|
nss_builtins_CreateSession(
|
||||||
(
|
NSSCKFWSession *fwSession,
|
||||||
NSSCKFWSession *fwSession,
|
CK_RV *pError)
|
||||||
CK_RV *pError
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NSSArena *arena;
|
NSSArena *arena;
|
||||||
NSSCKMDSession *rv;
|
NSSCKMDSession *rv;
|
||||||
|
|
||||||
arena = NSSCKFWSession_GetArena(fwSession, pError);
|
arena = NSSCKFWSession_GetArena(fwSession, pError);
|
||||||
if( (NSSArena *)NULL == arena ) {
|
if ((NSSArena *)NULL == arena) {
|
||||||
return (NSSCKMDSession *)NULL;
|
return (NSSCKMDSession *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nss_ZNEW(arena, NSSCKMDSession);
|
rv = nss_ZNEW(arena, NSSCKMDSession);
|
||||||
if( (NSSCKMDSession *)NULL == rv ) {
|
if ((NSSCKMDSession *)NULL == rv) {
|
||||||
*pError = CKR_HOST_MEMORY;
|
*pError = CKR_HOST_MEMORY;
|
||||||
return (NSSCKMDSession *)NULL;
|
return (NSSCKMDSession *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rv was zeroed when allocated, so we only
|
* rv was zeroed when allocated, so we only
|
||||||
* need to set the non-zero members.
|
* need to set the non-zero members.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rv->etc = (void *)fwSession;
|
rv->etc = (void *)fwSession;
|
||||||
/* rv->Close */
|
/* rv->Close */
|
||||||
/* rv->GetDeviceError */
|
/* rv->GetDeviceError */
|
||||||
/* rv->Login */
|
/* rv->Login */
|
||||||
/* rv->Logout */
|
/* rv->Logout */
|
||||||
/* rv->InitPIN */
|
/* rv->InitPIN */
|
||||||
/* rv->SetPIN */
|
/* rv->SetPIN */
|
||||||
/* rv->GetOperationStateLen */
|
/* rv->GetOperationStateLen */
|
||||||
/* rv->GetOperationState */
|
/* rv->GetOperationState */
|
||||||
/* rv->SetOperationState */
|
/* rv->SetOperationState */
|
||||||
/* rv->CreateObject */
|
/* rv->CreateObject */
|
||||||
/* rv->CopyObject */
|
/* rv->CopyObject */
|
||||||
rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
|
rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
|
||||||
/* rv->SeedRandom */
|
/* rv->SeedRandom */
|
||||||
/* rv->GetRandom */
|
/* rv->GetRandom */
|
||||||
/* rv->null */
|
/* rv->null */
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче