зеркало из 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
|
||||
67a788db9f07822cfef52351bbbe3745dff8bd7f FIREFOX_AURORA_44_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
|
||||
# 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";
|
||||
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 originalValue = envService.get("XPCSHELL_TEST_PROFILE_DIR");
|
||||
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.
|
||||
#--------------------------------------------------------
|
||||
|
||||
46.0a1
|
||||
47.0a1
|
||||
|
|
|
@ -2309,7 +2309,7 @@ public:
|
|||
|
||||
// Rooter class for MozMap; this is what we mostly use in the codegen.
|
||||
template<typename T>
|
||||
class MOZ_RAII MozMapRooter : private JS::CustomAutoRooter
|
||||
class MOZ_RAII MozMapRooter final : private JS::CustomAutoRooter
|
||||
{
|
||||
public:
|
||||
MozMapRooter(JSContext *aCx, MozMap<T>* aMozMap
|
||||
|
|
|
@ -412,8 +412,8 @@ private:
|
|||
|
||||
// Class for easily setting up a rooted typed array object on the stack
|
||||
template<typename ArrayType>
|
||||
class MOZ_RAII RootedTypedArray : public ArrayType,
|
||||
private TypedArrayRooter<ArrayType>
|
||||
class MOZ_RAII RootedTypedArray final : public ArrayType,
|
||||
private TypedArrayRooter<ArrayType>
|
||||
{
|
||||
public:
|
||||
explicit RootedTypedArray(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
|
|
|
@ -549,6 +549,9 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
|||
} else {
|
||||
// StartRemoteDrawingInRegion can mutate mInvalidRegion.
|
||||
mDrawTarget = mWidget->StartRemoteDrawingInRegion(mInvalidRegion);
|
||||
if (!mDrawTarget) {
|
||||
return;
|
||||
}
|
||||
mInvalidRect = mInvalidRegion.GetBounds();
|
||||
if (mInvalidRect.IsEmpty()) {
|
||||
mWidget->EndRemoteDrawingInRegion(mDrawTarget, mInvalidRegion);
|
||||
|
|
|
@ -2087,7 +2087,7 @@ RangeAnalysis::analyzeLoopPhi(MBasicBlock* header, LoopIterationBound* loopBound
|
|||
return;
|
||||
|
||||
if (!phi->range())
|
||||
phi->setRange(new(alloc()) Range());
|
||||
phi->setRange(new(alloc()) Range(phi));
|
||||
|
||||
LinearSum initialSum(alloc());
|
||||
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. */
|
||||
PL_strfree(pwdata.data);
|
||||
}
|
||||
if (email) {
|
||||
PL_strfree(email);
|
||||
}
|
||||
|
||||
/* 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,subPrime) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
|
||||
{ 0, }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* 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;
|
||||
NSSLOWKEYPrivateKey * rsa_private_key;
|
||||
NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
|
||||
NSSLOWKEYRSAKey, };
|
||||
NSSLOWKEYRSAKey };
|
||||
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
|
||||
NSSLOWKEYRSAKey, };
|
||||
NSSLOWKEYRSAKey };
|
||||
|
||||
low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
|
||||
low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
|
||||
|
@ -5610,7 +5610,7 @@ rsa_sigver_test(char *reqfn)
|
|||
SECStatus rv = SECFailure;
|
||||
NSSLOWKEYPublicKey * rsa_public_key;
|
||||
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
|
||||
NSSLOWKEYRSAKey, };
|
||||
NSSLOWKEYRSAKey };
|
||||
|
||||
/* convert to a low RSA public key */
|
||||
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];
|
||||
break;
|
||||
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];
|
||||
break;
|
||||
default:
|
||||
|
@ -232,6 +239,10 @@ prettyPrintObjectID(FILE *out, const unsigned char *data,
|
|||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
if (len == 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
val = data[0];
|
||||
i = val % 40;
|
||||
val = val / 40;
|
||||
|
@ -282,24 +293,17 @@ prettyPrintObjectID(FILE *out, const unsigned char *data,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally, on a new line, print the raw bytes (if requested).
|
||||
*/
|
||||
if (raw) {
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
rv = prettyPrintByte(out, *data++, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
if (raw) {
|
||||
rv = prettyPrintLeaf(out, data, len, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
return prettyNewline(out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *prettyTagType [32] = {
|
||||
|
@ -423,6 +427,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
|
|||
*indefinitep = PR_FALSE;
|
||||
|
||||
lbyte = *data++;
|
||||
lenLen = 1;
|
||||
if (lbyte >= 0x80) {
|
||||
/* Multibyte length */
|
||||
unsigned nb = (unsigned) (lbyte & 0x7f);
|
||||
|
@ -444,7 +449,7 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
|
|||
*lenp = 0;
|
||||
*indefinitep = PR_TRUE;
|
||||
}
|
||||
lenLen = nb + 1;
|
||||
lenLen += nb;
|
||||
if (raw) {
|
||||
unsigned int i;
|
||||
|
||||
|
@ -459,7 +464,6 @@ prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end
|
|||
}
|
||||
} else {
|
||||
*lenp = lbyte;
|
||||
lenLen = 1;
|
||||
if (raw) {
|
||||
rv = prettyPrintByte(out, lbyte, lv);
|
||||
if (rv < 0)
|
||||
|
|
|
@ -420,6 +420,9 @@ SECU_DefaultSSLDir(void)
|
|||
if (!dir)
|
||||
return NULL;
|
||||
|
||||
if (strlen(dir) >= PR_ARRAY_SIZE(sslDir)) {
|
||||
return NULL;
|
||||
}
|
||||
sprintf(sslDir, "%s", dir);
|
||||
|
||||
if (sslDir[strlen(sslDir)-1] == '/')
|
||||
|
@ -3300,6 +3303,7 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
|
|||
errstr = "[unknown usage].";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEC_ERROR_INADEQUATE_CERT_TYPE:
|
||||
flags = (unsigned int)((char *)node->arg - (char *)NULL);
|
||||
switch (flags) {
|
||||
|
@ -3326,6 +3330,7 @@ SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
|
|||
errstr = "[unknown usage].";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEC_ERROR_UNKNOWN_ISSUER:
|
||||
case SEC_ERROR_UNTRUSTED_ISSUER:
|
||||
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
|
||||
|
|
|
@ -154,7 +154,7 @@ testFunctionRef testFnRefTable[] = {
|
|||
{"test_mutex3", test_mutex3},
|
||||
{"test_object", test_object},
|
||||
{"test_oid", test_oid},
|
||||
/* {"test_rwlock", test_rwlock, }*/
|
||||
/* {"test_rwlock", test_rwlock }*/
|
||||
{"test_string", test_string},
|
||||
{"test_string2", test_string2},
|
||||
{"build_chain", build_chain},
|
||||
|
|
|
@ -28,7 +28,7 @@ const SEC_ASN1Template seckey_PQGParamsTemplate[] = {
|
|||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) },
|
||||
{ SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) },
|
||||
{ 0, }
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6,16 +6,36 @@
|
|||
DEPTH = ..
|
||||
# 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 \
|
||||
atob \
|
||||
$(BLTEST_SRCDIR) \
|
||||
btoa \
|
||||
certcgi \
|
||||
certutil \
|
||||
checkcert \
|
||||
chktest \
|
||||
crlutil \
|
||||
crmftest \
|
||||
|
@ -23,8 +43,6 @@ DIRS = lib \
|
|||
derdump \
|
||||
digest \
|
||||
httpserv \
|
||||
$(FIPSTEST_SRCDIR) \
|
||||
$(LOWHASHTEST_SRCDIR) \
|
||||
listsuites \
|
||||
makepqg \
|
||||
multinit \
|
||||
|
@ -47,7 +65,6 @@ DIRS = lib \
|
|||
selfserv \
|
||||
signtool \
|
||||
signver \
|
||||
$(SHLIBSIGN_SRCDIR) \
|
||||
smimetools \
|
||||
ssltap \
|
||||
strsclnt \
|
||||
|
@ -58,6 +75,13 @@ DIRS = lib \
|
|||
vfyserv \
|
||||
modutil \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
DIRS = \
|
||||
$(LIB_SRCDIRS) \
|
||||
$(SOFTOKEN_SRCDIRS) \
|
||||
$(NSS_SRCDIRS)
|
||||
|
||||
TEMPORARILY_DONT_BUILD = \
|
||||
$(NULL)
|
||||
|
|
|
@ -193,8 +193,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
|||
goto loser;
|
||||
}
|
||||
_this->relativePath = PR_Strdup(subval->string);
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
|
||||
/* Absolute directory */
|
||||
} else if( !PORT_Strcasecmp(subpair->key, ABSOLUTE_DIR_STRING)) {
|
||||
|
@ -206,8 +205,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
|||
goto loser;
|
||||
}
|
||||
_this->absolutePath = PR_Strdup(subval->string);
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
|
||||
/* file permissions */
|
||||
} else if( !PORT_Strcasecmp(subpair->key,
|
||||
|
@ -227,8 +225,7 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
|||
goto loser;
|
||||
}
|
||||
gotPerms = PR_TRUE;
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
}
|
||||
} else {
|
||||
if(!PORT_Strcasecmp(val->string, EXECUTABLE_STRING)) {
|
||||
|
@ -260,12 +257,10 @@ Pk11Install_File_Generate(Pk11Install_File* _this,
|
|||
|
||||
loser:
|
||||
if(iter) {
|
||||
Pk11Install_ListIter_delete(iter);
|
||||
PR_Free(iter);
|
||||
Pk11Install_ListIter_delete(&iter);
|
||||
}
|
||||
if(subiter) {
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
}
|
||||
return errStr;
|
||||
}
|
||||
|
@ -636,12 +631,15 @@ Pk11Install_PlatformName_GetVerString(Pk11Install_PlatformName* _this)
|
|||
void
|
||||
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("Digits: ");
|
||||
if(_this->numDigits == 0) {
|
||||
printf("None\n");
|
||||
} 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>");
|
||||
}
|
||||
|
@ -770,9 +768,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
|||
goto loser;
|
||||
}
|
||||
_this->moduleFile = PR_Strdup(subval->string);
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
gotModuleFile = PR_TRUE;
|
||||
} else if(!PORT_Strcasecmp(subpair->key, MODULE_NAME_STRING)){
|
||||
if(gotModuleName) {
|
||||
|
@ -788,9 +784,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
|||
goto loser;
|
||||
}
|
||||
_this->moduleName = PR_Strdup(subval->string);
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
gotModuleName = PR_TRUE;
|
||||
} else if(!PORT_Strcasecmp(subpair->key, MECH_FLAGS_STRING)) {
|
||||
endptr=NULL;
|
||||
|
@ -813,9 +807,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
|||
Pk11Install_PlatformName_GetString(&_this->name));
|
||||
goto loser;
|
||||
}
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter=NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
gotMech = PR_TRUE;
|
||||
} else if(!PORT_Strcasecmp(subpair->key,CIPHER_FLAGS_STRING)) {
|
||||
endptr=NULL;
|
||||
|
@ -838,9 +830,7 @@ Pk11Install_Platform_Generate(Pk11Install_Platform* _this,
|
|||
Pk11Install_PlatformName_GetString(&_this->name));
|
||||
goto loser;
|
||||
}
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter=NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
gotCipher = PR_TRUE;
|
||||
} else if(!PORT_Strcasecmp(subpair->key, FILES_STRING)) {
|
||||
if(gotFiles) {
|
||||
|
@ -1089,9 +1079,7 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
|
|||
}
|
||||
}
|
||||
}
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
} else if(!PORT_Strcasecmp(pair->key, PLATFORMS_STRING)) {
|
||||
subiter = Pk11Install_ListIter_new(pair->list);
|
||||
_this->numPlatforms = pair->list->numPairs;
|
||||
|
@ -1109,9 +1097,7 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
|
|||
}
|
||||
}
|
||||
}
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1192,14 +1178,10 @@ Pk11Install_Info_Generate(Pk11Install_Info* _this,
|
|||
|
||||
loser:
|
||||
if(iter) {
|
||||
Pk11Install_ListIter_delete(iter);
|
||||
PR_Free(iter);
|
||||
iter = NULL;
|
||||
Pk11Install_ListIter_delete(&iter);
|
||||
}
|
||||
if(subiter) {
|
||||
Pk11Install_ListIter_delete(subiter);
|
||||
PR_Free(subiter);
|
||||
subiter = NULL;
|
||||
Pk11Install_ListIter_delete(&subiter);
|
||||
}
|
||||
return errStr;
|
||||
}
|
||||
|
@ -1348,10 +1330,12 @@ Pk11Install_ListIter_new(const Pk11Install_ValueList *_list)
|
|||
|
||||
/****************************************************************************/
|
||||
void
|
||||
Pk11Install_ListIter_delete(Pk11Install_ListIter* _this)
|
||||
Pk11Install_ListIter_delete(Pk11Install_ListIter** _this)
|
||||
{
|
||||
_this->list=NULL;
|
||||
_this->current=NULL;
|
||||
(*_this)->list=NULL;
|
||||
(*_this)->current=NULL;
|
||||
PR_Free(*_this);
|
||||
*_this=NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
|
@ -124,7 +124,7 @@ Pk11Install_ListIter_init(Pk11Install_ListIter* _this);
|
|||
Pk11Install_ListIter*
|
||||
Pk11Install_ListIter_new(const Pk11Install_ValueList* _list);
|
||||
void
|
||||
Pk11Install_ListIter_delete(Pk11Install_ListIter* _this);
|
||||
Pk11Install_ListIter_delete(Pk11Install_ListIter** _this);
|
||||
void
|
||||
Pk11Install_ListIter_reset(Pk11Install_ListIter* _this);
|
||||
Pk11Install_Value*
|
||||
|
|
|
@ -44,8 +44,8 @@ SEC_ASN1Template CERTSignatureDataTemplate[] =
|
|||
offsetof(CERTSignedData,signatureAlgorithm),
|
||||
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
|
||||
{ SEC_ASN1_BIT_STRING,
|
||||
offsetof(CERTSignedData,signature), },
|
||||
{ 0, }
|
||||
offsetof(CERTSignedData,signature) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ EXTRA_SHARED_LIBS += \
|
|||
$(NULL)
|
||||
endif
|
||||
|
||||
ifndef NSS_BUILD_SOFTOKEN_ONLY
|
||||
PKIXLIB = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(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)pkixresults.$(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)
|
||||
|
||||
EXTRA_LIBS += \
|
||||
# breakdown for windows
|
||||
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) \
|
||||
$(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) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)certdb.$(LIB_SUFFIX) \
|
||||
$(SOFTOKENLIB) \
|
||||
$(CRYPTOLIB) \
|
||||
$(NULL)
|
||||
NSS_LIBS_3 = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nsspki.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nssdev.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
|
||||
$(PKIXLIB) \
|
||||
$(DBMLIB) \
|
||||
$(NULL)
|
||||
NSS_LIBS_4 = \
|
||||
$(SQLITE_LIB_DIR)/$(LIB_PREFIX)$(SQLITE_LIB_NAME).$(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)plds4.$(LIB_SUFFIX) \
|
||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
|
||||
$(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)
|
||||
#OS_LIBS += \
|
||||
|
@ -102,30 +168,13 @@ EXTRA_LIBS += \
|
|||
else
|
||||
|
||||
EXTRA_LIBS += \
|
||||
$(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) \
|
||||
$(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) \
|
||||
$(NSS_LIBS_1) \
|
||||
$(SECTOOL_LIB) \
|
||||
$(NSS_LIBS_2) \
|
||||
$(SOFTOKENLIB) \
|
||||
$(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) \
|
||||
$(NSS_LIBS_3) \
|
||||
$(CRYPTOLIB) \
|
||||
$(DBMLIB) \
|
||||
$(PKIXLIB) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nss.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)pk11wrap.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)certhi.$(LIB_SUFFIX) \
|
||||
$(NSS_LIBS_4) \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), AIX)
|
||||
|
|
|
@ -225,6 +225,7 @@ PrintParameterUsage()
|
|||
"-W override default DHE server weak parameters support, 0: disable, 1: enable\n"
|
||||
"-c Restrict ciphers\n"
|
||||
"-Y prints cipher values allowed for parameter -c and exits\n"
|
||||
"-G enables the extended master secret extension [RFC7627]\n"
|
||||
, stderr);
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ void printSecurityInfo(PRFileDesc *fd)
|
|||
{
|
||||
CERTCertificate * cert;
|
||||
const SECItemArray *csa;
|
||||
const SECItem *scts;
|
||||
SSL3Statistics * ssl3stats = SSL_GetStatistics();
|
||||
SECStatus result;
|
||||
SSLChannelInfo channel;
|
||||
|
@ -162,6 +163,11 @@ void printSecurityInfo(PRFileDesc *fd)
|
|||
fprintf(stderr, "Received %d Cert Status items (OCSP stapled data)\n",
|
||||
csa->len);
|
||||
}
|
||||
scts = SSL_PeerSignedCertTimestamps(fd);
|
||||
if (scts && scts->len) {
|
||||
fprintf(stderr, "Received a Signed Certificate Timestamp of length"
|
||||
" %u\n", scts->len);
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
"[-D | -d certdir] [-C] [-b | -R root-module] \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",
|
||||
progName);
|
||||
}
|
||||
|
@ -232,6 +238,7 @@ static void PrintParameterUsage(void)
|
|||
fprintf(stderr, "%-20s Enable compression.\n", "-z");
|
||||
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 signed_certificate_timestamp extension.\n", "-U");
|
||||
fprintf(stderr, "%-20s Enable the extended master secret extension (session hash).\n", "-G");
|
||||
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\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 IPv6 destination address\n", "-6");
|
||||
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)
|
||||
|
@ -920,6 +928,7 @@ int main(int argc, char **argv)
|
|||
int enableCompression = 0;
|
||||
int enableFalseStart = 0;
|
||||
int enableCertStatus = 0;
|
||||
int enableSignedCertTimestamps = 0;
|
||||
int forceFallbackSCSV = 0;
|
||||
int enableExtendedMasterSecret = 0;
|
||||
PRSocketOptionData opt;
|
||||
|
@ -970,7 +979,7 @@ int main(int argc, char **argv)
|
|||
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
|
||||
|
||||
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) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
|
@ -1023,6 +1032,8 @@ int main(int argc, char **argv)
|
|||
|
||||
case 'T': enableCertStatus = 1; break;
|
||||
|
||||
case 'U': enableSignedCertTimestamps = 1; break;
|
||||
|
||||
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
|
||||
enabledVersions, enableSSL2,
|
||||
&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);
|
||||
|
||||
serverCertAuth.dbHandle = CERT_GetDefaultCertDB();
|
||||
|
|
|
@ -104,7 +104,7 @@ endif
|
|||
DLL_SUFFIX = dll
|
||||
|
||||
ifdef NS_USE_GCC
|
||||
OS_CFLAGS += -mwindows -mms-bitfields -Werror
|
||||
OS_CFLAGS += -mwindows -mms-bitfields
|
||||
_GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY)
|
||||
DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB))
|
||||
ifdef BUILD_OPT
|
||||
|
|
|
@ -21,7 +21,7 @@ ifndef WARNING_CFLAGS
|
|||
# and fixing this would require rearchitecture
|
||||
WARNING_CFLAGS += -Qunused-arguments
|
||||
# -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
|
||||
# clang is unable to handle glib's expansion of strcmp and similar for optimized
|
||||
# builds, so ignore the resulting errors.
|
||||
|
|
|
@ -10,3 +10,4 @@
|
|||
*/
|
||||
|
||||
#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.
|
||||
|
||||
These aren't built by default, because they require C++.
|
||||
To build them, set ``NSS_BUILD_GTESTS=1''
|
||||
If your environment doesn't have C++ compiler suitable to build these tests,
|
||||
you may disable them using ``NSS_DISABLE_GTESTS=1''
|
||||
|
||||
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''
|
||||
|
|
|
@ -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). #
|
||||
#######################################################################
|
||||
|
||||
include ../common/gtest.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
|
@ -41,12 +42,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
|||
#######################################################################
|
||||
# (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 = \
|
||||
google_test \
|
||||
pk11_gtest \
|
||||
ssl_gtest \
|
||||
$(NULL)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! 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/.
|
||||
|
@ -20,11 +20,12 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
|||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include ../platlibs.mk
|
||||
include ../common/gtest.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
|
@ -37,12 +38,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
|||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (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 <memory>
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
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 kMasterSecretSize = 48;
|
||||
const size_t kPrfSeedSizeSha256 = 32;
|
||||
|
@ -143,7 +140,7 @@ class TlsPrfTest : public ::testing::Test {
|
|||
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS master_params = {
|
||||
hash_mech,
|
||||
toUcharPtr(kPrfSeed),
|
||||
seed_len,
|
||||
static_cast<CK_ULONG>(seed_len),
|
||||
version
|
||||
};
|
||||
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). #
|
||||
#######################################################################
|
||||
|
||||
include ../../cmd/platlibs.mk
|
||||
include ../common/gtest.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
|
@ -42,19 +42,4 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
|||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
MKPROG = $(CCC)
|
||||
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) {
|
||||
Assign(other.data(), other.len());
|
||||
}
|
||||
|
||||
void Assign(const uint8_t* data, size_t len) {
|
||||
Allocate(len);
|
||||
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len);
|
||||
if (data) {
|
||||
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.
|
||||
|
@ -166,6 +173,15 @@ inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) {
|
|||
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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,6 @@ CPPSRCS = \
|
|||
ssl_agent_unittest.cc \
|
||||
ssl_loopback_unittest.cc \
|
||||
ssl_extension_unittest.cc \
|
||||
ssl_prf_unittest.cc \
|
||||
ssl_skip_unittest.cc \
|
||||
ssl_gtest.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,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
|
|
|
@ -40,7 +40,9 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode, SSLKEAType kea
|
|||
error_code_(0),
|
||||
send_ctr_(0),
|
||||
recv_ctr_(0),
|
||||
expected_read_error_(false) {
|
||||
expected_read_error_(false),
|
||||
handshake_callback_(),
|
||||
auth_certificate_callback_() {
|
||||
|
||||
memset(&info_, 0, sizeof(info_));
|
||||
memset(&csinfo_, 0, sizeof(csinfo_));
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "ssl.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
#include "test_io.h"
|
||||
|
||||
|
@ -28,6 +29,16 @@ enum SessionResumptionMode {
|
|||
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 {
|
||||
public:
|
||||
enum Role { CLIENT, SERVER };
|
||||
|
@ -94,8 +105,12 @@ class TlsAgent : public PollTarget {
|
|||
void CheckExtendedMasterSecret(bool expected);
|
||||
void DisableRollbackDetection();
|
||||
|
||||
Role role() const { return role_; }
|
||||
|
||||
State state() const { return state_; }
|
||||
|
||||
SSLKEAType kea() const { return kea_; }
|
||||
|
||||
const char* state_str() const { return state_str(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_; }
|
||||
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:
|
||||
const static char* states[];
|
||||
|
||||
|
@ -148,6 +172,9 @@ class TlsAgent : public PollTarget {
|
|||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||
agent->CheckPreliminaryInfo();
|
||||
agent->auth_certificate_hook_called_ = true;
|
||||
if (agent->auth_certificate_callback_) {
|
||||
agent->auth_certificate_callback_(*agent, checksig, isServer);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -157,6 +184,9 @@ class TlsAgent : public PollTarget {
|
|||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||
EXPECT_TRUE(agent->expect_client_auth_);
|
||||
EXPECT_TRUE(isServer);
|
||||
if (agent->auth_certificate_callback_) {
|
||||
agent->auth_certificate_callback_(*agent, checksig, isServer);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -208,6 +238,9 @@ class TlsAgent : public PollTarget {
|
|||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||
agent->CheckPreliminaryInfo();
|
||||
agent->handshake_callback_called_ = true;
|
||||
if (agent->handshake_callback_) {
|
||||
agent->handshake_callback_(*agent);
|
||||
}
|
||||
}
|
||||
|
||||
void CheckCallbacks() const;
|
||||
|
@ -237,6 +270,8 @@ class TlsAgent : public PollTarget {
|
|||
size_t send_ctr_;
|
||||
size_t recv_ctr_;
|
||||
bool expected_read_error_;
|
||||
HandshakeCallbackFunction handshake_callback_;
|
||||
AuthCertificateCallbackFunction auth_certificate_callback_;
|
||||
};
|
||||
|
||||
class TlsAgentTestBase : public ::testing::Test {
|
||||
|
|
|
@ -46,6 +46,10 @@ ifndef NSS_DISABLE_DBM
|
|||
DBM_SRCDIR = dbm # Add the dbm directory to DIRS.
|
||||
endif
|
||||
|
||||
ifeq ($(NSS_BUILD_UTIL_ONLY),1)
|
||||
SYSINIT_SRCDIR=
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
@ -62,14 +66,28 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
|||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
ifeq ($(NSS_BUILD_WITHOUT_SOFTOKEN),1)
|
||||
# Not included when building nss without softoken
|
||||
UTIL_SRCDIR =
|
||||
FREEBL_SRCDIR =
|
||||
SOFTOKEN_SRCDIR =
|
||||
ifeq ($(NSS_BUILD_UTIL_ONLY),1)
|
||||
UTIL_SRCDIR = util
|
||||
FREEBL_SRCDIR =
|
||||
SOFTOKEN_SRCDIR =
|
||||
else
|
||||
# default is to include all
|
||||
UTIL_SRCDIR = util
|
||||
FREEBL_SRCDIR = freebl
|
||||
SOFTOKEN_SRCDIR = softoken
|
||||
ifeq ($(NSS_BUILD_SOFTOKEN_ONLY),1)
|
||||
UTIL_SRCDIR =
|
||||
FREEBL_SRCDIR = freebl
|
||||
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
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -32,7 +32,7 @@ typedef struct nssArenaMarkStr nssArenaMark;
|
|||
#ifdef DEBUG
|
||||
/*
|
||||
* ARENA_THREADMARK
|
||||
*
|
||||
*
|
||||
* Optionally, this arena implementation can be compiled with some
|
||||
* runtime checking enabled, which will catch the situation where
|
||||
* one thread "marks" the arena, another thread allocates memory,
|
||||
|
@ -68,14 +68,13 @@ typedef struct nssArenaMarkStr nssArenaMark;
|
|||
|
||||
typedef struct nssListStr nssList;
|
||||
typedef struct nssListIteratorStr nssListIterator;
|
||||
typedef PRBool (* nssListCompareFunc)(void *a, void *b);
|
||||
typedef PRIntn (* nssListSortFunc)(void *a, void *b);
|
||||
typedef void (* nssListElementDestructorFunc)(void *el);
|
||||
typedef PRBool (*nssListCompareFunc)(void *a, void *b);
|
||||
typedef PRIntn (*nssListSortFunc)(void *a, void *b);
|
||||
typedef void (*nssListElementDestructorFunc)(void *el);
|
||||
|
||||
typedef struct nssHashStr nssHash;
|
||||
typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
|
||||
void *value,
|
||||
void *arg);
|
||||
typedef void(PR_CALLBACK *nssHashIterator)(const void *key, void *value,
|
||||
void *arg);
|
||||
|
||||
/*
|
||||
* nssPointerTracker
|
||||
|
@ -89,9 +88,9 @@ typedef void (PR_CALLBACK *nssHashIterator)(const void *key,
|
|||
|
||||
#ifdef DEBUG
|
||||
struct nssPointerTrackerStr {
|
||||
PRCallOnceType once;
|
||||
PZLock *lock;
|
||||
PLHashTable *table;
|
||||
PRCallOnceType once;
|
||||
PZLock *lock;
|
||||
PLHashTable *table;
|
||||
};
|
||||
typedef struct nssPointerTrackerStr nssPointerTracker;
|
||||
#endif /* DEBUG */
|
||||
|
@ -107,16 +106,16 @@ typedef struct nssPointerTrackerStr nssPointerTracker;
|
|||
*/
|
||||
|
||||
enum nssStringTypeEnum {
|
||||
nssStringType_DirectoryString,
|
||||
nssStringType_TeletexString, /* Not "teletext" with trailing 't' */
|
||||
nssStringType_PrintableString,
|
||||
nssStringType_UniversalString,
|
||||
nssStringType_BMPString,
|
||||
nssStringType_UTF8String,
|
||||
nssStringType_PHGString,
|
||||
nssStringType_GeneralString,
|
||||
nssStringType_DirectoryString,
|
||||
nssStringType_TeletexString, /* Not "teletext" with trailing 't' */
|
||||
nssStringType_PrintableString,
|
||||
nssStringType_UniversalString,
|
||||
nssStringType_BMPString,
|
||||
nssStringType_UTF8String,
|
||||
nssStringType_PHGString,
|
||||
nssStringType_GeneralString,
|
||||
|
||||
nssStringType_Unknown = -1
|
||||
nssStringType_Unknown = -1
|
||||
};
|
||||
typedef enum nssStringTypeEnum nssStringType;
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
#endif /* BASE_H */
|
||||
#include <limits.h> /* for UINT_MAX */
|
||||
#include <string.h> /* for memmove */
|
||||
|
||||
|
@ -25,13 +25,13 @@
|
|||
*/
|
||||
|
||||
struct stack_header_str {
|
||||
PRUint16 space;
|
||||
PRUint16 count;
|
||||
PRUint16 space;
|
||||
PRUint16 count;
|
||||
};
|
||||
|
||||
struct error_stack_str {
|
||||
struct stack_header_str header;
|
||||
PRInt32 stack[1];
|
||||
struct stack_header_str header;
|
||||
PRInt32 stack[1];
|
||||
};
|
||||
typedef struct error_stack_str error_stack;
|
||||
|
||||
|
@ -62,9 +62,9 @@ static PRCallOnceType error_call_once;
|
|||
* This is the once-called callback.
|
||||
*/
|
||||
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 *
|
||||
error_get_my_stack ( void)
|
||||
error_get_my_stack(void)
|
||||
{
|
||||
PRStatus st;
|
||||
error_stack *rv;
|
||||
PRUintn new_size;
|
||||
PRUint32 new_bytes;
|
||||
error_stack *new_stack;
|
||||
PRStatus st;
|
||||
error_stack *rv;
|
||||
PRUintn new_size;
|
||||
PRUint32 new_bytes;
|
||||
error_stack *new_stack;
|
||||
|
||||
if( INVALID_TPD_INDEX == error_stack_index ) {
|
||||
st = PR_CallOnce(&error_call_once, error_once_function);
|
||||
if( PR_SUCCESS != st ) {
|
||||
return (error_stack *)NULL;
|
||||
if (INVALID_TPD_INDEX == error_stack_index) {
|
||||
st = PR_CallOnce(&error_call_once, error_once_function);
|
||||
if (PR_SUCCESS != st) {
|
||||
return (error_stack *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
|
||||
if( (error_stack *)NULL == rv ) {
|
||||
/* Doesn't exist; create one */
|
||||
new_size = 16;
|
||||
} else if( rv->header.count == rv->header.space &&
|
||||
rv->header.count < NSS_MAX_ERROR_STACK_COUNT ) {
|
||||
/* Too small, expand it */
|
||||
new_size = PR_MIN( rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
|
||||
} 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);
|
||||
rv = (error_stack *)PR_GetThreadPrivate(error_stack_index);
|
||||
if ((error_stack *)NULL == rv) {
|
||||
/* Doesn't exist; create one */
|
||||
new_size = 16;
|
||||
}
|
||||
else if (rv->header.count == rv->header.space &&
|
||||
rv->header.count < NSS_MAX_ERROR_STACK_COUNT) {
|
||||
/* Too small, expand it */
|
||||
new_size = PR_MIN(rv->header.space * 2, NSS_MAX_ERROR_STACK_COUNT);
|
||||
}
|
||||
else {
|
||||
/* Okay, return it */
|
||||
return rv;
|
||||
}
|
||||
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;
|
||||
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 */
|
||||
PR_SetThreadPrivate(error_stack_index, new_stack);
|
||||
return new_stack;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -151,19 +153,19 @@ error_get_my_stack ( void)
|
|||
*/
|
||||
|
||||
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 ) {
|
||||
return NSS_ERROR_NO_MEMORY; /* Good guess! */
|
||||
}
|
||||
if ((error_stack *)NULL == es) {
|
||||
return NSS_ERROR_NO_MEMORY; /* Good guess! */
|
||||
}
|
||||
|
||||
if( 0 == es->header.count ) {
|
||||
return 0;
|
||||
}
|
||||
if (0 == es->header.count) {
|
||||
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.
|
||||
* NOTE: the caller DOES NOT OWN the memory pointed to by the return
|
||||
* 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
|
||||
* zero-terminated. This routine may return NULL upon error; this
|
||||
* indicates a low-memory situation.
|
||||
|
@ -185,52 +187,53 @@ NSS_GetError ( void)
|
|||
*/
|
||||
|
||||
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 ) {
|
||||
return (PRInt32 *)NULL;
|
||||
}
|
||||
if ((error_stack *)NULL == es) {
|
||||
return (PRInt32 *)NULL;
|
||||
}
|
||||
|
||||
/* Make sure it's terminated */
|
||||
es->stack[ es->header.count ] = 0;
|
||||
/* Make sure it's terminated */
|
||||
es->stack[es->header.count] = 0;
|
||||
|
||||
return es->stack;
|
||||
return es->stack;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* of zero will clear the error stack.
|
||||
*/
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nss_SetError ( PRUint32 error)
|
||||
nss_SetError(PRUint32 error)
|
||||
{
|
||||
error_stack *es;
|
||||
error_stack *es;
|
||||
|
||||
if( 0 == error ) {
|
||||
nss_ClearErrorStack();
|
||||
if (0 == error) {
|
||||
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;
|
||||
}
|
||||
|
||||
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_ClearErrorStack ( void)
|
||||
nss_ClearErrorStack(void)
|
||||
{
|
||||
error_stack *es = error_get_my_stack();
|
||||
if( (error_stack *)NULL == es ) {
|
||||
/* Oh, well. */
|
||||
return;
|
||||
}
|
||||
error_stack *es = error_get_my_stack();
|
||||
if ((error_stack *)NULL == es) {
|
||||
/* Oh, well. */
|
||||
return;
|
||||
}
|
||||
|
||||
es->header.count = 0;
|
||||
es->stack[0] = 0;
|
||||
return;
|
||||
es->header.count = 0;
|
||||
es->stack[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -260,10 +263,10 @@ nss_ClearErrorStack ( void)
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nss_DestroyErrorStack ( void)
|
||||
nss_DestroyErrorStack(void)
|
||||
{
|
||||
if( INVALID_TPD_INDEX != error_stack_index ) {
|
||||
PR_SetThreadPrivate(error_stack_index, NULL);
|
||||
}
|
||||
return;
|
||||
if (INVALID_TPD_INDEX != error_stack_index) {
|
||||
PR_SetThreadPrivate(error_stack_index, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "nssbaset.h"
|
||||
#endif /* NSSBASET_H */
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
const NSSError NSS_ERROR_NO_ERROR = 0;
|
||||
const NSSError NSS_ERROR_INTERNAL_ERROR = 1;
|
||||
const NSSError NSS_ERROR_NO_MEMORY = 2;
|
||||
|
@ -60,3 +62,4 @@ const NSSError NSS_ERROR_ALREADY_INITIALIZED = 37;
|
|||
|
||||
const NSSError NSS_ERROR_PKCS11 = 38;
|
||||
|
||||
/* clang-format on */
|
|
@ -32,48 +32,42 @@
|
|||
*/
|
||||
|
||||
struct nssHashStr {
|
||||
NSSArena *arena;
|
||||
PRBool i_alloced_arena;
|
||||
PRLock *mutex;
|
||||
NSSArena *arena;
|
||||
PRBool i_alloced_arena;
|
||||
PRLock *mutex;
|
||||
|
||||
/*
|
||||
* The invariant that mutex protects is:
|
||||
* The count accurately reflects the hashtable state.
|
||||
*/
|
||||
/*
|
||||
* The invariant that mutex protects is:
|
||||
* The count accurately reflects the hashtable state.
|
||||
*/
|
||||
|
||||
PLHashTable *plHashTable;
|
||||
PRUint32 count;
|
||||
PLHashTable *plHashTable;
|
||||
PRUint32 count;
|
||||
};
|
||||
|
||||
static PLHashNumber
|
||||
nss_identity_hash
|
||||
(
|
||||
const void *key
|
||||
)
|
||||
nss_identity_hash(const void *key)
|
||||
{
|
||||
return (PLHashNumber)((char *)key - (char *)NULL);
|
||||
return (PLHashNumber)((char *)key - (char *)NULL);
|
||||
}
|
||||
|
||||
static PLHashNumber
|
||||
nss_item_hash
|
||||
(
|
||||
const void *key
|
||||
)
|
||||
nss_item_hash(const void *key)
|
||||
{
|
||||
unsigned int i;
|
||||
PLHashNumber h;
|
||||
NSSItem *it = (NSSItem *)key;
|
||||
h = 0;
|
||||
for (i=0; i<it->size; i++)
|
||||
h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i];
|
||||
return h;
|
||||
unsigned int i;
|
||||
PLHashNumber h;
|
||||
NSSItem *it = (NSSItem *)key;
|
||||
h = 0;
|
||||
for (i = 0; i < it->size; i++)
|
||||
h = PR_ROTATE_LEFT32(h, 4) ^ ((unsigned char *)it->data)[i];
|
||||
return h;
|
||||
}
|
||||
|
||||
static int
|
||||
nss_compare_items(const void *v1, const void *v2)
|
||||
{
|
||||
PRStatus ignore;
|
||||
return (int)nssItem_Equal((NSSItem *)v1, (NSSItem *)v2, &ignore);
|
||||
PRStatus 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 *
|
||||
nssHash_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRUint32 numBuckets,
|
||||
PLHashFunction keyHash,
|
||||
PLHashComparator keyCompare,
|
||||
PLHashComparator valueCompare
|
||||
)
|
||||
nssHash_Create(NSSArena *arenaOpt, PRUint32 numBuckets, PLHashFunction keyHash,
|
||||
PLHashComparator keyCompare, PLHashComparator valueCompare)
|
||||
{
|
||||
nssHash *rv;
|
||||
NSSArena *arena;
|
||||
PRBool i_alloced;
|
||||
nssHash *rv;
|
||||
NSSArena *arena;
|
||||
PRBool i_alloced;
|
||||
|
||||
#ifdef NSSDEBUG
|
||||
if( arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (nssHash *)NULL;
|
||||
}
|
||||
if (arenaOpt && PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (nssHash *)NULL;
|
||||
}
|
||||
#endif /* NSSDEBUG */
|
||||
|
||||
if (arenaOpt) {
|
||||
arena = arenaOpt;
|
||||
i_alloced = PR_FALSE;
|
||||
} else {
|
||||
arena = nssArena_Create();
|
||||
i_alloced = PR_TRUE;
|
||||
}
|
||||
if (arenaOpt) {
|
||||
arena = arenaOpt;
|
||||
i_alloced = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
arena = nssArena_Create();
|
||||
i_alloced = PR_TRUE;
|
||||
}
|
||||
|
||||
rv = nss_ZNEW(arena, nssHash);
|
||||
if( (nssHash *)NULL == rv ) {
|
||||
goto loser;
|
||||
}
|
||||
rv = nss_ZNEW(arena, nssHash);
|
||||
if ((nssHash *)NULL == rv) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv->mutex = PZ_NewLock(nssILockOther);
|
||||
if( (PZLock *)NULL == rv->mutex ) {
|
||||
goto loser;
|
||||
}
|
||||
rv->mutex = PZ_NewLock(nssILockOther);
|
||||
if ((PZLock *)NULL == rv->mutex) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv->plHashTable = PL_NewHashTable(numBuckets,
|
||||
keyHash, keyCompare, valueCompare,
|
||||
&nssArenaHashAllocOps, arena);
|
||||
if( (PLHashTable *)NULL == rv->plHashTable ) {
|
||||
(void)PZ_DestroyLock(rv->mutex);
|
||||
goto loser;
|
||||
}
|
||||
rv->plHashTable =
|
||||
PL_NewHashTable(numBuckets, keyHash, keyCompare, valueCompare,
|
||||
&nssArenaHashAllocOps, arena);
|
||||
if ((PLHashTable *)NULL == rv->plHashTable) {
|
||||
(void)PZ_DestroyLock(rv->mutex);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv->count = 0;
|
||||
rv->arena = arena;
|
||||
rv->i_alloced_arena = i_alloced;
|
||||
rv->count = 0;
|
||||
rv->arena = arena;
|
||||
rv->i_alloced_arena = i_alloced;
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
loser:
|
||||
(void)nss_ZFreeIf(rv);
|
||||
return (nssHash *)NULL;
|
||||
(void)nss_ZFreeIf(rv);
|
||||
return (nssHash *)NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -142,14 +131,10 @@ loser:
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT nssHash *
|
||||
nssHash_CreatePointer
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRUint32 numBuckets
|
||||
)
|
||||
nssHash_CreatePointer(NSSArena *arenaOpt, PRUint32 numBuckets)
|
||||
{
|
||||
return nssHash_Create(arenaOpt, numBuckets,
|
||||
nss_identity_hash, PL_CompareValues, PL_CompareValues);
|
||||
return nssHash_Create(arenaOpt, numBuckets, nss_identity_hash,
|
||||
PL_CompareValues, PL_CompareValues);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -157,14 +142,10 @@ nssHash_CreatePointer
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT nssHash *
|
||||
nssHash_CreateString
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRUint32 numBuckets
|
||||
)
|
||||
nssHash_CreateString(NSSArena *arenaOpt, PRUint32 numBuckets)
|
||||
{
|
||||
return nssHash_Create(arenaOpt, numBuckets,
|
||||
PL_HashString, PL_CompareStrings, PL_CompareStrings);
|
||||
return nssHash_Create(arenaOpt, numBuckets, PL_HashString,
|
||||
PL_CompareStrings, PL_CompareStrings);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -172,14 +153,10 @@ nssHash_CreateString
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT nssHash *
|
||||
nssHash_CreateItem
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRUint32 numBuckets
|
||||
)
|
||||
nssHash_CreateItem(NSSArena *arenaOpt, PRUint32 numBuckets)
|
||||
{
|
||||
return nssHash_Create(arenaOpt, numBuckets,
|
||||
nss_item_hash, nss_compare_items, PL_CompareValues);
|
||||
return nssHash_Create(arenaOpt, numBuckets, nss_item_hash,
|
||||
nss_compare_items, PL_CompareValues);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -187,18 +164,16 @@ nssHash_CreateItem
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT void
|
||||
nssHash_Destroy
|
||||
(
|
||||
nssHash *hash
|
||||
)
|
||||
nssHash_Destroy(nssHash *hash)
|
||||
{
|
||||
(void)PZ_DestroyLock(hash->mutex);
|
||||
PL_HashTableDestroy(hash->plHashTable);
|
||||
if (hash->i_alloced_arena) {
|
||||
nssArena_Destroy(hash->arena);
|
||||
} else {
|
||||
nss_ZFreeIf(hash);
|
||||
}
|
||||
(void)PZ_DestroyLock(hash->mutex);
|
||||
PL_HashTableDestroy(hash->plHashTable);
|
||||
if (hash->i_alloced_arena) {
|
||||
nssArena_Destroy(hash->arena);
|
||||
}
|
||||
else {
|
||||
nss_ZFreeIf(hash);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -206,31 +181,28 @@ nssHash_Destroy
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssHash_Add
|
||||
(
|
||||
nssHash *hash,
|
||||
const void *key,
|
||||
const void *value
|
||||
)
|
||||
nssHash_Add(nssHash *hash, const void *key, const void *value)
|
||||
{
|
||||
PRStatus error = PR_FAILURE;
|
||||
PLHashEntry *he;
|
||||
PRStatus error = PR_FAILURE;
|
||||
PLHashEntry *he;
|
||||
|
||||
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;
|
||||
}
|
||||
PZ_Lock(hash->mutex);
|
||||
|
||||
(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
|
||||
nssHash_Remove
|
||||
(
|
||||
nssHash *hash,
|
||||
const void *it
|
||||
)
|
||||
nssHash_Remove(nssHash *hash, const void *it)
|
||||
{
|
||||
PRBool found;
|
||||
PRBool found;
|
||||
|
||||
PZ_Lock(hash->mutex);
|
||||
PZ_Lock(hash->mutex);
|
||||
|
||||
found = PL_HashTableRemove(hash->plHashTable, it);
|
||||
if( found ) {
|
||||
hash->count--;
|
||||
}
|
||||
found = PL_HashTableRemove(hash->plHashTable, it);
|
||||
if (found) {
|
||||
hash->count--;
|
||||
}
|
||||
|
||||
(void)PZ_Unlock(hash->mutex);
|
||||
return;
|
||||
(void)PZ_Unlock(hash->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -262,20 +230,17 @@ nssHash_Remove
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT PRUint32
|
||||
nssHash_Count
|
||||
(
|
||||
nssHash *hash
|
||||
)
|
||||
nssHash_Count(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
|
||||
nssHash_Exists
|
||||
(
|
||||
nssHash *hash,
|
||||
const void *it
|
||||
)
|
||||
nssHash_Exists(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 ) {
|
||||
return PR_FALSE;
|
||||
} else {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if ((void *)NULL == value) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
else {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -309,39 +271,30 @@ nssHash_Exists
|
|||
*
|
||||
*/
|
||||
NSS_IMPLEMENT void *
|
||||
nssHash_Lookup
|
||||
(
|
||||
nssHash *hash,
|
||||
const void *it
|
||||
)
|
||||
nssHash_Lookup(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 {
|
||||
nssHashIterator fcn;
|
||||
void *closure;
|
||||
nssHashIterator fcn;
|
||||
void *closure;
|
||||
};
|
||||
|
||||
static PRIntn
|
||||
nss_hash_enumerator
|
||||
(
|
||||
PLHashEntry *he,
|
||||
PRIntn index,
|
||||
void *arg
|
||||
)
|
||||
nss_hash_enumerator(PLHashEntry *he, PRIntn index, void *arg)
|
||||
{
|
||||
struct arg_str *as = (struct arg_str *)arg;
|
||||
as->fcn(he->key, he->value, as->closure);
|
||||
return HT_ENUMERATE_NEXT;
|
||||
struct arg_str *as = (struct arg_str *)arg;
|
||||
as->fcn(he->key, he->value, as->closure);
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -350,22 +303,17 @@ nss_hash_enumerator
|
|||
* NOTE that the iteration function will be called with the hashtable locked.
|
||||
*/
|
||||
NSS_IMPLEMENT void
|
||||
nssHash_Iterate
|
||||
(
|
||||
nssHash *hash,
|
||||
nssHashIterator fcn,
|
||||
void *closure
|
||||
)
|
||||
nssHash_Iterate(nssHash *hash, nssHashIterator fcn, void *closure)
|
||||
{
|
||||
struct arg_str as;
|
||||
as.fcn = fcn;
|
||||
as.closure = closure;
|
||||
struct arg_str as;
|
||||
as.fcn = fcn;
|
||||
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"
|
||||
#endif /* BASE_H */
|
||||
|
||||
static void * PR_CALLBACK
|
||||
nss_arena_hash_alloc_table
|
||||
(
|
||||
void *pool,
|
||||
PRSize size
|
||||
)
|
||||
static void *PR_CALLBACK
|
||||
nss_arena_hash_alloc_table(void *pool, PRSize size)
|
||||
{
|
||||
NSSArena *arena = (NSSArena *)NULL;
|
||||
NSSArena *arena = (NSSArena *)NULL;
|
||||
|
||||
#ifdef NSSDEBUG
|
||||
if( (void *)NULL != arena ) {
|
||||
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
|
||||
return (void *)NULL;
|
||||
if ((void *)NULL != arena) {
|
||||
if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
|
||||
return (void *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NSSDEBUG */
|
||||
|
||||
return nss_ZAlloc(arena, size);
|
||||
return nss_ZAlloc(arena, size);
|
||||
}
|
||||
|
||||
static void PR_CALLBACK
|
||||
nss_arena_hash_free_table
|
||||
(
|
||||
void *pool,
|
||||
void *item
|
||||
)
|
||||
nss_arena_hash_free_table(void *pool, void *item)
|
||||
{
|
||||
(void)nss_ZFreeIf(item);
|
||||
(void)nss_ZFreeIf(item);
|
||||
}
|
||||
|
||||
static PLHashEntry * PR_CALLBACK
|
||||
nss_arena_hash_alloc_entry
|
||||
(
|
||||
void *pool,
|
||||
const void *key
|
||||
)
|
||||
static PLHashEntry *PR_CALLBACK
|
||||
nss_arena_hash_alloc_entry(void *pool, const void *key)
|
||||
{
|
||||
NSSArena *arena = NULL;
|
||||
NSSArena *arena = NULL;
|
||||
|
||||
#ifdef NSSDEBUG
|
||||
if( (void *)NULL != arena ) {
|
||||
if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
|
||||
return (void *)NULL;
|
||||
if ((void *)NULL != arena) {
|
||||
if (PR_SUCCESS != nssArena_verifyPointer(arena)) {
|
||||
return (void *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NSSDEBUG */
|
||||
|
||||
return nss_ZNEW(arena, PLHashEntry);
|
||||
return nss_ZNEW(arena, PLHashEntry);
|
||||
}
|
||||
|
||||
static void PR_CALLBACK
|
||||
nss_arena_hash_free_entry
|
||||
(
|
||||
void *pool,
|
||||
PLHashEntry *he,
|
||||
PRUintn flag
|
||||
)
|
||||
nss_arena_hash_free_entry(void *pool, PLHashEntry *he, PRUintn flag)
|
||||
{
|
||||
if( HT_FREE_ENTRY == flag ) {
|
||||
(void)nss_ZFreeIf(he);
|
||||
}
|
||||
if (HT_FREE_ENTRY == flag) {
|
||||
(void)nss_ZFreeIf(he);
|
||||
}
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT_DATA PLHashAllocOps
|
||||
nssArenaHashAllocOps = {
|
||||
nss_arena_hash_alloc_table,
|
||||
nss_arena_hash_free_table,
|
||||
nss_arena_hash_alloc_entry,
|
||||
nss_arena_hash_free_entry
|
||||
NSS_IMPLEMENT_DATA PLHashAllocOps nssArenaHashAllocOps = {
|
||||
nss_arena_hash_alloc_table, 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_ARENA_MARKED_BY_ANOTHER_THREAD
|
||||
* NSS_ERROR_INVALID_POINTER
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
* A pointer to an NSSItem upon success
|
||||
* NULL upon failure
|
||||
*/
|
||||
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
nssItem_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
NSSItem *rvOpt,
|
||||
PRUint32 length,
|
||||
const void *data
|
||||
)
|
||||
nssItem_Create(NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length,
|
||||
const void *data)
|
||||
{
|
||||
NSSItem *rv = (NSSItem *)NULL;
|
||||
NSSItem *rv = (NSSItem *)NULL;
|
||||
|
||||
#ifdef DEBUG
|
||||
if( (NSSArena *)NULL != arenaOpt ) {
|
||||
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
|
||||
return (NSSItem *)NULL;
|
||||
if ((NSSArena *)NULL != arenaOpt) {
|
||||
if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
|
||||
return (NSSItem *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (const void *)NULL == data ) {
|
||||
if( length > 0 ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (NSSItem *)NULL;
|
||||
if ((const void *)NULL == data) {
|
||||
if (length > 0) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (NSSItem *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
if( (NSSItem *)NULL == rvOpt ) {
|
||||
rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
|
||||
if( (NSSItem *)NULL == rv ) {
|
||||
goto loser;
|
||||
if ((NSSItem *)NULL == rvOpt) {
|
||||
rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem);
|
||||
if ((NSSItem *)NULL == rv) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = rvOpt;
|
||||
}
|
||||
} else {
|
||||
rv = rvOpt;
|
||||
}
|
||||
|
||||
rv->size = length;
|
||||
rv->data = nss_ZAlloc(arenaOpt, length);
|
||||
if( (void *)NULL == rv->data ) {
|
||||
goto loser;
|
||||
}
|
||||
rv->size = length;
|
||||
rv->data = nss_ZAlloc(arenaOpt, length);
|
||||
if ((void *)NULL == rv->data) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if( length > 0 ) {
|
||||
(void)nsslibc_memcpy(rv->data, data, length);
|
||||
}
|
||||
if (length > 0) {
|
||||
(void)nsslibc_memcpy(rv->data, data, length);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
|
||||
loser:
|
||||
if( rv != rvOpt ) {
|
||||
nss_ZFreeIf(rv);
|
||||
}
|
||||
loser:
|
||||
if (rv != rvOpt) {
|
||||
nss_ZFreeIf(rv);
|
||||
}
|
||||
|
||||
return (NSSItem *)NULL;
|
||||
return (NSSItem *)NULL;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT void
|
||||
nssItem_Destroy
|
||||
(
|
||||
NSSItem *item
|
||||
)
|
||||
nssItem_Destroy(NSSItem *item)
|
||||
{
|
||||
nss_ClearErrorStack();
|
||||
|
||||
nss_ZFreeIf(item->data);
|
||||
nss_ZFreeIf(item);
|
||||
nss_ClearErrorStack();
|
||||
|
||||
nss_ZFreeIf(item->data);
|
||||
nss_ZFreeIf(item);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -106,34 +98,29 @@ nssItem_Destroy
|
|||
* NSS_ERROR_NO_MEMORY
|
||||
* NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD
|
||||
* NSS_ERROR_INVALID_ITEM
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
* A pointer to an NSSItem upon success
|
||||
* NULL upon failure
|
||||
*/
|
||||
|
||||
NSS_IMPLEMENT NSSItem *
|
||||
nssItem_Duplicate
|
||||
(
|
||||
NSSItem *obj,
|
||||
NSSArena *arenaOpt,
|
||||
NSSItem *rvOpt
|
||||
)
|
||||
nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if( (NSSArena *)NULL != arenaOpt ) {
|
||||
if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {
|
||||
return (NSSItem *)NULL;
|
||||
if ((NSSArena *)NULL != arenaOpt) {
|
||||
if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
|
||||
return (NSSItem *)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (NSSItem *)NULL == obj ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
||||
return (NSSItem *)NULL;
|
||||
}
|
||||
if ((NSSItem *)NULL == obj) {
|
||||
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
||||
return (NSSItem *)NULL;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
|
||||
return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -151,18 +138,15 @@ nssItem_Duplicate
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssItem_verifyPointer
|
||||
(
|
||||
const NSSItem *item
|
||||
)
|
||||
nssItem_verifyPointer(const NSSItem *item)
|
||||
{
|
||||
if( ((const NSSItem *)NULL == item) ||
|
||||
(((void *)NULL == item->data) && (item->size > 0)) ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (((const NSSItem *)NULL == item) ||
|
||||
(((void *)NULL == item->data) && (item->size > 0))) {
|
||||
nss_SetError(NSS_ERROR_INVALID_ITEM);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
@ -181,28 +165,23 @@ nssItem_verifyPointer
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRBool
|
||||
nssItem_Equal
|
||||
(
|
||||
const NSSItem *one,
|
||||
const NSSItem *two,
|
||||
PRStatus *statusOpt
|
||||
)
|
||||
nssItem_Equal(const NSSItem *one, const NSSItem *two, PRStatus *statusOpt)
|
||||
{
|
||||
if( (PRStatus *)NULL != statusOpt ) {
|
||||
*statusOpt = PR_SUCCESS;
|
||||
}
|
||||
if ((PRStatus *)NULL != statusOpt) {
|
||||
*statusOpt = PR_SUCCESS;
|
||||
}
|
||||
|
||||
if( ((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two) ) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if( ((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two) ) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if( one->size != two->size ) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (one->size != two->size) {
|
||||
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
|
||||
*
|
||||
* This file contains our wrappers/reimplementations for "standard"
|
||||
* 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
|
||||
* get large. Most string/character stuff should be in utf8.c, not
|
||||
* This file contains our wrappers/reimplementations for "standard"
|
||||
* 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
|
||||
* 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
|
||||
* NSS to include files with angle brackets.
|
||||
*/
|
||||
|
@ -38,21 +38,16 @@
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT void *
|
||||
nsslibc_memcpy
|
||||
(
|
||||
void *dest,
|
||||
const void *source,
|
||||
PRUint32 n
|
||||
)
|
||||
nsslibc_memcpy(void *dest, const void *source, PRUint32 n)
|
||||
{
|
||||
#ifdef NSSDEBUG
|
||||
if( ((void *)NULL == dest) || ((const void *)NULL == source) ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (void *)NULL;
|
||||
}
|
||||
if (((void *)NULL == dest) || ((const void *)NULL == source)) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (void *)NULL;
|
||||
}
|
||||
#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 *
|
||||
nsslibc_memset
|
||||
(
|
||||
void *dest,
|
||||
PRUint8 byte,
|
||||
PRUint32 n
|
||||
)
|
||||
nsslibc_memset(void *dest, PRUint8 byte, PRUint32 n)
|
||||
{
|
||||
#ifdef NSSDEBUG
|
||||
if( ((void *)NULL == dest) ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (void *)NULL;
|
||||
}
|
||||
if (((void *)NULL == dest)) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return (void *)NULL;
|
||||
}
|
||||
#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
|
||||
nsslibc_memequal
|
||||
(
|
||||
const void *a,
|
||||
const void *b,
|
||||
PRUint32 len,
|
||||
PRStatus *statusOpt
|
||||
)
|
||||
nsslibc_memequal(const void *a, const void *b, PRUint32 len,
|
||||
PRStatus *statusOpt)
|
||||
{
|
||||
#ifdef NSSDEBUG
|
||||
if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
if( (PRStatus *)NULL != statusOpt ) {
|
||||
*statusOpt = PR_FAILURE;
|
||||
if ((((void *)NULL == a) || ((void *)NULL == b))) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
if ((PRStatus *)NULL != statusOpt) {
|
||||
*statusOpt = PR_FAILURE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif /* NSSDEBUG */
|
||||
|
||||
if( (PRStatus *)NULL != statusOpt ) {
|
||||
*statusOpt = PR_SUCCESS;
|
||||
}
|
||||
if ((PRStatus *)NULL != statusOpt) {
|
||||
*statusOpt = PR_SUCCESS;
|
||||
}
|
||||
|
||||
if( 0 == memcmp(a, b, len) ) {
|
||||
return PR_TRUE;
|
||||
} else {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (0 == memcmp(a, b, len)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
else {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -131,32 +117,26 @@ nsslibc_memequal
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRInt32
|
||||
nsslibc_memcmp
|
||||
(
|
||||
const void *a,
|
||||
const void *b,
|
||||
PRUint32 len,
|
||||
PRStatus *statusOpt
|
||||
)
|
||||
nsslibc_memcmp(const void *a, const void *b, PRUint32 len, PRStatus *statusOpt)
|
||||
{
|
||||
int v;
|
||||
int v;
|
||||
|
||||
#ifdef NSSDEBUG
|
||||
if( (((void *)NULL == a) || ((void *)NULL == b)) ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
if( (PRStatus *)NULL != statusOpt ) {
|
||||
*statusOpt = PR_FAILURE;
|
||||
if ((((void *)NULL == a) || ((void *)NULL == b))) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
if ((PRStatus *)NULL != statusOpt) {
|
||||
*statusOpt = PR_FAILURE;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
#endif /* NSSDEBUG */
|
||||
|
||||
if( (PRStatus *)NULL != statusOpt ) {
|
||||
*statusOpt = PR_SUCCESS;
|
||||
}
|
||||
if ((PRStatus *)NULL != statusOpt) {
|
||||
*statusOpt = PR_SUCCESS;
|
||||
}
|
||||
|
||||
v = memcmp(a, b, len);
|
||||
return (PRInt32)v;
|
||||
v = memcmp(a, b, len);
|
||||
return (PRInt32)v;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -13,19 +13,19 @@
|
|||
#endif /* BASE_H */
|
||||
|
||||
struct nssListElementStr {
|
||||
PRCList link;
|
||||
void *data;
|
||||
PRCList link;
|
||||
void *data;
|
||||
};
|
||||
|
||||
typedef struct nssListElementStr nssListElement;
|
||||
|
||||
struct nssListStr {
|
||||
NSSArena *arena;
|
||||
PZLock *lock;
|
||||
NSSArena *arena;
|
||||
PZLock *lock;
|
||||
nssListElement *head;
|
||||
PRUint32 count;
|
||||
PRUint32 count;
|
||||
nssListCompareFunc compareFunc;
|
||||
nssListSortFunc sortFunc;
|
||||
nssListSortFunc sortFunc;
|
||||
PRBool i_alloced_arena;
|
||||
};
|
||||
|
||||
|
@ -35,11 +35,13 @@ struct nssListIteratorStr {
|
|||
nssListElement *current;
|
||||
};
|
||||
|
||||
#define NSSLIST_LOCK_IF(list) \
|
||||
if ((list)->lock) PZ_Lock((list)->lock)
|
||||
#define NSSLIST_LOCK_IF(list) \
|
||||
if ((list)->lock) \
|
||||
PZ_Lock((list)->lock)
|
||||
|
||||
#define NSSLIST_UNLOCK_IF(list) \
|
||||
if ((list)->lock) PZ_Unlock((list)->lock)
|
||||
#define NSSLIST_UNLOCK_IF(list) \
|
||||
if ((list)->lock) \
|
||||
PZ_Unlock((list)->lock)
|
||||
|
||||
static PRBool
|
||||
pointer_compare(void *a, void *b)
|
||||
|
@ -54,61 +56,59 @@ nsslist_get_matching_element(nssList *list, void *data)
|
|||
nssListElement *node;
|
||||
node = list->head;
|
||||
if (!node) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
link = &node->link;
|
||||
while (node) {
|
||||
/* using a callback slows things down when it's just compare ... */
|
||||
if (list->compareFunc(node->data, data)) {
|
||||
break;
|
||||
}
|
||||
link = &node->link;
|
||||
if (link == PR_LIST_TAIL(&list->head->link)) {
|
||||
node = NULL;
|
||||
break;
|
||||
}
|
||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
/* using a callback slows things down when it's just compare ... */
|
||||
if (list->compareFunc(node->data, data)) {
|
||||
break;
|
||||
}
|
||||
link = &node->link;
|
||||
if (link == PR_LIST_TAIL(&list->head->link)) {
|
||||
node = NULL;
|
||||
break;
|
||||
}
|
||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT nssList *
|
||||
nssList_Create
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRBool threadSafe
|
||||
)
|
||||
nssList_Create(NSSArena *arenaOpt, PRBool threadSafe)
|
||||
{
|
||||
NSSArena *arena;
|
||||
nssList *list;
|
||||
PRBool i_alloced;
|
||||
if (arenaOpt) {
|
||||
arena = arenaOpt;
|
||||
i_alloced = PR_FALSE;
|
||||
} else {
|
||||
arena = nssArena_Create();
|
||||
i_alloced = PR_TRUE;
|
||||
arena = arenaOpt;
|
||||
i_alloced = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
arena = nssArena_Create();
|
||||
i_alloced = PR_TRUE;
|
||||
}
|
||||
if (!arena) {
|
||||
return (nssList *)NULL;
|
||||
return (nssList *)NULL;
|
||||
}
|
||||
list = nss_ZNEW(arena, nssList);
|
||||
if (!list) {
|
||||
if (!arenaOpt) {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
return (nssList *)NULL;
|
||||
if (!arenaOpt) {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
return (nssList *)NULL;
|
||||
}
|
||||
if (threadSafe) {
|
||||
list->lock = PZ_NewLock(nssILockOther);
|
||||
if (!list->lock) {
|
||||
if (arenaOpt) {
|
||||
nss_ZFreeIf(list);
|
||||
} else {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
return (nssList *)NULL;
|
||||
}
|
||||
list->lock = PZ_NewLock(nssILockOther);
|
||||
if (!list->lock) {
|
||||
if (arenaOpt) {
|
||||
nss_ZFreeIf(list);
|
||||
}
|
||||
else {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
return (nssList *)NULL;
|
||||
}
|
||||
}
|
||||
list->arena = arena;
|
||||
list->i_alloced_arena = i_alloced;
|
||||
|
@ -120,14 +120,14 @@ NSS_IMPLEMENT PRStatus
|
|||
nssList_Destroy(nssList *list)
|
||||
{
|
||||
if (!list->i_alloced_arena) {
|
||||
nssList_Clear(list, NULL);
|
||||
nssList_Clear(list, NULL);
|
||||
}
|
||||
if (list->lock) {
|
||||
(void)PZ_DestroyLock(list->lock);
|
||||
(void)PZ_DestroyLock(list->lock);
|
||||
}
|
||||
if (list->i_alloced_arena) {
|
||||
NSSArena_Destroy(list->arena);
|
||||
list = NULL;
|
||||
NSSArena_Destroy(list->arena);
|
||||
list = NULL;
|
||||
}
|
||||
nss_ZFreeIf(list);
|
||||
return PR_SUCCESS;
|
||||
|
@ -161,13 +161,14 @@ nssList_Clear(nssList *list, nssListElementDestructorFunc destructor)
|
|||
node = list->head;
|
||||
list->head = NULL;
|
||||
while (node && list->count > 0) {
|
||||
if (destructor) (*destructor)(node->data);
|
||||
link = &node->link;
|
||||
tmp = (nssListElement *)PR_NEXT_LINK(link);
|
||||
PR_REMOVE_LINK(link);
|
||||
nss_ZFreeIf(node);
|
||||
node = tmp;
|
||||
--list->count;
|
||||
if (destructor)
|
||||
(*destructor)(node->data);
|
||||
link = &node->link;
|
||||
tmp = (nssListElement *)PR_NEXT_LINK(link);
|
||||
PR_REMOVE_LINK(link);
|
||||
nss_ZFreeIf(node);
|
||||
node = tmp;
|
||||
--list->count;
|
||||
}
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
}
|
||||
|
@ -177,38 +178,41 @@ nsslist_add_element(nssList *list, void *data)
|
|||
{
|
||||
nssListElement *node = nss_ZNEW(list->arena, nssListElement);
|
||||
if (!node) {
|
||||
return PR_FAILURE;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
PR_INIT_CLIST(&node->link);
|
||||
node->data = data;
|
||||
if (list->head) {
|
||||
if (list->sortFunc) {
|
||||
PRCList *link;
|
||||
nssListElement *currNode;
|
||||
currNode = list->head;
|
||||
/* insert in ordered list */
|
||||
while (currNode) {
|
||||
link = &currNode->link;
|
||||
if (list->sortFunc(data, currNode->data) <= 0) {
|
||||
/* new element goes before current node */
|
||||
PR_INSERT_BEFORE(&node->link, link);
|
||||
/* reset head if this is first */
|
||||
if (currNode == list->head) list->head = node;
|
||||
break;
|
||||
}
|
||||
if (link == PR_LIST_TAIL(&list->head->link)) {
|
||||
/* reached end of list, append */
|
||||
PR_INSERT_AFTER(&node->link, link);
|
||||
break;
|
||||
}
|
||||
currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
|
||||
}
|
||||
} else {
|
||||
/* not sorting */
|
||||
PR_APPEND_LINK(&node->link, &list->head->link);
|
||||
}
|
||||
} else {
|
||||
list->head = node;
|
||||
if (list->sortFunc) {
|
||||
PRCList *link;
|
||||
nssListElement *currNode;
|
||||
currNode = list->head;
|
||||
/* insert in ordered list */
|
||||
while (currNode) {
|
||||
link = &currNode->link;
|
||||
if (list->sortFunc(data, currNode->data) <= 0) {
|
||||
/* new element goes before current node */
|
||||
PR_INSERT_BEFORE(&node->link, link);
|
||||
/* reset head if this is first */
|
||||
if (currNode == list->head)
|
||||
list->head = node;
|
||||
break;
|
||||
}
|
||||
if (link == PR_LIST_TAIL(&list->head->link)) {
|
||||
/* reached end of list, append */
|
||||
PR_INSERT_AFTER(&node->link, link);
|
||||
break;
|
||||
}
|
||||
currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* not sorting */
|
||||
PR_APPEND_LINK(&node->link, &list->head->link);
|
||||
}
|
||||
}
|
||||
else {
|
||||
list->head = node;
|
||||
}
|
||||
++list->count;
|
||||
return PR_SUCCESS;
|
||||
|
@ -231,9 +235,9 @@ nssList_AddUnique(nssList *list, void *data)
|
|||
NSSLIST_LOCK_IF(list);
|
||||
node = nsslist_get_matching_element(list, data);
|
||||
if (node) {
|
||||
/* already in, finish */
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return PR_SUCCESS;
|
||||
/* already in, finish */
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
nssrv = nsslist_add_element(list, data);
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
|
@ -247,14 +251,14 @@ nssList_Remove(nssList *list, void *data)
|
|||
NSSLIST_LOCK_IF(list);
|
||||
node = nsslist_get_matching_element(list, data);
|
||||
if (node) {
|
||||
if (node == list->head) {
|
||||
list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
}
|
||||
PR_REMOVE_LINK(&node->link);
|
||||
nss_ZFreeIf(node);
|
||||
if (--list->count == 0) {
|
||||
list->head = NULL;
|
||||
}
|
||||
if (node == list->head) {
|
||||
list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
}
|
||||
PR_REMOVE_LINK(&node->link);
|
||||
nss_ZFreeIf(node);
|
||||
if (--list->count == 0) {
|
||||
list->head = NULL;
|
||||
}
|
||||
}
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return PR_SUCCESS;
|
||||
|
@ -284,16 +288,17 @@ nssList_GetArray(nssList *list, void **rvArray, PRUint32 maxElements)
|
|||
PR_ASSERT(maxElements > 0);
|
||||
node = list->head;
|
||||
if (!node) {
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
NSSLIST_LOCK_IF(list);
|
||||
while (node) {
|
||||
rvArray[i++] = node->data;
|
||||
if (i == maxElements) break;
|
||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
if (node == list->head) {
|
||||
break;
|
||||
}
|
||||
rvArray[i++] = node->data;
|
||||
if (i == maxElements)
|
||||
break;
|
||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
if (node == list->head) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return PR_SUCCESS;
|
||||
|
@ -306,18 +311,18 @@ nssList_Clone(nssList *list)
|
|||
nssListElement *node;
|
||||
rvList = nssList_Create(NULL, (list->lock != NULL));
|
||||
if (!rvList) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
NSSLIST_LOCK_IF(list);
|
||||
if (list->count > 0) {
|
||||
node = list->head;
|
||||
while (PR_TRUE) {
|
||||
nssList_Add(rvList, node->data);
|
||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
if (node == list->head) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = list->head;
|
||||
while (PR_TRUE) {
|
||||
nssList_Add(rvList, node->data);
|
||||
node = (nssListElement *)PR_NEXT_LINK(&node->link);
|
||||
if (node == list->head) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
NSSLIST_UNLOCK_IF(list);
|
||||
return rvList;
|
||||
|
@ -329,21 +334,21 @@ nssList_CreateIterator(nssList *list)
|
|||
nssListIterator *rvIterator;
|
||||
rvIterator = nss_ZNEW(NULL, nssListIterator);
|
||||
if (!rvIterator) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
rvIterator->list = nssList_Clone(list);
|
||||
if (!rvIterator->list) {
|
||||
nss_ZFreeIf(rvIterator);
|
||||
return NULL;
|
||||
nss_ZFreeIf(rvIterator);
|
||||
return NULL;
|
||||
}
|
||||
rvIterator->current = rvIterator->list->head;
|
||||
if (list->lock) {
|
||||
rvIterator->lock = PZ_NewLock(nssILockOther);
|
||||
if (!rvIterator->lock) {
|
||||
nssList_Destroy(rvIterator->list);
|
||||
nss_ZFreeIf(rvIterator);
|
||||
rvIterator = NULL;
|
||||
}
|
||||
rvIterator->lock = PZ_NewLock(nssILockOther);
|
||||
if (!rvIterator->lock) {
|
||||
nssList_Destroy(rvIterator->list);
|
||||
nss_ZFreeIf(rvIterator);
|
||||
rvIterator = NULL;
|
||||
}
|
||||
}
|
||||
return rvIterator;
|
||||
}
|
||||
|
@ -352,7 +357,7 @@ NSS_IMPLEMENT void
|
|||
nssListIterator_Destroy(nssListIterator *iter)
|
||||
{
|
||||
if (iter->lock) {
|
||||
(void)PZ_DestroyLock(iter->lock);
|
||||
(void)PZ_DestroyLock(iter->lock);
|
||||
}
|
||||
nssList_Destroy(iter->list);
|
||||
nss_ZFreeIf(iter);
|
||||
|
@ -363,7 +368,7 @@ nssListIterator_Start(nssListIterator *iter)
|
|||
{
|
||||
NSSLIST_LOCK_IF(iter);
|
||||
if (iter->list->count == 0) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
iter->current = iter->list->head;
|
||||
return iter->current->data;
|
||||
|
@ -375,17 +380,17 @@ nssListIterator_Next(nssListIterator *iter)
|
|||
nssListElement *node;
|
||||
PRCList *link;
|
||||
if (iter->list->count == 1 || iter->current == NULL) {
|
||||
/* Reached the end of the list. Don't change the state, force to
|
||||
* user to call nssList_Finish to clean up.
|
||||
*/
|
||||
return NULL;
|
||||
/* Reached the end of the list. Don't change the state, force to
|
||||
* user to call nssList_Finish to clean up.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
|
||||
link = &node->link;
|
||||
if (link == PR_LIST_TAIL(&iter->list->head->link)) {
|
||||
/* Signal the end of the list. */
|
||||
iter->current = NULL;
|
||||
return node->data;
|
||||
/* Signal the end of the list. */
|
||||
iter->current = NULL;
|
||||
return node->data;
|
||||
}
|
||||
iter->current = node;
|
||||
return node->data;
|
||||
|
@ -397,4 +402,3 @@ nssListIterator_Finish(nssListIterator *iter)
|
|||
iter->current = iter->list->head;
|
||||
return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,7 @@ PR_BEGIN_EXTERN_C
|
|||
* A pointer to an NSSArena upon success
|
||||
*/
|
||||
|
||||
NSS_EXTERN NSSArena *
|
||||
NSSArena_Create
|
||||
(
|
||||
void
|
||||
);
|
||||
NSS_EXTERN NSSArena *NSSArena_Create(void);
|
||||
|
||||
extern const NSSError NSS_ERROR_NO_MEMORY;
|
||||
|
||||
|
@ -56,7 +52,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
|
|||
* NSSArena_Destroy
|
||||
*
|
||||
* 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
|
||||
* create an error stack and return PR_FAILURE.
|
||||
*
|
||||
|
@ -68,11 +64,7 @@ extern const NSSError NSS_ERROR_NO_MEMORY;
|
|||
* PR_FAILURE upon failure
|
||||
*/
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSSArena_Destroy
|
||||
(
|
||||
NSSArena *arena
|
||||
);
|
||||
NSS_EXTERN PRStatus NSSArena_Destroy(NSSArena *arena);
|
||||
|
||||
extern const NSSError NSS_ERROR_INVALID_ARENA;
|
||||
|
||||
|
@ -100,25 +92,21 @@ extern const NSSError NSS_ERROR_INVALID_ARENA;
|
|||
* A nonzero error number
|
||||
*/
|
||||
|
||||
NSS_EXTERN NSSError
|
||||
NSS_GetError
|
||||
(
|
||||
void
|
||||
);
|
||||
NSS_EXTERN NSSError NSS_GetError(void);
|
||||
|
||||
extern const NSSError NSS_ERROR_NO_ERROR;
|
||||
|
||||
/*
|
||||
* NSS_GetErrorStack
|
||||
*
|
||||
* This routine returns a pointer to an array of NSSError values,
|
||||
* containingthe entire sequence or "stack" of errors set by the most
|
||||
* recent NSS library routine called by the same thread calling this
|
||||
* routine. NOTE: the caller DOES NOT OWN the memory pointed to by
|
||||
* the return value. The pointer will remain valid until the calling
|
||||
* thread calls another NSS routine. The lowest-level (most specific)
|
||||
* error is first in the array, and the highest-level is last. The
|
||||
* array is zero-terminated. This routine may return NULL upon error;
|
||||
* This routine returns a pointer to an array of NSSError values,
|
||||
* containingthe entire sequence or "stack" of errors set by the most
|
||||
* recent NSS library routine called by the same thread calling this
|
||||
* routine. NOTE: the caller DOES NOT OWN the memory pointed to by
|
||||
* the return value. The pointer will remain valid until the calling
|
||||
* thread calls another NSS routine. The lowest-level (most specific)
|
||||
* error is first in the array, and the highest-level is last. The
|
||||
* array is zero-terminated. This routine may return NULL upon error;
|
||||
* this indicates a low-memory situation.
|
||||
*
|
||||
* Return value:
|
||||
|
@ -126,21 +114,17 @@ extern const NSSError NSS_ERROR_NO_ERROR;
|
|||
* A NON-caller-owned pointer to an array of NSSError values
|
||||
*/
|
||||
|
||||
NSS_EXTERN NSSError *
|
||||
NSS_GetErrorStack
|
||||
(
|
||||
void
|
||||
);
|
||||
NSS_EXTERN NSSError *NSS_GetErrorStack(void);
|
||||
|
||||
/*
|
||||
* NSS_ZNEW
|
||||
*
|
||||
* This preprocessor macro will allocate memory for a new object
|
||||
* of the specified type with nss_ZAlloc, and will cast the
|
||||
* return value appropriately. If the optional arena argument is
|
||||
* non-null, the memory will be obtained from that arena; otherwise,
|
||||
* 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 value appropriately. If the optional arena argument is
|
||||
* non-null, the memory will be obtained from that arena; otherwise,
|
||||
* the memory will be obtained from the heap. This routine may
|
||||
* return NULL upon error, in which case it will have set an error
|
||||
* upon the error stack.
|
||||
*
|
||||
* The error may be one of the following values:
|
||||
|
@ -152,7 +136,6 @@ NSS_GetErrorStack
|
|||
* 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)))
|
||||
|
||||
/*
|
||||
|
@ -160,10 +143,10 @@ NSS_GetErrorStack
|
|||
*
|
||||
* This preprocessor macro will allocate memory for an array of
|
||||
* new objects, and will cast the return value appropriately.
|
||||
* If the optional arena argument is non-null, the memory will
|
||||
* be obtained from that arena; otherwise, the memory will be
|
||||
* obtained from the heap. This routine may return NULL upon
|
||||
* error, in which case it will have set an error upon the error
|
||||
* If the optional arena argument is non-null, the memory will
|
||||
* be obtained from that arena; otherwise, the memory will be
|
||||
* obtained from the heap. This routine may return NULL upon
|
||||
* error, in which case it will have set an error upon the error
|
||||
* stack. The array size may be specified as zero.
|
||||
*
|
||||
* The error may be one of the following values:
|
||||
|
@ -175,20 +158,19 @@ NSS_GetErrorStack
|
|||
* 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) ((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
|
||||
|
||||
#define NSS_ZNEWARRAY(arenaOpt, type, quantity) \
|
||||
((type *)NSS_ZAlloc((arenaOpt), sizeof(type) * (quantity)))
|
||||
|
||||
/*
|
||||
* 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
|
||||
* the optional arena argument is non-null, the memory will be
|
||||
* obtained from that arena; otherwise, the memory will be obtained
|
||||
* from the heap. This routine may return NULL upon error, in
|
||||
* 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
|
||||
* be expanded by calling NSS_ZRealloc.
|
||||
*
|
||||
|
@ -202,21 +184,16 @@ NSS_GetErrorStack
|
|||
* A pointer to the new segment of zeroed memory
|
||||
*/
|
||||
|
||||
NSS_EXTERN void *
|
||||
NSS_ZAlloc
|
||||
(
|
||||
NSSArena *arenaOpt,
|
||||
PRUint32 size
|
||||
);
|
||||
NSS_EXTERN void *NSS_ZAlloc(NSSArena *arenaOpt, PRUint32 size);
|
||||
|
||||
/*
|
||||
* NSS_ZRealloc
|
||||
*
|
||||
* 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
|
||||
* obtained or released -- is in either case zeroed. This routine
|
||||
* may return NULL upon failure, in which case it will have placed
|
||||
* obtained or released -- is in either case zeroed. This routine
|
||||
* may return NULL upon failure, in which case it will have placed
|
||||
* an error on the error stack.
|
||||
*
|
||||
* The error may be one of the following values:
|
||||
|
@ -229,13 +206,7 @@ NSS_ZAlloc
|
|||
* A pointer to the replacement segment of memory
|
||||
*/
|
||||
|
||||
NSS_EXTERN void *
|
||||
NSS_ZRealloc
|
||||
(
|
||||
void *pointer,
|
||||
PRUint32 newSize
|
||||
);
|
||||
|
||||
NSS_EXTERN void *NSS_ZRealloc(void *pointer, PRUint32 newSize);
|
||||
|
||||
/*
|
||||
* NSS_ZFreeIf
|
||||
|
@ -255,11 +226,7 @@ NSS_ZRealloc
|
|||
* PR_FAILURE
|
||||
*/
|
||||
|
||||
NSS_EXTERN PRStatus
|
||||
NSS_ZFreeIf
|
||||
(
|
||||
void *pointer
|
||||
);
|
||||
NSS_EXTERN PRStatus NSS_ZFreeIf(void *pointer);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
* NSS_EXTERN, NSS_IMPLEMENT, NSS_EXTERN_DATA, NSS_IMPLEMENT_DATA
|
||||
*
|
||||
* 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
|
||||
* of certain OS requirements on platforms not supported by NSS.
|
||||
*/
|
||||
|
||||
#define DUMMY /* dummy */
|
||||
#define NSS_EXTERN extern
|
||||
#define NSS_EXTERN_DATA extern
|
||||
#define NSS_IMPLEMENT
|
||||
#define NSS_IMPLEMENT_DATA
|
||||
#define DUMMY /* dummy */
|
||||
#define NSS_EXTERN extern
|
||||
#define NSS_EXTERN_DATA extern
|
||||
#define NSS_IMPLEMENT
|
||||
#define NSS_IMPLEMENT_DATA
|
||||
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
@ -47,7 +47,7 @@ typedef PRInt32 NSSError;
|
|||
*
|
||||
* Arenas are logical sets of heap memory, from which memory may be
|
||||
* 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.
|
||||
* However, as they are not backed by shared memory, they may only be
|
||||
* used within one process.
|
||||
|
@ -64,12 +64,11 @@ typedef struct NSSArenaStr NSSArena;
|
|||
*/
|
||||
|
||||
struct NSSItemStr {
|
||||
void *data;
|
||||
PRUint32 size;
|
||||
void *data;
|
||||
PRUint32 size;
|
||||
};
|
||||
typedef struct NSSItemStr NSSItem;
|
||||
|
||||
|
||||
/*
|
||||
* NSSBER
|
||||
*
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
/*
|
||||
* tracker.c
|
||||
*
|
||||
*
|
||||
* This file contains the code used by the pointer-tracking calls used
|
||||
* in the debug builds to catch bad pointers. The entire contents are
|
||||
* only available in debug builds (both internal and external builds).
|
||||
|
@ -24,12 +24,9 @@
|
|||
*/
|
||||
|
||||
static PLHashNumber PR_CALLBACK
|
||||
identity_hash
|
||||
(
|
||||
const void *key
|
||||
)
|
||||
identity_hash(const void *key)
|
||||
{
|
||||
return (PLHashNumber)((char *)key - (char *)NULL);
|
||||
return (PLHashNumber)((char *)key - (char *)NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -41,44 +38,38 @@ identity_hash
|
|||
*/
|
||||
|
||||
static PRStatus
|
||||
trackerOnceFunc
|
||||
(
|
||||
void *arg
|
||||
)
|
||||
trackerOnceFunc(void *arg)
|
||||
{
|
||||
nssPointerTracker *tracker = (nssPointerTracker *)arg;
|
||||
nssPointerTracker *tracker = (nssPointerTracker *)arg;
|
||||
|
||||
tracker->lock = PZ_NewLock(nssILockOther);
|
||||
if( (PZLock *)NULL == tracker->lock ) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
tracker->lock = PZ_NewLock(nssILockOther);
|
||||
if ((PZLock *)NULL == tracker->lock) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
tracker->table = PL_NewHashTable(0,
|
||||
identity_hash,
|
||||
PL_CompareValues,
|
||||
PL_CompareValues,
|
||||
(PLHashAllocOps *)NULL,
|
||||
(void *)NULL);
|
||||
if( (PLHashTable *)NULL == tracker->table ) {
|
||||
PZ_DestroyLock(tracker->lock);
|
||||
tracker->lock = (PZLock *)NULL;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
tracker->table =
|
||||
PL_NewHashTable(0, identity_hash, PL_CompareValues, PL_CompareValues,
|
||||
(PLHashAllocOps *)NULL, (void *)NULL);
|
||||
if ((PLHashTable *)NULL == tracker->table) {
|
||||
PZ_DestroyLock(tracker->lock);
|
||||
tracker->lock = (PZLock *)NULL;
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* nssPointerTracker_initialize
|
||||
*
|
||||
* This method is only present in debug builds.
|
||||
*
|
||||
*
|
||||
* This routine initializes an nssPointerTracker object. Note that
|
||||
* the object must have been declared *static* to guarantee that it
|
||||
* is in a zeroed state initially. This routine is idempotent, and
|
||||
* may even be safely called by multiple threads simultaneously with
|
||||
* the same argument. This routine returns a PRStatus value; if
|
||||
* successful, it will return PR_SUCCESS. On failure it will set an
|
||||
* may even be safely called by multiple threads simultaneously with
|
||||
* the same argument. This routine returns a PRStatus value; if
|
||||
* successful, it will return PR_SUCCESS. On failure it will set an
|
||||
* error on the error stack and return PR_FAILURE.
|
||||
*
|
||||
* The error may be one of the following values:
|
||||
|
@ -90,17 +81,14 @@ trackerOnceFunc
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssPointerTracker_initialize
|
||||
(
|
||||
nssPointerTracker *tracker
|
||||
)
|
||||
nssPointerTracker_initialize(nssPointerTracker *tracker)
|
||||
{
|
||||
PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
|
||||
if( PR_SUCCESS != rv ) {
|
||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||
}
|
||||
PRStatus rv = PR_CallOnceWithArg(&tracker->once, trackerOnceFunc, tracker);
|
||||
if (PR_SUCCESS != rv) {
|
||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||
}
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef DONT_DESTROY_EMPTY_TABLES
|
||||
|
@ -114,14 +102,9 @@ nssPointerTracker_initialize
|
|||
*/
|
||||
|
||||
static PRIntn PR_CALLBACK
|
||||
count_entries
|
||||
(
|
||||
PLHashEntry *he,
|
||||
PRIntn index,
|
||||
void *arg
|
||||
)
|
||||
count_entries(PLHashEntry *he, PRIntn index, void *arg)
|
||||
{
|
||||
return HT_ENUMERATE_NEXT;
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
#endif /* DONT_DESTROY_EMPTY_TABLES */
|
||||
|
||||
|
@ -138,7 +121,7 @@ static const PRCallOnceType zero_once;
|
|||
* nssPointerTracker_finalize
|
||||
*
|
||||
* This method is only present in debug builds.
|
||||
*
|
||||
*
|
||||
* This routine returns the nssPointerTracker object to the pre-
|
||||
* initialized state, releasing all resources used by the object.
|
||||
* It will *NOT* destroy the objects being tracked by the pointer
|
||||
|
@ -160,58 +143,54 @@ static const PRCallOnceType zero_once;
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssPointerTracker_finalize
|
||||
(
|
||||
nssPointerTracker *tracker
|
||||
)
|
||||
nssPointerTracker_finalize(nssPointerTracker *tracker)
|
||||
{
|
||||
PZLock *lock;
|
||||
PZLock *lock;
|
||||
|
||||
if( (nssPointerTracker *)NULL == tracker ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((nssPointerTracker *)NULL == tracker) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if( (PZLock *)NULL == tracker->lock ) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((PZLock *)NULL == tracker->lock) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
lock = tracker->lock;
|
||||
PZ_Lock(lock);
|
||||
lock = tracker->lock;
|
||||
PZ_Lock(lock);
|
||||
|
||||
if( (PLHashTable *)NULL == tracker->table ) {
|
||||
PZ_Unlock(lock);
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((PLHashTable *)NULL == tracker->table) {
|
||||
PZ_Unlock(lock);
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef DONT_DESTROY_EMPTY_TABLES
|
||||
/*
|
||||
* I changed my mind; I think we don't want this after all.
|
||||
* Comments?
|
||||
*/
|
||||
count = PL_HashTableEnumerateEntries(tracker->table,
|
||||
count_entries,
|
||||
(void *)NULL);
|
||||
/*
|
||||
* I changed my mind; I think we don't want this after all.
|
||||
* Comments?
|
||||
*/
|
||||
count = PL_HashTableEnumerateEntries(tracker->table, count_entries,
|
||||
(void *)NULL);
|
||||
|
||||
if( 0 != count ) {
|
||||
PZ_Unlock(lock);
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if (0 != count) {
|
||||
PZ_Unlock(lock);
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_EMPTY);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#endif /* DONT_DESTROY_EMPTY_TABLES */
|
||||
|
||||
PL_HashTableDestroy(tracker->table);
|
||||
/* memset(tracker, 0, sizeof(nssPointerTracker)); */
|
||||
tracker->once = zero_once;
|
||||
tracker->lock = (PZLock *)NULL;
|
||||
tracker->table = (PLHashTable *)NULL;
|
||||
PL_HashTableDestroy(tracker->table);
|
||||
/* memset(tracker, 0, sizeof(nssPointerTracker)); */
|
||||
tracker->once = zero_once;
|
||||
tracker->lock = (PZLock *)NULL;
|
||||
tracker->table = (PLHashTable *)NULL;
|
||||
|
||||
PZ_Unlock(lock);
|
||||
PZ_DestroyLock(lock);
|
||||
PZ_Unlock(lock);
|
||||
PZ_DestroyLock(lock);
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -238,63 +217,59 @@ nssPointerTracker_finalize
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssPointerTracker_add
|
||||
(
|
||||
nssPointerTracker *tracker,
|
||||
const void *pointer
|
||||
)
|
||||
nssPointerTracker_add(nssPointerTracker *tracker, const void *pointer)
|
||||
{
|
||||
void *check;
|
||||
PLHashEntry *entry;
|
||||
void *check;
|
||||
PLHashEntry *entry;
|
||||
|
||||
if( (nssPointerTracker *)NULL == tracker ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((nssPointerTracker *)NULL == tracker) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if( (PZLock *)NULL == tracker->lock ) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((PZLock *)NULL == tracker->lock) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
if ((PLHashEntry *)NULL == entry) {
|
||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
entry = PL_HashTableAdd(tracker->table, pointer, (void *)pointer);
|
||||
|
||||
PZ_Unlock(tracker->lock);
|
||||
|
||||
if( (PLHashEntry *)NULL == entry ) {
|
||||
nss_SetError(NSS_ERROR_NO_MEMORY);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nssPointerTracker_remove
|
||||
*
|
||||
* 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
|
||||
* object; rather, this should be called from the object's destructor.
|
||||
* The nssPointerTracker is threadsafe, but this call is not
|
||||
* idempotent. This routine returns a PRStatus value; if successful
|
||||
* it will return PR_SUCCESS. On failure it will set an error on the
|
||||
* The nssPointerTracker is threadsafe, but this call is not
|
||||
* idempotent. This routine returns a PRStatus value; if successful
|
||||
* it will return PR_SUCCESS. On failure it will set an error on the
|
||||
* error stack and return PR_FAILURE.
|
||||
*
|
||||
* The error may be one of the following values:
|
||||
|
@ -308,41 +283,37 @@ nssPointerTracker_add
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssPointerTracker_remove
|
||||
(
|
||||
nssPointerTracker *tracker,
|
||||
const void *pointer
|
||||
)
|
||||
nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer)
|
||||
{
|
||||
PRBool registered;
|
||||
PRBool registered;
|
||||
|
||||
if( (nssPointerTracker *)NULL == tracker ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((nssPointerTracker *)NULL == tracker) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if( (PZLock *)NULL == tracker->lock ) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((PZLock *)NULL == tracker->lock) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
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);
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
registered = PL_HashTableRemove(tracker->table, pointer);
|
||||
PZ_Unlock(tracker->lock);
|
||||
if (!registered) {
|
||||
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if( !registered ) {
|
||||
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -354,10 +325,10 @@ nssPointerTracker_remove
|
|||
* with the nssPointerTracker object. The nssPointerTracker object is
|
||||
* threadsafe, and this call may be safely called from multiple threads
|
||||
* simultaneously with the same arguments. This routine returns a
|
||||
* PRStatus value; if the pointer is registered this will return
|
||||
* PR_SUCCESS. Otherwise it will set an error on the error stack and
|
||||
* return PR_FAILURE. Although the error is suitable for leaving on
|
||||
* the stack, callers may wish to augment the information available by
|
||||
* PRStatus value; if the pointer is registered this will return
|
||||
* PR_SUCCESS. Otherwise it will set an error on the error stack and
|
||||
* return PR_FAILURE. Although the error is suitable for leaving on
|
||||
* the stack, callers may wish to augment the information available by
|
||||
* placing a more type-specific error on the stack.
|
||||
*
|
||||
* The error may be one of the following values:
|
||||
|
@ -371,41 +342,37 @@ nssPointerTracker_remove
|
|||
*/
|
||||
|
||||
NSS_IMPLEMENT PRStatus
|
||||
nssPointerTracker_verify
|
||||
(
|
||||
nssPointerTracker *tracker,
|
||||
const void *pointer
|
||||
)
|
||||
nssPointerTracker_verify(nssPointerTracker *tracker, const void *pointer)
|
||||
{
|
||||
void *check;
|
||||
void *check;
|
||||
|
||||
if( (nssPointerTracker *)NULL == tracker ) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((nssPointerTracker *)NULL == tracker) {
|
||||
nss_SetError(NSS_ERROR_INVALID_POINTER);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if( (PZLock *)NULL == tracker->lock ) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
if ((PZLock *)NULL == tracker->lock) {
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
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);
|
||||
nss_SetError(NSS_ERROR_TRACKER_NOT_INITIALIZED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
check = PL_HashTableLookup(tracker->table, pointer);
|
||||
PZ_Unlock(tracker->lock);
|
||||
if ((void *)NULL == check) {
|
||||
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
if( (void *)NULL == check ) {
|
||||
nss_SetError(NSS_ERROR_POINTER_NOT_REGISTERED);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -5,18 +5,17 @@
|
|||
#ifndef _CERTDB_H_
|
||||
#define _CERTDB_H_
|
||||
|
||||
|
||||
/* common flags for all types of certificates */
|
||||
#define CERTDB_TERMINAL_RECORD (1u<<0)
|
||||
#define CERTDB_TRUSTED (1u<<1)
|
||||
#define CERTDB_SEND_WARN (1u<<2)
|
||||
#define CERTDB_VALID_CA (1u<<3)
|
||||
#define CERTDB_TRUSTED_CA (1u<<4) /* trusted for issuing server certs */
|
||||
#define CERTDB_NS_TRUSTED_CA (1u<<5)
|
||||
#define CERTDB_USER (1u<<6)
|
||||
#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_GOVT_APPROVED_CA (1u<<9) /* can do strong crypto in export ver */
|
||||
#define CERTDB_TERMINAL_RECORD (1u << 0)
|
||||
#define CERTDB_TRUSTED (1u << 1)
|
||||
#define CERTDB_SEND_WARN (1u << 2)
|
||||
#define CERTDB_VALID_CA (1u << 3)
|
||||
#define CERTDB_TRUSTED_CA (1u << 4) /* trusted for issuing server certs */
|
||||
#define CERTDB_NS_TRUSTED_CA (1u << 5)
|
||||
#define CERTDB_USER (1u << 6)
|
||||
#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_GOVT_APPROVED_CA (1u << 9) /* can do strong crypto in export ver */
|
||||
|
||||
/* old usage, to keep old programs compiling */
|
||||
/* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
|
||||
|
@ -26,54 +25,48 @@
|
|||
#if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
|
||||
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
|
||||
#else
|
||||
typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated
|
||||
("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD")));
|
||||
typedef unsigned int __CERTDB_VALID_PEER __attribute__((
|
||||
deprecated("CERTDB_VALID_PEER is now CERTDB_TERMINAL_RECORD")));
|
||||
#endif
|
||||
#define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER) CERTDB_TERMINAL_RECORD)
|
||||
#define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER)CERTDB_TERMINAL_RECORD)
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#pragma deprecated(CERTDB_VALID_PEER)
|
||||
#endif
|
||||
#define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
|
||||
#define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
|
||||
#endif
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
CERTSignedCrl *
|
||||
SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type);
|
||||
CERTSignedCrl *SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey,
|
||||
int type);
|
||||
|
||||
CERTSignedCrl *
|
||||
SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type);
|
||||
CERTSignedCrl *SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey,
|
||||
int type);
|
||||
|
||||
CERTSignedCrl *
|
||||
SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type);
|
||||
CERTSignedCrl *SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl,
|
||||
int type);
|
||||
|
||||
PRBool
|
||||
SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
|
||||
CERTCertDBHandle *handle);
|
||||
CERTSignedCrl *
|
||||
SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
|
||||
PRBool SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
|
||||
CERTCertDBHandle *handle);
|
||||
CERTSignedCrl *SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl,
|
||||
int type);
|
||||
|
||||
SECStatus
|
||||
SEC_DeletePermCRL(CERTSignedCrl *crl);
|
||||
SECStatus SEC_DeletePermCRL(CERTSignedCrl *crl);
|
||||
|
||||
SECStatus SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes,
|
||||
int type);
|
||||
|
||||
SECStatus
|
||||
SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type);
|
||||
SECStatus SEC_DestroyCrl(CERTSignedCrl *crl);
|
||||
|
||||
SECStatus
|
||||
SEC_DestroyCrl(CERTSignedCrl *crl);
|
||||
CERTSignedCrl *SEC_DupCrl(CERTSignedCrl *acrl);
|
||||
|
||||
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);
|
||||
|
||||
PRBool
|
||||
SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
|
||||
PRBool SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old);
|
||||
|
||||
/*
|
||||
** 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)
|
||||
** "notAfter" is the end of the validity period (next update)
|
||||
*/
|
||||
SECStatus
|
||||
SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
|
||||
SECStatus SEC_GetCrlTimes(CERTCrl *crl, PRTime *notBefore, PRTime *notAfter);
|
||||
|
||||
/*
|
||||
** 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
|
||||
** "t" is the time to check against
|
||||
*/
|
||||
SECCertTimeValidity
|
||||
SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
|
||||
SECCertTimeValidity SEC_CheckCrlTimes(CERTCrl *crl, PRTime t);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
|
|
|
@ -38,8 +38,7 @@ struct OpaqueCRLFieldsStr {
|
|||
|
||||
typedef struct PreAllocatorStr PreAllocator;
|
||||
|
||||
struct PreAllocatorStr
|
||||
{
|
||||
struct PreAllocatorStr {
|
||||
PRSize len;
|
||||
void* data;
|
||||
PRSize used;
|
||||
|
@ -56,32 +55,31 @@ struct CRLEntryCacheStr {
|
|||
CRLEntryCache *prev, *next;
|
||||
};
|
||||
|
||||
#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
|
||||
if we have CRL objects with an invalid DER or signature. Can be
|
||||
cleared if the invalid objects are deleted from the token */
|
||||
#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
|
||||
new fetch succeeds */
|
||||
#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set
|
||||
if we have CRL objects with an invalid DER or signature. Can be
|
||||
cleared if the invalid objects are deleted from the token */
|
||||
#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
|
||||
new fetch succeeds */
|
||||
|
||||
#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 */
|
||||
#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 */
|
||||
|
||||
typedef enum {
|
||||
CRL_OriginToken = 0, /* CRL came from PKCS#11 token */
|
||||
CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */
|
||||
CRL_OriginToken = 0, /* CRL came from PKCS#11 token */
|
||||
CRL_OriginExplicit = 1 /* CRL was explicitly added to the cache, from RAM */
|
||||
} CRLOrigin;
|
||||
|
||||
typedef enum {
|
||||
dpcacheNoEntry = 0, /* no entry found for this SN */
|
||||
dpcacheFoundEntry = 1, /* entry found for this SN */
|
||||
dpcacheCallerError = 2, /* invalid args */
|
||||
dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */
|
||||
/* or unverified */
|
||||
dpcacheEmpty = 4, /* no CRL in cache */
|
||||
dpcacheLookupError = 5 /* internal error */
|
||||
dpcacheNoEntry = 0, /* no entry found for this SN */
|
||||
dpcacheFoundEntry = 1, /* entry found for this SN */
|
||||
dpcacheCallerError = 2, /* invalid args */
|
||||
dpcacheInvalidCacheError = 3, /* CRL in cache may be bad DER */
|
||||
/* or unverified */
|
||||
dpcacheEmpty = 4, /* no CRL in cache */
|
||||
dpcacheLookupError = 5 /* internal error */
|
||||
} dpcacheStatus;
|
||||
|
||||
|
||||
struct CachedCrlStr {
|
||||
CERTSignedCrl* crl;
|
||||
CRLOrigin origin;
|
||||
|
@ -98,11 +96,11 @@ struct CachedCrlStr {
|
|||
*/
|
||||
PLHashTable* entries;
|
||||
PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */
|
||||
PRBool sigChecked; /* this CRL signature has already been checked */
|
||||
PRBool sigValid; /* signature verification status .
|
||||
Only meaningful if checked is PR_TRUE . */
|
||||
PRBool unbuildable; /* Avoid using assosiated CRL is it fails
|
||||
* a decoding step */
|
||||
PRBool sigChecked; /* this CRL signature has already been checked */
|
||||
PRBool sigValid; /* signature verification status .
|
||||
Only meaningful if checked is PR_TRUE . */
|
||||
PRBool unbuildable; /* Avoid using assosiated CRL is it fails
|
||||
* a decoding step */
|
||||
};
|
||||
|
||||
/* CRL distribution point cache object
|
||||
|
@ -116,15 +114,15 @@ struct CRLDPCacheStr {
|
|||
#else
|
||||
PRLock* lock;
|
||||
#endif
|
||||
SECItem *issuerDERCert; /* issuer DER cert. Don't hold a reference
|
||||
to the actual cert so the trust can be
|
||||
updated on the cert automatically.
|
||||
XXX there may be multiple issuer certs,
|
||||
with different validity dates. Also
|
||||
need to deal with SKID/AKID . See
|
||||
bugzilla 217387, 233118 */
|
||||
SECItem* issuerDERCert; /* issuer DER cert. Don't hold a reference
|
||||
to the actual cert so the trust can be
|
||||
updated on the cert automatically.
|
||||
XXX there may be multiple issuer certs,
|
||||
with different validity dates. Also
|
||||
need to deal with SKID/AKID . See
|
||||
bugzilla 217387, 233118 */
|
||||
|
||||
CERTCertDBHandle *dbHandle;
|
||||
CERTCertDBHandle* dbHandle;
|
||||
|
||||
SECItem* subject; /* DER of issuer subject */
|
||||
SECItem* distributionPoint; /* DER of distribution point. This may be
|
||||
|
@ -133,31 +131,31 @@ struct CRLDPCacheStr {
|
|||
Currently not used. */
|
||||
|
||||
/* array of full CRLs matching this distribution point */
|
||||
PRUint32 ncrls; /* total number of CRLs in crls */
|
||||
CachedCrl** crls; /* array of all matching CRLs */
|
||||
PRUint32 ncrls; /* total number of CRLs in crls */
|
||||
CachedCrl** crls; /* array of all matching CRLs */
|
||||
/* 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
|
||||
separate list in order to avoid extra lookups, decodes, and copies */
|
||||
|
||||
/* 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
|
||||
/* for future use */
|
||||
PRInt32 numdeltas; /* number of delta CRLs used for the cache */
|
||||
CachedCrl** deltas; /* delta CRLs used for the cache */
|
||||
#endif
|
||||
/* cache invalidity bitflag */
|
||||
PRUint16 invalid; /* this state will be set if either
|
||||
CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
|
||||
In those cases, all certs are considered to have unknown status.
|
||||
The invalid state can only be cleared during an update if all
|
||||
error states are cleared */
|
||||
PRBool refresh; /* manual refresh from tokens has been forced */
|
||||
PRBool mustchoose; /* trigger reselection algorithm, for case when
|
||||
RAM CRL objects are dropped from the cache */
|
||||
PRTime lastfetch; /* time a CRL token fetch was last performed */
|
||||
PRTime lastcheck; /* time CRL token objects were last checked for
|
||||
existence */
|
||||
PRUint16 invalid; /* this state will be set if either
|
||||
CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set.
|
||||
In those cases, all certs are considered to have unknown status.
|
||||
The invalid state can only be cleared during an update if all
|
||||
error states are cleared */
|
||||
PRBool refresh; /* manual refresh from tokens has been forced */
|
||||
PRBool mustchoose; /* trigger reselection algorithm, for case when
|
||||
RAM CRL objects are dropped from the cache */
|
||||
PRTime lastfetch; /* time a CRL token fetch was last performed */
|
||||
PRTime lastcheck; /* time CRL token objects were last checked for
|
||||
existence */
|
||||
};
|
||||
|
||||
/* CRL issuer cache object
|
||||
|
@ -168,7 +166,7 @@ struct CRLDPCacheStr {
|
|||
*/
|
||||
|
||||
struct CRLIssuerCacheStr {
|
||||
SECItem* subject; /* DER of issuer subject */
|
||||
SECItem* subject; /* DER of issuer subject */
|
||||
CRLDPCache* dpp;
|
||||
};
|
||||
|
||||
|
@ -194,46 +192,40 @@ SECStatus ShutdownCRLCache(void);
|
|||
** null-terminated strings, terminated by a zero-length string.
|
||||
** 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
|
||||
* and to keep track of the checks for user certificates in each slot
|
||||
*/
|
||||
SECStatus
|
||||
cert_CreateSubjectKeyIDHashTable(void);
|
||||
SECStatus cert_CreateSubjectKeyIDHashTable(void);
|
||||
|
||||
SECStatus
|
||||
cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert);
|
||||
SECStatus cert_AddSubjectKeyIDMapping(SECItem* subjKeyID,
|
||||
CERTCertificate* cert);
|
||||
|
||||
SECStatus
|
||||
cert_UpdateSubjectKeyIDSlotCheck(SECItem *slotid, int series);
|
||||
SECStatus cert_UpdateSubjectKeyIDSlotCheck(SECItem* slotid, int series);
|
||||
|
||||
int
|
||||
cert_SubjectKeyIDSlotCheckSeries(SECItem *slotid);
|
||||
int cert_SubjectKeyIDSlotCheckSeries(SECItem* slotid);
|
||||
|
||||
/*
|
||||
* Call this function to remove an entry from the mapping table.
|
||||
*/
|
||||
SECStatus
|
||||
cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID);
|
||||
SECStatus cert_RemoveSubjectKeyIDMapping(SECItem* subjKeyID);
|
||||
|
||||
SECStatus
|
||||
cert_DestroySubjectKeyIDHashTable(void);
|
||||
SECStatus cert_DestroySubjectKeyIDHashTable(void);
|
||||
|
||||
SECItem*
|
||||
cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID);
|
||||
SECItem* cert_FindDERCertBySubjectKeyID(SECItem* subjKeyID);
|
||||
|
||||
/* return maximum length of AVA value based on its type OID tag. */
|
||||
extern int cert_AVAOidTagToMaxLen(SECOidTag tag);
|
||||
|
||||
/* Make an AVA, allocated from pool, from OID and DER encoded value */
|
||||
extern CERTAVA * CERT_CreateAVAFromRaw(PLArenaPool *pool,
|
||||
const SECItem * OID, const SECItem * value);
|
||||
extern CERTAVA* CERT_CreateAVAFromRaw(PLArenaPool* pool, const SECItem* OID,
|
||||
const SECItem* value);
|
||||
|
||||
/* Make an AVA from binary input specified by SECItem */
|
||||
extern CERTAVA * CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind,
|
||||
int valueType, SECItem *value);
|
||||
extern CERTAVA* CERT_CreateAVAFromSECItem(PLArenaPool* arena, SECOidTag kind,
|
||||
int valueType, SECItem* value);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* flags are defined immediately below.
|
||||
*/
|
||||
SECStatus
|
||||
cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
PRBool checkSig, SECCertUsage certUsage, PRTime t,
|
||||
PRUint32 flags, void *wincx, CERTVerifyLog *log);
|
||||
SECStatus cert_VerifyCertWithFlags(CERTCertDBHandle* handle,
|
||||
CERTCertificate* cert, PRBool checkSig,
|
||||
SECCertUsage certUsage, PRTime t,
|
||||
PRUint32 flags, void* wincx,
|
||||
CERTVerifyLog* log);
|
||||
|
||||
/* Use the default settings.
|
||||
* cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS, ...) is
|
||||
|
@ -281,15 +274,10 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
|
||||
/* Interface function for libpkix cert validation engine:
|
||||
* cert_verify wrapper. */
|
||||
SECStatus
|
||||
cert_VerifyCertChainPkix(CERTCertificate *cert,
|
||||
PRBool checkSig,
|
||||
SECCertUsage requiredUsage,
|
||||
PRTime time,
|
||||
void *wincx,
|
||||
CERTVerifyLog *log,
|
||||
PRBool *sigError,
|
||||
PRBool *revoked);
|
||||
SECStatus cert_VerifyCertChainPkix(CERTCertificate* cert, PRBool checkSig,
|
||||
SECCertUsage requiredUsage, PRTime time,
|
||||
void* wincx, CERTVerifyLog* log,
|
||||
PRBool* sigError, PRBool* revoked);
|
||||
|
||||
SECStatus cert_InitLocks(void);
|
||||
|
||||
|
@ -298,17 +286,16 @@ SECStatus cert_DestroyLocks(void);
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
extern PRUint32 cert_ComputeCertType(CERTCertificate *cert);
|
||||
extern PRUint32 cert_ComputeCertType(CERTCertificate* cert);
|
||||
|
||||
void cert_AddToVerifyLog(CERTVerifyLog *log,CERTCertificate *cert,
|
||||
long errorCode, unsigned int depth,
|
||||
void *arg);
|
||||
void cert_AddToVerifyLog(CERTVerifyLog* log, CERTCertificate* cert,
|
||||
long errorCode, unsigned int depth, void* arg);
|
||||
|
||||
/* 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
|
||||
* encoding of the GeneralName should be used, if available.
|
||||
*/
|
||||
|
||||
|
||||
SECStatus cert_CacheCRLByGeneralName(CERTCertDBHandle* dbhandle, SECItem* crl,
|
||||
const SECItem* canonicalizedName);
|
||||
|
||||
|
@ -336,15 +323,15 @@ struct NamedCRLCacheStr {
|
|||
* and read by cert_FindCRLByGeneralName */
|
||||
struct NamedCRLCacheEntryStr {
|
||||
SECItem* canonicalizedName;
|
||||
SECItem* crl; /* DER, kept only if CRL
|
||||
* is successfully cached */
|
||||
SECItem* crl; /* DER, kept only if CRL
|
||||
* is successfully cached */
|
||||
PRBool inCRLCache;
|
||||
PRTime successfulInsertionTime; /* insertion time */
|
||||
PRTime lastAttemptTime; /* time of last call to
|
||||
cert_CacheCRLByGeneralName with this name */
|
||||
PRBool badDER; /* ASN.1 error */
|
||||
PRBool dupe; /* matching DER CRL already in CRL cache */
|
||||
PRBool unsupported; /* IDP, delta, any other reason */
|
||||
PRBool badDER; /* ASN.1 error */
|
||||
PRBool dupe; /* matching DER CRL already in CRL cache */
|
||||
PRBool unsupported; /* IDP, delta, any other reason */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
@ -355,12 +342,12 @@ typedef enum {
|
|||
|
||||
/* Returns detailed status of the cert(revStatus variable). Tells if
|
||||
* issuer cache has OriginFetchedWithTimeout crl in it. */
|
||||
SECStatus
|
||||
cert_CheckCertRevocationStatus(CERTCertificate* cert, CERTCertificate* issuer,
|
||||
const SECItem* dp, PRTime t, void *wincx,
|
||||
CERTRevocationStatus *revStatus,
|
||||
CERTCRLEntryReasonCode *revReason);
|
||||
|
||||
SECStatus cert_CheckCertRevocationStatus(CERTCertificate* cert,
|
||||
CERTCertificate* issuer,
|
||||
const SECItem* dp, PRTime t,
|
||||
void* wincx,
|
||||
CERTRevocationStatus* revStatus,
|
||||
CERTCRLEntryReasonCode* revReason);
|
||||
|
||||
SECStatus cert_AcquireNamedCRLCache(NamedCRLCache** returned);
|
||||
|
||||
|
@ -374,26 +361,21 @@ SECStatus cert_FindCRLByGeneralName(NamedCRLCache* ncc,
|
|||
SECStatus cert_ReleaseNamedCRLCache(NamedCRLCache* ncc);
|
||||
|
||||
/* This is private for now. Maybe shoule be public. */
|
||||
CERTGeneralName *
|
||||
cert_GetSubjectAltNameList(const CERTCertificate *cert, PLArenaPool *arena);
|
||||
CERTGeneralName* cert_GetSubjectAltNameList(const CERTCertificate* cert,
|
||||
PLArenaPool* arena);
|
||||
|
||||
/* Count DNS names and IP addresses in a list of GeneralNames */
|
||||
PRUint32
|
||||
cert_CountDNSPatterns(CERTGeneralName *firstName);
|
||||
PRUint32 cert_CountDNSPatterns(CERTGeneralName* firstName);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* 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
|
||||
* 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
|
||||
* particular usage.
|
||||
*/
|
||||
SECStatus
|
||||
cert_CheckLeafTrust(CERTCertificate *cert,
|
||||
SECCertUsage usage,
|
||||
unsigned int *failedFlags,
|
||||
PRBool *isTrusted);
|
||||
SECStatus cert_CheckLeafTrust(CERTCertificate* cert, SECCertUsage usage,
|
||||
unsigned int* failedFlags, PRBool* isTrusted);
|
||||
|
||||
#endif /* _CERTI_H_ */
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -15,17 +15,15 @@
|
|||
#include "secerr.h"
|
||||
|
||||
SECStatus
|
||||
CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid,
|
||||
SECItem *value)
|
||||
CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, SECItem *value)
|
||||
{
|
||||
return (cert_FindExtensionByOID (cert->extensions, oid, value));
|
||||
return (cert_FindExtensionByOID(cert->extensions, oid, value));
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
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
|
||||
|
@ -34,13 +32,13 @@ SetExts(void *object, CERTCertExtension **exts)
|
|||
CERTCertificate *cert = (CERTCertificate *)object;
|
||||
|
||||
cert->extensions = exts;
|
||||
DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
|
||||
DER_SetUInteger(cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3);
|
||||
}
|
||||
|
||||
void *
|
||||
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)
|
||||
{
|
||||
|
||||
return (CERT_FindBitStringExtension
|
||||
(cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
|
||||
return (CERT_FindBitStringExtension(
|
||||
cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get the value of a string type extension
|
||||
*/
|
||||
char *
|
||||
CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag)
|
||||
{
|
||||
SECItem wrapperItem, tmpItem = {siBuffer,0};
|
||||
SECItem wrapperItem, tmpItem = { siBuffer, 0 };
|
||||
SECStatus rv;
|
||||
PLArenaPool *arena = NULL;
|
||||
char *retstring = NULL;
|
||||
|
||||
|
||||
wrapperItem.data = NULL;
|
||||
tmpItem.data = NULL;
|
||||
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if ( ! arena ) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = cert_FindExtension(cert->extensions, oidtag,
|
||||
&wrapperItem);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
|
||||
if (!arena) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
||||
SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
|
||||
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
rv = cert_FindExtension(cert->extensions, oidtag, &wrapperItem);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
retstring = (char *)PORT_Alloc(tmpItem.len + 1 );
|
||||
if ( retstring == NULL ) {
|
||||
goto loser;
|
||||
rv = SEC_QuickDERDecodeItem(
|
||||
arena, &tmpItem, SEC_ASN1_GET(SEC_IA5StringTemplate), &wrapperItem);
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
|
||||
retstring = (char *)PORT_Alloc(tmpItem.len + 1);
|
||||
if (retstring == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PORT_Memcpy(retstring, tmpItem.data, tmpItem.len);
|
||||
retstring[tmpItem.len] = '\0';
|
||||
|
||||
loser:
|
||||
if ( arena ) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
|
||||
if ( wrapperItem.data ) {
|
||||
PORT_Free(wrapperItem.data);
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
|
||||
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,
|
||||
SEC_OID_X509_KEY_USAGE, retItem));
|
||||
SEC_OID_X509_KEY_USAGE, retItem));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -127,24 +123,25 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
|
|||
{
|
||||
|
||||
SECStatus rv;
|
||||
SECItem encodedValue = {siBuffer, NULL, 0 };
|
||||
SECItem decodedValue = {siBuffer, NULL, 0 };
|
||||
SECItem encodedValue = { siBuffer, NULL, 0 };
|
||||
SECItem decodedValue = { siBuffer, NULL, 0 };
|
||||
|
||||
rv = cert_FindExtension
|
||||
(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue);
|
||||
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID,
|
||||
&encodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (tmpArena) {
|
||||
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
&encodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
|
||||
}
|
||||
PORT_FreeArena(tmpArena, PR_FALSE);
|
||||
} else {
|
||||
rv = SECFailure;
|
||||
}
|
||||
PLArenaPool *tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (tmpArena) {
|
||||
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
&encodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
|
||||
}
|
||||
PORT_FreeArena(tmpArena, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
rv = SECFailure;
|
||||
}
|
||||
}
|
||||
SECITEM_FreeItem(&encodedValue, PR_FALSE);
|
||||
return rv;
|
||||
|
@ -152,7 +149,7 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
|
|||
|
||||
SECStatus
|
||||
CERT_FindBasicConstraintExten(CERTCertificate *cert,
|
||||
CERTBasicConstraints *value)
|
||||
CERTBasicConstraints *value)
|
||||
{
|
||||
SECItem encodedExtenValue;
|
||||
SECStatus rv;
|
||||
|
@ -161,42 +158,42 @@ CERT_FindBasicConstraintExten(CERTCertificate *cert,
|
|||
encodedExtenValue.len = 0;
|
||||
|
||||
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS,
|
||||
&encodedExtenValue);
|
||||
if ( rv != SECSuccess ) {
|
||||
return (rv);
|
||||
&encodedExtenValue);
|
||||
if (rv != SECSuccess) {
|
||||
return (rv);
|
||||
}
|
||||
|
||||
rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue);
|
||||
|
||||
rv = CERT_DecodeBasicConstraintValue(value, &encodedExtenValue);
|
||||
|
||||
/* free the raw extension data */
|
||||
PORT_Free(encodedExtenValue.data);
|
||||
encodedExtenValue.data = NULL;
|
||||
|
||||
return(rv);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
CERTAuthKeyID *
|
||||
CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert)
|
||||
CERT_FindAuthKeyIDExten(PLArenaPool *arena, CERTCertificate *cert)
|
||||
{
|
||||
SECItem encodedExtenValue;
|
||||
SECStatus rv;
|
||||
CERTAuthKeyID *ret;
|
||||
|
||||
|
||||
encodedExtenValue.data = NULL;
|
||||
encodedExtenValue.len = 0;
|
||||
|
||||
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID,
|
||||
&encodedExtenValue);
|
||||
if ( rv != SECSuccess ) {
|
||||
return (NULL);
|
||||
&encodedExtenValue);
|
||||
if (rv != SECSuccess) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue);
|
||||
ret = CERT_DecodeAuthKeyID(arena, &encodedExtenValue);
|
||||
|
||||
PORT_Free(encodedExtenValue.data);
|
||||
encodedExtenValue.data = NULL;
|
||||
|
||||
return(ret);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
@ -207,9 +204,9 @@ CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage)
|
|||
|
||||
/* There is no extension, v1 or v2 certificate */
|
||||
if (cert->extensions == NULL) {
|
||||
return (SECSuccess);
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
|
||||
keyUsage.data = NULL;
|
||||
|
||||
/* 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);
|
||||
if (rv == SECFailure) {
|
||||
rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ?
|
||||
SECSuccess : SECFailure;
|
||||
} else if (!(keyUsage.data[0] & usage)) {
|
||||
PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID);
|
||||
rv = SECFailure;
|
||||
rv = (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) ? SECSuccess
|
||||
: 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);
|
||||
}
|
||||
|
|
|
@ -16,93 +16,93 @@
|
|||
#include "secerr.h"
|
||||
|
||||
#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 */
|
||||
#endif
|
||||
|
||||
static CERTCertExtension *
|
||||
GetExtension (CERTCertExtension **extensions, SECItem *oid)
|
||||
GetExtension(CERTCertExtension **extensions, SECItem *oid)
|
||||
{
|
||||
CERTCertExtension **exts;
|
||||
CERTCertExtension *ext = NULL;
|
||||
SECComparison comp;
|
||||
|
||||
exts = extensions;
|
||||
|
||||
if (exts) {
|
||||
while ( *exts ) {
|
||||
ext = *exts;
|
||||
comp = SECITEM_CompareItem(oid, &ext->id);
|
||||
if ( comp == SECEqual )
|
||||
break;
|
||||
|
||||
exts++;
|
||||
}
|
||||
return (*exts ? ext : NULL);
|
||||
if (exts) {
|
||||
while (*exts) {
|
||||
ext = *exts;
|
||||
comp = SECITEM_CompareItem(oid, &ext->id);
|
||||
if (comp == SECEqual)
|
||||
break;
|
||||
|
||||
exts++;
|
||||
}
|
||||
return (*exts ? ext : NULL);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value)
|
||||
cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid,
|
||||
SECItem *value)
|
||||
{
|
||||
CERTCertExtension *ext;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
ext = GetExtension (extensions, oid);
|
||||
|
||||
ext = GetExtension(extensions, oid);
|
||||
if (ext == NULL) {
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
return (SECFailure);
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
return (SECFailure);
|
||||
}
|
||||
if (value)
|
||||
rv = SECITEM_CopyItem(NULL, value, &ext->value);
|
||||
rv = SECITEM_CopyItem(NULL, value, &ext->value);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical)
|
||||
CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag,
|
||||
PRBool *isCritical)
|
||||
{
|
||||
CERTCertExtension *ext;
|
||||
SECOidData *oid;
|
||||
|
||||
if (!isCritical)
|
||||
return (SECSuccess);
|
||||
|
||||
return (SECSuccess);
|
||||
|
||||
/* find the extension in the extensions list */
|
||||
oid = SECOID_FindOIDByTag((SECOidTag)tag);
|
||||
if ( !oid ) {
|
||||
return(SECFailure);
|
||||
if (!oid) {
|
||||
return (SECFailure);
|
||||
}
|
||||
ext = GetExtension (extensions, &oid->oid);
|
||||
ext = GetExtension(extensions, &oid->oid);
|
||||
if (ext == NULL) {
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
return (SECFailure);
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/* If the criticality is omitted, then it is false by default.
|
||||
ex->critical.data is NULL */
|
||||
if (ext->critical.data == NULL)
|
||||
*isCritical = PR_FALSE;
|
||||
*isCritical = PR_FALSE;
|
||||
else
|
||||
*isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
|
||||
return (SECSuccess);
|
||||
*isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
|
||||
{
|
||||
SECOidData *oid;
|
||||
|
||||
|
||||
oid = SECOID_FindOIDByTag((SECOidTag)tag);
|
||||
if ( !oid ) {
|
||||
return(SECFailure);
|
||||
if (!oid) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return(cert_FindExtensionByOID(extensions, &oid->oid, value));
|
||||
return (cert_FindExtensionByOID(extensions, &oid->oid, value));
|
||||
}
|
||||
|
||||
|
||||
typedef struct _extNode {
|
||||
struct _extNode *next;
|
||||
CERTCertExtension *ext;
|
||||
|
@ -115,7 +115,7 @@ typedef struct {
|
|||
PLArenaPool *arena;
|
||||
extNode *head;
|
||||
int count;
|
||||
}extRec;
|
||||
} extRec;
|
||||
|
||||
/*
|
||||
* cert_StartExtensions
|
||||
|
@ -125,20 +125,20 @@ typedef struct {
|
|||
*/
|
||||
void *
|
||||
cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
||||
void (*setExts)(void *object, CERTCertExtension **exts))
|
||||
void (*setExts)(void *object, CERTCertExtension **exts))
|
||||
{
|
||||
PLArenaPool *arena;
|
||||
extRec *handle;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if ( !arena ) {
|
||||
return(0);
|
||||
if (!arena) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
|
||||
if ( !handle ) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return(0);
|
||||
if (!handle) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
handle->object = owner;
|
||||
|
@ -148,8 +148,8 @@ cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
|||
handle->arena = arena;
|
||||
handle->head = 0;
|
||||
handle->count = 0;
|
||||
|
||||
return(handle);
|
||||
|
||||
return (handle);
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
SECStatus
|
||||
CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value,
|
||||
PRBool critical, PRBool copyData)
|
||||
CERT_AddExtensionByOID(void *exthandle, SECItem *oid, SECItem *value,
|
||||
PRBool critical, PRBool copyData)
|
||||
{
|
||||
CERTCertExtension *ext;
|
||||
SECStatus rv;
|
||||
extNode *node;
|
||||
extRec *handle;
|
||||
|
||||
|
||||
handle = (extRec *)exthandle;
|
||||
|
||||
/* allocate space for extension and list node */
|
||||
ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena,
|
||||
sizeof(CERTCertExtension));
|
||||
if ( !ext ) {
|
||||
return(SECFailure);
|
||||
ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena,
|
||||
sizeof(CERTCertExtension));
|
||||
if (!ext) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
|
||||
if ( !node ) {
|
||||
return(SECFailure);
|
||||
node = (extNode *)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
|
||||
if (!node) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
/* add to list */
|
||||
node->next = handle->head;
|
||||
handle->head = node;
|
||||
|
||||
|
||||
/* point to ext struct */
|
||||
node->ext = ext;
|
||||
|
||||
|
||||
/* the object ID of the extension */
|
||||
ext->id = *oid;
|
||||
|
||||
|
||||
/* set critical field */
|
||||
if ( critical ) {
|
||||
ext->critical.data = (unsigned char*)&hextrue;
|
||||
ext->critical.len = 1;
|
||||
if (critical) {
|
||||
ext->critical.data = (unsigned char *)&hextrue;
|
||||
ext->critical.len = 1;
|
||||
}
|
||||
|
||||
/* set the value */
|
||||
if ( copyData ) {
|
||||
rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
|
||||
if ( rv ) {
|
||||
return(SECFailure);
|
||||
}
|
||||
} else {
|
||||
ext->value = *value;
|
||||
if (copyData) {
|
||||
rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
|
||||
if (rv) {
|
||||
return (SECFailure);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ext->value = *value;
|
||||
}
|
||||
|
||||
handle->count++;
|
||||
|
||||
return(SECSuccess);
|
||||
|
||||
handle->count++;
|
||||
|
||||
return (SECSuccess);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_AddExtension(void *exthandle, int idtag, SECItem *value,
|
||||
PRBool critical, PRBool copyData)
|
||||
CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical,
|
||||
PRBool copyData)
|
||||
{
|
||||
SECOidData *oid;
|
||||
|
||||
|
||||
oid = SECOID_FindOIDByTag((SECOidTag)idtag);
|
||||
if ( !oid ) {
|
||||
return(SECFailure);
|
||||
if (!oid) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData));
|
||||
return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical,
|
||||
copyData));
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
|
||||
PRBool critical, const SEC_ASN1Template *atemplate)
|
||||
PRBool critical, const SEC_ASN1Template *atemplate)
|
||||
{
|
||||
extRec *handle;
|
||||
SECItem *encitem;
|
||||
|
@ -236,45 +237,43 @@ CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
|
|||
handle = (extRec *)exthandle;
|
||||
|
||||
encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
|
||||
if ( encitem == NULL ) {
|
||||
return(SECFailure);
|
||||
if (encitem == NULL) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value)
|
||||
PrepareBitStringForEncoding(SECItem *bitsmap, SECItem *value)
|
||||
{
|
||||
unsigned char onebyte;
|
||||
unsigned int i, len = 0;
|
||||
unsigned char onebyte;
|
||||
unsigned int i, len = 0;
|
||||
|
||||
/* to prevent warning on some platform at compile time */
|
||||
onebyte = '\0';
|
||||
/* Get the position of the right-most turn-on bit */
|
||||
for (i = 0; i < (value->len ) * 8; ++i) {
|
||||
if (i % 8 == 0)
|
||||
onebyte = value->data[i/8];
|
||||
if (onebyte & 0x80)
|
||||
len = i;
|
||||
onebyte <<= 1;
|
||||
|
||||
}
|
||||
bitsmap->data = value->data;
|
||||
/* Add one here since we work with base 1 */
|
||||
bitsmap->len = len + 1;
|
||||
/* to prevent warning on some platform at compile time */
|
||||
onebyte = '\0';
|
||||
/* Get the position of the right-most turn-on bit */
|
||||
for (i = 0; i < (value->len) * 8; ++i) {
|
||||
if (i % 8 == 0)
|
||||
onebyte = value->data[i / 8];
|
||||
if (onebyte & 0x80)
|
||||
len = i;
|
||||
onebyte <<= 1;
|
||||
}
|
||||
bitsmap->data = value->data;
|
||||
/* Add one here since we work with base 1 */
|
||||
bitsmap->len = len + 1;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag,
|
||||
SECItem *value, PRBool critical)
|
||||
CERT_EncodeAndAddBitStrExtension(void *exthandle, int idtag, SECItem *value,
|
||||
PRBool critical)
|
||||
{
|
||||
SECItem bitsmap;
|
||||
|
||||
PrepareBitStringForEncoding (&bitsmap, value);
|
||||
return (CERT_EncodeAndAddExtension
|
||||
(exthandle, idtag, &bitsmap, critical,
|
||||
SEC_ASN1_GET(SEC_BitStringTemplate)));
|
||||
SECItem bitsmap;
|
||||
|
||||
PrepareBitStringForEncoding(&bitsmap, value);
|
||||
return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical,
|
||||
SEC_ASN1_GET(SEC_BitStringTemplate)));
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
@ -284,53 +283,53 @@ CERT_FinishExtensions(void *exthandle)
|
|||
extNode *node;
|
||||
CERTCertExtension **exts;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
|
||||
handle = (extRec *)exthandle;
|
||||
|
||||
/* allocate space for extensions array */
|
||||
exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
|
||||
handle->count + 1);
|
||||
handle->count + 1);
|
||||
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
|
||||
switch (handle->type) {
|
||||
case CertificateExtensions:
|
||||
handle->owner.cert->extensions = exts;
|
||||
DER_SetUInteger (ownerArena, &(handle->owner.cert->version),
|
||||
SEC_CERTIFICATE_VERSION_3);
|
||||
break;
|
||||
case CrlExtensions:
|
||||
handle->owner.crl->extensions = exts;
|
||||
DER_SetUInteger (ownerArena, &(handle->owner.crl->version),
|
||||
SEC_CRL_VERSION_2);
|
||||
break;
|
||||
case OCSPRequestExtensions:
|
||||
handle->owner.request->tbsRequest->requestExtensions = exts;
|
||||
break;
|
||||
case OCSPSingleRequestExtensions:
|
||||
handle->owner.singleRequest->singleRequestExtensions = exts;
|
||||
break;
|
||||
case OCSPResponseSingleExtensions:
|
||||
handle->owner.singleResponse->singleExtensions = exts;
|
||||
break;
|
||||
case CertificateExtensions:
|
||||
handle->owner.cert->extensions = exts;
|
||||
DER_SetUInteger(ownerArena, &(handle->owner.cert->version),
|
||||
SEC_CERTIFICATE_VERSION_3);
|
||||
break;
|
||||
case CrlExtensions:
|
||||
handle->owner.crl->extensions = exts;
|
||||
DER_SetUInteger(ownerArena, &(handle->owner.crl->version),
|
||||
SEC_CRL_VERSION_2);
|
||||
break;
|
||||
case OCSPRequestExtensions:
|
||||
handle->owner.request->tbsRequest->requestExtensions = exts;
|
||||
break;
|
||||
case OCSPSingleRequestExtensions:
|
||||
handle->owner.singleRequest->singleRequestExtensions = exts;
|
||||
break;
|
||||
case OCSPResponseSingleExtensions:
|
||||
handle->owner.singleResponse->singleExtensions = exts;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
handle->setExts(handle->object, exts);
|
||||
|
||||
|
||||
/* update the version number */
|
||||
|
||||
/* copy each extension pointer */
|
||||
node = handle->head;
|
||||
while ( node ) {
|
||||
*exts = node->ext;
|
||||
|
||||
node = node->next;
|
||||
exts++;
|
||||
while (node) {
|
||||
*exts = node->ext;
|
||||
|
||||
node = node->next;
|
||||
exts++;
|
||||
}
|
||||
|
||||
/* terminate the array of extensions */
|
||||
|
@ -352,14 +351,14 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
|||
SECOidTag tag;
|
||||
extNode *node;
|
||||
extRec *handle = exthandle;
|
||||
|
||||
|
||||
if (!exthandle || !extensions) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
while ((ext = *extensions++) != NULL) {
|
||||
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 (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
|
||||
break;
|
||||
|
@ -372,15 +371,15 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
|||
}
|
||||
if (node == NULL) {
|
||||
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) {
|
||||
PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
/* add to list */
|
||||
rv = CERT_AddExtensionByOID (exthandle, &ext->id, &ext->value,
|
||||
critical, PR_TRUE);
|
||||
rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value,
|
||||
critical, PR_TRUE);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
|
@ -392,108 +391,107 @@ CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
|
|||
* get the value of the Netscape Certificate Type Extension
|
||||
*/
|
||||
SECStatus
|
||||
CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag,
|
||||
SECItem *retItem)
|
||||
CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
|
||||
SECItem *retItem)
|
||||
{
|
||||
SECItem wrapperItem, tmpItem = {siBuffer,0};
|
||||
SECItem wrapperItem, tmpItem = { siBuffer, 0 };
|
||||
SECStatus rv;
|
||||
PLArenaPool *arena = NULL;
|
||||
|
||||
|
||||
wrapperItem.data = NULL;
|
||||
tmpItem.data = NULL;
|
||||
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if ( ! arena ) {
|
||||
return(SECFailure);
|
||||
|
||||
if (!arena) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
|
||||
rv = cert_FindExtension(extensions, tag, &wrapperItem);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
||||
SEC_ASN1_GET(SEC_BitStringTemplate),
|
||||
&wrapperItem);
|
||||
rv = SEC_QuickDERDecodeItem(
|
||||
arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);
|
||||
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 );
|
||||
if ( retItem->data == NULL ) {
|
||||
goto loser;
|
||||
retItem->data = (unsigned char *)PORT_Alloc((tmpItem.len + 7) >> 3);
|
||||
if (retItem->data == NULL) {
|
||||
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;
|
||||
|
||||
|
||||
rv = SECSuccess;
|
||||
goto done;
|
||||
|
||||
|
||||
loser:
|
||||
rv = SECFailure;
|
||||
|
||||
done:
|
||||
if ( arena ) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
|
||||
if ( wrapperItem.data ) {
|
||||
PORT_Free(wrapperItem.data);
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
|
||||
return(rv);
|
||||
if (wrapperItem.data) {
|
||||
PORT_Free(wrapperItem.data);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
PRBool
|
||||
cert_HasCriticalExtension (CERTCertExtension **extensions)
|
||||
cert_HasCriticalExtension(CERTCertExtension **extensions)
|
||||
{
|
||||
CERTCertExtension **exts;
|
||||
CERTCertExtension *ext = NULL;
|
||||
PRBool hasCriticalExten = PR_FALSE;
|
||||
|
||||
|
||||
exts = extensions;
|
||||
|
||||
|
||||
if (exts) {
|
||||
while ( *exts ) {
|
||||
ext = *exts;
|
||||
/* If the criticality is omitted, it's non-critical */
|
||||
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
||||
hasCriticalExten = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
exts++;
|
||||
}
|
||||
while (*exts) {
|
||||
ext = *exts;
|
||||
/* If the criticality is omitted, it's non-critical */
|
||||
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
||||
hasCriticalExten = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
exts++;
|
||||
}
|
||||
}
|
||||
return (hasCriticalExten);
|
||||
}
|
||||
|
||||
PRBool
|
||||
cert_HasUnknownCriticalExten (CERTCertExtension **extensions)
|
||||
cert_HasUnknownCriticalExten(CERTCertExtension **extensions)
|
||||
{
|
||||
CERTCertExtension **exts;
|
||||
CERTCertExtension *ext = NULL;
|
||||
PRBool hasUnknownCriticalExten = PR_FALSE;
|
||||
|
||||
|
||||
exts = extensions;
|
||||
|
||||
|
||||
if (exts) {
|
||||
while ( *exts ) {
|
||||
ext = *exts;
|
||||
/* If the criticality is omitted, it's non-critical.
|
||||
If an extension is critical, make sure that we know
|
||||
how to process the extension.
|
||||
while (*exts) {
|
||||
ext = *exts;
|
||||
/* If the criticality is omitted, it's non-critical.
|
||||
If an extension is critical, make sure that we know
|
||||
how to process the extension.
|
||||
*/
|
||||
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
||||
if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) {
|
||||
hasUnknownCriticalExten = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
exts++;
|
||||
}
|
||||
if (ext->critical.data && ext->critical.data[0] == 0xff) {
|
||||
if (SECOID_KnownCertExtenOID(&ext->id) == PR_FALSE) {
|
||||
hasUnknownCriticalExten = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
exts++;
|
||||
}
|
||||
}
|
||||
return (hasUnknownCriticalExten);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CERTXUTL_H_
|
||||
#define _CERTXUTL_H_
|
||||
|
||||
|
@ -23,28 +22,23 @@ typedef enum {
|
|||
} ExtensionsType;
|
||||
#endif
|
||||
|
||||
extern PRBool
|
||||
cert_HasCriticalExtension (CERTCertExtension **extensions);
|
||||
extern PRBool cert_HasCriticalExtension(CERTCertExtension **extensions);
|
||||
|
||||
extern SECStatus
|
||||
CERT_FindBitStringExtension (CERTCertExtension **extensions,
|
||||
int tag, SECItem *retItem);
|
||||
extern void *
|
||||
cert_StartExtensions (void *owner, PLArenaPool *arena,
|
||||
void (*setExts)(void *object, CERTCertExtension **exts));
|
||||
extern SECStatus CERT_FindBitStringExtension(CERTCertExtension **extensions,
|
||||
int tag, SECItem *retItem);
|
||||
extern void *cert_StartExtensions(void *owner, PLArenaPool *arena,
|
||||
void (*setExts)(void *object,
|
||||
CERTCertExtension **exts));
|
||||
|
||||
extern SECStatus
|
||||
cert_FindExtension (CERTCertExtension **extensions, int tag, SECItem *value);
|
||||
extern SECStatus cert_FindExtension(CERTCertExtension **extensions, int tag,
|
||||
SECItem *value);
|
||||
|
||||
extern SECStatus
|
||||
cert_FindExtensionByOID (CERTCertExtension **extensions,
|
||||
SECItem *oid, SECItem *value);
|
||||
extern SECStatus cert_FindExtensionByOID(CERTCertExtension **extensions,
|
||||
SECItem *oid, SECItem *value);
|
||||
|
||||
extern SECStatus
|
||||
cert_GetExtenCriticality (CERTCertExtension **extensions,
|
||||
int tag, PRBool *isCritical);
|
||||
extern SECStatus cert_GetExtenCriticality(CERTCertExtension **extensions,
|
||||
int tag, PRBool *isCritical);
|
||||
|
||||
extern PRBool
|
||||
cert_HasUnknownCriticalExten (CERTCertExtension **extensions);
|
||||
extern PRBool cert_HasUnknownCriticalExten(CERTCertExtension **extensions);
|
||||
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -17,89 +17,76 @@ SEC_BEGIN_PROTOS
|
|||
|
||||
extern const SEC_ASN1Template CERT_GeneralNamesTemplate[];
|
||||
|
||||
extern SECItem **
|
||||
cert_EncodeGeneralNames(PLArenaPool *arena, CERTGeneralName *names);
|
||||
extern SECItem **cert_EncodeGeneralNames(PLArenaPool *arena,
|
||||
CERTGeneralName *names);
|
||||
|
||||
extern CERTGeneralName *
|
||||
cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName);
|
||||
extern CERTGeneralName *cert_DecodeGeneralNames(PLArenaPool *arena,
|
||||
SECItem **encodedGenName);
|
||||
|
||||
extern SECStatus
|
||||
cert_DestroyGeneralNames(CERTGeneralName *name);
|
||||
extern SECStatus cert_DestroyGeneralNames(CERTGeneralName *name);
|
||||
|
||||
extern SECStatus
|
||||
cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena,
|
||||
SECItem *dest);
|
||||
extern SECStatus cert_EncodeNameConstraints(CERTNameConstraints *constraints,
|
||||
PLArenaPool *arena, SECItem *dest);
|
||||
|
||||
extern CERTNameConstraints *
|
||||
cert_DecodeNameConstraints(PLArenaPool *arena, const SECItem *encodedConstraints);
|
||||
extern CERTNameConstraints *cert_DecodeNameConstraints(
|
||||
PLArenaPool *arena, const SECItem *encodedConstraints);
|
||||
|
||||
extern CERTGeneralName *
|
||||
cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2);
|
||||
extern CERTGeneralName *cert_CombineNamesLists(CERTGeneralName *list1,
|
||||
CERTGeneralName *list2);
|
||||
|
||||
extern CERTNameConstraint *
|
||||
cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2);
|
||||
extern CERTNameConstraint *cert_CombineConstraintsLists(
|
||||
CERTNameConstraint *list1, CERTNameConstraint *list2);
|
||||
|
||||
/*********************************************************************/
|
||||
/* A thread safe implementation of General Names */
|
||||
/*********************************************************************/
|
||||
|
||||
/* Destroy a Single CERTGeneralName */
|
||||
void
|
||||
CERT_DestroyGeneralName(CERTGeneralName *name);
|
||||
void CERT_DestroyGeneralName(CERTGeneralName *name);
|
||||
|
||||
SECStatus
|
||||
CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
|
||||
SECStatus CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b);
|
||||
|
||||
SECStatus
|
||||
CERT_CopyGeneralName(PLArenaPool *arena,
|
||||
CERTGeneralName *dest,
|
||||
CERTGeneralName *src);
|
||||
SECStatus CERT_CopyGeneralName(PLArenaPool *arena, 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 */
|
||||
|
||||
/* Destroys a CERTGeneralNameList */
|
||||
void
|
||||
CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
|
||||
void CERT_DestroyGeneralNameList(CERTGeneralNameList *list);
|
||||
|
||||
/* Creates a CERTGeneralNameList */
|
||||
CERTGeneralNameList *
|
||||
CERT_CreateGeneralNameList(CERTGeneralName *name);
|
||||
CERTGeneralNameList *CERT_CreateGeneralNameList(CERTGeneralName *name);
|
||||
|
||||
/* Compares two CERTGeneralNameList */
|
||||
SECStatus
|
||||
CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b);
|
||||
SECStatus CERT_CompareGeneralNameLists(CERTGeneralNameList *a,
|
||||
CERTGeneralNameList *b);
|
||||
|
||||
/* returns a copy of the first name of the type requested */
|
||||
void *
|
||||
CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
|
||||
CERTGeneralNameType type,
|
||||
PLArenaPool *arena);
|
||||
void *CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,
|
||||
CERTGeneralNameType type,
|
||||
PLArenaPool *arena);
|
||||
|
||||
/* Adds a name to the tail of the list */
|
||||
void
|
||||
CERT_AddGeneralNameToList(CERTGeneralNameList *list,
|
||||
CERTGeneralNameType type,
|
||||
void *data, SECItem *oid);
|
||||
void CERT_AddGeneralNameToList(CERTGeneralNameList *list,
|
||||
CERTGeneralNameType type, void *data,
|
||||
SECItem *oid);
|
||||
|
||||
/* returns a duplicate of the CERTGeneralNameList */
|
||||
CERTGeneralNameList *
|
||||
CERT_DupGeneralNameList(CERTGeneralNameList *list);
|
||||
CERTGeneralNameList *CERT_DupGeneralNameList(CERTGeneralNameList *list);
|
||||
|
||||
/* returns the number of CERTGeneralName objects in the doubly linked
|
||||
** list of which *names is a member.
|
||||
*/
|
||||
extern int
|
||||
CERT_GetNamesLength(CERTGeneralName *names);
|
||||
extern int CERT_GetNamesLength(CERTGeneralName *names);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
SECStatus
|
||||
CERT_CompareNameSpace(CERTCertificate *cert,
|
||||
CERTGeneralName *namesList,
|
||||
CERTCertificate **certsList,
|
||||
PLArenaPool *reqArena,
|
||||
CERTCertificate **pBadCert);
|
||||
SECStatus CERT_CompareNameSpace(CERTCertificate *cert,
|
||||
CERTGeneralName *namesList,
|
||||
CERTCertificate **certsList,
|
||||
PLArenaPool *reqArena,
|
||||
CERTCertificate **pBadCert);
|
||||
|
||||
SEC_END_PROTOS
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "cert.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 "secitem.h"
|
||||
#include <stdarg.h>
|
||||
|
@ -12,29 +12,25 @@
|
|||
#include "certi.h"
|
||||
|
||||
static const SEC_ASN1Template cert_AVATemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTAVA) },
|
||||
{ SEC_ASN1_OBJECT_ID,
|
||||
offsetof(CERTAVA,type), },
|
||||
{ SEC_ASN1_ANY,
|
||||
offsetof(CERTAVA,value), },
|
||||
{ 0, }
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAVA) },
|
||||
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAVA, type) },
|
||||
{ SEC_ASN1_ANY, offsetof(CERTAVA, value) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template CERT_RDNTemplate[] = {
|
||||
{ SEC_ASN1_SET_OF,
|
||||
offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) }
|
||||
{ SEC_ASN1_SET_OF, offsetof(CERTRDN, avas), cert_AVATemplate,
|
||||
sizeof(CERTRDN) }
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
CountArray(void **array)
|
||||
{
|
||||
int count = 0;
|
||||
if (array) {
|
||||
while (*array++) {
|
||||
count++;
|
||||
}
|
||||
while (*array++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
@ -49,36 +45,37 @@ AddToArray(PLArenaPool *arena, void **array, void *element)
|
|||
count = 0;
|
||||
ap = array;
|
||||
if (ap) {
|
||||
while (*ap++) {
|
||||
count++;
|
||||
}
|
||||
while (*ap++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (array) {
|
||||
array = (void**) PORT_ArenaGrow(arena, array,
|
||||
(count + 1) * sizeof(void *),
|
||||
(count + 2) * sizeof(void *));
|
||||
} else {
|
||||
array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
|
||||
array =
|
||||
(void **)PORT_ArenaGrow(arena, array, (count + 1) * sizeof(void *),
|
||||
(count + 2) * sizeof(void *));
|
||||
}
|
||||
else {
|
||||
array = (void **)PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *));
|
||||
}
|
||||
if (array) {
|
||||
array[count] = element;
|
||||
array[count+1] = 0;
|
||||
array[count] = element;
|
||||
array[count + 1] = 0;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
SECOidTag
|
||||
CERT_GetAVATag(CERTAVA *ava)
|
||||
{
|
||||
SECOidData *oid;
|
||||
if (!ava->type.data) return (SECOidTag)-1;
|
||||
if (!ava->type.data)
|
||||
return (SECOidTag)-1;
|
||||
|
||||
oid = SECOID_FindOID(&ava->type);
|
||||
|
||||
if ( oid ) {
|
||||
return(oid->offset);
|
||||
|
||||
if (oid) {
|
||||
return (oid->offset);
|
||||
}
|
||||
return (SECOidTag)-1;
|
||||
}
|
||||
|
@ -89,25 +86,25 @@ SetupAVAType(PLArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp)
|
|||
unsigned char *oid;
|
||||
unsigned oidLen;
|
||||
unsigned char *cp;
|
||||
int maxLen;
|
||||
int maxLen;
|
||||
SECOidData *oidrec;
|
||||
|
||||
oidrec = SECOID_FindOIDByTag(type);
|
||||
if (oidrec == NULL)
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
|
||||
oid = oidrec->oid.data;
|
||||
oidLen = oidrec->oid.len;
|
||||
|
||||
maxLen = cert_AVAOidTagToMaxLen(type);
|
||||
if (maxLen < 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen);
|
||||
it->data = cp = (unsigned char *)PORT_ArenaAlloc(arena, oidLen);
|
||||
if (cp == NULL) {
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
it->len = oidLen;
|
||||
PORT_Memcpy(cp, oid, oidLen);
|
||||
|
@ -123,65 +120,66 @@ SetupAVAValue(PLArenaPool *arena, int valueType, const SECItem *in,
|
|||
unsigned valueLen, valueLenLen, total;
|
||||
unsigned ucs4Len = 0, ucs4MaxLen;
|
||||
|
||||
value = in->data;
|
||||
value = in->data;
|
||||
valueLen = in->len;
|
||||
switch (valueType) {
|
||||
case SEC_ASN1_PRINTABLE_STRING:
|
||||
case SEC_ASN1_IA5_STRING:
|
||||
case SEC_ASN1_T61_STRING:
|
||||
case SEC_ASN1_UTF8_STRING: /* no conversion required */
|
||||
break;
|
||||
case SEC_ASN1_UNIVERSAL_STRING:
|
||||
ucs4MaxLen = valueLen * 6;
|
||||
ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
|
||||
if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen,
|
||||
ucs4Val, ucs4MaxLen, &ucs4Len)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
value = ucs4Val;
|
||||
valueLen = ucs4Len;
|
||||
maxLen *= 4;
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
case SEC_ASN1_PRINTABLE_STRING:
|
||||
case SEC_ASN1_IA5_STRING:
|
||||
case SEC_ASN1_T61_STRING:
|
||||
case SEC_ASN1_UTF8_STRING: /* no conversion required */
|
||||
break;
|
||||
case SEC_ASN1_UNIVERSAL_STRING:
|
||||
ucs4MaxLen = valueLen * 6;
|
||||
ucs4Val = (PRUint8 *)PORT_ArenaZAlloc(arena, ucs4MaxLen);
|
||||
if (!ucs4Val ||
|
||||
!PORT_UCS4_UTF8Conversion(PR_TRUE, value, valueLen, ucs4Val,
|
||||
ucs4MaxLen, &ucs4Len)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
value = ucs4Val;
|
||||
valueLen = ucs4Len;
|
||||
maxLen *= 4;
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (valueLen > maxLen) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
valueLenLen = DER_LengthLength(valueLen);
|
||||
total = 1 + valueLenLen + valueLen;
|
||||
cp = (PRUint8*)PORT_ArenaAlloc(arena, total);
|
||||
cp = (PRUint8 *)PORT_ArenaAlloc(arena, total);
|
||||
if (!cp) {
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
out->data = cp;
|
||||
out->len = total;
|
||||
out->len = total;
|
||||
cp = (PRUint8 *)DER_StoreHeader(cp, valueType, valueLen);
|
||||
PORT_Memcpy(cp, value, valueLen);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
CERTAVA *
|
||||
CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem * OID,
|
||||
const SECItem * value)
|
||||
CERT_CreateAVAFromRaw(PLArenaPool *pool, const SECItem *OID,
|
||||
const SECItem *value)
|
||||
{
|
||||
CERTAVA *ava;
|
||||
int rv;
|
||||
|
||||
ava = PORT_ArenaZNew(pool, CERTAVA);
|
||||
if (ava) {
|
||||
rv = SECITEM_CopyItem(pool, &ava->type, OID);
|
||||
if (rv)
|
||||
return NULL;
|
||||
rv = SECITEM_CopyItem(pool, &ava->type, OID);
|
||||
if (rv)
|
||||
return NULL;
|
||||
|
||||
rv = SECITEM_CopyItem(pool, &ava->value, value);
|
||||
if (rv)
|
||||
return NULL;
|
||||
rv = SECITEM_CopyItem(pool, &ava->value, value);
|
||||
if (rv)
|
||||
return NULL;
|
||||
}
|
||||
return ava;
|
||||
}
|
||||
|
@ -194,18 +192,18 @@ CERT_CreateAVAFromSECItem(PLArenaPool *arena, SECOidTag kind, int valueType,
|
|||
int rv;
|
||||
unsigned maxLen;
|
||||
|
||||
ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
||||
ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
||||
if (ava) {
|
||||
rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
|
||||
if (rv) {
|
||||
/* Illegal AVA type */
|
||||
return NULL;
|
||||
}
|
||||
rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
|
||||
if (rv) {
|
||||
/* Illegal value type */
|
||||
return NULL;
|
||||
}
|
||||
rv = SetupAVAType(arena, kind, &ava->type, &maxLen);
|
||||
if (rv) {
|
||||
/* Illegal AVA type */
|
||||
return NULL;
|
||||
}
|
||||
rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen);
|
||||
if (rv) {
|
||||
/* Illegal value type */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ava;
|
||||
}
|
||||
|
@ -216,7 +214,7 @@ CERT_CreateAVA(PLArenaPool *arena, SECOidTag kind, int valueType, char *value)
|
|||
SECItem item = { siBuffer, NULL, 0 };
|
||||
|
||||
item.data = (PRUint8 *)value;
|
||||
item.len = PORT_Strlen(value);
|
||||
item.len = PORT_Strlen(value);
|
||||
|
||||
return CERT_CreateAVAFromSECItem(arena, kind, valueType, &item);
|
||||
}
|
||||
|
@ -227,16 +225,18 @@ CERT_CopyAVA(PLArenaPool *arena, CERTAVA *from)
|
|||
CERTAVA *ava;
|
||||
int rv;
|
||||
|
||||
ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
||||
ava = (CERTAVA *)PORT_ArenaZAlloc(arena, sizeof(CERTAVA));
|
||||
if (ava) {
|
||||
rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
|
||||
if (rv) goto loser;
|
||||
rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
|
||||
if (rv) goto loser;
|
||||
rv = SECITEM_CopyItem(arena, &ava->type, &from->type);
|
||||
if (rv)
|
||||
goto loser;
|
||||
rv = SECITEM_CopyItem(arena, &ava->value, &from->value);
|
||||
if (rv)
|
||||
goto loser;
|
||||
}
|
||||
return ava;
|
||||
|
||||
loser:
|
||||
loser:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -249,34 +249,34 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
|
|||
unsigned count;
|
||||
CERTAVA **avap;
|
||||
|
||||
rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN));
|
||||
rdn = (CERTRDN *)PORT_ArenaAlloc(arena, sizeof(CERTRDN));
|
||||
if (rdn) {
|
||||
/* Count number of avas going into the rdn */
|
||||
count = 0;
|
||||
if (ava0) {
|
||||
count++;
|
||||
va_start(ap, ava0);
|
||||
while ((ava = va_arg(ap, CERTAVA*)) != 0) {
|
||||
count++;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
/* Count number of avas going into the rdn */
|
||||
count = 0;
|
||||
if (ava0) {
|
||||
count++;
|
||||
va_start(ap, ava0);
|
||||
while ((ava = va_arg(ap, CERTAVA *)) != 0) {
|
||||
count++;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* Now fill in the pointers */
|
||||
rdn->avas = avap =
|
||||
(CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*));
|
||||
if (!avap) {
|
||||
return 0;
|
||||
}
|
||||
if (ava0) {
|
||||
*avap++ = ava0;
|
||||
va_start(ap, ava0);
|
||||
while ((ava = va_arg(ap, CERTAVA*)) != 0) {
|
||||
*avap++ = ava;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
*avap++ = 0;
|
||||
/* Now fill in the pointers */
|
||||
rdn->avas = avap =
|
||||
(CERTAVA **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTAVA *));
|
||||
if (!avap) {
|
||||
return 0;
|
||||
}
|
||||
if (ava0) {
|
||||
*avap++ = ava0;
|
||||
va_start(ap, ava0);
|
||||
while ((ava = va_arg(ap, CERTAVA *)) != 0) {
|
||||
*avap++ = ava;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
*avap++ = 0;
|
||||
}
|
||||
return rdn;
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ CERT_CreateRDN(PLArenaPool *arena, CERTAVA *ava0, ...)
|
|||
SECStatus
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -297,20 +297,20 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
|
|||
/* Copy each ava from from */
|
||||
avas = from->avas;
|
||||
if (avas) {
|
||||
if (avas[0] == NULL) {
|
||||
rv = CERT_AddAVA(arena, to, NULL);
|
||||
return rv;
|
||||
}
|
||||
while ((fava = *avas++) != 0) {
|
||||
tava = CERT_CopyAVA(arena, fava);
|
||||
if (!tava) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
rv = CERT_AddAVA(arena, to, tava);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
if (avas[0] == NULL) {
|
||||
rv = CERT_AddAVA(arena, to, NULL);
|
||||
return rv;
|
||||
}
|
||||
while ((fava = *avas++) != 0) {
|
||||
tava = CERT_CopyAVA(arena, fava);
|
||||
if (!tava) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
rv = CERT_AddAVA(arena, to, tava);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -318,8 +318,8 @@ CERT_CopyRDN(PLArenaPool *arena, CERTRDN *to, CERTRDN *from)
|
|||
/************************************************************************/
|
||||
|
||||
const SEC_ASN1Template CERT_NameTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE_OF,
|
||||
offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) }
|
||||
{ SEC_ASN1_SEQUENCE_OF, offsetof(CERTName, rdns), CERT_RDNTemplate,
|
||||
sizeof(CERTName) }
|
||||
};
|
||||
|
||||
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate)
|
||||
|
@ -333,71 +333,72 @@ CERT_CreateName(CERTRDN *rdn0, ...)
|
|||
unsigned count;
|
||||
CERTRDN **rdnp;
|
||||
PLArenaPool *arena;
|
||||
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if ( !arena ) {
|
||||
return(0);
|
||||
if (!arena) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName));
|
||||
|
||||
name = (CERTName *)PORT_ArenaAlloc(arena, sizeof(CERTName));
|
||||
if (name) {
|
||||
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);
|
||||
}
|
||||
name->arena = arena;
|
||||
|
||||
/* Allocate space (including space for terminal null ptr) */
|
||||
name->rdns = rdnp =
|
||||
(CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*));
|
||||
if (!name->rdns) {
|
||||
goto loser;
|
||||
}
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Now fill in the pointers */
|
||||
if (count > 0) {
|
||||
*rdnp++ = rdn0;
|
||||
va_start(ap, rdn0);
|
||||
while ((rdn = va_arg(ap, CERTRDN*)) != 0) {
|
||||
*rdnp++ = rdn;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
/* Allocate space (including space for terminal null ptr) */
|
||||
name->rdns = rdnp =
|
||||
(CERTRDN **)PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN *));
|
||||
if (!name->rdns) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* null terminate the list */
|
||||
*rdnp++ = 0;
|
||||
/* Now fill in the pointers */
|
||||
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;
|
||||
|
||||
loser:
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
CERT_DestroyName(CERTName *name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
if (name) {
|
||||
PLArenaPool *arena = name->arena;
|
||||
name->rdns = NULL;
|
||||
name->arena = NULL;
|
||||
if (arena) PORT_FreeArena(arena, PR_FALSE);
|
||||
name->arena = NULL;
|
||||
if (arena)
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -408,8 +409,8 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
|
|||
SECStatus rv = SECSuccess;
|
||||
|
||||
if (!to || !from) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
CERT_DestroyName(to);
|
||||
|
@ -418,23 +419,23 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
|
|||
/* Copy each rdn from from */
|
||||
rdns = from->rdns;
|
||||
if (rdns) {
|
||||
if (rdns[0] == NULL) {
|
||||
rv = CERT_AddRDN(to, NULL);
|
||||
return rv;
|
||||
}
|
||||
while ((frdn = *rdns++) != NULL) {
|
||||
trdn = CERT_CreateRDN(arena, NULL);
|
||||
if (!trdn) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
rv = CERT_CopyRDN(arena, trdn, frdn);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = CERT_AddRDN(to, trdn);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
if (rdns[0] == NULL) {
|
||||
rv = CERT_AddRDN(to, NULL);
|
||||
return rv;
|
||||
}
|
||||
while ((frdn = *rdns++) != NULL) {
|
||||
trdn = CERT_CreateRDN(arena, NULL);
|
||||
if (!trdn) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
rv = CERT_CopyRDN(arena, trdn, frdn);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = CERT_AddRDN(to, trdn);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -442,34 +443,36 @@ CERT_CopyName(PLArenaPool *arena, CERTName *to, const CERTName *from)
|
|||
/************************************************************************/
|
||||
|
||||
static void
|
||||
canonicalize(SECItem * foo)
|
||||
canonicalize(SECItem *foo)
|
||||
{
|
||||
int ch, lastch, len, src, dest;
|
||||
|
||||
/* strip trailing whitespace. */
|
||||
len = foo->len;
|
||||
while (len > 0 && ((ch = foo->data[len - 1]) == ' ' ||
|
||||
ch == '\t' || ch == '\r' || ch == '\n')) {
|
||||
len--;
|
||||
while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || ch == '\t' ||
|
||||
ch == '\r' || ch == '\n')) {
|
||||
len--;
|
||||
}
|
||||
|
||||
src = 0;
|
||||
/* strip leading whitespace. */
|
||||
while (src < len && ((ch = foo->data[src]) == ' ' ||
|
||||
ch == '\t' || ch == '\r' || ch == '\n')) {
|
||||
src++;
|
||||
while (src < len && ((ch = foo->data[src]) == ' ' || ch == '\t' ||
|
||||
ch == '\r' || ch == '\n')) {
|
||||
src++;
|
||||
}
|
||||
dest = 0; lastch = ' ';
|
||||
dest = 0;
|
||||
lastch = ' ';
|
||||
while (src < len) {
|
||||
ch = foo->data[src++];
|
||||
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
|
||||
ch = ' ';
|
||||
if (ch == lastch)
|
||||
continue;
|
||||
} else if (ch >= 'A' && ch <= 'Z') {
|
||||
ch |= 0x20; /* downshift */
|
||||
}
|
||||
foo->data[dest++] = lastch = ch;
|
||||
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {
|
||||
ch = ' ';
|
||||
if (ch == lastch)
|
||||
continue;
|
||||
}
|
||||
else if (ch >= 'A' && ch <= 'Z') {
|
||||
ch |= 0x20; /* downshift */
|
||||
}
|
||||
foo->data[dest++] = lastch = ch;
|
||||
}
|
||||
foo->len = dest;
|
||||
}
|
||||
|
@ -479,14 +482,13 @@ SECComparison
|
|||
CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b)
|
||||
{
|
||||
SECComparison rv = SECLessThan;
|
||||
SECItem * aVal = CERT_DecodeAVAValue(a);
|
||||
SECItem * bVal = CERT_DecodeAVAValue(b);
|
||||
SECItem *aVal = CERT_DecodeAVAValue(a);
|
||||
SECItem *bVal = CERT_DecodeAVAValue(b);
|
||||
|
||||
if (aVal && aVal->len && aVal->data &&
|
||||
bVal && bVal->len && bVal->data) {
|
||||
canonicalize(aVal);
|
||||
canonicalize(bVal);
|
||||
rv = SECITEM_CompareItem(aVal, bVal);
|
||||
if (aVal && aVal->len && aVal->data && bVal && bVal->len && bVal->data) {
|
||||
canonicalize(aVal);
|
||||
canonicalize(bVal);
|
||||
rv = SECITEM_CompareItem(aVal, bVal);
|
||||
}
|
||||
SECITEM_FreeItem(aVal, 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);
|
||||
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. */
|
||||
rv = SECITEM_CompareItem(&a->value, &b->value);
|
||||
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) {
|
||||
/* Here, the values did not match.
|
||||
** If the values had different encodings, convert them to the same
|
||||
** encoding and compare that way.
|
||||
*/
|
||||
if (a->value.data[0] != b->value.data[0]) {
|
||||
/* encodings differ. Convert both to UTF-8 and compare. */
|
||||
SECItem * aVal = CERT_DecodeAVAValue(&a->value);
|
||||
SECItem * bVal = CERT_DecodeAVAValue(&b->value);
|
||||
if (aVal && aVal->len && aVal->data &&
|
||||
bVal && bVal->len && bVal->data) {
|
||||
rv = SECITEM_CompareItem(aVal, bVal);
|
||||
}
|
||||
SECITEM_FreeItem(aVal, PR_TRUE);
|
||||
SECITEM_FreeItem(bVal, PR_TRUE);
|
||||
} else if (a->value.data[0] == 0x13) { /* both are printable strings. */
|
||||
/* printable strings */
|
||||
rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
|
||||
}
|
||||
/* Here, the values did not match.
|
||||
** If the values had different encodings, convert them to the same
|
||||
** encoding and compare that way.
|
||||
*/
|
||||
if (a->value.data[0] != b->value.data[0]) {
|
||||
/* encodings differ. Convert both to UTF-8 and compare. */
|
||||
SECItem *aVal = CERT_DecodeAVAValue(&a->value);
|
||||
SECItem *bVal = CERT_DecodeAVAValue(&b->value);
|
||||
if (aVal && aVal->len && aVal->data && bVal && bVal->len &&
|
||||
bVal->data) {
|
||||
rv = SECITEM_CompareItem(aVal, bVal);
|
||||
}
|
||||
SECITEM_FreeItem(aVal, PR_TRUE);
|
||||
SECITEM_FreeItem(bVal, PR_TRUE);
|
||||
}
|
||||
else if (a->value.data[0] == 0x13) { /* both are printable strings. */
|
||||
/* printable strings */
|
||||
rv = CERT_CompareDERPrintableStrings(&a->value, &b->value);
|
||||
}
|
||||
}
|
||||
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
|
||||
** not equal
|
||||
*/
|
||||
ac = CountArray((void**) aavas);
|
||||
bc = CountArray((void**) bavas);
|
||||
if (ac < bc) return SECLessThan;
|
||||
if (ac > bc) return SECGreaterThan;
|
||||
ac = CountArray((void **)aavas);
|
||||
bc = CountArray((void **)bavas);
|
||||
if (ac < bc)
|
||||
return SECLessThan;
|
||||
if (ac > bc)
|
||||
return SECGreaterThan;
|
||||
|
||||
while (NULL != (aava = *aavas++)) {
|
||||
for (bavas = b->avas; NULL != (bava = *bavas++); ) {
|
||||
rv = SECITEM_CompareItem(&aava->type, &bava->type);
|
||||
if (SECEqual == rv) {
|
||||
rv = CERT_CompareAVA(aava, bava);
|
||||
if (SECEqual != rv)
|
||||
return rv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bava) /* didn't find a match */
|
||||
return SECGreaterThan;
|
||||
for (bavas = b->avas; NULL != (bava = *bavas++);) {
|
||||
rv = SECITEM_CompareItem(&aava->type, &bava->type);
|
||||
if (SECEqual == rv) {
|
||||
rv = CERT_CompareAVA(aava, bava);
|
||||
if (SECEqual != rv)
|
||||
return rv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bava) /* didn't find a match */
|
||||
return SECGreaterThan;
|
||||
}
|
||||
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
|
||||
** not equal
|
||||
*/
|
||||
ac = CountArray((void**) ardns);
|
||||
bc = CountArray((void**) brdns);
|
||||
if (ac < bc) return SECLessThan;
|
||||
if (ac > bc) return SECGreaterThan;
|
||||
ac = CountArray((void **)ardns);
|
||||
bc = CountArray((void **)brdns);
|
||||
if (ac < bc)
|
||||
return SECLessThan;
|
||||
if (ac > bc)
|
||||
return SECGreaterThan;
|
||||
|
||||
for (;;) {
|
||||
ardn = *ardns++;
|
||||
brdn = *brdns++;
|
||||
if (!ardn) {
|
||||
break;
|
||||
}
|
||||
rv = CERT_CompareRDN(ardn, brdn);
|
||||
if (rv) return rv;
|
||||
ardn = *ardns++;
|
||||
brdn = *brdns++;
|
||||
if (!ardn) {
|
||||
break;
|
||||
}
|
||||
rv = CERT_CompareRDN(ardn, brdn);
|
||||
if (rv)
|
||||
return rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -600,47 +608,47 @@ CERT_CompareName(const CERTName *a, const CERTName *b)
|
|||
SECItem *
|
||||
CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
{
|
||||
SECItem *retItem;
|
||||
const SEC_ASN1Template *theTemplate = NULL;
|
||||
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
|
||||
SECItem avaValue = {siBuffer, 0};
|
||||
PLArenaPool *newarena = NULL;
|
||||
SECItem *retItem;
|
||||
const SEC_ASN1Template *theTemplate = NULL;
|
||||
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
|
||||
SECItem avaValue = { siBuffer, 0 };
|
||||
PLArenaPool *newarena = NULL;
|
||||
|
||||
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(derAVAValue->data[0]) {
|
||||
case SEC_ASN1_UNIVERSAL_STRING:
|
||||
convert = conv_ucs4;
|
||||
theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_IA5_STRING:
|
||||
theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_PRINTABLE_STRING:
|
||||
theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_T61_STRING:
|
||||
/*
|
||||
* Per common practice, we're not decoding actual T.61, but instead
|
||||
* treating T61-labeled strings as containing ISO-8859-1.
|
||||
*/
|
||||
convert = conv_iso88591;
|
||||
theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_BMP_STRING:
|
||||
convert = conv_ucs2;
|
||||
theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_UTF8_STRING:
|
||||
/* No conversion needed ! */
|
||||
theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
switch (derAVAValue->data[0]) {
|
||||
case SEC_ASN1_UNIVERSAL_STRING:
|
||||
convert = conv_ucs4;
|
||||
theTemplate = SEC_ASN1_GET(SEC_UniversalStringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_IA5_STRING:
|
||||
theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_PRINTABLE_STRING:
|
||||
theTemplate = SEC_ASN1_GET(SEC_PrintableStringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_T61_STRING:
|
||||
/*
|
||||
* Per common practice, we're not decoding actual T.61, but instead
|
||||
* treating T61-labeled strings as containing ISO-8859-1.
|
||||
*/
|
||||
convert = conv_iso88591;
|
||||
theTemplate = SEC_ASN1_GET(SEC_T61StringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_BMP_STRING:
|
||||
convert = conv_ucs2;
|
||||
theTemplate = SEC_ASN1_GET(SEC_BMPStringTemplate);
|
||||
break;
|
||||
case SEC_ASN1_UTF8_STRING:
|
||||
/* No conversion needed ! */
|
||||
theTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate);
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PORT_Memset(&avaValue, 0, sizeof(SECItem));
|
||||
|
@ -648,51 +656,54 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
|||
if (!newarena) {
|
||||
return NULL;
|
||||
}
|
||||
if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue)
|
||||
!= SECSuccess) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
return NULL;
|
||||
if (SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) !=
|
||||
SECSuccess) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (convert != conv_none) {
|
||||
unsigned int utf8ValLen = avaValue.len * 3;
|
||||
unsigned char *utf8Val = (unsigned char*)
|
||||
PORT_ArenaZAlloc(newarena, utf8ValLen);
|
||||
unsigned int utf8ValLen = avaValue.len * 3;
|
||||
unsigned char *utf8Val =
|
||||
(unsigned char *)PORT_ArenaZAlloc(newarena, utf8ValLen);
|
||||
|
||||
switch (convert) {
|
||||
case conv_ucs4:
|
||||
if(avaValue.len % 4 != 0 ||
|
||||
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
|
||||
utf8Val, utf8ValLen, &utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case conv_ucs2:
|
||||
if(avaValue.len % 2 != 0 ||
|
||||
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len,
|
||||
utf8Val, utf8ValLen, &utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case conv_iso88591:
|
||||
if(!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
|
||||
utf8Val, utf8ValLen, &utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case conv_none:
|
||||
PORT_Assert(0); /* not reached */
|
||||
break;
|
||||
}
|
||||
|
||||
avaValue.data = utf8Val;
|
||||
avaValue.len = utf8ValLen;
|
||||
case conv_ucs4:
|
||||
if (avaValue.len % 4 != 0 ||
|
||||
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data,
|
||||
avaValue.len, utf8Val, utf8ValLen,
|
||||
&utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case conv_ucs2:
|
||||
if (avaValue.len % 2 != 0 ||
|
||||
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data,
|
||||
avaValue.len, utf8Val, utf8ValLen,
|
||||
&utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case conv_iso88591:
|
||||
if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
|
||||
utf8Val, utf8ValLen,
|
||||
&utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case conv_none:
|
||||
PORT_Assert(0); /* not reached */
|
||||
break;
|
||||
}
|
||||
|
||||
avaValue.data = utf8Val;
|
||||
avaValue.len = utf8ValLen;
|
||||
}
|
||||
|
||||
retItem = SECITEM_DupItem(&avaValue);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -3,7 +3,7 @@
|
|||
* 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 "secasn1.h"
|
||||
#include "secport.h"
|
||||
#include "certt.h"
|
||||
#include "certt.h"
|
||||
#include "genname.h"
|
||||
#include "secerr.h"
|
||||
|
||||
|
@ -24,105 +24,106 @@ SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
|
|||
const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
||||
offsetof(CERTAuthKeyID,keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate)},
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate},
|
||||
offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
|
||||
offsetof(CERTAuthKeyID,authCertSerialNumber),
|
||||
SEC_ASN1_SUB(SEC_IntegerTemplate) },
|
||||
offsetof(CERTAuthKeyID, authCertSerialNumber),
|
||||
SEC_ASN1_SUB(SEC_IntegerTemplate) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
SECStatus CERT_EncodeAuthKeyID (PLArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue)
|
||||
SECStatus
|
||||
CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
PORT_Assert (value);
|
||||
PORT_Assert (arena);
|
||||
PORT_Assert (value->DERAuthCertIssuer == NULL);
|
||||
PORT_Assert (encodedValue);
|
||||
|
||||
PORT_Assert(value);
|
||||
PORT_Assert(arena);
|
||||
PORT_Assert(value->DERAuthCertIssuer == NULL);
|
||||
PORT_Assert(encodedValue);
|
||||
|
||||
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
|
||||
(arena, value->authCertIssuer);
|
||||
if (!value->DERAuthCertIssuer) {
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (value->authCertSerialNumber.data) {
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
break;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (SEC_ASN1EncodeItem (arena, encodedValue, value,
|
||||
CERTAuthKeyIDTemplate) == NULL)
|
||||
break;
|
||||
rv = SECSuccess;
|
||||
value->DERAuthCertIssuer =
|
||||
cert_EncodeGeneralNames(arena, value->authCertIssuer);
|
||||
if (!value->DERAuthCertIssuer) {
|
||||
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);
|
||||
return(rv);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
CERTAuthKeyID *
|
||||
CERT_DecodeAuthKeyID (PLArenaPool *arena, const SECItem *encodedValue)
|
||||
CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
|
||||
{
|
||||
CERTAuthKeyID * value = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
void * mark;
|
||||
SECItem newEncodedValue;
|
||||
CERTAuthKeyID *value = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
void *mark;
|
||||
SECItem newEncodedValue;
|
||||
|
||||
PORT_Assert(arena);
|
||||
|
||||
PORT_Assert (arena);
|
||||
|
||||
do {
|
||||
mark = PORT_ArenaMark (arena);
|
||||
value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value));
|
||||
if (value == NULL)
|
||||
break;
|
||||
value->DERAuthCertIssuer = NULL;
|
||||
mark = PORT_ArenaMark(arena);
|
||||
value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value));
|
||||
if (value == NULL)
|
||||
break;
|
||||
value->DERAuthCertIssuer = NULL;
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
|
||||
if ( rv != SECSuccess ) {
|
||||
break;
|
||||
if (rv != SECSuccess) {
|
||||
break;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem
|
||||
(arena, value, CERTAuthKeyIDTemplate, &newEncodedValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate,
|
||||
&newEncodedValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
|
||||
value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer);
|
||||
if (value->authCertIssuer == NULL)
|
||||
break;
|
||||
|
||||
/* what if the general name contains other format but not URI ?
|
||||
hl
|
||||
*/
|
||||
if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
|
||||
(!value->authCertSerialNumber.data && value->authCertIssuer)){
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
break;
|
||||
}
|
||||
value->authCertIssuer =
|
||||
cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer);
|
||||
if (value->authCertIssuer == NULL)
|
||||
break;
|
||||
|
||||
/* what if the general name contains other format but not URI ?
|
||||
hl
|
||||
*/
|
||||
if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
|
||||
(!value->authCertSerialNumber.data && value->authCertIssuer)) {
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
PORT_ArenaRelease (arena, mark);
|
||||
return ((CERTAuthKeyID *)NULL);
|
||||
}
|
||||
PORT_ArenaRelease(arena, mark);
|
||||
return ((CERTAuthKeyID *)NULL);
|
||||
}
|
||||
PORT_ArenaUnmark(arena, mark);
|
||||
return (value);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
* 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 <limits.h> /* for LONG_MAX */
|
||||
#include <limits.h> /* for LONG_MAX */
|
||||
#include "seccomon.h"
|
||||
#include "secdert.h"
|
||||
#include "secoidt.h"
|
||||
|
@ -18,128 +18,132 @@
|
|||
#include "prprf.h"
|
||||
#include "secerr.h"
|
||||
|
||||
typedef struct EncodedContext{
|
||||
typedef struct EncodedContext {
|
||||
SECItem isCA;
|
||||
SECItem pathLenConstraint;
|
||||
SECItem encodedValue;
|
||||
PLArenaPool *arena;
|
||||
}EncodedContext;
|
||||
} EncodedContext;
|
||||
|
||||
static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(EncodedContext) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
||||
offsetof(EncodedContext,isCA)},
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(EncodedContext) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
||||
offsetof(EncodedContext, isCA) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
|
||||
offsetof(EncodedContext,pathLenConstraint) },
|
||||
{ 0, }
|
||||
offsetof(EncodedContext, pathLenConstraint) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static unsigned char hexTrue = 0xff;
|
||||
static unsigned char hexFalse = 0x00;
|
||||
|
||||
#define GEN_BREAK(status) rv = status; break;
|
||||
#define GEN_BREAK(status) \
|
||||
rv = status; \
|
||||
break;
|
||||
|
||||
SECStatus CERT_EncodeBasicConstraintValue
|
||||
(PLArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue)
|
||||
SECStatus
|
||||
CERT_EncodeBasicConstraintValue(PLArenaPool *arena, CERTBasicConstraints *value,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
EncodedContext encodeContext;
|
||||
PLArenaPool *our_pool = NULL;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
do {
|
||||
PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
|
||||
if (!value->isCA && value->pathLenConstraint >= 0) {
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
GEN_BREAK (SECFailure);
|
||||
}
|
||||
PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
|
||||
if (!value->isCA && value->pathLenConstraint >= 0) {
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
GEN_BREAK(SECFailure);
|
||||
}
|
||||
|
||||
encodeContext.arena = arena;
|
||||
if (value->isCA == PR_TRUE) {
|
||||
encodeContext.isCA.data = &hexTrue ;
|
||||
encodeContext.isCA.len = 1;
|
||||
}
|
||||
if (value->isCA == PR_TRUE) {
|
||||
encodeContext.isCA.data = &hexTrue;
|
||||
encodeContext.isCA.len = 1;
|
||||
}
|
||||
|
||||
/* If the pathLenConstraint is less than 0, then it should be
|
||||
* omitted from the encoding.
|
||||
*/
|
||||
if (value->isCA && value->pathLenConstraint >= 0) {
|
||||
our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (our_pool == NULL) {
|
||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
||||
GEN_BREAK (SECFailure);
|
||||
}
|
||||
if (SEC_ASN1EncodeUnsignedInteger
|
||||
(our_pool, &encodeContext.pathLenConstraint,
|
||||
(unsigned long)value->pathLenConstraint) == NULL) {
|
||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
||||
GEN_BREAK (SECFailure);
|
||||
}
|
||||
}
|
||||
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
|
||||
CERTBasicConstraintsTemplate) == NULL) {
|
||||
GEN_BREAK (SECFailure);
|
||||
}
|
||||
/* If the pathLenConstraint is less than 0, then it should be
|
||||
* omitted from the encoding.
|
||||
*/
|
||||
if (value->isCA && value->pathLenConstraint >= 0) {
|
||||
our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (our_pool == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
GEN_BREAK(SECFailure);
|
||||
}
|
||||
if (SEC_ASN1EncodeUnsignedInteger(
|
||||
our_pool, &encodeContext.pathLenConstraint,
|
||||
(unsigned long)value->pathLenConstraint) == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
GEN_BREAK(SECFailure);
|
||||
}
|
||||
}
|
||||
if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
|
||||
CERTBasicConstraintsTemplate) == NULL) {
|
||||
GEN_BREAK(SECFailure);
|
||||
}
|
||||
} while (0);
|
||||
if (our_pool)
|
||||
PORT_FreeArena (our_pool, PR_FALSE);
|
||||
return(rv);
|
||||
|
||||
PORT_FreeArena(our_pool, PR_FALSE);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
SECStatus CERT_DecodeBasicConstraintValue
|
||||
(CERTBasicConstraints *value, const SECItem *encodedValue)
|
||||
SECStatus
|
||||
CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
|
||||
const SECItem *encodedValue)
|
||||
{
|
||||
EncodedContext decodeContext;
|
||||
PLArenaPool *our_pool;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
do {
|
||||
PORT_Memset (&decodeContext, 0, sizeof (decodeContext));
|
||||
/* initialize the value just in case we got "0x30 00", or when the
|
||||
pathLenConstraint is omitted.
|
||||
PORT_Memset(&decodeContext, 0, sizeof(decodeContext));
|
||||
/* initialize the value just in case we got "0x30 00", or when the
|
||||
pathLenConstraint is omitted.
|
||||
*/
|
||||
decodeContext.isCA.data =&hexFalse;
|
||||
decodeContext.isCA.len = 1;
|
||||
|
||||
our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (our_pool == NULL) {
|
||||
PORT_SetError (SEC_ERROR_NO_MEMORY);
|
||||
GEN_BREAK (SECFailure);
|
||||
}
|
||||
decodeContext.isCA.data = &hexFalse;
|
||||
decodeContext.isCA.len = 1;
|
||||
|
||||
our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (our_pool == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
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);
|
||||
PORT_FreeArena (our_pool, PR_FALSE);
|
||||
PORT_FreeArena(our_pool, PR_FALSE);
|
||||
return (rv);
|
||||
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* X.509 Extension Encoding
|
||||
* X.509 Extension Encoding
|
||||
*/
|
||||
|
||||
#include "prtypes.h"
|
||||
|
@ -20,12 +20,10 @@
|
|||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
|
||||
|
||||
static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
|
||||
{ SEC_ASN1_OCTET_STRING }
|
||||
};
|
||||
|
||||
|
||||
static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
|
||||
{ SEC_ASN1_IA5_STRING }
|
||||
};
|
||||
|
@ -33,40 +31,34 @@ static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
|
|||
SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
|
||||
|
||||
static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
||||
offsetof(CERTPrivKeyUsagePeriod, notBefore),
|
||||
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
||||
offsetof(CERTPrivKeyUsagePeriod, notAfter),
|
||||
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate)},
|
||||
{ 0, }
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
|
||||
offsetof(CERTPrivKeyUsagePeriod, notBefore),
|
||||
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
||||
offsetof(CERTPrivKeyUsagePeriod, notAfter),
|
||||
SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
const SEC_ASN1Template CERTAltNameTemplate[] = {
|
||||
{ SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
|
||||
CERT_GeneralNamesTemplate}
|
||||
{ SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
|
||||
CERT_GeneralNamesTemplate }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTAuthInfoAccess) },
|
||||
{ SEC_ASN1_OBJECT_ID,
|
||||
offsetof(CERTAuthInfoAccess, method) },
|
||||
{ SEC_ASN1_ANY,
|
||||
offsetof(CERTAuthInfoAccess, derLocation) },
|
||||
{ 0, }
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthInfoAccess) },
|
||||
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAuthInfoAccess, method) },
|
||||
{ SEC_ASN1_ANY, offsetof(CERTAuthInfoAccess, derLocation) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
|
||||
};
|
||||
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
|
||||
SECStatus
|
||||
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
@ -75,27 +67,26 @@ CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem* srcString,
|
|||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (SEC_ASN1EncodeItem (arena, encodedValue, srcString,
|
||||
CERTSubjectKeyIDTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
|
||||
CERTSubjectKeyIDTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
return(rv);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
||||
CERTPrivKeyUsagePeriod *pkup,
|
||||
SECItem *encodedValue)
|
||||
CERTPrivKeyUsagePeriod *pkup,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
if (SEC_ASN1EncodeItem (arena, encodedValue, pkup,
|
||||
CERTPrivateKeyUsagePeriodTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
if (SEC_ASN1EncodeItem(arena, encodedValue, pkup,
|
||||
CERTPrivateKeyUsagePeriodTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
}
|
||||
return(rv);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
CERTPrivKeyUsagePeriod *
|
||||
|
@ -107,63 +98,62 @@ CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
|
|||
|
||||
/* allocate the certificate policies structure */
|
||||
pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
|
||||
if ( pPeriod == NULL ) {
|
||||
goto loser;
|
||||
if (pPeriod == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
|
||||
pPeriod->arena = arena;
|
||||
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, pPeriod,
|
||||
CERTPrivateKeyUsagePeriodTemplate,
|
||||
&newExtnValue);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
rv = SEC_QuickDERDecodeItem(
|
||||
arena, pPeriod, CERTPrivateKeyUsagePeriodTemplate, &newExtnValue);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
return pPeriod;
|
||||
|
||||
|
||||
loser:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value, SECItem *encodedValue)
|
||||
SECStatus
|
||||
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
SECItem encodeContext;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
|
||||
|
||||
PORT_Memset (&encodeContext, 0, sizeof (encodeContext));
|
||||
|
||||
if (value != NULL) {
|
||||
encodeContext.data = (unsigned char *)value;
|
||||
encodeContext.len = strlen(value);
|
||||
encodeContext.data = (unsigned char *)value;
|
||||
encodeContext.len = strlen(value);
|
||||
}
|
||||
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext,
|
||||
CERTIA5TypeTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
|
||||
CERTIA5TypeTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
return(rv);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue)
|
||||
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
SECItem **encodedGenName;
|
||||
SECStatus rv = SECSuccess;
|
||||
SECItem **encodedGenName;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
encodedGenName = cert_EncodeGeneralNames(arena, value);
|
||||
if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName,
|
||||
CERT_GeneralNamesTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
|
||||
CERT_GeneralNamesTemplate) == NULL) {
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -172,9 +162,9 @@ CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value, SECIte
|
|||
CERTGeneralName *
|
||||
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
CERTAltNameEncodedContext encodedContext;
|
||||
SECItem* newEncodedAltName;
|
||||
SECStatus rv = SECSuccess;
|
||||
CERTAltNameEncodedContext encodedContext;
|
||||
SECItem *newEncodedAltName;
|
||||
|
||||
if (!reqArena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -188,14 +178,13 @@ CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
|
|||
|
||||
encodedContext.encodedGenName = NULL;
|
||||
PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
|
||||
rv = SEC_QuickDERDecodeItem (reqArena, &encodedContext,
|
||||
CERT_GeneralNamesTemplate, newEncodedAltName);
|
||||
rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
|
||||
CERT_GeneralNamesTemplate, newEncodedAltName);
|
||||
if (rv == SECFailure) {
|
||||
goto loser;
|
||||
goto loser;
|
||||
}
|
||||
if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
|
||||
return cert_DecodeGeneralNames(reqArena,
|
||||
encodedContext.encodedGenName);
|
||||
return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
|
||||
/* Extension contained an empty GeneralNames sequence */
|
||||
/* Treat as extension not found */
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
|
||||
|
@ -203,35 +192,32 @@ loser:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
||||
CERTNameConstraints *value,
|
||||
SECItem *encodedValue)
|
||||
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
||||
CERTNameConstraints *value,
|
||||
SECItem *encodedValue)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
rv = cert_EncodeNameConstraints(value, arena, encodedValue);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
CERTNameConstraints *
|
||||
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
|
||||
const SECItem *encodedConstraints)
|
||||
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
|
||||
const SECItem *encodedConstraints)
|
||||
{
|
||||
return cert_DecodeNameConstraints(arena, encodedConstraints);
|
||||
}
|
||||
|
||||
|
||||
CERTAuthInfoAccess **
|
||||
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
|
||||
const SECItem *encodedExtension)
|
||||
const SECItem *encodedExtension)
|
||||
{
|
||||
CERTAuthInfoAccess **info = NULL;
|
||||
SECStatus rv;
|
||||
int i;
|
||||
SECItem* newEncodedExtension;
|
||||
SECItem *newEncodedExtension;
|
||||
|
||||
if (!reqArena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -243,24 +229,22 @@ CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
|
||||
newEncodedExtension);
|
||||
rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
|
||||
newEncodedExtension);
|
||||
if (rv != SECSuccess || info == NULL) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; info[i] != NULL; i++) {
|
||||
info[i]->location = CERT_DecodeGeneralName(reqArena,
|
||||
&(info[i]->derLocation),
|
||||
NULL);
|
||||
info[i]->location =
|
||||
CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
|
||||
CERTAuthInfoAccess **info,
|
||||
SECItem *dest)
|
||||
CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
|
||||
SECItem *dest)
|
||||
{
|
||||
SECItem *dummy;
|
||||
int i;
|
||||
|
@ -268,19 +252,18 @@ CERT_EncodeInfoAccessExtension(PLArenaPool *arena,
|
|||
PORT_Assert(info != NULL);
|
||||
PORT_Assert(dest != NULL);
|
||||
if (info == NULL || dest == NULL) {
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
for (i = 0; info[i] != NULL; i++) {
|
||||
if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
|
||||
arena) == NULL)
|
||||
/* Note that this may leave some of the locations filled in. */
|
||||
return SECFailure;
|
||||
if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
|
||||
arena) == NULL)
|
||||
/* Note that this may leave some of the locations filled in. */
|
||||
return SECFailure;
|
||||
}
|
||||
dummy = SEC_ASN1EncodeItem(arena, dest, &info,
|
||||
CERTAuthInfoAccessTemplate);
|
||||
dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
|
||||
if (dummy == NULL) {
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
|
@ -10,27 +10,21 @@ typedef struct CERTAltNameEncodedContextStr {
|
|||
SECItem **encodedGenName;
|
||||
} CERTAltNameEncodedContext;
|
||||
|
||||
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
extern SECStatus
|
||||
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
||||
CERTPrivKeyUsagePeriod *pkup,
|
||||
SECItem *encodedValue);
|
||||
extern SECStatus CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
|
||||
CERTPrivKeyUsagePeriod *pkup,
|
||||
SECItem *encodedValue);
|
||||
|
||||
extern SECStatus
|
||||
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
||||
CERTNameConstraints *value,
|
||||
SECItem *encodedValue);
|
||||
extern SECStatus CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
|
||||
CERTNameConstraints *value,
|
||||
SECItem *encodedValue);
|
||||
|
||||
extern SECStatus
|
||||
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
|
||||
SECItem *encodedValue);
|
||||
extern SECStatus CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
|
||||
SECItem *encodedValue);
|
||||
|
||||
SECStatus
|
||||
cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
|
||||
CERTAuthInfoAccess **info,
|
||||
SECItem *dest);
|
||||
SECStatus cert_EncodeAuthInfoAccessExtension(PLArenaPool *arena,
|
||||
CERTAuthInfoAccess **info,
|
||||
SECItem *dest);
|
||||
SEC_END_PROTOS
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -22,31 +22,33 @@ static char *hex = "0123456789ABCDEF";
|
|||
/*
|
||||
** 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;
|
||||
char *rv, *o;
|
||||
|
||||
if (!i->len) {
|
||||
return PORT_Strdup("00");
|
||||
return PORT_Strdup("00");
|
||||
}
|
||||
|
||||
rv = o = (char*) PORT_Alloc(i->len * 3);
|
||||
if (!rv) return rv;
|
||||
rv = o = (char *)PORT_Alloc(i->len * 3);
|
||||
if (!rv)
|
||||
return rv;
|
||||
|
||||
cp = i->data;
|
||||
end = cp + i->len;
|
||||
while (cp < end) {
|
||||
unsigned char ch = *cp++;
|
||||
*o++ = hex[(ch >> 4) & 0xf];
|
||||
*o++ = hex[ch & 0xf];
|
||||
if (cp != end) {
|
||||
if (do_colon) {
|
||||
*o++ = ':';
|
||||
}
|
||||
}
|
||||
unsigned char ch = *cp++;
|
||||
*o++ = hex[(ch >> 4) & 0xf];
|
||||
*o++ = hex[ch & 0xf];
|
||||
if (cp != end) {
|
||||
if (do_colon) {
|
||||
*o++ = ':';
|
||||
}
|
||||
}
|
||||
}
|
||||
*o = 0; /* Null terminate the string */
|
||||
*o = 0; /* Null terminate the string */
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -58,132 +60,132 @@ char *CERT_Hexify (SECItem *i, int do_colon)
|
|||
#define MAX_OUS 20
|
||||
#define MAX_DC MAX_OUS
|
||||
|
||||
|
||||
char *CERT_FormatName (CERTName *name)
|
||||
char *
|
||||
CERT_FormatName(CERTName *name)
|
||||
{
|
||||
CERTRDN** rdns;
|
||||
CERTRDN * rdn;
|
||||
CERTAVA** avas;
|
||||
CERTAVA* ava;
|
||||
char * buf = 0;
|
||||
char * tmpbuf = 0;
|
||||
SECItem * cn = 0;
|
||||
SECItem * email = 0;
|
||||
SECItem * org = 0;
|
||||
SECItem * loc = 0;
|
||||
SECItem * state = 0;
|
||||
SECItem * country = 0;
|
||||
SECItem * dq = 0;
|
||||
CERTRDN **rdns;
|
||||
CERTRDN *rdn;
|
||||
CERTAVA **avas;
|
||||
CERTAVA *ava;
|
||||
char *buf = 0;
|
||||
char *tmpbuf = 0;
|
||||
SECItem *cn = 0;
|
||||
SECItem *email = 0;
|
||||
SECItem *org = 0;
|
||||
SECItem *loc = 0;
|
||||
SECItem *state = 0;
|
||||
SECItem *country = 0;
|
||||
SECItem *dq = 0;
|
||||
|
||||
unsigned len = 0;
|
||||
int tag;
|
||||
int i;
|
||||
int ou_count = 0;
|
||||
int dc_count = 0;
|
||||
PRBool first;
|
||||
SECItem * orgunit[MAX_OUS];
|
||||
SECItem * dc[MAX_DC];
|
||||
unsigned len = 0;
|
||||
int tag;
|
||||
int i;
|
||||
int ou_count = 0;
|
||||
int dc_count = 0;
|
||||
PRBool first;
|
||||
SECItem *orgunit[MAX_OUS];
|
||||
SECItem *dc[MAX_DC];
|
||||
|
||||
/* Loop over name components and gather the interesting ones */
|
||||
rdns = name->rdns;
|
||||
while ((rdn = *rdns++) != 0) {
|
||||
avas = rdn->avas;
|
||||
while ((ava = *avas++) != 0) {
|
||||
tag = CERT_GetAVATag(ava);
|
||||
switch(tag) {
|
||||
case SEC_OID_AVA_COMMON_NAME:
|
||||
if (cn) {
|
||||
break;
|
||||
}
|
||||
cn = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!cn) {
|
||||
goto loser;
|
||||
}
|
||||
len += cn->len;
|
||||
break;
|
||||
case SEC_OID_AVA_COUNTRY_NAME:
|
||||
if (country) {
|
||||
break;
|
||||
}
|
||||
country = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!country) {
|
||||
goto loser;
|
||||
}
|
||||
len += country->len;
|
||||
break;
|
||||
case SEC_OID_AVA_LOCALITY:
|
||||
if (loc) {
|
||||
break;
|
||||
}
|
||||
loc = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!loc) {
|
||||
goto loser;
|
||||
}
|
||||
len += loc->len;
|
||||
break;
|
||||
case SEC_OID_AVA_STATE_OR_PROVINCE:
|
||||
if (state) {
|
||||
break;
|
||||
}
|
||||
state = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!state) {
|
||||
goto loser;
|
||||
}
|
||||
len += state->len;
|
||||
break;
|
||||
case SEC_OID_AVA_ORGANIZATION_NAME:
|
||||
if (org) {
|
||||
break;
|
||||
}
|
||||
org = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!org) {
|
||||
goto loser;
|
||||
}
|
||||
len += org->len;
|
||||
break;
|
||||
case SEC_OID_AVA_DN_QUALIFIER:
|
||||
if (dq) {
|
||||
break;
|
||||
}
|
||||
dq = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!dq) {
|
||||
goto loser;
|
||||
}
|
||||
len += dq->len;
|
||||
break;
|
||||
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
|
||||
if (ou_count < MAX_OUS) {
|
||||
orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!orgunit[ou_count]) {
|
||||
goto loser;
|
||||
avas = rdn->avas;
|
||||
while ((ava = *avas++) != 0) {
|
||||
tag = CERT_GetAVATag(ava);
|
||||
switch (tag) {
|
||||
case SEC_OID_AVA_COMMON_NAME:
|
||||
if (cn) {
|
||||
break;
|
||||
}
|
||||
cn = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!cn) {
|
||||
goto loser;
|
||||
}
|
||||
len += cn->len;
|
||||
break;
|
||||
case SEC_OID_AVA_COUNTRY_NAME:
|
||||
if (country) {
|
||||
break;
|
||||
}
|
||||
country = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!country) {
|
||||
goto loser;
|
||||
}
|
||||
len += country->len;
|
||||
break;
|
||||
case SEC_OID_AVA_LOCALITY:
|
||||
if (loc) {
|
||||
break;
|
||||
}
|
||||
loc = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!loc) {
|
||||
goto loser;
|
||||
}
|
||||
len += loc->len;
|
||||
break;
|
||||
case SEC_OID_AVA_STATE_OR_PROVINCE:
|
||||
if (state) {
|
||||
break;
|
||||
}
|
||||
state = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!state) {
|
||||
goto loser;
|
||||
}
|
||||
len += state->len;
|
||||
break;
|
||||
case SEC_OID_AVA_ORGANIZATION_NAME:
|
||||
if (org) {
|
||||
break;
|
||||
}
|
||||
org = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!org) {
|
||||
goto loser;
|
||||
}
|
||||
len += org->len;
|
||||
break;
|
||||
case SEC_OID_AVA_DN_QUALIFIER:
|
||||
if (dq) {
|
||||
break;
|
||||
}
|
||||
dq = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!dq) {
|
||||
goto loser;
|
||||
}
|
||||
len += dq->len;
|
||||
break;
|
||||
case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME:
|
||||
if (ou_count < MAX_OUS) {
|
||||
orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!orgunit[ou_count]) {
|
||||
goto loser;
|
||||
}
|
||||
len += orgunit[ou_count++]->len;
|
||||
}
|
||||
break;
|
||||
case SEC_OID_AVA_DC:
|
||||
if (dc_count < MAX_DC) {
|
||||
dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!dc[dc_count]) {
|
||||
goto loser;
|
||||
}
|
||||
len += dc[dc_count++]->len;
|
||||
}
|
||||
break;
|
||||
case SEC_OID_PKCS9_EMAIL_ADDRESS:
|
||||
case SEC_OID_RFC1274_MAIL:
|
||||
if (email) {
|
||||
break;
|
||||
}
|
||||
email = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!email) {
|
||||
goto loser;
|
||||
}
|
||||
len += email->len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
len += orgunit[ou_count++]->len;
|
||||
}
|
||||
break;
|
||||
case SEC_OID_AVA_DC:
|
||||
if (dc_count < MAX_DC) {
|
||||
dc[dc_count] = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!dc[dc_count]) {
|
||||
goto loser;
|
||||
}
|
||||
len += dc[dc_count++]->len;
|
||||
}
|
||||
break;
|
||||
case SEC_OID_PKCS9_EMAIL_ADDRESS:
|
||||
case SEC_OID_RFC1274_MAIL:
|
||||
if (email) {
|
||||
break;
|
||||
}
|
||||
email = CERT_DecodeAVAValue(&ava->value);
|
||||
if (!email) {
|
||||
goto loser;
|
||||
}
|
||||
len += email->len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX - add some for formatting */
|
||||
|
@ -191,109 +193,108 @@ char *CERT_FormatName (CERTName *name)
|
|||
|
||||
/* allocate buffer */
|
||||
buf = (char *)PORT_Alloc(len);
|
||||
if ( !buf ) {
|
||||
goto loser;
|
||||
if (!buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
tmpbuf = buf;
|
||||
|
||||
if ( cn ) {
|
||||
PORT_Memcpy(tmpbuf, cn->data, cn->len);
|
||||
tmpbuf += cn->len;
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
|
||||
if (cn) {
|
||||
PORT_Memcpy(tmpbuf, cn->data, cn->len);
|
||||
tmpbuf += cn->len;
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
if ( email ) {
|
||||
PORT_Memcpy(tmpbuf, email->data, email->len);
|
||||
tmpbuf += ( email->len );
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
if (email) {
|
||||
PORT_Memcpy(tmpbuf, email->data, email->len);
|
||||
tmpbuf += (email->len);
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
for (i=ou_count-1; i >= 0; i--) {
|
||||
PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
|
||||
tmpbuf += ( orgunit[i]->len );
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
for (i = ou_count - 1; i >= 0; i--) {
|
||||
PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len);
|
||||
tmpbuf += (orgunit[i]->len);
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
if ( dq ) {
|
||||
PORT_Memcpy(tmpbuf, dq->data, dq->len);
|
||||
tmpbuf += ( dq->len );
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
if (dq) {
|
||||
PORT_Memcpy(tmpbuf, dq->data, dq->len);
|
||||
tmpbuf += (dq->len);
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
if ( org ) {
|
||||
PORT_Memcpy(tmpbuf, org->data, org->len);
|
||||
tmpbuf += ( org->len );
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
if (org) {
|
||||
PORT_Memcpy(tmpbuf, org->data, org->len);
|
||||
tmpbuf += (org->len);
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
for (i=dc_count-1; i >= 0; i--) {
|
||||
PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
|
||||
tmpbuf += ( dc[i]->len );
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
for (i = dc_count - 1; i >= 0; i--) {
|
||||
PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len);
|
||||
tmpbuf += (dc[i]->len);
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
first = PR_TRUE;
|
||||
if ( loc ) {
|
||||
PORT_Memcpy(tmpbuf, loc->data, loc->len);
|
||||
tmpbuf += ( loc->len );
|
||||
first = PR_FALSE;
|
||||
if (loc) {
|
||||
PORT_Memcpy(tmpbuf, loc->data, loc->len);
|
||||
tmpbuf += (loc->len);
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if ( state ) {
|
||||
if ( !first ) {
|
||||
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
||||
tmpbuf += COMMALEN;
|
||||
}
|
||||
PORT_Memcpy(tmpbuf, state->data, state->len);
|
||||
tmpbuf += ( state->len );
|
||||
first = PR_FALSE;
|
||||
if (state) {
|
||||
if (!first) {
|
||||
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
||||
tmpbuf += COMMALEN;
|
||||
}
|
||||
PORT_Memcpy(tmpbuf, state->data, state->len);
|
||||
tmpbuf += (state->len);
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if ( country ) {
|
||||
if ( !first ) {
|
||||
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
||||
tmpbuf += COMMALEN;
|
||||
}
|
||||
PORT_Memcpy(tmpbuf, country->data, country->len);
|
||||
tmpbuf += ( country->len );
|
||||
first = PR_FALSE;
|
||||
if (country) {
|
||||
if (!first) {
|
||||
PORT_Memcpy(tmpbuf, COMMA, COMMALEN);
|
||||
tmpbuf += COMMALEN;
|
||||
}
|
||||
PORT_Memcpy(tmpbuf, country->data, country->len);
|
||||
tmpbuf += (country->len);
|
||||
first = PR_FALSE;
|
||||
}
|
||||
if ( !first ) {
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
if (!first) {
|
||||
PORT_Memcpy(tmpbuf, BREAK, BREAKLEN);
|
||||
tmpbuf += BREAKLEN;
|
||||
}
|
||||
|
||||
*tmpbuf = 0;
|
||||
|
||||
/* fall through and clean */
|
||||
/* fall through and clean */
|
||||
loser:
|
||||
if ( cn ) {
|
||||
SECITEM_FreeItem(cn, PR_TRUE);
|
||||
if (cn) {
|
||||
SECITEM_FreeItem(cn, PR_TRUE);
|
||||
}
|
||||
if ( email ) {
|
||||
SECITEM_FreeItem(email, PR_TRUE);
|
||||
if (email) {
|
||||
SECITEM_FreeItem(email, PR_TRUE);
|
||||
}
|
||||
for (i=ou_count-1; i >= 0; i--) {
|
||||
SECITEM_FreeItem(orgunit[i], PR_TRUE);
|
||||
for (i = ou_count - 1; i >= 0; i--) {
|
||||
SECITEM_FreeItem(orgunit[i], PR_TRUE);
|
||||
}
|
||||
if ( dq ) {
|
||||
SECITEM_FreeItem(dq, PR_TRUE);
|
||||
if (dq) {
|
||||
SECITEM_FreeItem(dq, PR_TRUE);
|
||||
}
|
||||
if ( org ) {
|
||||
SECITEM_FreeItem(org, PR_TRUE);
|
||||
if (org) {
|
||||
SECITEM_FreeItem(org, PR_TRUE);
|
||||
}
|
||||
for (i=dc_count-1; i >= 0; i--) {
|
||||
SECITEM_FreeItem(dc[i], PR_TRUE);
|
||||
for (i = dc_count - 1; i >= 0; i--) {
|
||||
SECITEM_FreeItem(dc[i], PR_TRUE);
|
||||
}
|
||||
if ( loc ) {
|
||||
SECITEM_FreeItem(loc, PR_TRUE);
|
||||
if (loc) {
|
||||
SECITEM_FreeItem(loc, PR_TRUE);
|
||||
}
|
||||
if ( state ) {
|
||||
SECITEM_FreeItem(state, PR_TRUE);
|
||||
if (state) {
|
||||
SECITEM_FreeItem(state, PR_TRUE);
|
||||
}
|
||||
if ( country ) {
|
||||
SECITEM_FreeItem(country, PR_TRUE);
|
||||
if (country) {
|
||||
SECITEM_FreeItem(country, PR_TRUE);
|
||||
}
|
||||
|
||||
return(buf);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ SEC_ASN1_MKSUB(SEC_AnyTemplate)
|
|||
|
||||
const SEC_ASN1Template CERT_AttributeTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTAttribute) },
|
||||
0, NULL, sizeof(CERTAttribute) },
|
||||
{ SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) },
|
||||
{ SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(CERTAttribute, attrValue),
|
||||
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
||||
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -27,18 +27,18 @@ const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = {
|
|||
|
||||
const SEC_ASN1Template CERT_CertificateRequestTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTCertificateRequest) },
|
||||
0, NULL, sizeof(CERTCertificateRequest) },
|
||||
{ SEC_ASN1_INTEGER,
|
||||
offsetof(CERTCertificateRequest,version) },
|
||||
offsetof(CERTCertificateRequest, version) },
|
||||
{ SEC_ASN1_INLINE,
|
||||
offsetof(CERTCertificateRequest,subject),
|
||||
CERT_NameTemplate },
|
||||
offsetof(CERTCertificateRequest, subject),
|
||||
CERT_NameTemplate },
|
||||
{ SEC_ASN1_INLINE,
|
||||
offsetof(CERTCertificateRequest,subjectPublicKeyInfo),
|
||||
CERT_SubjectPublicKeyInfoTemplate },
|
||||
offsetof(CERTCertificateRequest, subjectPublicKeyInfo),
|
||||
CERT_SubjectPublicKeyInfoTemplate },
|
||||
{ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(CERTCertificateRequest,attributes),
|
||||
CERT_SetOfAttributeTemplate },
|
||||
offsetof(CERTCertificateRequest, attributes),
|
||||
CERT_SetOfAttributeTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -46,25 +46,25 @@ SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate)
|
|||
|
||||
CERTCertificate *
|
||||
CERT_CreateCertificate(unsigned long serialNumber,
|
||||
CERTName *issuer,
|
||||
CERTValidity *validity,
|
||||
CERTCertificateRequest *req)
|
||||
CERTName *issuer,
|
||||
CERTValidity *validity,
|
||||
CERTCertificateRequest *req)
|
||||
{
|
||||
CERTCertificate *c;
|
||||
int rv;
|
||||
PLArenaPool *arena;
|
||||
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if ( !arena ) {
|
||||
return(0);
|
||||
|
||||
if (!arena) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
|
||||
|
||||
|
||||
if (!c) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return 0;
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->referenceCount = 1;
|
||||
|
@ -75,44 +75,50 @@ CERT_CreateCertificate(unsigned long serialNumber,
|
|||
* If extensions are added, it will get changed as appropriate.
|
||||
*/
|
||||
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);
|
||||
if (rv) goto loser;
|
||||
if (rv)
|
||||
goto loser;
|
||||
|
||||
rv = CERT_CopyName(arena, &c->issuer, issuer);
|
||||
if (rv) goto loser;
|
||||
if (rv)
|
||||
goto loser;
|
||||
|
||||
rv = CERT_CopyValidity(arena, &c->validity, validity);
|
||||
if (rv) goto loser;
|
||||
if (rv)
|
||||
goto loser;
|
||||
|
||||
rv = CERT_CopyName(arena, &c->subject, &req->subject);
|
||||
if (rv) goto loser;
|
||||
if (rv)
|
||||
goto loser;
|
||||
rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo,
|
||||
&req->subjectPublicKeyInfo);
|
||||
if (rv) goto loser;
|
||||
&req->subjectPublicKeyInfo);
|
||||
if (rv)
|
||||
goto loser;
|
||||
|
||||
return c;
|
||||
|
||||
loser:
|
||||
loser:
|
||||
CERT_DestroyCertificate(c);
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* encodes attributes as a SET OF xxxxxxx. That is, it expects to encode
|
||||
* each of the Attributes, not have them pre-encoded. Consequently an
|
||||
* array of SECItems containing encoded Attributes is of no value to this
|
||||
* each of the Attributes, not have them pre-encoded. Consequently an
|
||||
* array of SECItems containing encoded Attributes is of no value to this
|
||||
* function. But we cannot change the signature of this public function.
|
||||
* 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
|
||||
* 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.
|
||||
|
@ -120,95 +126,95 @@ CERT_CreateCertificate(unsigned long serialNumber,
|
|||
|
||||
CERTCertificateRequest *
|
||||
CERT_CreateCertificateRequest(CERTName *subject,
|
||||
CERTSubjectPublicKeyInfo *spki,
|
||||
SECItem **attributes)
|
||||
CERTSubjectPublicKeyInfo *spki,
|
||||
SECItem **attributes)
|
||||
{
|
||||
CERTCertificateRequest *certreq;
|
||||
PLArenaPool *arena;
|
||||
CERTAttribute * attribute;
|
||||
SECOidData * oidData;
|
||||
CERTAttribute *attribute;
|
||||
SECOidData *oidData;
|
||||
SECStatus rv;
|
||||
int i = 0;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if ( arena == NULL ) {
|
||||
return NULL;
|
||||
if (arena == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
certreq = PORT_ArenaZNew(arena, CERTCertificateRequest);
|
||||
if (!certreq) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return NULL;
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
/* below here it is safe to goto loser */
|
||||
|
||||
certreq->arena = arena;
|
||||
|
||||
|
||||
rv = DER_SetUInteger(arena, &certreq->version,
|
||||
SEC_CERTIFICATE_REQUEST_VERSION);
|
||||
SEC_CERTIFICATE_REQUEST_VERSION);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
goto loser;
|
||||
|
||||
rv = CERT_CopyName(arena, &certreq->subject, subject);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
goto loser;
|
||||
|
||||
rv = SECKEY_CopySubjectPublicKeyInfo(arena,
|
||||
&certreq->subjectPublicKeyInfo,
|
||||
spki);
|
||||
&certreq->subjectPublicKeyInfo,
|
||||
spki);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
goto loser;
|
||||
|
||||
certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute*, 2);
|
||||
if(!certreq->attributes)
|
||||
goto loser;
|
||||
certreq->attributes = PORT_ArenaZNewArray(arena, CERTAttribute *, 2);
|
||||
if (!certreq->attributes)
|
||||
goto loser;
|
||||
|
||||
/* Copy over attribute information */
|
||||
if (!attributes || !attributes[0]) {
|
||||
/*
|
||||
/*
|
||||
** Invent empty attribute information. According to the
|
||||
** pkcs#10 spec, attributes has this ASN.1 type:
|
||||
**
|
||||
** attributes [0] IMPLICIT Attributes
|
||||
**
|
||||
**
|
||||
** Which means, we should create a NULL terminated list
|
||||
** with the first entry being NULL;
|
||||
*/
|
||||
certreq->attributes[0] = NULL;
|
||||
return certreq;
|
||||
}
|
||||
certreq->attributes[0] = NULL;
|
||||
return certreq;
|
||||
}
|
||||
|
||||
/* allocate space for attributes */
|
||||
attribute = PORT_ArenaZNew(arena, CERTAttribute);
|
||||
if (!attribute)
|
||||
goto loser;
|
||||
if (!attribute)
|
||||
goto loser;
|
||||
|
||||
oidData = SECOID_FindOIDByTag( SEC_OID_PKCS9_EXTENSION_REQUEST );
|
||||
oidData = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
|
||||
PORT_Assert(oidData);
|
||||
if (!oidData)
|
||||
goto loser;
|
||||
goto loser;
|
||||
rv = SECITEM_CopyItem(arena, &attribute->attrType, &oidData->oid);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
goto loser;
|
||||
|
||||
for (i = 0; attributes[i] != NULL ; i++)
|
||||
;
|
||||
attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i+1);
|
||||
if (!attribute->attrValue)
|
||||
goto loser;
|
||||
for (i = 0; attributes[i] != NULL; i++)
|
||||
;
|
||||
attribute->attrValue = PORT_ArenaZNewArray(arena, SECItem *, i + 1);
|
||||
if (!attribute->attrValue)
|
||||
goto loser;
|
||||
|
||||
/* copy attributes */
|
||||
for (i = 0; attributes[i]; i++) {
|
||||
/*
|
||||
/*
|
||||
** Attributes are a SetOf Attribute which implies
|
||||
** lexigraphical ordering. It is assumes that the
|
||||
** attributes are passed in sorted. If we need to
|
||||
** add functionality to sort them, there is an
|
||||
** example in the PKCS 7 code.
|
||||
*/
|
||||
attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
|
||||
if(!attribute->attrValue[i])
|
||||
goto loser;
|
||||
attribute->attrValue[i] = SECITEM_ArenaDupItem(arena, attributes[i]);
|
||||
if (!attribute->attrValue[i])
|
||||
goto loser;
|
||||
}
|
||||
|
||||
certreq->attributes[0] = attribute;
|
||||
|
@ -224,7 +230,7 @@ void
|
|||
CERT_DestroyCertificateRequest(CERTCertificateRequest *req)
|
||||
{
|
||||
if (req && req->arena) {
|
||||
PORT_FreeArena(req->arena, PR_FALSE);
|
||||
PORT_FreeArena(req->arena, PR_FALSE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -241,11 +247,11 @@ setCRExt(void *o, CERTCertExtension **exts)
|
|||
** attribute list by CERT_FinishCRAttributes().
|
||||
*/
|
||||
extern void *cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
|
||||
void (*setExts)(void *object, CERTCertExtension **exts));
|
||||
void (*setExts)(void *object, CERTCertExtension **exts));
|
||||
void *
|
||||
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
|
||||
CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
|
||||
{ SECItem *extlist;
|
||||
{
|
||||
SECItem *extlist;
|
||||
SECOidData *oidrec;
|
||||
CERTAttribute *attribute;
|
||||
|
||||
|
||||
if (!req || !req->arena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (req->attributes == NULL || req->attributes[0] == NULL)
|
||||
return SECSuccess;
|
||||
|
||||
extlist = SEC_ASN1EncodeItem(req->arena, NULL, &req->attributes,
|
||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
|
||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate));
|
||||
if (extlist == NULL)
|
||||
return(SECFailure);
|
||||
return (SECFailure);
|
||||
|
||||
oidrec = SECOID_FindOIDByTag(SEC_OID_PKCS9_EXTENSION_REQUEST);
|
||||
if (oidrec == NULL)
|
||||
return SECFailure;
|
||||
return SECFailure;
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
if (req->attributes == NULL || attribute == NULL ||
|
||||
SECITEM_CopyItem(req->arena, &attribute->attrType, &oidrec->oid) != 0) {
|
||||
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)
|
||||
return SECFailure;
|
||||
|
@ -303,22 +310,22 @@ CERT_FinishCertificateRequestAttributes(CERTCertificateRequest *req)
|
|||
|
||||
SECStatus
|
||||
CERT_GetCertificateRequestExtensions(CERTCertificateRequest *req,
|
||||
CERTCertExtension ***exts)
|
||||
CERTCertExtension ***exts)
|
||||
{
|
||||
if (req == NULL || exts == NULL) {
|
||||
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);
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return(SEC_ASN1DecodeItem(req->arena, exts,
|
||||
SEC_ASN1_GET(CERT_SequenceOfCertExtensionTemplate),
|
||||
(*req->attributes)->attrValue[0]));
|
||||
if (req->attributes == NULL || *req->attributes == NULL)
|
||||
return SECSuccess;
|
||||
|
||||
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
|
||||
CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value)
|
||||
{
|
||||
return (cert_FindExtensionByOID (crl->extensions, oid, value));
|
||||
return (cert_FindExtensionByOID(crl->extensions, oid, value));
|
||||
}
|
||||
|
||||
|
||||
SECStatus
|
||||
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 */
|
||||
static void
|
||||
SetCrlExts(void *object, CERTCertExtension **exts)
|
||||
|
@ -35,13 +33,13 @@ SetCrlExts(void *object, CERTCertExtension **exts)
|
|||
CERTCrl *crl = (CERTCrl *)object;
|
||||
|
||||
crl->extensions = exts;
|
||||
DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2);
|
||||
DER_SetUInteger(crl->arena, &crl->version, SEC_CRL_VERSION_2);
|
||||
}
|
||||
|
||||
void *
|
||||
CERT_StartCRLExtensions(CERTCrl *crl)
|
||||
{
|
||||
return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts));
|
||||
return (cert_StartExtensions((void *)crl, crl->arena, SetCrlExts));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -55,11 +53,12 @@ SetCrlEntryExts(void *object, CERTCertExtension **exts)
|
|||
void *
|
||||
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,
|
||||
SECItem *value)
|
||||
SECStatus
|
||||
CERT_FindCRLNumberExten(PLArenaPool *arena, CERTCrl *crl,
|
||||
SECItem *value)
|
||||
{
|
||||
SECItem encodedExtenValue;
|
||||
SECItem *tmpItem = NULL;
|
||||
|
@ -70,91 +69,94 @@ SECStatus CERT_FindCRLNumberExten (PLArenaPool *arena, CERTCrl *crl,
|
|||
encodedExtenValue.len = 0;
|
||||
|
||||
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_CRL_NUMBER,
|
||||
&encodedExtenValue);
|
||||
if ( rv != SECSuccess )
|
||||
return (rv);
|
||||
&encodedExtenValue);
|
||||
if (rv != SECSuccess)
|
||||
return (rv);
|
||||
|
||||
mark = PORT_ArenaMark(arena);
|
||||
|
||||
tmpItem = SECITEM_ArenaDupItem(arena, &encodedExtenValue);
|
||||
if (tmpItem) {
|
||||
rv = SEC_QuickDERDecodeItem (arena, value,
|
||||
SEC_ASN1_GET(SEC_IntegerTemplate),
|
||||
tmpItem);
|
||||
} else {
|
||||
rv = SEC_QuickDERDecodeItem(arena, value,
|
||||
SEC_ASN1_GET(SEC_IntegerTemplate),
|
||||
tmpItem);
|
||||
}
|
||||
else {
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
PORT_Free (encodedExtenValue.data);
|
||||
PORT_Free(encodedExtenValue.data);
|
||||
if (rv == SECFailure) {
|
||||
PORT_ArenaRelease(arena, mark);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
PORT_ArenaUnmark(arena, mark);
|
||||
}
|
||||
return (rv);
|
||||
}
|
||||
|
||||
SECStatus CERT_FindCRLEntryReasonExten (CERTCrlEntry *crlEntry,
|
||||
CERTCRLEntryReasonCode *value)
|
||||
SECStatus
|
||||
CERT_FindCRLEntryReasonExten(CERTCrlEntry *crlEntry,
|
||||
CERTCRLEntryReasonCode *value)
|
||||
{
|
||||
SECItem wrapperItem = {siBuffer,0};
|
||||
SECItem tmpItem = {siBuffer,0};
|
||||
SECItem wrapperItem = { siBuffer, 0 };
|
||||
SECItem tmpItem = { siBuffer, 0 };
|
||||
SECStatus rv;
|
||||
PLArenaPool *arena = NULL;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if ( ! arena ) {
|
||||
return(SECFailure);
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
|
||||
|
||||
rv = cert_FindExtension(crlEntry->extensions, SEC_OID_X509_REASON_CODE,
|
||||
&wrapperItem);
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, &tmpItem,
|
||||
SEC_ASN1_GET(SEC_EnumeratedTemplate),
|
||||
&wrapperItem);
|
||||
|
||||
if ( rv != SECSuccess ) {
|
||||
goto loser;
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*value = (CERTCRLEntryReasonCode) DER_GetInteger(&tmpItem);
|
||||
*value = (CERTCRLEntryReasonCode)DER_GetInteger(&tmpItem);
|
||||
|
||||
loser:
|
||||
if ( arena ) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
|
||||
if ( wrapperItem.data ) {
|
||||
PORT_Free(wrapperItem.data);
|
||||
|
||||
if (wrapperItem.data) {
|
||||
PORT_Free(wrapperItem.data);
|
||||
}
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, PRTime *value)
|
||||
SECStatus
|
||||
CERT_FindInvalidDateExten(CERTCrl *crl, PRTime *value)
|
||||
{
|
||||
SECItem encodedExtenValue;
|
||||
SECItem decodedExtenValue = {siBuffer,0};
|
||||
SECItem decodedExtenValue = { siBuffer, 0 };
|
||||
SECStatus rv;
|
||||
|
||||
encodedExtenValue.data = decodedExtenValue.data = NULL;
|
||||
encodedExtenValue.len = decodedExtenValue.len = 0;
|
||||
|
||||
rv = cert_FindExtension
|
||||
(crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue);
|
||||
if ( rv != SECSuccess )
|
||||
return (rv);
|
||||
rv = cert_FindExtension(crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue);
|
||||
if (rv != SECSuccess)
|
||||
return (rv);
|
||||
|
||||
rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue,
|
||||
SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
|
||||
&encodedExtenValue);
|
||||
rv = SEC_ASN1DecodeItem(NULL, &decodedExtenValue,
|
||||
SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
|
||||
&encodedExtenValue);
|
||||
if (rv == SECSuccess)
|
||||
rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
|
||||
PORT_Free (decodedExtenValue.data);
|
||||
PORT_Free (encodedExtenValue.data);
|
||||
rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue);
|
||||
PORT_Free(decodedExtenValue.data);
|
||||
PORT_Free(encodedExtenValue.data);
|
||||
return (rv);
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -9,7 +9,6 @@
|
|||
#ifndef _OCSP_H_
|
||||
#define _OCSP_H_
|
||||
|
||||
|
||||
#include "plarena.h"
|
||||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
|
@ -17,7 +16,6 @@
|
|||
#include "certt.h"
|
||||
#include "ocspt.h"
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
|
@ -134,7 +132,7 @@ CERT_DisableOCSPChecking(CERTCertDBHandle *handle);
|
|||
*/
|
||||
extern SECStatus
|
||||
CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle,
|
||||
const char *url, const char *name);
|
||||
const char *url, const char *name);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
@ -191,7 +189,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
|
|||
|
||||
/*
|
||||
* 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.
|
||||
* INPUTS:
|
||||
* CERTCertList *certList
|
||||
|
@ -203,7 +201,7 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
|
|||
* to this routine), who knows about where the request(s) are being
|
||||
* sent and whether there are any trusted responders in place.
|
||||
* 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
|
||||
* but has no effect on the request itself.
|
||||
* PRBool addServiceLocator
|
||||
|
@ -221,9 +219,9 @@ extern SECStatus CERT_ForcePostMethodForOCSP(PRBool forcePost);
|
|||
* Other errors are low-level problems (no memory, bad database, etc.).
|
||||
*/
|
||||
extern CERTOCSPRequest *
|
||||
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
|
||||
PRBool addServiceLocator,
|
||||
CERTCertificate *signerCert);
|
||||
CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
|
||||
PRBool addServiceLocator,
|
||||
CERTCertificate *signerCert);
|
||||
|
||||
/*
|
||||
* FUNCTION: CERT_AddOCSPAcceptableResponses
|
||||
|
@ -243,13 +241,13 @@ CERT_CreateOCSPRequest(CERTCertList *certList, PRTime time,
|
|||
*/
|
||||
extern SECStatus
|
||||
CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request,
|
||||
SECOidTag responseType0, ...);
|
||||
SECOidTag responseType0, ...);
|
||||
|
||||
/*
|
||||
/*
|
||||
* FUNCTION: CERT_EncodeOCSPRequest
|
||||
* DER encodes an OCSP Request, possibly adding a signature as well.
|
||||
* XXX Signing is not yet supported, however; see comments in code.
|
||||
* INPUTS:
|
||||
* INPUTS:
|
||||
* PLArenaPool *arena
|
||||
* The return value is allocated from here.
|
||||
* 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).
|
||||
*/
|
||||
extern SECItem *
|
||||
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
|
||||
void *pwArg);
|
||||
CERT_EncodeOCSPRequest(PLArenaPool *arena, CERTOCSPRequest *request,
|
||||
void *pwArg);
|
||||
|
||||
/*
|
||||
* FUNCTION: CERT_DecodeOCSPRequest
|
||||
|
@ -341,7 +339,7 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
|
|||
* const char *location
|
||||
* The location of the OCSP responder (a URL).
|
||||
* 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
|
||||
* but has no other bearing on the operation.
|
||||
* PRBool addServiceLocator
|
||||
|
@ -369,10 +367,10 @@ CERT_DestroyOCSPResponse(CERTOCSPResponse *response);
|
|||
*/
|
||||
extern SECItem *
|
||||
CERT_GetEncodedOCSPResponse(PLArenaPool *arena, CERTCertList *certList,
|
||||
const char *location, PRTime time,
|
||||
PRBool addServiceLocator,
|
||||
CERTCertificate *signerCert, void *pwArg,
|
||||
CERTOCSPRequest **pRequest);
|
||||
const char *location, PRTime time,
|
||||
PRBool addServiceLocator,
|
||||
CERTCertificate *signerCert, void *pwArg,
|
||||
CERTOCSPRequest **pRequest);
|
||||
|
||||
/*
|
||||
* 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.)
|
||||
*/
|
||||
extern SECStatus
|
||||
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
|
||||
CERTCertDBHandle *handle, void *pwArg,
|
||||
CERTCertificate **pSignerCert,
|
||||
CERTCertificate *issuerCert);
|
||||
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
|
||||
CERTCertDBHandle *handle, void *pwArg,
|
||||
CERTCertificate **pSignerCert,
|
||||
CERTCertificate *issuerCert);
|
||||
|
||||
/*
|
||||
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
|
||||
|
@ -425,7 +423,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
|
|||
* 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.
|
||||
* Any other error will also result in a NULL being returned.
|
||||
*
|
||||
*
|
||||
* This result should be freed (via PORT_Free) when no longer in use.
|
||||
*/
|
||||
extern char *
|
||||
|
@ -433,21 +431,21 @@ CERT_GetOCSPAuthorityInfoAccessLocation(const CERTCertificate *cert);
|
|||
|
||||
/*
|
||||
* FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack
|
||||
* This function serves two purposes.
|
||||
* 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
|
||||
* This function serves two purposes.
|
||||
* 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
|
||||
* 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.
|
||||
* 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().
|
||||
* RETURN:
|
||||
* SECSuccess or SECFailure (if the library is not yet intialized)
|
||||
*/
|
||||
extern SECStatus
|
||||
CERT_RegisterAlternateOCSPAIAInfoCallBack(
|
||||
CERT_StringFromCertFcn newCallback,
|
||||
CERT_StringFromCertFcn * oldCallback);
|
||||
CERT_StringFromCertFcn newCallback,
|
||||
CERT_StringFromCertFcn *oldCallback);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* verifying the signer's cert, or low-level problems (error allocating
|
||||
* memory, error performing ASN.1 decoding, etc.).
|
||||
*/
|
||||
extern SECStatus
|
||||
*/
|
||||
extern SECStatus
|
||||
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
PRTime time, void *pwArg);
|
||||
PRTime time, void *pwArg);
|
||||
|
||||
/*
|
||||
* FUNCTION: CERT_CacheOCSPResponseFromSideChannel
|
||||
|
@ -556,10 +554,10 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
*/
|
||||
extern SECStatus
|
||||
CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
||||
CERTCertificate *cert,
|
||||
PRTime time,
|
||||
const SECItem *encodedResponse,
|
||||
void *pwArg);
|
||||
CERTCertificate *cert,
|
||||
PRTime time,
|
||||
const SECItem *encodedResponse,
|
||||
void *pwArg);
|
||||
|
||||
/*
|
||||
* FUNCTION: CERT_GetOCSPStatusForCertID
|
||||
|
@ -581,11 +579,11 @@ CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
|
|||
* Return values are the same as those for CERT_CheckOCSPStatus
|
||||
*/
|
||||
extern SECStatus
|
||||
CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
CERTOCSPCertID *certID,
|
||||
CERTCertificate *signerCert,
|
||||
PRTime time);
|
||||
CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
CERTOCSPCertID *certID,
|
||||
CERTCertificate *signerCert,
|
||||
PRTime time);
|
||||
|
||||
/*
|
||||
* FUNCTION CERT_GetOCSPResponseStatus
|
||||
|
@ -619,10 +617,10 @@ CERT_GetOCSPResponseStatus(CERTOCSPResponse *response);
|
|||
* the issuing CA may be an older expired certificate.
|
||||
* RETURN:
|
||||
* 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.
|
||||
*/
|
||||
extern CERTOCSPCertID*
|
||||
extern CERTOCSPCertID *
|
||||
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.
|
||||
* INPUTS:
|
||||
* 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.
|
||||
* RETURN:
|
||||
* SECSuccess if freeing the memory was successful. Returns
|
||||
|
@ -638,31 +636,30 @@ CERT_CreateOCSPCertID(CERTCertificate *cert, PRTime time);
|
|||
* a call to CERT_CreateOCSPCertID.
|
||||
*/
|
||||
extern SECStatus
|
||||
CERT_DestroyOCSPCertID(CERTOCSPCertID* certID);
|
||||
CERT_DestroyOCSPCertID(CERTOCSPCertID *certID);
|
||||
|
||||
|
||||
extern CERTOCSPSingleResponse*
|
||||
extern CERTOCSPSingleResponse *
|
||||
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
||||
CERTOCSPCertID *id,
|
||||
PRTime thisUpdate,
|
||||
const PRTime *nextUpdate);
|
||||
|
||||
extern CERTOCSPSingleResponse*
|
||||
extern CERTOCSPSingleResponse *
|
||||
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
||||
CERTOCSPCertID *id,
|
||||
PRTime thisUpdate,
|
||||
const PRTime *nextUpdate);
|
||||
|
||||
extern CERTOCSPSingleResponse*
|
||||
extern CERTOCSPSingleResponse *
|
||||
CERT_CreateOCSPSingleResponseRevoked(
|
||||
PLArenaPool *arena,
|
||||
CERTOCSPCertID *id,
|
||||
PRTime thisUpdate,
|
||||
const PRTime *nextUpdate,
|
||||
PRTime revocationTime,
|
||||
const CERTCRLEntryReasonCode* revocationReason);
|
||||
const CERTCRLEntryReasonCode *revocationReason);
|
||||
|
||||
extern SECItem*
|
||||
extern SECItem *
|
||||
CERT_CreateEncodedOCSPSuccessResponse(
|
||||
PLArenaPool *arena,
|
||||
CERTCertificate *responderCert,
|
||||
|
@ -703,7 +700,7 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
|||
* SEC_ERROR_INVALID_ARGS
|
||||
* Other errors are low-level problems (no memory, bad database, etc.).
|
||||
*/
|
||||
extern SECItem*
|
||||
extern SECItem *
|
||||
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error);
|
||||
|
||||
/* 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
|
||||
* internal HTTP client is used.
|
||||
*/
|
||||
SECItem* CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
|
||||
SECItem *CERT_PostOCSPRequest(PLArenaPool *arena, const char *location,
|
||||
const SECItem *encodedRequest);
|
||||
|
||||
/************************************************************************/
|
||||
|
|
|
@ -35,13 +35,15 @@ ocsp_VerifyResponseSignature(CERTCertificate *signerCert,
|
|||
void *pwArg);
|
||||
|
||||
CERTOCSPRequest *
|
||||
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
|
||||
CERTCertificate *singleCert,
|
||||
cert_CreateSingleCertOCSPRequest(CERTOCSPCertID *certID,
|
||||
CERTCertificate *singleCert,
|
||||
PRTime time,
|
||||
PRBool addServiceLocator,
|
||||
CERTCertificate *signerCert);
|
||||
|
||||
typedef enum { ocspMissing, ocspFresh, ocspStale } OCSPFreshness;
|
||||
typedef enum { ocspMissing,
|
||||
ocspFresh,
|
||||
ocspStale } OCSPFreshness;
|
||||
|
||||
SECStatus
|
||||
ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
||||
|
@ -84,13 +86,13 @@ ocsp_GetCachedOCSPResponseStatus(CERTOCSPCertID *certID,
|
|||
*/
|
||||
|
||||
SECStatus
|
||||
cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
CERTOCSPCertID *certID,
|
||||
CERTCertificate *signerCert,
|
||||
PRTime time,
|
||||
PRBool *certIDWasConsumed,
|
||||
SECStatus *cacheUpdateStatus);
|
||||
cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
CERTOCSPCertID *certID,
|
||||
CERTCertificate *signerCert,
|
||||
PRTime time,
|
||||
PRBool *certIDWasConsumed,
|
||||
SECStatus *cacheUpdateStatus);
|
||||
|
||||
/*
|
||||
* FUNCTION: cert_RememberOCSPProcessingFailure
|
||||
|
@ -109,7 +111,7 @@ cert_ProcessOCSPResponse(CERTCertDBHandle *handle,
|
|||
|
||||
SECStatus
|
||||
cert_RememberOCSPProcessingFailure(CERTOCSPCertID *certID,
|
||||
PRBool *certIDWasConsumed);
|
||||
PRBool *certIDWasConsumed);
|
||||
|
||||
/*
|
||||
* FUNCTION: ocsp_GetResponderLocation
|
||||
|
@ -146,11 +148,11 @@ size_t
|
|||
ocsp_UrlEncodeBase64Buf(const char *base64Buf, char *outputBuf);
|
||||
|
||||
SECStatus
|
||||
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
CERTOCSPCertID *certID,
|
||||
CERTCertificate *signerCert,
|
||||
PRTime time,
|
||||
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
CERTOCSPCertID *certID,
|
||||
CERTCertificate *signerCert,
|
||||
PRTime time,
|
||||
CERTOCSPSingleResponse **pSingleResponse);
|
||||
|
||||
SECStatus
|
||||
|
@ -158,7 +160,7 @@ ocsp_CertHasGoodStatus(ocspCertStatus *status, PRTime time);
|
|||
|
||||
void
|
||||
ocsp_CacheSingleResponse(CERTOCSPCertID *certID,
|
||||
CERTOCSPSingleResponse *single,
|
||||
PRBool *certIDWasConsumed);
|
||||
CERTOCSPSingleResponse *single,
|
||||
PRBool *certIDWasConsumed);
|
||||
|
||||
#endif /* _OCSPI_H_ */
|
||||
|
|
|
@ -19,12 +19,11 @@
|
|||
#include "ocspi.h"
|
||||
#include "pk11pub.h"
|
||||
|
||||
|
||||
extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
|
||||
extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
|
||||
extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];
|
||||
|
||||
ocspCertStatus*
|
||||
ocspCertStatus *
|
||||
ocsp_CreateCertStatus(PLArenaPool *arena,
|
||||
ocspCertStatusType status,
|
||||
PRTime revocationTime)
|
||||
|
@ -45,7 +44,7 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
|
|||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
cs = PORT_ArenaZNew(arena, ocspCertStatus);
|
||||
if (!cs)
|
||||
return NULL;
|
||||
|
@ -71,8 +70,9 @@ ocsp_CreateCertStatus(PLArenaPool *arena,
|
|||
if (!cs->certStatusInfo.revokedInfo->revocationReason)
|
||||
return NULL;
|
||||
if (DER_TimeToGeneralizedTimeArena(arena,
|
||||
&cs->certStatusInfo.revokedInfo->revocationTime,
|
||||
revocationTime) != SECSuccess)
|
||||
&cs->certStatusInfo.revokedInfo->revocationTime,
|
||||
revocationTime) !=
|
||||
SECSuccess)
|
||||
return NULL;
|
||||
break;
|
||||
default:
|
||||
|
@ -91,11 +91,11 @@ static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
|
|||
|
||||
static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
|
||||
{ SEC_ASN1_GENERALIZED_TIME,
|
||||
offsetof(ocspRevokedInfo, revocationTime) },
|
||||
offsetof(ocspRevokedInfo, revocationTime) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0,
|
||||
offsetof(ocspRevokedInfo, revocationReason),
|
||||
mySEC_PointerToEnumeratedTemplate },
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(ocspRevokedInfo, revocationReason),
|
||||
mySEC_PointerToEnumeratedTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -110,26 +110,26 @@ static const SEC_ASN1Template mySEC_NullTemplate[] = {
|
|||
|
||||
static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
|
||||
{ SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
|
||||
0, sizeof(ocspCertStatus) },
|
||||
0, sizeof(ocspCertStatus) },
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
0, mySEC_NullTemplate, ocspCertStatus_good },
|
||||
0, mySEC_NullTemplate, ocspCertStatus_good },
|
||||
{ SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
|
||||
SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
|
||||
ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
|
||||
SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
|
||||
ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | 2,
|
||||
0, mySEC_NullTemplate, ocspCertStatus_unknown },
|
||||
0, mySEC_NullTemplate, ocspCertStatus_unknown },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(SECAlgorithmID) },
|
||||
0, NULL, sizeof(SECAlgorithmID) },
|
||||
{ SEC_ASN1_OBJECT_ID,
|
||||
offsetof(SECAlgorithmID,algorithm), },
|
||||
offsetof(SECAlgorithmID, algorithm) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
|
||||
offsetof(SECAlgorithmID,parameters), },
|
||||
{ 0, }
|
||||
offsetof(SECAlgorithmID, parameters) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template mySEC_AnyTemplate[] = {
|
||||
|
@ -153,7 +153,7 @@ static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
|
|||
};
|
||||
|
||||
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[] = {
|
||||
|
@ -162,29 +162,29 @@ static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
|
|||
|
||||
static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTOCSPCertID) },
|
||||
0, NULL, sizeof(CERTOCSPCertID) },
|
||||
{ SEC_ASN1_INLINE,
|
||||
offsetof(CERTOCSPCertID, hashAlgorithm),
|
||||
mySECOID_AlgorithmIDTemplate },
|
||||
offsetof(CERTOCSPCertID, hashAlgorithm),
|
||||
mySECOID_AlgorithmIDTemplate },
|
||||
{ SEC_ASN1_OCTET_STRING,
|
||||
offsetof(CERTOCSPCertID, issuerNameHash) },
|
||||
offsetof(CERTOCSPCertID, issuerNameHash) },
|
||||
{ SEC_ASN1_OCTET_STRING,
|
||||
offsetof(CERTOCSPCertID, issuerKeyHash) },
|
||||
offsetof(CERTOCSPCertID, issuerKeyHash) },
|
||||
{ SEC_ASN1_INTEGER,
|
||||
offsetof(CERTOCSPCertID, serialNumber) },
|
||||
offsetof(CERTOCSPCertID, serialNumber) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTCertExtension) },
|
||||
0, NULL, sizeof(CERTCertExtension) },
|
||||
{ SEC_ASN1_OBJECT_ID,
|
||||
offsetof(CERTCertExtension,id) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
||||
offsetof(CERTCertExtension,critical) },
|
||||
offsetof(CERTCertExtension, id) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */
|
||||
offsetof(CERTCertExtension, critical) },
|
||||
{ SEC_ASN1_OCTET_STRING,
|
||||
offsetof(CERTCertExtension,value) },
|
||||
{ 0, }
|
||||
offsetof(CERTCertExtension, value) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
|
||||
|
@ -197,66 +197,65 @@ static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[]
|
|||
|
||||
static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTOCSPSingleResponse) },
|
||||
0, NULL, sizeof(CERTOCSPSingleResponse) },
|
||||
{ SEC_ASN1_POINTER,
|
||||
offsetof(CERTOCSPSingleResponse, certID),
|
||||
ocsp_myCertIDTemplate },
|
||||
offsetof(CERTOCSPSingleResponse, certID),
|
||||
ocsp_myCertIDTemplate },
|
||||
{ SEC_ASN1_ANY,
|
||||
offsetof(CERTOCSPSingleResponse, derCertStatus) },
|
||||
offsetof(CERTOCSPSingleResponse, derCertStatus) },
|
||||
{ SEC_ASN1_GENERALIZED_TIME,
|
||||
offsetof(CERTOCSPSingleResponse, thisUpdate) },
|
||||
offsetof(CERTOCSPSingleResponse, thisUpdate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(CERTOCSPSingleResponse, nextUpdate),
|
||||
mySEC_PointerToGeneralizedTimeTemplate },
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(CERTOCSPSingleResponse, nextUpdate),
|
||||
mySEC_PointerToGeneralizedTimeTemplate },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(CERTOCSPSingleResponse, singleExtensions),
|
||||
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(CERTOCSPSingleResponse, singleExtensions),
|
||||
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(ocspResponseData) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(ocspResponseData, version),
|
||||
mySEC_PointerToIntegerTemplate },
|
||||
0, NULL, sizeof(ocspResponseData) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(ocspResponseData, version),
|
||||
mySEC_PointerToIntegerTemplate },
|
||||
{ SEC_ASN1_ANY,
|
||||
offsetof(ocspResponseData, derResponderID) },
|
||||
offsetof(ocspResponseData, derResponderID) },
|
||||
{ SEC_ASN1_GENERALIZED_TIME,
|
||||
offsetof(ocspResponseData, producedAt) },
|
||||
offsetof(ocspResponseData, producedAt) },
|
||||
{ SEC_ASN1_SEQUENCE_OF,
|
||||
offsetof(ocspResponseData, responses),
|
||||
ocsp_mySingleResponseTemplate },
|
||||
offsetof(ocspResponseData, responses),
|
||||
ocsp_mySingleResponseTemplate },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(ocspResponseData, responseExtensions),
|
||||
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
|
||||
offsetof(ocspResponseData, responseExtensions),
|
||||
myCERT_PointerToSequenceOfCertExtensionTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(ocspBasicOCSPResponse) },
|
||||
0, NULL, sizeof(ocspBasicOCSPResponse) },
|
||||
{ SEC_ASN1_POINTER,
|
||||
offsetof(ocspBasicOCSPResponse, tbsResponseData),
|
||||
ocsp_myResponseDataTemplate },
|
||||
offsetof(ocspBasicOCSPResponse, tbsResponseData),
|
||||
ocsp_myResponseDataTemplate },
|
||||
{ SEC_ASN1_INLINE,
|
||||
offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
|
||||
mySECOID_AlgorithmIDTemplate },
|
||||
offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
|
||||
mySECOID_AlgorithmIDTemplate },
|
||||
{ SEC_ASN1_BIT_STRING,
|
||||
offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
|
||||
offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
|
||||
mySEC_PointerToSequenceOfAnyTemplate },
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
|
||||
offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
|
||||
mySEC_PointerToSequenceOfAnyTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static CERTOCSPSingleResponse*
|
||||
static CERTOCSPSingleResponse *
|
||||
ocsp_CreateSingleResponse(PLArenaPool *arena,
|
||||
CERTOCSPCertID *id, ocspCertStatus *status,
|
||||
PRTime thisUpdate, const PRTime *nextUpdate)
|
||||
|
@ -274,25 +273,25 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
|
|||
sr->arena = arena;
|
||||
sr->certID = id;
|
||||
sr->certStatus = status;
|
||||
if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate)
|
||||
!= SECSuccess)
|
||||
if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) !=
|
||||
SECSuccess)
|
||||
return NULL;
|
||||
sr->nextUpdate = NULL;
|
||||
if (nextUpdate) {
|
||||
sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
|
||||
if (!sr->nextUpdate)
|
||||
return NULL;
|
||||
if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate)
|
||||
!= SECSuccess)
|
||||
if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) !=
|
||||
SECSuccess)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1);
|
||||
sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension *, 1);
|
||||
if (!sr->singleExtensions)
|
||||
return NULL;
|
||||
|
||||
sr->singleExtensions[0] = NULL;
|
||||
|
||||
|
||||
if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
|
||||
status, ocsp_CertStatusTemplate))
|
||||
return NULL;
|
||||
|
@ -300,13 +299,13 @@ ocsp_CreateSingleResponse(PLArenaPool *arena,
|
|||
return sr;
|
||||
}
|
||||
|
||||
CERTOCSPSingleResponse*
|
||||
CERTOCSPSingleResponse *
|
||||
CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
||||
CERTOCSPCertID *id,
|
||||
PRTime thisUpdate,
|
||||
const PRTime *nextUpdate)
|
||||
{
|
||||
ocspCertStatus * cs;
|
||||
ocspCertStatus *cs;
|
||||
if (!arena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
|
@ -317,13 +316,13 @@ CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
|
|||
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
||||
}
|
||||
|
||||
CERTOCSPSingleResponse*
|
||||
CERTOCSPSingleResponse *
|
||||
CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
||||
CERTOCSPCertID *id,
|
||||
PRTime thisUpdate,
|
||||
const PRTime *nextUpdate)
|
||||
{
|
||||
ocspCertStatus * cs;
|
||||
ocspCertStatus *cs;
|
||||
if (!arena) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
|
@ -334,16 +333,16 @@ CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
|
|||
return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
|
||||
}
|
||||
|
||||
CERTOCSPSingleResponse*
|
||||
CERTOCSPSingleResponse *
|
||||
CERT_CreateOCSPSingleResponseRevoked(
|
||||
PLArenaPool *arena,
|
||||
CERTOCSPCertID *id,
|
||||
PRTime thisUpdate,
|
||||
const PRTime *nextUpdate,
|
||||
PRTime revocationTime,
|
||||
const CERTCRLEntryReasonCode* revocationReason)
|
||||
const CERTCRLEntryReasonCode *revocationReason)
|
||||
{
|
||||
ocspCertStatus * cs;
|
||||
ocspCertStatus *cs;
|
||||
/* revocationReason is not yet supported, so it must be NULL. */
|
||||
if (!arena || revocationReason) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -357,7 +356,7 @@ CERT_CreateOCSPSingleResponseRevoked(
|
|||
|
||||
/* responderCert == 0 means:
|
||||
* create a response with an invalid signature (for testing purposes) */
|
||||
SECItem*
|
||||
SECItem *
|
||||
CERT_CreateEncodedOCSPSuccessResponse(
|
||||
PLArenaPool *arena,
|
||||
CERTCertificate *responderCert,
|
||||
|
@ -373,12 +372,12 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
|||
ocspBasicOCSPResponse *br = NULL;
|
||||
ocspResponseBytes *rb = NULL;
|
||||
CERTOCSPResponse *response = NULL;
|
||||
|
||||
|
||||
SECOidTag algID;
|
||||
SECOidData *od = NULL;
|
||||
SECKEYPrivateKey *privKey = NULL;
|
||||
SECItem *result = NULL;
|
||||
|
||||
|
||||
if (!arena || !responses) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
|
@ -408,114 +407,114 @@ CERT_CreateEncodedOCSPSuccessResponse(
|
|||
response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
|
||||
if (!response)
|
||||
goto done;
|
||||
|
||||
rd->version.data=NULL;
|
||||
rd->version.len=0;
|
||||
|
||||
rd->version.data = NULL;
|
||||
rd->version.len = 0;
|
||||
rd->responseExtensions = NULL;
|
||||
rd->responses = responses;
|
||||
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
|
||||
!= SECSuccess)
|
||||
if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) !=
|
||||
SECSuccess)
|
||||
goto done;
|
||||
|
||||
if (!responderCert) {
|
||||
/* use invalid signature for testing purposes */
|
||||
unsigned char dummyChar = 'd';
|
||||
SECItem dummy;
|
||||
/* use invalid signature for testing purposes */
|
||||
unsigned char dummyChar = 'd';
|
||||
SECItem dummy;
|
||||
|
||||
dummy.len = 1;
|
||||
dummy.data = &dummyChar;
|
||||
dummy.len = 1;
|
||||
dummy.data = &dummyChar;
|
||||
|
||||
/* it's easier to produdce a keyHash out of nowhere,
|
||||
* than to produce an encoded subject,
|
||||
* 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;
|
||||
/* it's easier to produdce a keyHash out of nowhere,
|
||||
* than to produce an encoded subject,
|
||||
* so for our dummy response we always use byKey
|
||||
*/
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||
ocsp_ResponderIDByKeyTemplate))
|
||||
goto done;
|
||||
rid->responderIDType = ocspResponderID_byKey;
|
||||
if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
|
||||
&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,
|
||||
ocsp_myResponseDataTemplate))
|
||||
goto done;
|
||||
br->tbsResponseData = rd;
|
||||
|
||||
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
|
||||
if (!br->responseSignature.derCerts)
|
||||
goto done;
|
||||
br->responseSignature.derCerts[0] = NULL;
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
||||
ocsp_myResponseDataTemplate))
|
||||
goto done;
|
||||
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
goto done;
|
||||
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
|
||||
if (!br->responseSignature.derCerts)
|
||||
goto done;
|
||||
br->responseSignature.derCerts[0] = NULL;
|
||||
|
||||
/* match the regular signature code, which doesn't use the arena */
|
||||
if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
|
||||
goto done;
|
||||
PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
goto done;
|
||||
|
||||
/* convert len-in-bytes to len-in-bits */
|
||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||
/* match the regular signature code, which doesn't use the arena */
|
||||
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 {
|
||||
rid->responderIDType = responderIDType;
|
||||
if (responderIDType == ocspResponderID_byName) {
|
||||
responderIDTemplate = ocsp_ResponderIDByNameTemplate;
|
||||
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
|
||||
&responderCert->subject) != SECSuccess)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
|
||||
if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
|
||||
SEC_OID_SHA1, &rid->responderIDValue.keyHash))
|
||||
goto done;
|
||||
}
|
||||
rid->responderIDType = responderIDType;
|
||||
if (responderIDType == ocspResponderID_byName) {
|
||||
responderIDTemplate = ocsp_ResponderIDByNameTemplate;
|
||||
if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
|
||||
&responderCert->subject) != SECSuccess)
|
||||
goto done;
|
||||
}
|
||||
else {
|
||||
responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
|
||||
if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
|
||||
SEC_OID_SHA1, &rid->responderIDValue.keyHash))
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||
responderIDTemplate))
|
||||
goto done;
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
|
||||
responderIDTemplate))
|
||||
goto done;
|
||||
|
||||
br->tbsResponseData = rd;
|
||||
br->tbsResponseData = rd;
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
||||
ocsp_myResponseDataTemplate))
|
||||
goto done;
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
|
||||
ocsp_myResponseDataTemplate))
|
||||
goto done;
|
||||
|
||||
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
|
||||
if (!br->responseSignature.derCerts)
|
||||
goto done;
|
||||
br->responseSignature.derCerts[0] = NULL;
|
||||
br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1);
|
||||
if (!br->responseSignature.derCerts)
|
||||
goto done;
|
||||
br->responseSignature.derCerts[0] = NULL;
|
||||
|
||||
privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
|
||||
if (!privKey)
|
||||
goto done;
|
||||
privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
|
||||
if (!privKey)
|
||||
goto done;
|
||||
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
goto done;
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
goto done;
|
||||
|
||||
if (SEC_SignData(&br->responseSignature.signature,
|
||||
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
|
||||
privKey, algID)
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
if (SEC_SignData(&br->responseSignature.signature,
|
||||
br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
|
||||
privKey, algID) !=
|
||||
SECSuccess)
|
||||
goto done;
|
||||
|
||||
/* convert len-in-bytes to len-in-bits */
|
||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||
/* convert len-in-bytes to len-in-bits */
|
||||
br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
|
||||
|
||||
/* br->responseSignature.signature wasn't allocated from arena,
|
||||
* we must free it when done. */
|
||||
/* br->responseSignature.signature wasn't allocated from arena,
|
||||
* we must free it when done. */
|
||||
}
|
||||
|
||||
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0)
|
||||
!= SECSuccess)
|
||||
goto done;
|
||||
if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) !=
|
||||
SECSuccess)
|
||||
goto done;
|
||||
|
||||
if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
|
||||
ocsp_EncodeBasicOCSPResponseTemplate))
|
||||
|
@ -552,15 +551,15 @@ done:
|
|||
|
||||
static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTOCSPResponse) },
|
||||
0, NULL, sizeof(CERTOCSPResponse) },
|
||||
{ SEC_ASN1_ENUMERATED,
|
||||
offsetof(CERTOCSPResponse, responseStatus) },
|
||||
offsetof(CERTOCSPResponse, responseStatus) },
|
||||
{ 0, 0,
|
||||
mySEC_NullTemplate },
|
||||
mySEC_NullTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
SECItem*
|
||||
SECItem *
|
||||
CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
|
||||
{
|
||||
CERTOCSPResponse response;
|
||||
|
|
|
@ -46,8 +46,8 @@ typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse;
|
|||
* dependent, and should be opaque to the user.
|
||||
*/
|
||||
|
||||
typedef void * SEC_HTTP_SERVER_SESSION;
|
||||
typedef void * SEC_HTTP_REQUEST_SESSION;
|
||||
typedef void *SEC_HTTP_SERVER_SESSION;
|
||||
typedef void *SEC_HTTP_REQUEST_SESSION;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)(
|
||||
const char *host,
|
||||
PRUint16 portnum,
|
||||
SEC_HTTP_SERVER_SESSION *pSession);
|
||||
const char *host,
|
||||
PRUint16 portnum,
|
||||
SEC_HTTP_SERVER_SESSION *pSession);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* the caller may wait on the poll descriptor, and should call this function
|
||||
* again until SECSuccess (and a zero value at "pPollDesc") is obtained.
|
||||
*/
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)(
|
||||
SEC_HTTP_SERVER_SESSION session,
|
||||
PRPollDesc **pPollDesc);
|
||||
SEC_HTTP_SERVER_SESSION session,
|
||||
PRPollDesc **pPollDesc);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* response pointers that might have been returned by prior server or request
|
||||
* functions.
|
||||
*/
|
||||
*/
|
||||
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
|
||||
|
@ -111,30 +111,30 @@ typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)(
|
|||
* after processing is finished.
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpRequest_CreateFcn)(
|
||||
SEC_HTTP_SERVER_SESSION session,
|
||||
const char *http_protocol_variant, /* usually "http" */
|
||||
const char *path_and_query_string,
|
||||
const char *http_request_method,
|
||||
const PRIntervalTime timeout,
|
||||
SEC_HTTP_REQUEST_SESSION *pRequest);
|
||||
SEC_HTTP_SERVER_SESSION session,
|
||||
const char *http_protocol_variant, /* usually "http" */
|
||||
const char *path_and_query_string,
|
||||
const char *http_request_method,
|
||||
const PRIntervalTime timeout,
|
||||
SEC_HTTP_REQUEST_SESSION *pRequest);
|
||||
|
||||
/*
|
||||
* This function sets data to be sent to the server for an HTTP request
|
||||
* of http_request_method == POST. If a particular implementation
|
||||
* supports it, the details for the POST request can be set by calling
|
||||
* of http_request_method == POST. If a particular implementation
|
||||
* supports it, the details for the POST request can be set by calling
|
||||
* 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.
|
||||
*
|
||||
* Setting http_content_type is optional, the parameter may
|
||||
* by NULL or the empty string.
|
||||
*/
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)(
|
||||
SEC_HTTP_REQUEST_SESSION request,
|
||||
const char *http_data,
|
||||
const PRUint32 http_data_len,
|
||||
const char *http_content_type);
|
||||
SEC_HTTP_REQUEST_SESSION request,
|
||||
const char *http_data,
|
||||
const PRUint32 http_data_len,
|
||||
const char *http_content_type);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* should implement an AddRequestHeaderFcn function that returns immediately.
|
||||
*/
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
||||
SEC_HTTP_REQUEST_SESSION request,
|
||||
const char *http_header_name,
|
||||
const char *http_header_value);
|
||||
SEC_HTTP_REQUEST_SESSION request,
|
||||
const char *http_header_name,
|
||||
const char *http_header_value);
|
||||
|
||||
/*
|
||||
* This function initiates or continues an HTTP request. After
|
||||
|
@ -180,10 +180,10 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
|||
* size, the function will return SECFailure.
|
||||
* http_response_data_len will be set to a value different from zero to
|
||||
* 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.
|
||||
* 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,
|
||||
* Any other out value combined with a return value of SECFailure
|
||||
* will indicate the actual size of the server data.
|
||||
|
@ -195,64 +195,64 @@ typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)(
|
|||
* the completion of the operation.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)(
|
||||
SEC_HTTP_REQUEST_SESSION request,
|
||||
PRPollDesc **pPollDesc,
|
||||
PRUint16 *http_response_code,
|
||||
const char **http_response_content_type,
|
||||
const char **http_response_headers,
|
||||
const char **http_response_data,
|
||||
PRUint32 *http_response_data_len);
|
||||
SEC_HTTP_REQUEST_SESSION request,
|
||||
PRPollDesc **pPollDesc,
|
||||
PRUint16 *http_response_code,
|
||||
const char **http_response_content_type,
|
||||
const char **http_response_headers,
|
||||
const char **http_response_data,
|
||||
PRUint32 *http_response_data_len);
|
||||
|
||||
/*
|
||||
* Calling CancelFcn asks for premature termination of the request.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
*/
|
||||
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
|
||||
* has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has
|
||||
* returned SECSuccess, or the request has been canceled with
|
||||
* a call to SEC_HttpRequest_CancelFcn.
|
||||
*
|
||||
* This function frees the client state object, closes all sockets,
|
||||
* discards all partial results, frees any memory that was allocated
|
||||
*
|
||||
* This function frees the client state object, closes all sockets,
|
||||
* discards all partial results, frees any memory that was allocated
|
||||
* by the client, and invalidates all response pointers that might
|
||||
* have been returned by SEC_HttpRequest_TrySendAndReceiveFcn
|
||||
*/
|
||||
*/
|
||||
typedef SECStatus (*SEC_HttpRequest_FreeFcn)(
|
||||
SEC_HTTP_REQUEST_SESSION request);
|
||||
SEC_HTTP_REQUEST_SESSION request);
|
||||
|
||||
typedef struct SEC_HttpClientFcnV1Struct {
|
||||
SEC_HttpServer_CreateSessionFcn createSessionFcn;
|
||||
SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn;
|
||||
SEC_HttpServer_FreeSessionFcn freeSessionFcn;
|
||||
SEC_HttpRequest_CreateFcn createFcn;
|
||||
SEC_HttpRequest_SetPostDataFcn setPostDataFcn;
|
||||
SEC_HttpRequest_AddHeaderFcn addHeaderFcn;
|
||||
SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn;
|
||||
SEC_HttpRequest_CancelFcn cancelFcn;
|
||||
SEC_HttpRequest_FreeFcn freeFcn;
|
||||
SEC_HttpServer_CreateSessionFcn createSessionFcn;
|
||||
SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn;
|
||||
SEC_HttpServer_FreeSessionFcn freeSessionFcn;
|
||||
SEC_HttpRequest_CreateFcn createFcn;
|
||||
SEC_HttpRequest_SetPostDataFcn setPostDataFcn;
|
||||
SEC_HttpRequest_AddHeaderFcn addHeaderFcn;
|
||||
SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn;
|
||||
SEC_HttpRequest_CancelFcn cancelFcn;
|
||||
SEC_HttpRequest_FreeFcn freeFcn;
|
||||
} SEC_HttpClientFcnV1;
|
||||
|
||||
typedef struct SEC_HttpClientFcnStruct {
|
||||
PRInt16 version;
|
||||
union {
|
||||
SEC_HttpClientFcnV1 ftable1;
|
||||
/* SEC_HttpClientFcnV2 ftable2; */
|
||||
/* ... */
|
||||
} fcnTable;
|
||||
PRInt16 version;
|
||||
union {
|
||||
SEC_HttpClientFcnV1 ftable1;
|
||||
/* SEC_HttpClientFcnV2 ftable2; */
|
||||
/* ... */
|
||||
} fcnTable;
|
||||
} SEC_HttpClientFcn;
|
||||
|
||||
/*
|
||||
|
@ -293,7 +293,7 @@ typedef enum {
|
|||
*/
|
||||
|
||||
typedef enum {
|
||||
ocspResponderID_other = -1, /* unknown kind of responderID */
|
||||
ocspResponderID_other = -1, /* unknown kind of responderID */
|
||||
ocspResponderID_byName = 1,
|
||||
ocspResponderID_byKey = 2
|
||||
} CERTOCSPResponderIDType;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "seccomon.h"
|
||||
#include "secoidt.h"
|
||||
|
||||
|
||||
/*
|
||||
* Some notes about naming conventions...
|
||||
*
|
||||
|
@ -49,7 +48,6 @@
|
|||
* way around (reference before definition).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Forward-declarations of internal-only data structures.
|
||||
*
|
||||
|
@ -67,12 +65,11 @@ typedef struct ocspSingleRequestStr ocspSingleRequest;
|
|||
typedef struct ocspSingleResponseStr ocspSingleResponse;
|
||||
typedef struct ocspTBSRequestStr ocspTBSRequest;
|
||||
|
||||
|
||||
/*
|
||||
* An OCSPRequest; this is what is sent (encoded) to an OCSP responder.
|
||||
*/
|
||||
struct CERTOCSPRequestStr {
|
||||
PLArenaPool *arena; /* local; not part of encoding */
|
||||
PLArenaPool *arena; /* local; not part of encoding */
|
||||
ocspTBSRequest *tbsRequest;
|
||||
ocspSignature *optionalSignature;
|
||||
};
|
||||
|
@ -92,12 +89,12 @@ struct CERTOCSPRequestStr {
|
|||
* in-progress extensions as they are optionally added to the request.
|
||||
*/
|
||||
struct ocspTBSRequestStr {
|
||||
SECItem version; /* an INTEGER */
|
||||
SECItem *derRequestorName; /* encoded GeneralName; see above */
|
||||
CERTGeneralNameList *requestorName; /* local; not part of encoding */
|
||||
SECItem version; /* an INTEGER */
|
||||
SECItem *derRequestorName; /* encoded GeneralName; see above */
|
||||
CERTGeneralNameList *requestorName; /* local; not part of encoding */
|
||||
ocspSingleRequest **requestList;
|
||||
CERTCertExtension **requestExtensions;
|
||||
void *extensionHandle; /* local; not part of encoding */
|
||||
void *extensionHandle; /* local; not part of encoding */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -124,12 +121,12 @@ struct ocspTBSRequestStr {
|
|||
*/
|
||||
struct ocspSignatureStr {
|
||||
SECAlgorithmID signatureAlgorithm;
|
||||
SECItem signature; /* a BIT STRING */
|
||||
SECItem **derCerts; /* a SEQUENCE OF Certificate */
|
||||
CERTCertificate *cert; /* local; not part of encoding */
|
||||
PRBool wasChecked; /* local; not part of encoding */
|
||||
SECStatus status; /* local; not part of encoding */
|
||||
int failureReason; /* local; not part of encoding */
|
||||
SECItem signature; /* a BIT STRING */
|
||||
SECItem **derCerts; /* a SEQUENCE OF Certificate */
|
||||
CERTCertificate *cert; /* local; not part of encoding */
|
||||
PRBool wasChecked; /* local; not part of encoding */
|
||||
SECStatus status; /* 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
|
||||
* consistent with the parallel type "SingleResponse", I called it a
|
||||
* "SingleRequest".
|
||||
*
|
||||
*
|
||||
* XXX figure out how to get rid of that arena -- there must be a way
|
||||
*/
|
||||
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
|
||||
* routines, on creation only */
|
||||
CERTOCSPCertID *reqCert;
|
||||
|
@ -160,14 +157,14 @@ struct ocspSingleRequestStr {
|
|||
*/
|
||||
struct CERTOCSPCertIDStr {
|
||||
SECAlgorithmID hashAlgorithm;
|
||||
SECItem issuerNameHash; /* an OCTET STRING */
|
||||
SECItem issuerKeyHash; /* an OCTET STRING */
|
||||
SECItem serialNumber; /* an INTEGER */
|
||||
SECItem issuerSHA1NameHash; /* keep other hashes around when */
|
||||
SECItem issuerMD5NameHash; /* we have them */
|
||||
SECItem issuerNameHash; /* an OCTET STRING */
|
||||
SECItem issuerKeyHash; /* an OCTET STRING */
|
||||
SECItem serialNumber; /* an INTEGER */
|
||||
SECItem issuerSHA1NameHash; /* keep other hashes around when */
|
||||
SECItem issuerMD5NameHash; /* we have them */
|
||||
SECItem issuerMD2NameHash;
|
||||
SECItem issuerSHA1KeyHash; /* keep other hashes around when */
|
||||
SECItem issuerMD5KeyHash; /* we have them */
|
||||
SECItem issuerSHA1KeyHash; /* keep other hashes around when */
|
||||
SECItem issuerMD5KeyHash; /* we have them */
|
||||
SECItem issuerMD2KeyHash;
|
||||
PLArenaPool *poolp;
|
||||
};
|
||||
|
@ -209,10 +206,10 @@ typedef enum {
|
|||
* type ocspResponseStatus.
|
||||
*/
|
||||
struct CERTOCSPResponseStr {
|
||||
PLArenaPool *arena; /* local; not part of encoding */
|
||||
SECItem responseStatus; /* an ENUMERATED, see above */
|
||||
ocspResponseStatus statusValue; /* local; not part of encoding */
|
||||
ocspResponseBytes *responseBytes; /* only when status is successful */
|
||||
PLArenaPool *arena; /* local; not part of encoding */
|
||||
SECItem responseStatus; /* an ENUMERATED, see above */
|
||||
ocspResponseStatus statusValue; /* local; not part of encoding */
|
||||
ocspResponseBytes *responseBytes; /* only when status is successful */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -230,12 +227,12 @@ struct CERTOCSPResponseStr {
|
|||
* response types, just add them to the union.
|
||||
*/
|
||||
struct ocspResponseBytesStr {
|
||||
SECItem responseType; /* an OBJECT IDENTIFIER */
|
||||
SECOidTag responseTypeTag; /* local; not part of encoding */
|
||||
SECItem response; /* an OCTET STRING */
|
||||
SECItem responseType; /* an OBJECT IDENTIFIER */
|
||||
SECOidTag responseTypeTag; /* local; not part of encoding */
|
||||
SECItem response; /* an OCTET STRING */
|
||||
union {
|
||||
ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
|
||||
} decodedResponse; /* local; not part of encoding */
|
||||
ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */
|
||||
} decodedResponse; /* local; not part of encoding */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -250,7 +247,7 @@ struct ocspResponseBytesStr {
|
|||
*/
|
||||
struct ocspBasicOCSPResponseStr {
|
||||
SECItem tbsResponseDataDER;
|
||||
ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
|
||||
ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
|
||||
ocspSignature responseSignature;
|
||||
};
|
||||
|
||||
|
@ -260,38 +257,38 @@ struct ocspBasicOCSPResponseStr {
|
|||
* (a per-certificate status).
|
||||
*/
|
||||
struct ocspResponseDataStr {
|
||||
SECItem version; /* an INTEGER */
|
||||
SECItem version; /* an INTEGER */
|
||||
SECItem derResponderID;
|
||||
ocspResponderID *responderID; /* local; not part of encoding */
|
||||
SECItem producedAt; /* a GeneralizedTime */
|
||||
ocspResponderID *responderID; /* local; not part of encoding */
|
||||
SECItem producedAt; /* a GeneralizedTime */
|
||||
CERTOCSPSingleResponse **responses;
|
||||
CERTCertExtension **responseExtensions;
|
||||
};
|
||||
|
||||
struct ocspResponderIDStr {
|
||||
CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */
|
||||
CERTOCSPResponderIDType responderIDType; /* local; not part of encoding */
|
||||
union {
|
||||
CERTName name; /* when ocspResponderID_byName */
|
||||
SECItem keyHash; /* when ocspResponderID_byKey */
|
||||
SECItem other; /* when ocspResponderID_other */
|
||||
CERTName name; /* when ocspResponderID_byName */
|
||||
SECItem keyHash; /* when ocspResponderID_byKey */
|
||||
SECItem other; /* when ocspResponderID_other */
|
||||
} responderIDValue;
|
||||
};
|
||||
|
||||
/*
|
||||
* The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
* routines, on creation only */
|
||||
CERTOCSPCertID *certID;
|
||||
SECItem derCertStatus;
|
||||
ocspCertStatus *certStatus; /* local; not part of encoding */
|
||||
SECItem thisUpdate; /* a GeneralizedTime */
|
||||
SECItem *nextUpdate; /* a GeneralizedTime */
|
||||
ocspCertStatus *certStatus; /* local; not part of encoding */
|
||||
SECItem thisUpdate; /* a GeneralizedTime */
|
||||
SECItem *nextUpdate; /* a GeneralizedTime */
|
||||
CERTCertExtension **singleExtensions;
|
||||
};
|
||||
|
||||
|
@ -313,10 +310,10 @@ struct CERTOCSPSingleResponseStr {
|
|||
*/
|
||||
|
||||
typedef enum {
|
||||
ocspCertStatus_good, /* cert is not revoked */
|
||||
ocspCertStatus_revoked, /* cert is revoked */
|
||||
ocspCertStatus_unknown, /* cert was unknown to the responder */
|
||||
ocspCertStatus_other /* status was not an expected value */
|
||||
ocspCertStatus_good, /* cert is not revoked */
|
||||
ocspCertStatus_revoked, /* cert is revoked */
|
||||
ocspCertStatus_unknown, /* cert was unknown to the responder */
|
||||
ocspCertStatus_other /* status was not an expected value */
|
||||
} ocspCertStatusType;
|
||||
|
||||
/*
|
||||
|
@ -327,13 +324,13 @@ typedef enum {
|
|||
* gives more detailed information.)
|
||||
*/
|
||||
struct ocspCertStatusStr {
|
||||
ocspCertStatusType certStatusType; /* local; not part of encoding */
|
||||
ocspCertStatusType certStatusType; /* local; not part of encoding */
|
||||
union {
|
||||
SECItem *goodInfo; /* when ocspCertStatus_good */
|
||||
ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
|
||||
SECItem *unknownInfo; /* when ocspCertStatus_unknown */
|
||||
SECItem *otherInfo; /* when ocspCertStatus_other */
|
||||
} certStatusInfo;
|
||||
SECItem *goodInfo; /* when ocspCertStatus_good */
|
||||
ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */
|
||||
SECItem *unknownInfo; /* when ocspCertStatus_unknown */
|
||||
SECItem *otherInfo; /* when ocspCertStatus_other */
|
||||
} certStatusInfo;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -341,8 +338,8 @@ struct ocspCertStatusStr {
|
|||
* was revoked and why.
|
||||
*/
|
||||
struct ocspRevokedInfoStr {
|
||||
SECItem revocationTime; /* a GeneralizedTime */
|
||||
SECItem *revocationReason; /* a CRLReason; ignored for now */
|
||||
SECItem revocationTime; /* a GeneralizedTime */
|
||||
SECItem *revocationReason; /* a CRLReason; ignored for now */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -353,7 +350,7 @@ struct ocspRevokedInfoStr {
|
|||
*/
|
||||
struct ocspServiceLocatorStr {
|
||||
CERTName *issuer;
|
||||
SECItem locator; /* DER encoded authInfoAccess extension from cert */
|
||||
SECItem locator; /* DER encoded authInfoAccess extension from cert */
|
||||
};
|
||||
|
||||
#endif /* _OCSPTI_H_ */
|
||||
|
|
|
@ -12,203 +12,201 @@
|
|||
SEC_ASN1_MKSUB(SEC_AnyTemplate)
|
||||
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
|
||||
|
||||
extern void PrepareBitStringForEncoding (SECItem *bitMap, SECItem *value);
|
||||
extern void PrepareBitStringForEncoding(SECItem *bitMap, SECItem *value);
|
||||
|
||||
static const SEC_ASN1Template FullNameTemplate[] = {
|
||||
{SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
||||
offsetof (CRLDistributionPoint,derFullName),
|
||||
CERT_GeneralNamesTemplate}
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
||||
offsetof(CRLDistributionPoint, derFullName),
|
||||
CERT_GeneralNamesTemplate }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template RelativeNameTemplate[] = {
|
||||
{SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
||||
offsetof (CRLDistributionPoint,distPoint.relativeName),
|
||||
CERT_RDNTemplate}
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
||||
offsetof(CRLDistributionPoint, distPoint.relativeName),
|
||||
CERT_RDNTemplate }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template DistributionPointNameTemplate[] = {
|
||||
{ SEC_ASN1_CHOICE,
|
||||
offsetof(CRLDistributionPoint, distPointType), NULL,
|
||||
sizeof(CRLDistributionPoint) },
|
||||
offsetof(CRLDistributionPoint, distPointType), NULL,
|
||||
sizeof(CRLDistributionPoint) },
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0,
|
||||
offsetof (CRLDistributionPoint, derFullName),
|
||||
CERT_GeneralNamesTemplate, generalName },
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
||||
offsetof (CRLDistributionPoint, distPoint.relativeName),
|
||||
CERT_RDNTemplate, relativeDistinguishedName },
|
||||
offsetof(CRLDistributionPoint, derFullName),
|
||||
CERT_GeneralNamesTemplate, generalName },
|
||||
{ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1,
|
||||
offsetof(CRLDistributionPoint, distPoint.relativeName),
|
||||
CERT_RDNTemplate, relativeDistinguishedName },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template CRLDistributionPointTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
|
||||
offsetof(CRLDistributionPoint,derDistPoint),
|
||||
SEC_ASN1_SUB(SEC_AnyTemplate)},
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
||||
offsetof(CRLDistributionPoint,bitsmap),
|
||||
SEC_ASN1_SUB(SEC_BitStringTemplate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||
SEC_ASN1_CONSTRUCTED | 2,
|
||||
offsetof(CRLDistributionPoint, derCrlIssuer),
|
||||
CERT_GeneralNamesTemplate},
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||
SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | SEC_ASN1_XTRN | 0,
|
||||
offsetof(CRLDistributionPoint, derDistPoint),
|
||||
SEC_ASN1_SUB(SEC_AnyTemplate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
|
||||
offsetof(CRLDistributionPoint, bitsmap),
|
||||
SEC_ASN1_SUB(SEC_BitStringTemplate) },
|
||||
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
|
||||
SEC_ASN1_CONSTRUCTED | 2,
|
||||
offsetof(CRLDistributionPoint, derCrlIssuer),
|
||||
CERT_GeneralNamesTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = {
|
||||
{SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate}
|
||||
{ SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate }
|
||||
};
|
||||
|
||||
SECStatus
|
||||
CERT_EncodeCRLDistributionPoints (PLArenaPool *arena,
|
||||
CERTCrlDistributionPoints *value,
|
||||
SECItem *derValue)
|
||||
CERT_EncodeCRLDistributionPoints(PLArenaPool *arena,
|
||||
CERTCrlDistributionPoints *value,
|
||||
SECItem *derValue)
|
||||
{
|
||||
CRLDistributionPoint **pointList, *point;
|
||||
PLArenaPool *ourPool = NULL;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
PORT_Assert (derValue);
|
||||
PORT_Assert (value && value->distPoints);
|
||||
PORT_Assert(derValue);
|
||||
PORT_Assert(value && value->distPoints);
|
||||
|
||||
do {
|
||||
ourPool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (ourPool == NULL) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
pointList = value->distPoints;
|
||||
while (*pointList) {
|
||||
point = *pointList;
|
||||
point->derFullName = NULL;
|
||||
point->derDistPoint.data = NULL;
|
||||
ourPool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (ourPool == NULL) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (point->distPointType) {
|
||||
case generalName:
|
||||
point->derFullName = cert_EncodeGeneralNames
|
||||
(ourPool, point->distPoint.fullName);
|
||||
|
||||
if (!point->derFullName ||
|
||||
!SEC_ASN1EncodeItem (ourPool, &point->derDistPoint,
|
||||
point, FullNameTemplate))
|
||||
rv = SECFailure;
|
||||
break;
|
||||
pointList = value->distPoints;
|
||||
while (*pointList) {
|
||||
point = *pointList;
|
||||
point->derFullName = NULL;
|
||||
point->derDistPoint.data = NULL;
|
||||
|
||||
case relativeDistinguishedName:
|
||||
if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
|
||||
point, RelativeNameTemplate))
|
||||
rv = SECFailure;
|
||||
break;
|
||||
switch (point->distPointType) {
|
||||
case generalName:
|
||||
point->derFullName = cert_EncodeGeneralNames(ourPool, point->distPoint.fullName);
|
||||
|
||||
default:
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
if (!point->derFullName ||
|
||||
!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
|
||||
point, FullNameTemplate))
|
||||
rv = SECFailure;
|
||||
break;
|
||||
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
case relativeDistinguishedName:
|
||||
if (!SEC_ASN1EncodeItem(ourPool, &point->derDistPoint,
|
||||
point, RelativeNameTemplate))
|
||||
rv = SECFailure;
|
||||
break;
|
||||
|
||||
if (point->reasons.data)
|
||||
PrepareBitStringForEncoding (&point->bitsmap, &point->reasons);
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
if (point->crlIssuer) {
|
||||
point->derCrlIssuer = cert_EncodeGeneralNames
|
||||
(ourPool, point->crlIssuer);
|
||||
if (!point->derCrlIssuer) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++pointList;
|
||||
}
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
if (!SEC_ASN1EncodeItem(arena, derValue, value,
|
||||
CERTCRLDistributionPointsTemplate)) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
|
||||
if (point->reasons.data)
|
||||
PrepareBitStringForEncoding(&point->bitsmap, &point->reasons);
|
||||
|
||||
if (point->crlIssuer) {
|
||||
point->derCrlIssuer = cert_EncodeGeneralNames(ourPool, point->crlIssuer);
|
||||
if (!point->derCrlIssuer) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++pointList;
|
||||
}
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
if (!SEC_ASN1EncodeItem(arena, derValue, value,
|
||||
CERTCRLDistributionPointsTemplate)) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
} while (0);
|
||||
PORT_FreeArena (ourPool, PR_FALSE);
|
||||
PORT_FreeArena(ourPool, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
CERTCrlDistributionPoints *
|
||||
CERT_DecodeCRLDistributionPoints (PLArenaPool *arena, SECItem *encodedValue)
|
||||
CERT_DecodeCRLDistributionPoints(PLArenaPool *arena, SECItem *encodedValue)
|
||||
{
|
||||
CERTCrlDistributionPoints *value = NULL;
|
||||
CRLDistributionPoint **pointList, *point;
|
||||
SECStatus rv = SECSuccess;
|
||||
SECItem newEncodedValue;
|
||||
CERTCrlDistributionPoints *value = NULL;
|
||||
CRLDistributionPoint **pointList, *point;
|
||||
SECStatus rv = SECSuccess;
|
||||
SECItem newEncodedValue;
|
||||
|
||||
PORT_Assert (arena);
|
||||
do {
|
||||
value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
|
||||
if (value == NULL) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
PORT_Assert(arena);
|
||||
do {
|
||||
value = PORT_ArenaZNew(arena, CERTCrlDistributionPoints);
|
||||
if (value == NULL) {
|
||||
rv = SECFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
break;
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(arena, &value->distPoints,
|
||||
CERTCRLDistributionPointsTemplate, &newEncodedValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
rv = SEC_QuickDERDecodeItem(arena, &value->distPoints,
|
||||
CERTCRLDistributionPointsTemplate, &newEncodedValue);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
|
||||
pointList = value->distPoints;
|
||||
while (NULL != (point = *pointList)) {
|
||||
pointList = value->distPoints;
|
||||
while (NULL != (point = *pointList)) {
|
||||
|
||||
/* get the data if the distributionPointName is not omitted */
|
||||
if (point->derDistPoint.data != NULL) {
|
||||
rv = SEC_QuickDERDecodeItem(arena, point,
|
||||
DistributionPointNameTemplate, &(point->derDistPoint));
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
/* get the data if the distributionPointName is not omitted */
|
||||
if (point->derDistPoint.data != NULL) {
|
||||
rv = SEC_QuickDERDecodeItem(arena, point,
|
||||
DistributionPointNameTemplate, &(point->derDistPoint));
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
|
||||
switch (point->distPointType) {
|
||||
case generalName:
|
||||
point->distPoint.fullName =
|
||||
cert_DecodeGeneralNames(arena, point->derFullName);
|
||||
rv = point->distPoint.fullName ? SECSuccess : SECFailure;
|
||||
break;
|
||||
switch (point->distPointType) {
|
||||
case generalName:
|
||||
point->distPoint.fullName =
|
||||
cert_DecodeGeneralNames(arena, point->derFullName);
|
||||
rv = point->distPoint.fullName ? SECSuccess : SECFailure;
|
||||
break;
|
||||
|
||||
case relativeDistinguishedName:
|
||||
break;
|
||||
case relativeDistinguishedName:
|
||||
break;
|
||||
|
||||
default:
|
||||
PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
} /* end switch */
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
} /* end if */
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
|
||||
rv = SECFailure;
|
||||
break;
|
||||
} /* end switch */
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
} /* end if */
|
||||
|
||||
/* Get the reason code if it's not omitted in the encoding */
|
||||
if (point->bitsmap.data != NULL) {
|
||||
SECItem bitsmap = point->bitsmap;
|
||||
DER_ConvertBitString(&bitsmap);
|
||||
rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
/* Get the reason code if it's not omitted in the encoding */
|
||||
if (point->bitsmap.data != NULL) {
|
||||
SECItem bitsmap = point->bitsmap;
|
||||
DER_ConvertBitString(&bitsmap);
|
||||
rv = SECITEM_CopyItem(arena, &point->reasons, &bitsmap);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the crl issuer name if it's not omitted in the encoding */
|
||||
if (point->derCrlIssuer != NULL) {
|
||||
point->crlIssuer = cert_DecodeGeneralNames(arena,
|
||||
point->derCrlIssuer);
|
||||
if (!point->crlIssuer)
|
||||
break;
|
||||
}
|
||||
++pointList;
|
||||
} /* end while points remain */
|
||||
} while (0);
|
||||
return (rv == SECSuccess ? value : NULL);
|
||||
/* Get the crl issuer name if it's not omitted in the encoding */
|
||||
if (point->derCrlIssuer != NULL) {
|
||||
point->crlIssuer = cert_DecodeGeneralNames(arena,
|
||||
point->derCrlIssuer);
|
||||
if (!point->crlIssuer)
|
||||
break;
|
||||
}
|
||||
++pointList;
|
||||
} /* end while points remain */
|
||||
} while (0);
|
||||
return (rv == SECSuccess ? value : NULL);
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
* builtins/anchor.c
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "builtins.h"
|
||||
|
||||
#define MODULE_NAME builtins
|
||||
#define INSTANCE_NAME (NSSCKMDInstance *)&nss_builtins_mdInstance
|
||||
#define INSTANCE_NAME (NSSCKMDInstance *) & nss_builtins_mdInstance
|
||||
#include "nssck.api"
|
||||
|
|
|
@ -14,258 +14,250 @@
|
|||
*/
|
||||
|
||||
struct builtinsFOStr {
|
||||
NSSArena *arena;
|
||||
CK_ULONG n;
|
||||
CK_ULONG i;
|
||||
builtinsInternalObject **objs;
|
||||
NSSArena *arena;
|
||||
CK_ULONG n;
|
||||
CK_ULONG i;
|
||||
builtinsInternalObject **objs;
|
||||
};
|
||||
|
||||
static void
|
||||
builtins_mdFindObjects_Final
|
||||
(
|
||||
NSSCKMDFindObjects *mdFindObjects,
|
||||
NSSCKFWFindObjects *fwFindObjects,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance
|
||||
)
|
||||
builtins_mdFindObjects_Final(
|
||||
NSSCKMDFindObjects *mdFindObjects,
|
||||
NSSCKFWFindObjects *fwFindObjects,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance)
|
||||
{
|
||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
||||
NSSArena *arena = fo->arena;
|
||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
||||
NSSArena *arena = fo->arena;
|
||||
|
||||
nss_ZFreeIf(fo->objs);
|
||||
nss_ZFreeIf(fo);
|
||||
nss_ZFreeIf(mdFindObjects);
|
||||
if ((NSSArena *)NULL != arena) {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
nss_ZFreeIf(fo->objs);
|
||||
nss_ZFreeIf(fo);
|
||||
nss_ZFreeIf(mdFindObjects);
|
||||
if ((NSSArena *)NULL != arena) {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
static NSSCKMDObject *
|
||||
builtins_mdFindObjects_Next
|
||||
(
|
||||
NSSCKMDFindObjects *mdFindObjects,
|
||||
NSSCKFWFindObjects *fwFindObjects,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
NSSArena *arena,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdFindObjects_Next(
|
||||
NSSCKMDFindObjects *mdFindObjects,
|
||||
NSSCKFWFindObjects *fwFindObjects,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
NSSArena *arena,
|
||||
CK_RV *pError)
|
||||
{
|
||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
||||
builtinsInternalObject *io;
|
||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
|
||||
builtinsInternalObject *io;
|
||||
|
||||
if( fo->i == fo->n ) {
|
||||
*pError = CKR_OK;
|
||||
return (NSSCKMDObject *)NULL;
|
||||
}
|
||||
if (fo->i == fo->n) {
|
||||
*pError = CKR_OK;
|
||||
return (NSSCKMDObject *)NULL;
|
||||
}
|
||||
|
||||
io = fo->objs[ fo->i ];
|
||||
fo->i++;
|
||||
io = fo->objs[fo->i];
|
||||
fo->i++;
|
||||
|
||||
return nss_builtins_CreateMDObject(arena, io, pError);
|
||||
return nss_builtins_CreateMDObject(arena, io, pError);
|
||||
}
|
||||
|
||||
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;
|
||||
int len = 0;
|
||||
|
||||
if (*src ++ != 2) {
|
||||
return 0;
|
||||
if (*src++ != 2) {
|
||||
return 0;
|
||||
}
|
||||
len = *src++;
|
||||
if (len & 0x80) {
|
||||
int count = len & 0x7f;
|
||||
len =0;
|
||||
int count = len & 0x7f;
|
||||
len = 0;
|
||||
|
||||
if (count+2 > size) {
|
||||
return 0;
|
||||
}
|
||||
while (count-- > 0) {
|
||||
len = (len << 8) | *src++;
|
||||
}
|
||||
if (count + 2 > size) {
|
||||
return 0;
|
||||
}
|
||||
while (count-- > 0) {
|
||||
len = (len << 8) | *src++;
|
||||
}
|
||||
}
|
||||
if (len + (src-start) != size) {
|
||||
return 0;
|
||||
if (len + (src - start) != size) {
|
||||
return 0;
|
||||
}
|
||||
*dest = src;
|
||||
return len;
|
||||
}
|
||||
|
||||
static CK_BBOOL
|
||||
builtins_attrmatch
|
||||
(
|
||||
CK_ATTRIBUTE_PTR a,
|
||||
const NSSItem *b
|
||||
)
|
||||
builtins_attrmatch(
|
||||
CK_ATTRIBUTE_PTR a,
|
||||
const NSSItem *b)
|
||||
{
|
||||
PRBool prb;
|
||||
PRBool prb;
|
||||
|
||||
if( a->ulValueLen != b->size ) {
|
||||
/* match a decoded serial number */
|
||||
if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
|
||||
int len;
|
||||
unsigned char *data = NULL;
|
||||
if (a->ulValueLen != b->size) {
|
||||
/* match a decoded serial number */
|
||||
if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
|
||||
int len;
|
||||
unsigned char *data = NULL;
|
||||
|
||||
len = builtins_derUnwrapInt(b->data,b->size,&data);
|
||||
if (data &&
|
||||
(len == a->ulValueLen) &&
|
||||
nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
|
||||
return CK_TRUE;
|
||||
}
|
||||
len = builtins_derUnwrapInt(b->data, b->size, &data);
|
||||
if (data &&
|
||||
(len == a->ulValueLen) &&
|
||||
nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
|
||||
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 ) {
|
||||
return CK_TRUE;
|
||||
} else {
|
||||
return CK_FALSE;
|
||||
}
|
||||
if (PR_TRUE == prb) {
|
||||
return CK_TRUE;
|
||||
}
|
||||
else {
|
||||
return CK_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static CK_BBOOL
|
||||
builtins_match
|
||||
(
|
||||
CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulAttributeCount,
|
||||
builtinsInternalObject *o
|
||||
)
|
||||
builtins_match(
|
||||
CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulAttributeCount,
|
||||
builtinsInternalObject *o)
|
||||
{
|
||||
CK_ULONG i;
|
||||
CK_ULONG i;
|
||||
|
||||
for( i = 0; i < ulAttributeCount; i++ ) {
|
||||
CK_ULONG j;
|
||||
for (i = 0; i < ulAttributeCount; i++) {
|
||||
CK_ULONG j;
|
||||
|
||||
for( j = 0; j < o->n; j++ ) {
|
||||
if( o->types[j] == pTemplate[i].type ) {
|
||||
if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) {
|
||||
return CK_FALSE;
|
||||
} else {
|
||||
break;
|
||||
for (j = 0; j < o->n; j++) {
|
||||
if (o->types[j] == pTemplate[i].type) {
|
||||
if (CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j])) {
|
||||
return CK_FALSE;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == o->n) {
|
||||
/* Loop ran to the end: no matching attribute */
|
||||
return CK_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( j == o->n ) {
|
||||
/* Loop ran to the end: no matching attribute */
|
||||
return CK_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Every attribute passed */
|
||||
return CK_TRUE;
|
||||
/* Every attribute passed */
|
||||
return CK_TRUE;
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCKMDFindObjects *
|
||||
nss_builtins_FindObjectsInit
|
||||
(
|
||||
NSSCKFWSession *fwSession,
|
||||
CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulAttributeCount,
|
||||
CK_RV *pError
|
||||
)
|
||||
nss_builtins_FindObjectsInit(
|
||||
NSSCKFWSession *fwSession,
|
||||
CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulAttributeCount,
|
||||
CK_RV *pError)
|
||||
{
|
||||
/* This could be made more efficient. I'm rather rushed. */
|
||||
NSSArena *arena;
|
||||
NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
|
||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
|
||||
/* This could be made more efficient. I'm rather rushed. */
|
||||
NSSArena *arena;
|
||||
NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
|
||||
struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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
|
||||
* array later if the number of matches exceeds STACK_BUF_LENGTH.
|
||||
*/
|
||||
#define STACK_BUF_LENGTH 1
|
||||
builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
|
||||
builtinsInternalObject **temp = stackTemp;
|
||||
PRBool tempIsHeapAllocated = PR_FALSE;
|
||||
PRUint32 i;
|
||||
#define STACK_BUF_LENGTH 1
|
||||
builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
|
||||
builtinsInternalObject **temp = stackTemp;
|
||||
PRBool tempIsHeapAllocated = PR_FALSE;
|
||||
PRUint32 i;
|
||||
|
||||
arena = NSSArena_Create();
|
||||
if( (NSSArena *)NULL == arena ) {
|
||||
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++;
|
||||
arena = NSSArena_Create();
|
||||
if ((NSSArena *)NULL == arena) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
|
||||
fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
|
||||
if( (builtinsInternalObject **)NULL == fo->objs ) {
|
||||
*pError = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
rv = nss_ZNEW(arena, NSSCKMDFindObjects);
|
||||
if ((NSSCKMDFindObjects *)NULL == rv) {
|
||||
*pError = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
(void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
|
||||
if (tempIsHeapAllocated) {
|
||||
nss_ZFreeIf(temp);
|
||||
temp = (builtinsInternalObject **)NULL;
|
||||
}
|
||||
fo = nss_ZNEW(arena, struct builtinsFOStr);
|
||||
if ((struct builtinsFOStr *)NULL == fo) {
|
||||
*pError = CKR_HOST_MEMORY;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return rv;
|
||||
fo->arena = arena;
|
||||
/* fo->n and fo->i are already zero */
|
||||
|
||||
loser:
|
||||
if (tempIsHeapAllocated) {
|
||||
nss_ZFreeIf(temp);
|
||||
}
|
||||
nss_ZFreeIf(fo);
|
||||
nss_ZFreeIf(rv);
|
||||
if ((NSSArena *)NULL != arena) {
|
||||
NSSArena_Destroy(arena);
|
||||
}
|
||||
return (NSSCKMDFindObjects *)NULL;
|
||||
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);
|
||||
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
|
||||
*
|
||||
* This file implements the NSSCKMDInstance object for the
|
||||
* This file implements the NSSCKMDInstance object for the
|
||||
* "builtin objects" cryptoki module.
|
||||
*/
|
||||
|
||||
|
@ -16,84 +16,72 @@
|
|||
*/
|
||||
|
||||
static CK_ULONG
|
||||
builtins_mdInstance_GetNSlots
|
||||
(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdInstance_GetNSlots(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError)
|
||||
{
|
||||
return (CK_ULONG)1;
|
||||
return (CK_ULONG)1;
|
||||
}
|
||||
|
||||
static CK_VERSION
|
||||
builtins_mdInstance_GetCryptokiVersion
|
||||
(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance
|
||||
)
|
||||
builtins_mdInstance_GetCryptokiVersion(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance)
|
||||
{
|
||||
return nss_builtins_CryptokiVersion;
|
||||
return nss_builtins_CryptokiVersion;
|
||||
}
|
||||
|
||||
static NSSUTF8 *
|
||||
builtins_mdInstance_GetManufacturerID
|
||||
(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdInstance_GetManufacturerID(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError)
|
||||
{
|
||||
return (NSSUTF8 *)nss_builtins_ManufacturerID;
|
||||
return (NSSUTF8 *)nss_builtins_ManufacturerID;
|
||||
}
|
||||
|
||||
static NSSUTF8 *
|
||||
builtins_mdInstance_GetLibraryDescription
|
||||
(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdInstance_GetLibraryDescription(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError)
|
||||
{
|
||||
return (NSSUTF8 *)nss_builtins_LibraryDescription;
|
||||
return (NSSUTF8 *)nss_builtins_LibraryDescription;
|
||||
}
|
||||
|
||||
static CK_VERSION
|
||||
builtins_mdInstance_GetLibraryVersion
|
||||
(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance
|
||||
)
|
||||
builtins_mdInstance_GetLibraryVersion(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance)
|
||||
{
|
||||
#define NSS_VERSION_VARIABLE __nss_builtins_version
|
||||
#include "verref.h"
|
||||
return nss_builtins_LibraryVersion;
|
||||
return nss_builtins_LibraryVersion;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
builtins_mdInstance_GetSlots
|
||||
(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
NSSCKMDSlot *slots[]
|
||||
)
|
||||
builtins_mdInstance_GetSlots(
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
NSSCKMDSlot *slots[])
|
||||
{
|
||||
slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
|
||||
return CKR_OK;
|
||||
slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
const NSSCKMDInstance
|
||||
nss_builtins_mdInstance = {
|
||||
(void *)NULL, /* etc */
|
||||
NULL, /* Initialize */
|
||||
NULL, /* Finalize */
|
||||
builtins_mdInstance_GetNSlots,
|
||||
builtins_mdInstance_GetCryptokiVersion,
|
||||
builtins_mdInstance_GetManufacturerID,
|
||||
builtins_mdInstance_GetLibraryDescription,
|
||||
builtins_mdInstance_GetLibraryVersion,
|
||||
NULL, /* ModuleHandlesSessionObjects -- defaults to false */
|
||||
builtins_mdInstance_GetSlots,
|
||||
NULL, /* WaitForSlotEvent */
|
||||
(void *)NULL /* null terminator */
|
||||
};
|
||||
nss_builtins_mdInstance = {
|
||||
(void *)NULL, /* etc */
|
||||
NULL, /* Initialize */
|
||||
NULL, /* Finalize */
|
||||
builtins_mdInstance_GetNSlots,
|
||||
builtins_mdInstance_GetCryptokiVersion,
|
||||
builtins_mdInstance_GetManufacturerID,
|
||||
builtins_mdInstance_GetLibraryDescription,
|
||||
builtins_mdInstance_GetLibraryVersion,
|
||||
NULL, /* ModuleHandlesSessionObjects -- defaults to false */
|
||||
builtins_mdInstance_GetSlots,
|
||||
NULL, /* WaitForSlotEvent */
|
||||
(void *)NULL /* null terminator */
|
||||
};
|
||||
|
|
|
@ -24,199 +24,183 @@
|
|||
*/
|
||||
|
||||
static CK_RV
|
||||
builtins_mdObject_Destroy
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance
|
||||
)
|
||||
builtins_mdObject_Destroy(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance)
|
||||
{
|
||||
return CKR_SESSION_READ_ONLY;
|
||||
return CKR_SESSION_READ_ONLY;
|
||||
}
|
||||
|
||||
static CK_BBOOL
|
||||
builtins_mdObject_IsTokenObject
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance
|
||||
)
|
||||
builtins_mdObject_IsTokenObject(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance)
|
||||
{
|
||||
return CK_TRUE;
|
||||
return CK_TRUE;
|
||||
}
|
||||
|
||||
static CK_ULONG
|
||||
builtins_mdObject_GetAttributeCount
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdObject_GetAttributeCount(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError)
|
||||
{
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
return io->n;
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
return io->n;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
builtins_mdObject_GetAttributeTypes
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_TYPE_PTR typeArray,
|
||||
CK_ULONG ulCount
|
||||
)
|
||||
builtins_mdObject_GetAttributeTypes(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_TYPE_PTR typeArray,
|
||||
CK_ULONG ulCount)
|
||||
{
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
|
||||
if( io->n != ulCount ) {
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
if (io->n != ulCount) {
|
||||
return CKR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
for( i = 0; i < io->n; i++ ) {
|
||||
typeArray[i] = io->types[i];
|
||||
}
|
||||
for (i = 0; i < io->n; i++) {
|
||||
typeArray[i] = io->types[i];
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_ULONG
|
||||
builtins_mdObject_GetAttributeSize
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_TYPE attribute,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdObject_GetAttributeSize(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_TYPE attribute,
|
||||
CK_RV *pError)
|
||||
{
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
|
||||
for( i = 0; i < io->n; i++ ) {
|
||||
if( attribute == io->types[i] ) {
|
||||
return (CK_ULONG)(io->items[i].size);
|
||||
for (i = 0; i < io->n; i++) {
|
||||
if (attribute == io->types[i]) {
|
||||
return (CK_ULONG)(io->items[i].size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
return 0;
|
||||
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NSSCKFWItem
|
||||
builtins_mdObject_GetAttribute
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_TYPE attribute,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdObject_GetAttribute(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_TYPE attribute,
|
||||
CK_RV *pError)
|
||||
{
|
||||
NSSCKFWItem mdItem;
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
NSSCKFWItem mdItem;
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
|
||||
mdItem.needsFreeing = PR_FALSE;
|
||||
mdItem.item = (NSSItem*) NULL;
|
||||
mdItem.needsFreeing = PR_FALSE;
|
||||
mdItem.item = (NSSItem *)NULL;
|
||||
|
||||
for( i = 0; i < io->n; i++ ) {
|
||||
if( attribute == io->types[i] ) {
|
||||
mdItem.item = (NSSItem*) &io->items[i];
|
||||
return mdItem;
|
||||
for (i = 0; i < io->n; i++) {
|
||||
if (attribute == io->types[i]) {
|
||||
mdItem.item = (NSSItem *)&io->items[i];
|
||||
return mdItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
return mdItem;
|
||||
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
return mdItem;
|
||||
}
|
||||
|
||||
static CK_ULONG
|
||||
builtins_mdObject_GetObjectSize
|
||||
(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdObject_GetObjectSize(
|
||||
NSSCKMDObject *mdObject,
|
||||
NSSCKFWObject *fwObject,
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_RV *pError)
|
||||
{
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
CK_ULONG rv = sizeof(CK_ULONG);
|
||||
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
|
||||
CK_ULONG i;
|
||||
CK_ULONG rv = sizeof(CK_ULONG);
|
||||
|
||||
for( i = 0; i < io->n; i++ ) {
|
||||
rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
|
||||
}
|
||||
for (i = 0; i < io->n; i++) {
|
||||
rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const NSSCKMDObject
|
||||
builtins_prototype_mdObject = {
|
||||
(void *)NULL, /* etc */
|
||||
NULL, /* Finalize */
|
||||
builtins_mdObject_Destroy,
|
||||
builtins_mdObject_IsTokenObject,
|
||||
builtins_mdObject_GetAttributeCount,
|
||||
builtins_mdObject_GetAttributeTypes,
|
||||
builtins_mdObject_GetAttributeSize,
|
||||
builtins_mdObject_GetAttribute,
|
||||
NULL, /* FreeAttribute */
|
||||
NULL, /* SetAttribute */
|
||||
builtins_mdObject_GetObjectSize,
|
||||
(void *)NULL /* null terminator */
|
||||
};
|
||||
builtins_prototype_mdObject = {
|
||||
(void *)NULL, /* etc */
|
||||
NULL, /* Finalize */
|
||||
builtins_mdObject_Destroy,
|
||||
builtins_mdObject_IsTokenObject,
|
||||
builtins_mdObject_GetAttributeCount,
|
||||
builtins_mdObject_GetAttributeTypes,
|
||||
builtins_mdObject_GetAttributeSize,
|
||||
builtins_mdObject_GetAttribute,
|
||||
NULL, /* FreeAttribute */
|
||||
NULL, /* SetAttribute */
|
||||
builtins_mdObject_GetObjectSize,
|
||||
(void *)NULL /* null terminator */
|
||||
};
|
||||
|
||||
NSS_IMPLEMENT NSSCKMDObject *
|
||||
nss_builtins_CreateMDObject
|
||||
(
|
||||
NSSArena *arena,
|
||||
builtinsInternalObject *io,
|
||||
CK_RV *pError
|
||||
)
|
||||
nss_builtins_CreateMDObject(
|
||||
NSSArena *arena,
|
||||
builtinsInternalObject *io,
|
||||
CK_RV *pError)
|
||||
{
|
||||
if ( (void*)NULL == io->mdObject.etc) {
|
||||
(void) nsslibc_memcpy(&io->mdObject,&builtins_prototype_mdObject,
|
||||
sizeof(builtins_prototype_mdObject));
|
||||
io->mdObject.etc = (void *)io;
|
||||
}
|
||||
if ((void *)NULL == io->mdObject.etc) {
|
||||
(void)nsslibc_memcpy(&io->mdObject, &builtins_prototype_mdObject,
|
||||
sizeof(builtins_prototype_mdObject));
|
||||
io->mdObject.etc = (void *)io;
|
||||
}
|
||||
|
||||
return &io->mdObject;
|
||||
return &io->mdObject;
|
||||
}
|
||||
|
|
|
@ -7,69 +7,65 @@
|
|||
/*
|
||||
* builtins/session.c
|
||||
*
|
||||
* This file implements the NSSCKMDSession object for the
|
||||
* This file implements the NSSCKMDSession object for the
|
||||
* "builtin objects" cryptoki module.
|
||||
*/
|
||||
|
||||
static NSSCKMDFindObjects *
|
||||
builtins_mdSession_FindObjectsInit
|
||||
(
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulAttributeCount,
|
||||
CK_RV *pError
|
||||
)
|
||||
builtins_mdSession_FindObjectsInit(
|
||||
NSSCKMDSession *mdSession,
|
||||
NSSCKFWSession *fwSession,
|
||||
NSSCKMDToken *mdToken,
|
||||
NSSCKFWToken *fwToken,
|
||||
NSSCKMDInstance *mdInstance,
|
||||
NSSCKFWInstance *fwInstance,
|
||||
CK_ATTRIBUTE_PTR pTemplate,
|
||||
CK_ULONG ulAttributeCount,
|
||||
CK_RV *pError)
|
||||
{
|
||||
return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
|
||||
return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
|
||||
}
|
||||
|
||||
NSS_IMPLEMENT NSSCKMDSession *
|
||||
nss_builtins_CreateSession
|
||||
(
|
||||
NSSCKFWSession *fwSession,
|
||||
CK_RV *pError
|
||||
)
|
||||
nss_builtins_CreateSession(
|
||||
NSSCKFWSession *fwSession,
|
||||
CK_RV *pError)
|
||||
{
|
||||
NSSArena *arena;
|
||||
NSSCKMDSession *rv;
|
||||
NSSArena *arena;
|
||||
NSSCKMDSession *rv;
|
||||
|
||||
arena = NSSCKFWSession_GetArena(fwSession, pError);
|
||||
if( (NSSArena *)NULL == arena ) {
|
||||
return (NSSCKMDSession *)NULL;
|
||||
}
|
||||
arena = NSSCKFWSession_GetArena(fwSession, pError);
|
||||
if ((NSSArena *)NULL == arena) {
|
||||
return (NSSCKMDSession *)NULL;
|
||||
}
|
||||
|
||||
rv = nss_ZNEW(arena, NSSCKMDSession);
|
||||
if( (NSSCKMDSession *)NULL == rv ) {
|
||||
*pError = CKR_HOST_MEMORY;
|
||||
return (NSSCKMDSession *)NULL;
|
||||
}
|
||||
rv = nss_ZNEW(arena, NSSCKMDSession);
|
||||
if ((NSSCKMDSession *)NULL == rv) {
|
||||
*pError = CKR_HOST_MEMORY;
|
||||
return (NSSCKMDSession *)NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* rv was zeroed when allocated, so we only
|
||||
* need to set the non-zero members.
|
||||
*/
|
||||
/*
|
||||
* rv was zeroed when allocated, so we only
|
||||
* need to set the non-zero members.
|
||||
*/
|
||||
|
||||
rv->etc = (void *)fwSession;
|
||||
/* rv->Close */
|
||||
/* rv->GetDeviceError */
|
||||
/* rv->Login */
|
||||
/* rv->Logout */
|
||||
/* rv->InitPIN */
|
||||
/* rv->SetPIN */
|
||||
/* rv->GetOperationStateLen */
|
||||
/* rv->GetOperationState */
|
||||
/* rv->SetOperationState */
|
||||
/* rv->CreateObject */
|
||||
/* rv->CopyObject */
|
||||
rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
|
||||
/* rv->SeedRandom */
|
||||
/* rv->GetRandom */
|
||||
/* rv->null */
|
||||
rv->etc = (void *)fwSession;
|
||||
/* rv->Close */
|
||||
/* rv->GetDeviceError */
|
||||
/* rv->Login */
|
||||
/* rv->Logout */
|
||||
/* rv->InitPIN */
|
||||
/* rv->SetPIN */
|
||||
/* rv->GetOperationStateLen */
|
||||
/* rv->GetOperationState */
|
||||
/* rv->SetOperationState */
|
||||
/* rv->CreateObject */
|
||||
/* rv->CopyObject */
|
||||
rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
|
||||
/* rv->SeedRandom */
|
||||
/* rv->GetRandom */
|
||||
/* rv->null */
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче